import { useCallback, useMemo, useState } from 'react';
import { FormProvider, useForm, useWatch } from 'react-hook-form';

import { useDrawerV2 } from '@material-hu/hooks/useDrawerV2';
import Stack from '@material-hu/mui/Stack';

import Accordion from '@material-hu/components/design-system/Accordion';
import Alert from '@material-hu/components/design-system/Alert';
import CardContainer from '@material-hu/components/design-system/CardContainer';
import FormCheckbox from '@material-hu/components/design-system/Checkbox/Checkbox/form';
import Title from '@material-hu/components/design-system/Title';

import { type SegmentationType } from 'src/types/user';
import { useLokaliseTranslation } from 'src/utils/i18n';

import FormSegmentationGroupSelector from '../FormInputs/FormSegmentationGroupSelector';

import { CollaboratorsAccordion } from './components/CollaboratorsAccordion';
import { APPROVAL_STEPS_FORM_FIELDS, generateStepId } from './constants';
import {
  type ApprovalStep,
  type ApprovalStepInput,
  type ApprovalStepsListProps,
  type ApprovalStepUser,
} from './types';
import { approvalStepsToInput } from './useEnrichedApprovalSteps';

type SegmentationData = {
  id: number;
  usersCount: number;
};

type UseApprovalStepDrawerProps = {
  stepIndex?: number;
  setApprovalUsers: (value: ApprovalStep[]) => void;
  approvalUsers: ApprovalStep[];
  usersService: ApprovalStepsListProps['approvalStepDrawerProps']['usersService'];
  drawerProps?: {
    onSave?: (
      updatedApprovalUsers: ApprovalStepInput[],
      action?: 'create' | 'edit',
    ) => void;
  };
};

const DEFAULT_STEP_VALUES: Pick<
  ApprovalStep,
  | 'boss'
  | 'secondBoss'
  | 'designatedReviewer'
  | 'itemIds'
  | 'users'
  | 'userIds'
  | 'stepId'
> = {
  boss: false,
  secondBoss: false,
  designatedReviewer: false,
  // Adding assertions to avoid never[] type errors
  itemIds: [] as number[],
  users: [] as ApprovalStepUser[],
  userIds: [] as number[],
  stepId: undefined,
};

export const useApprovalStepDrawer = ({
  stepIndex,
  setApprovalUsers,
  approvalUsers,
  usersService,
  drawerProps,
}: UseApprovalStepDrawerProps) => {
  const { t } = useLokaliseTranslation('approval_requests');
  const [segmentationData, setSegmentationData] = useState<SegmentationData[]>(
    [],
  );

  const [activeStepIndex, setActiveStepIndex] = useState(stepIndex ?? 0);
  const currentStepInfo = approvalUsers[activeStepIndex] ?? DEFAULT_STEP_VALUES;

  const approvalForm = useForm<ApprovalStep>({
    defaultValues: DEFAULT_STEP_VALUES,
    values: currentStepInfo,
  });

  const segmentationItemIds = useWatch({
    control: approvalForm.control,
    name: APPROVAL_STEPS_FORM_FIELDS.itemIds,
  });

  const shouldRenderFooter = segmentationItemIds.length > 0;
  const reachedSegmentationUsersCount = useMemo(
    () =>
      segmentationItemIds.reduce(
        (acc, curr) =>
          acc +
          (segmentationData.find(item => item.id === curr)?.usersCount || 0),
        0,
      ),
    [segmentationItemIds, segmentationData],
  );

  const handleStepUpdate = (stepIndex: number | undefined) => {
    const stepValues = approvalForm.getValues();
    const newStep: ApprovalStep = {
      ...stepValues,
      stepId: currentStepInfo?.stepId ?? generateStepId(),
      userIds: stepValues.users.map(u => u.id),
    };
    const updatedApprovalUsers = [...approvalUsers];
    const index = stepIndex ?? 0;
    const isCreate = index >= updatedApprovalUsers.length;
    if (isCreate) {
      updatedApprovalUsers.push(newStep);
    } else {
      updatedApprovalUsers[index] = newStep;
    }
    drawerProps?.onSave?.(
      approvalStepsToInput(updatedApprovalUsers),
      isCreate ? 'create' : 'edit',
    );
    setApprovalUsers(updatedApprovalUsers);
    approvalForm.reset();
    closeDrawer();
  };

  const { drawer, showDrawer, closeDrawer } = useDrawerV2<{
    stepIndex?: number;
  }>(({ open, stepIndex: currentStepIndex }) => ({
    title: t('step_configuration.select_approvers'),
    onClose: () => {
      approvalForm.reset();
      closeDrawer();
    },
    children: (
      <FormProvider {...approvalForm}>
        <Stack sx={{ gap: 2 }}>
          <CollaboratorsAccordion
            shouldFetchSelectedCollaborators={open}
            usersService={usersService}
          />
          <Accordion
            title={t('step_configuration.assign_by_role')}
            description={t('step_configuration.assign_by_role_helper')}
            elevation={0}
            defaultExpanded={true}
            sx={{
              backgroundColor: ({ palette }) =>
                palette.new.background.elements.grey,
            }}
            customDetail={
              <CardContainer fullWidth>
                <Stack sx={{ gap: 2 }}>
                  <FormCheckbox
                    name={APPROVAL_STEPS_FORM_FIELDS.boss}
                    checkBoxProps={{
                      label: t('step_configuration.direct_boss'),
                      description: t('step_configuration.direct_boss_helper'),
                    }}
                  />
                  <FormCheckbox
                    name={APPROVAL_STEPS_FORM_FIELDS.secondBoss}
                    checkBoxProps={{
                      label: t('step_configuration.second_boss'),
                      description: t('step_configuration.second_boss_helper'),
                    }}
                  />
                  <FormCheckbox
                    name={APPROVAL_STEPS_FORM_FIELDS.designatedReviewer}
                    checkBoxProps={{
                      label: t('step_configuration.designated_approver'),
                      description: t(
                        'step_configuration.designated_reviewer_helper',
                      ),
                    }}
                  />
                </Stack>
              </CardContainer>
            }
          />

          <Stack sx={{ gap: 2 }}>
            <Title
              variant="M"
              title={t('general:segmentation')}
              description={t('step_configuration.approval_segmentation_helper')}
            />
            <FormSegmentationGroupSelector
              name={APPROVAL_STEPS_FORM_FIELDS.itemIds}
              showHeader={false}
              withUsersCount={true}
              queryOptions={{
                onSuccess: (data: SegmentationType[]) => {
                  setSegmentationData(
                    data
                      .flatMap(item => item.items)
                      .map(item => ({
                        id: item.id,
                        usersCount: Number(item.usersCount || 0),
                      })),
                  );
                },
              }}
              sx={{
                '& .MuiAccordion-root': {
                  backgroundColor: ({ palette }) =>
                    palette.new.background.elements.grey,
                },
              }}
            />
          </Stack>
        </Stack>
      </FormProvider>
    ),
    primaryButtonProps: {
      children: t('general:save'),
      onClick: () => {
        handleStepUpdate(currentStepIndex);
      },
    },
    secondaryButtonProps: {
      children: t('general:cancel'),
      onClick: () => {
        approvalForm.reset();
        closeDrawer();
      },
    },
    ...(shouldRenderFooter && {
      footer: (
        <Alert
          severity="info"
          title={t('step_configuration.total_users_in_approval_step', {
            count: reachedSegmentationUsersCount,
          })}
        />
      ),
    }),
  }));

  const showApprovalStepDrawer = useCallback(
    (options?: { stepIndex: number }) => {
      const index = options?.stepIndex ?? 0;
      setActiveStepIndex(index);
      showDrawer({ stepIndex: index });
    },
    [showDrawer],
  );

  return {
    approvalStepDrawer: drawer,
    showApprovalStepDrawer,
  };
};
