import { useState } from 'react';
import { Helmet } from 'react-helmet-async';
import {
  FormProvider,
  useFieldArray,
  useForm,
  useWatch,
} from 'react-hook-form';
import { useNavigate } from 'react-router';

import { isEmpty, isNil } from 'lodash-es';
import Stack from '@material-hu/mui/Stack';
import { colorPalette } from '@material-hu/theme/hugo/colors';

import TaskFocusLayout from '@material-hu/components/composed-components/TaskFocusLayout';

import {
  type Competency,
  type CompetencyProfile,
  type CreateCompetencyProfileParams,
} from 'src/types/competencies';
import { formatTitle } from 'src/utils/helmetUtils';
import { useLokaliseTranslation } from 'src/utils/i18n';

import {
  COMPETENCIES_CREATE_STEPS,
  type CompetenciesCreateStepId,
} from '../../constants';
import { competenciesRoutes } from '../../routes';
import { type CompetenciesProfileStep } from '../../types';
import { isValidForm } from '../../utils';

import AssignmentStepContent from './AssignmentStep/AssignmentStepContent';
import {
  type AssignSegmentationConditionType,
  type SegmentationConditionAll,
  type SegmentationConditionUsers,
} from './AssignmentStep/types';
import CompetenciesStepContent from './CompetenciesStep/CompetenciesStepContent';
import CompetenciesBank from './CompetenciesStep/components/CompetenciesBank';
import CompetenciesBankTrigger from './CompetenciesStep/components/CompetenciesBank/components/CompetenciesBankTrigger';
import DetailsStepContent from './DetailsStep/DetailsStepContent';
import StepsSideBar from './StepsSideBar';
import { type CompetenciesGroupForm, type ConditionWithId } from './types';
import {
  ensureConditionIds,
  generateConditionId,
  stripConditionIds,
} from './utils';

type CompetencyProfileFormProps = {
  onSubmit: (data: CreateCompetencyProfileParams) => void;
  initialState?: CompetencyProfile;
};

const CompetencyProfileForm = (props: CompetencyProfileFormProps) => {
  const { onSubmit, initialState } = props;
  const { t } = useLokaliseTranslation('competencies');
  const [open, setOpen] = useState(false);

  const navigate = useNavigate();

  const [activeStep, setActiveStep] = useState<CompetenciesCreateStepId>(
    COMPETENCIES_CREATE_STEPS.DETAILS,
  );

  const form = useForm<CompetenciesGroupForm>({
    mode: 'onChange',
    defaultValues: {
      name: initialState?.name || '',
      description: initialState?.description || '',
      competencies: initialState?.competencies || [],
      audienceQuery: {
        conditions: ensureConditionIds(
          initialState?.audienceQuery?.conditions ?? [],
        ),
      },
    },
  });

  const handleOpenCompetenciesBank = () => {
    setOpen(true);
  };

  const handleCloseCompetenciesBank = () => {
    setOpen(false);
  };

  const name = useWatch({ control: form.control, name: 'name' });

  const competencies = useWatch({
    control: form.control,
    name: 'competencies',
  });

  const audienceQuery = useWatch({
    control: form.control,
    name: 'audienceQuery',
  });

  const { append, remove } = useFieldArray({
    name: `competencies`,
    control: form.control,
  });

  const {
    append: appendAudienceCondition,
    remove: removeAudienceCondition,
    replace: replaceAudienceConditions,
  } = useFieldArray({
    name: 'audienceQuery.conditions',
    control: form.control,
  });

  const handleAddCompetency = (competency: Competency) => {
    append(competency);
  };

  const handleRemoveCompetency = (competencyIndex: number) => {
    remove(competencyIndex);
  };

  const handleAddSegmentationCondition = (
    condition: AssignSegmentationConditionType,
  ) => {
    const conditions = audienceQuery.conditions;

    if (isEmpty(conditions)) {
      appendAudienceCondition([
        { ...condition, id: generateConditionId() },
      ] as CompetenciesGroupForm['audienceQuery']['conditions']);
      return;
    }

    // Prevent adding additional conditions if the first condition is of type "ALL".
    if (conditions[0].type === 'ALL') return;

    appendAudienceCondition([
      { ...condition, id: generateConditionId() },
    ] as CompetenciesGroupForm['audienceQuery']['conditions']);
  };

  const handleAddDirectCondition = (condition: SegmentationConditionUsers) => {
    const conditions = audienceQuery.conditions;

    if (isEmpty(conditions)) {
      appendAudienceCondition([{ ...condition, id: generateConditionId() }]);
      return;
    }

    // Prevent adding additional conditions if the first condition is of type "ALL".
    if (conditions[0].type === 'ALL') return;

    appendAudienceCondition([{ ...condition, id: generateConditionId() }]);
  };

  const handleAddAllCondition = (condition: SegmentationConditionAll) => {
    replaceAudienceConditions([{ ...condition, id: generateConditionId() }]);
  };

  const handleRemoveCondition = (condition: ConditionWithId) => {
    const index = audienceQuery.conditions.findIndex(
      c => c.id === condition.id,
    );
    if (index >= 0) removeAudienceCondition(index);
  };

  const handleReplaceCondition = (
    conditionId: string,
    newCondition: SegmentationConditionUsers | AssignSegmentationConditionType,
  ) => {
    const index = audienceQuery.conditions.findIndex(c => c.id === conditionId);
    if (index < 0) return;
    const newConditions = [...audienceQuery.conditions];
    newConditions[index] = {
      ...newCondition,
      id: conditionId,
    } as ConditionWithId;
    replaceAudienceConditions(newConditions);
  };

  const steps: CompetenciesProfileStep[] = [
    {
      id: COMPETENCIES_CREATE_STEPS.DETAILS,
      label: t('general:details'),
      completed: false,
    },
    {
      id: COMPETENCIES_CREATE_STEPS.COMPETENCIES,
      label: t('competencies'),
      completed: false,
    },
    {
      id: COMPETENCIES_CREATE_STEPS.ASSIGNMENT,
      label: t('assignment'),
      completed: false,
    },
  ];

  const handleSaveStepData = () => {
    const formValues = form.getValues();

    onSubmit({
      name: formValues.name,
      description: formValues.description,
      competenciesIds: formValues.competencies.map(competency => competency.id),
      audienceQuery: {
        conditions: stripConditionIds(formValues.audienceQuery.conditions),
      },
    });
  };

  return (
    <FormProvider {...form}>
      <TaskFocusLayout
        slotProps={{
          root: {
            sx: {
              height: '100vh',
            },
          },
          header: {
            title: `${isNil(initialState) ? t('general:new') : t('general:edit')} ${t('competencies_profile').toLowerCase()}`,
            onClose: () => navigate(competenciesRoutes.base()),
            mainActions: [
              {
                key: 'save',
                children: t('general:save'),
                onClick: () => handleSaveStepData(),
                disabled:
                  !form.formState.isDirty ||
                  !isValidForm(name, {
                    conditions: stripConditionIds(audienceQuery.conditions),
                  }),
              },
            ],
          },
        }}
      >
        <Stack
          sx={{
            height: '100vh',
            backgroundColor: colorPalette.hugoBackground.neutralBgTerciary,
          }}
        >
          <Helmet>
            <title>{formatTitle(t('create_profile'))}</title>
          </Helmet>
          <Stack
            sx={{
              flexDirection: 'row',
              gap: 3,
              flex: 1,
              overflow: 'hidden',
              position: 'relative',
              backgroundColor: colorPalette.hugoBackground.neutralBg,
            }}
          >
            <StepsSideBar
              steps={steps}
              activeStep={activeStep}
              onSelectStep={setActiveStep}
            />
            <Stack
              sx={{
                flex: 1,
                px: 3,
                pt: 3,
                backgroundColor: colorPalette.hugoBackground.neutralBg,
                overflow: 'auto',
              }}
            >
              {activeStep === COMPETENCIES_CREATE_STEPS.DETAILS && (
                <DetailsStepContent />
              )}
              {activeStep === COMPETENCIES_CREATE_STEPS.COMPETENCIES && (
                <CompetenciesStepContent
                  onRemoveCompetency={handleRemoveCompetency}
                  formCompetencies={competencies}
                />
              )}
              {activeStep === COMPETENCIES_CREATE_STEPS.ASSIGNMENT && (
                <AssignmentStepContent
                  formAudienceQuery={audienceQuery}
                  onAddDirectCondition={handleAddDirectCondition}
                  onAddAllCondition={handleAddAllCondition}
                  onAddSegmentationCondition={handleAddSegmentationCondition}
                  onReplaceCondition={handleReplaceCondition}
                  onRemoveCondition={handleRemoveCondition}
                />
              )}
            </Stack>
            {activeStep === COMPETENCIES_CREATE_STEPS.COMPETENCIES && (
              <>
                <CompetenciesBank
                  onClose={handleCloseCompetenciesBank}
                  open={open}
                  onAddCompetency={handleAddCompetency}
                  formCompetencies={competencies}
                />
                <CompetenciesBankTrigger
                  onOpen={handleOpenCompetenciesBank}
                  open={open}
                />
              </>
            )}
          </Stack>
        </Stack>
      </TaskFocusLayout>
    </FormProvider>
  );
};

export default CompetencyProfileForm;
