import { useCallback, useState } from 'react';
import {
  FormProvider,
  type UseFieldArrayRemove,
  useFieldArray,
  useForm,
  useWatch,
} from 'react-hook-form';
import { useMutation, useQueryClient } from 'react-query';

import { IconEye } from '@tabler/icons-react';
import { useModal } from '@material-hu/hooks/useModal';
import Stack from '@material-hu/mui/Stack';
import { appearFromBottom } from '@material-hu/utils/animations';

import Button from '@material-hu/components/design-system/Buttons/Button';
import Dialog from '@material-hu/components/design-system/Dialog';
import TaskFocusHeader from '@material-hu/components/design-system/Header/TaskFocus';
import useSnackbar from '@material-hu/components/design-system/Snackbar';
import { useDrawerLayer } from '@material-hu/components/layers/Drawers';

import { updateDynamicForm } from 'src/services/dynamicFormsService';
import {
  DynamicFormActionType,
  DynamicFormEventType,
  DynamicFormType,
  type UpdateDynamicForm,
} from 'src/types/dynamicForms';
import { convertDynamicFormSectionsToSurveySections } from 'src/utils/dynamicForms';
import { useLokaliseTranslation } from 'src/utils/i18n';

import { useConfirmActionModal } from '../../hooks/useUnsavedChangesModal';
import QuestionnairePreviewDrawerContent, {
  QUESTIONNAIRE_PREVIEW_DRAWER_ID,
} from '../forms/StepActionForms/shared/Preview/QuestionnairePreviewDrawerContent';
import SurveySectionForm from '../forms/SurveySectionForm';
import SurveySectionList from '../SurveySectionList';

import {
  type SurveySectionFormValues,
  type SurveySetupScreenFormValues,
  type SurveySetupScreenProps,
} from './types';
import {
  convertFormValuesToDynamicFormSections,
  createPlaceholderSection,
  parseSections,
  surveySetupScreenResolver,
} from './utils';

const SurveySetupScreen = ({
  title,
  onClose,
  dynamicFormData,
  sections,
}: SurveySetupScreenProps) => {
  const queryClient = useQueryClient();
  const { t } = useLokaliseTranslation('employee_lifecycle');
  const { enqueueSnackbar } = useSnackbar();
  const { openDrawer } = useDrawerLayer();
  const form = useForm<SurveySetupScreenFormValues>({
    defaultValues: {
      sections: parseSections(sections || []) || [createPlaceholderSection()],
    },
    resolver: surveySetupScreenResolver,
  });

  const { fields, append, remove } = useFieldArray({
    name: 'sections',
    control: form.control,
  });

  const { isDirty } = form.formState;

  const updateFormMutation = useMutation({
    mutationFn: (values: SurveySetupScreenFormValues) => {
      const sectionsWithErrors = values.sections.filter(section => {
        return section?.questions?.length === 0;
      });

      if (sectionsWithErrors.length > 0) {
        throw new Error('no_questions_error');
      }

      const parsedSections = convertFormValuesToDynamicFormSections(values);

      if (!dynamicFormData?.formTag) {
        throw new Error('Form tag is required');
      }

      return updateDynamicForm(dynamicFormData?.formTag || '', {
        sectionsCount: parsedSections.length,
        sections: parsedSections,
        title: title || dynamicFormData?.formTitle || 'Form title',
        type: DynamicFormType.REGULAR,
        initialAction: {
          type: DynamicFormActionType.STATIC,
          event: DynamicFormEventType.FORM_START,
          nameId: 'action',
          nextSection: parsedSections[0].nameId,
        },
      } as UpdateDynamicForm);
    },
    onError: (error: Error) => {
      if (error?.message === 'no_questions_error') {
        enqueueSnackbar({
          variant: 'error',
          title: t(
            'process_stepper.steps.process.actions.survey.actions.save.error',
          ),
          description: t(
            'process_stepper.steps.process.actions.survey.actions.save.error_description',
          ),
        });
        return;
      }
      enqueueSnackbar({
        variant: 'error',
        title: t(
          'process_stepper.steps.process.actions.survey.actions.save.error',
        ),
      });
      console.error(error);
    },
    onSuccess: response => {
      enqueueSnackbar({
        variant: 'success',
        title: t(
          'process_stepper.steps.process.actions.survey.actions.save.success',
        ),
      });
      // TODO: Move this to the appropriate query key handler
      queryClient.invalidateQueries(['dynamicForm', dynamicFormData?.formTag]);
      onClose?.({
        sections: convertDynamicFormSectionsToSurveySections(
          response.data.sections,
          'Empty',
        ),
      });
    },
  });

  const confirmUnsavedChangesModal = useConfirmActionModal({
    title: t(
      'process_stepper.steps.process.actions.survey.form.exit_dialog.title',
    ),
    description: t(
      'process_stepper.steps.process.actions.survey.form.exit_dialog.description',
    ),
    onConfirm: () => {
      onClose?.(form.getValues());
    },
  });

  const confirmSectionDeleteModal = useModal(Dialog, {});

  const [selectedSectionId, setSelectedSectionId] = useState<string | null>(
    fields?.[0]?.sectionId || null,
  );

  const handleSectionSelect = (sectionId: string) => {
    setSelectedSectionId(sectionId);
  };

  const handleSectionAppend = (data: SurveySectionFormValues) => {
    append(data);
    setSelectedSectionId(data?.sectionId);
  };

  const removeSection = (index: number) => {
    if (fields.length === 1) {
      const placeholderSection = createPlaceholderSection();
      remove(index);
      append(placeholderSection);
      setSelectedSectionId(placeholderSection.sectionId);
      return;
    }

    const nextSelectedSectionId =
      index === 0 ? fields[1]?.sectionId : fields[index - 1]?.sectionId;

    if (nextSelectedSectionId) {
      setSelectedSectionId(nextSelectedSectionId);
    }
    remove(index);
  };

  const handleSectionRemove: UseFieldArrayRemove = index => {
    const sectionIndex = index as number;
    const sectionValues = form.getValues(`sections.${sectionIndex}`);
    const sectionQuestions = sectionValues?.questions;

    if (sectionQuestions?.length > 0) {
      confirmSectionDeleteModal.showModal({
        title: t('surveys:section_form.actions.delete.confirm_dialog.title'),
        textBody: t(
          'surveys:section_form.actions.delete.confirm_dialog.description',
        ),
        secondaryButtonProps: {
          children: t('general:cancel'),
          onClick: () => {
            confirmSectionDeleteModal.closeModal();
          },
        },
        primaryButtonProps: {
          children: t(
            'surveys:section_form.actions.delete.confirm_dialog.confirm',
          ),
          onClick: () => {
            removeSection?.(index as number);
            confirmSectionDeleteModal.closeModal();
          },
        },
      });
      return;
    } else {
      removeSection?.(index as number);
      return;
    }
  };

  const handleScreenClose = () => {
    if (isDirty) {
      confirmUnsavedChangesModal?.showModal();
    } else {
      onClose?.(form.getValues());
    }
  };

  const handleSubmit = (values: SurveySetupScreenFormValues) => {
    updateFormMutation.mutate(values);
  };

  const watchedSections =
    useWatch({ control: form.control, name: 'sections' }) ?? [];
  const hasQuestions = watchedSections.some(
    section => (section.questions?.length ?? 0) > 0,
  );

  const handleOpenPreview = useCallback(() => {
    const liveSections = form.getValues('sections') ?? [];
    openDrawer(
      {
        content: (
          <QuestionnairePreviewDrawerContent
            sections={liveSections}
            formTitle={title || dynamicFormData?.formTitle}
          />
        ),
        wrapperProps: {
          disableEscapeKeyDown: false,
          // Same initial width as the action drawer; resized at runtime by
          // usePreviewState inside QuestionnairePreviewDrawerContent.
          PaperProps: {
            sx: { maxWidth: '800px', width: 'min(800px, 100%)' },
          },
        },
      },
      QUESTIONNAIRE_PREVIEW_DRAWER_ID,
    );
  }, [openDrawer, form, title, dynamicFormData?.formTitle]);

  return (
    <FormProvider {...form}>
      {confirmUnsavedChangesModal.modal}
      {confirmSectionDeleteModal.modal}
      <Stack
        sx={{
          backgroundColor: theme => theme.palette.new.background.layout.default,
          minHeight: '100vh',
          overflow: 'auto',
        }}
      >
        <Stack sx={{ top: 0, position: 'sticky', zIndex: 10 }}>
          <TaskFocusHeader
            title={t('process_stepper.steps.process.actions.survey.title')}
            onClose={handleScreenClose}
            mainActions={[
              {
                key: 'preview',
                children: t('employee_lifecycle:preview.cta_preview'),
                variant: 'secondary',
                startIcon: <IconEye size={16} />,
                // Disabled until at least one question exists (per design spec).
                disabled: !hasQuestions,
                onClick: handleOpenPreview,
              },
              {
                key: 'create',
                children: t(
                  'process_stepper.steps.process.actions.survey.actions.edit_config.title',
                ),
                variant: 'secondary',
                onClick: () => {
                  handleScreenClose();
                },
              },
            ]}
          />
        </Stack>

        <Stack sx={{ flex: 1, flexDirection: 'row' }}>
          <SurveySectionList
            sx={{
              backgroundColor: theme =>
                theme.palette.new.background.layout.tertiary,
              flex: 1,
              maxWidth: '340px',
            }}
            currentSectionId={
              selectedSectionId || sections?.[0]?.sectionId || null
            }
            onSectionSelect={handleSectionSelect}
            onSectionAppend={data =>
              handleSectionAppend(data as SurveySectionFormValues)
            }
            onSectionRemove={handleSectionRemove}
          />

          <Stack
            sx={{
              backgroundColor: theme =>
                theme.palette.new.background.layout.default,
              flex: 1,
              minHeight: '100%',
              minWidth: 0,
            }}
          >
            {fields?.map(
              (field, index) =>
                field.sectionId === selectedSectionId && (
                  <SurveySectionForm
                    key={field.id}
                    index={index}
                    onCancel={handleScreenClose}
                    onDismiss={handleScreenClose}
                    onSubmit={handleScreenClose}
                    sx={{
                      animate: `${appearFromBottom} 0.125s ease-in-out`,
                    }}
                    section={field}
                  />
                ),
            )}
          </Stack>
        </Stack>
        <Stack
          sx={{
            backgroundColor: theme =>
              theme.palette.new.background.layout.tertiary,
            flexDirection: 'row',
            justifyContent: 'end',
            alignItems: 'center',
          }}
        >
          <Stack
            sx={{
              flexDirection: 'row',
              justifyContent: 'end',
              maxWidth: '1140px',
              mx: 'auto',
              gap: 2,
              width: '100%',
              padding: 2,
            }}
          >
            <Button
              size="large"
              variant="tertiary"
              disabled={updateFormMutation.isLoading}
              onClick={handleScreenClose}
            >
              {t('general:back')}
            </Button>
            <Button
              size="large"
              variant="primary"
              onClick={form.handleSubmit(handleSubmit)}
              loading={updateFormMutation.isLoading}
            >
              {t(
                'process_stepper.steps.process.actions.survey.actions.save.title',
              )}
            </Button>
          </Stack>
        </Stack>
      </Stack>
    </FormProvider>
  );
};

export default SurveySetupScreen;
