import { useEffect, useMemo } from 'react';
import {
  FormProvider,
  type Resolver,
  useForm,
  useWatch,
} from 'react-hook-form';

import { yupResolver } from '@hookform/resolvers/yup';
import { isEqual, isNil } from 'lodash-es';
import { type GetDrawerConfiguration } from '@material-hu/hooks/useDrawerV2';
import Stack from '@material-hu/mui/Stack';

import { CriteriaType } from '@material-hu/components/composed-components/audience/Audience/types';

import useGetAudienceCount from 'src/components/Audience/hooks/useGetAudienceCount';
import { criteriasToSegmentationExpression } from 'src/components/Audience/utils/criteriasToSegmentationExpression';
import usePrevious from 'src/hooks/usePrevious';
import { useLokaliseTranslation } from 'src/utils/i18n';

import SegmentationSelectionDrawer from 'src/components/Audience/CriteriaSelectionDrawers/hugo/SegmentationSelectionDrawer';
import { newDefaultConditionLineValues } from 'src/components/Audience/CriteriaSelectionDrawers/hugo/SegmentationSelectionDrawer/constants';
import { type NewSegmentationCondition } from 'src/components/Audience/queries';

import SegmentationConditionLines from '../components/SegmentationConditionLines';
import {
  type AssignSegmentationConditionType,
  SegmentationCondition,
  type SegmentationSelectionFormValues,
} from '../types';
import { conditionLinesToSegmentationCondition } from '../utils';
import { getSegmentationCriteriaFormSchema } from '../validation';

const isConditionComplete = (condition: NewSegmentationCondition) =>
  (condition?.field?.id != null && (condition?.value?.length ?? 0) > 0) ??
  false;

const defaultValues = {
  conditions: [newDefaultConditionLineValues],
};

export type SegmentationSelectionDrawerProps = {
  onConfirm?: (condition: AssignSegmentationConditionType) => Promise<void>;
  onCancel?: () => void;
  formId: string;
  value: { conditions: NewSegmentationCondition[] };
  disabled?: boolean;
  loading?: boolean;
  minimumSelectionCount?: number;
};

const useSegmentationCriteriaDrawerContent: GetDrawerConfiguration<
  SegmentationSelectionDrawerProps
> = args => {
  const {
    onConfirm,
    formId,
    value,
    disabled,
    loading,
    minimumSelectionCount = 0,
  } = args;

  const { t } = useLokaliseTranslation(['audience', 'competencies']);

  const form = useForm<SegmentationSelectionFormValues>({
    resolver: yupResolver(
      getSegmentationCriteriaFormSchema(t),
    ) as unknown as Resolver<SegmentationSelectionFormValues>,
    defaultValues: {
      ...defaultValues,
      ...value,
    },
  });

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

  const prevConditions = usePrevious(value?.conditions);

  // biome-ignore lint/correctness/useExhaustiveDependencies: we don't want to re-run this effect every time the form changes
  useEffect(() => {
    if (isNil(value?.conditions)) return;
    if (!isEqual(prevConditions, value?.conditions)) {
      form.reset({
        conditions: value?.conditions ?? [],
      });
    }
  }, [prevConditions, value?.conditions]);

  const handleSubmit = async (values: {
    conditions: NewSegmentationCondition[];
  }) => {
    const condition = conditionLinesToSegmentationCondition(values.conditions);
    if (
      condition.type === SegmentationCondition.ITEMS &&
      (condition.segmentationItemIds?.length ?? 0) === 0
    ) {
      return;
    }
    await onConfirm?.(condition);
    form.reset({ ...values });
  };

  const enableQuery = Boolean(
    conditions?.[0]?.value?.length && !isNil(conditions?.[0]?.field?.id),
  );

  const expression = criteriasToSegmentationExpression([
    { type: CriteriaType.SEGMENTATION, conditions: conditions ?? [] },
  ]);
  const { data: count, isLoading: countLoading } =
    useGetAudienceCount(expression);

  const completedRulesCount = useMemo(
    () => conditions?.filter(isConditionComplete).length ?? 0,
    [conditions],
  );

  const shouldShowMinimumWarning =
    completedRulesCount < minimumSelectionCount ||
    (minimumSelectionCount > 0 && completedRulesCount === 1);

  const handleCancel = () => {
    form.reset({
      ...defaultValues,
      conditions: prevConditions ?? [newDefaultConditionLineValues],
    });
    args.closeDrawer();
  };

  return {
    children: (
      <FormProvider {...form}>
        <form
          id={formId}
          onSubmit={form.handleSubmit(handleSubmit)}
        />
        <Stack sx={{ flex: 1 }}>
          <SegmentationSelectionDrawer.Header
            description={t('competencies:segmentation_drawer_description', {
              defaultValue: t('audience:segmented_users_description'),
            })}
          />
          <SegmentationConditionLines
            name="conditions"
            disabled={disabled}
            minimumSelectionCount={minimumSelectionCount}
            onlyAnd={false}
            deleteTooltip={t('audience:cant_delete_rule_tooltip', {
              defaultValue: '',
            })}
          />
          <SegmentationSelectionDrawer.Footer
            count={count ?? 0}
            showCount={enableQuery}
            loadingCount={countLoading}
            alertProps={{
              severity: shouldShowMinimumWarning ? 'warning' : 'info',
              description: shouldShowMinimumWarning
                ? t('audience:segmented_users_alert_description', {
                    defaultValue: '',
                  })
                : '',
            }}
          />
        </Stack>
      </FormProvider>
    ),
    disableEscapeKeyDown: true,
    title: t('audience:segmented_users_title'),
    primaryButtonProps: {
      variant: 'primary',
      type: 'submit',
      form: formId,
      fullWidth: true,
      children: t('general:apply'),
      disabled: disabled || isEqual(prevConditions, conditions),
      loading,
    },
    secondaryButtonProps: {
      type: 'reset',
      form: formId,
      onClick: handleCancel,
      fullWidth: true,
      children: t('general:cancel'),
    },
    onClose: handleCancel,
  };
};

export default useSegmentationCriteriaDrawerContent;
