import { useTranslation } from 'react-i18next';

import AllSummaryCard from '@composed-components/audience/AllSummaryCard';
import CriteriaAutocomplete from '@composed-components/audience/CriteriaAutocomplete';
import IndividualSummaryCard from '@composed-components/audience/IndividualSummaryCard';
import SegmentationSummaryCard from '@composed-components/audience/SegmentationSummaryCard';
import { type DefaultItemType } from '@composed-components/ConditionLine/types';
import Alert from '@design-system/Alert';

import useAudienceDrawers from '../hooks/useAudienceDrawers';
import {
  type CriteriaEntry,
  type CriteriaSummaryProps,
  CriteriaType,
} from '../types';
import { getAvailableCriteriaTypes } from '../utils';

const CriteriaSummary = <
  FieldItemType extends DefaultItemType = DefaultItemType,
  ValueItemType extends DefaultItemType = DefaultItemType,
>({
  segmentationDrawerProps,
  individualDrawerProps,
  getSegmentationDescription,
  getIndividualDescription,
  onBeforeDelete,
  showAllSelectedAlert = true,
  availableCriteriaTypes,
}: CriteriaSummaryProps<FieldItemType, ValueItemType>) => {
  const { t } = useTranslation('material_hu_only');
  const {
    criterias,
    setValue,
    getValues,
    typedEmptyCondition,
    segmentationInputProps,
    segmentationCriteriaDrawer,
    showSegmentationCriteriaDrawer,
    segmentationCriteriaForm,
    individualCriteriaDrawer,
    showIndividualCriteriaDrawer,
    individualCriteriaForm,
  } = useAudienceDrawers<FieldItemType, ValueItemType>({
    segmentationDrawerProps,
    individualDrawerProps,
  });

  const updateCriterias = (
    next: CriteriaEntry<FieldItemType, ValueItemType>[],
  ) => {
    setValue('criterias', next, { shouldDirty: true });
  };

  const handleSegmentationClick = (editIndex?: number) => {
    const existingEntry =
      editIndex !== undefined ? criterias[editIndex] : undefined;
    const conditions =
      existingEntry?.type === CriteriaType.SEGMENTATION
        ? existingEntry.conditions
        : [typedEmptyCondition];

    segmentationCriteriaForm.reset({ conditions });

    showSegmentationCriteriaDrawer({
      onConfirm: values => {
        const entry: CriteriaEntry<FieldItemType, ValueItemType> = {
          type: CriteriaType.SEGMENTATION,
          conditions: values.conditions,
        };
        if (editIndex !== undefined) {
          updateCriterias(
            criterias.map((c, i) => (i === editIndex ? entry : c)),
          );
        } else {
          updateCriterias([...criterias, entry]);
        }
      },
      inputProps: segmentationInputProps,
    });
  };

  const handleIndividualClick = (editIndex?: number) => {
    const existingEntry =
      editIndex !== undefined ? criterias[editIndex] : undefined;
    const userIds =
      existingEntry?.type === CriteriaType.INDIVIDUAL
        ? existingEntry.userIds
        : new Set<string | number>();

    individualCriteriaForm.reset({ userIds, search: '' });

    showIndividualCriteriaDrawer({
      onConfirm: values => {
        const entry: CriteriaEntry<FieldItemType, ValueItemType> = {
          type: CriteriaType.INDIVIDUAL,
          userIds: values.userIds ?? new Set(),
        };
        if (editIndex !== undefined) {
          updateCriterias(
            criterias.map((c, i) => (i === editIndex ? entry : c)),
          );
        } else {
          updateCriterias([...criterias, entry]);
        }
      },
    });
  };

  const handleDelete = (index: number) => {
    const doDelete = () => {
      const current = getValues('criterias') ?? [];
      updateCriterias(current.filter((_, i) => i !== index));
    };

    if (onBeforeDelete) {
      onBeforeDelete(index, criterias[index], doDelete);
    } else {
      doDelete();
    }
  };

  const availableTypes = getAvailableCriteriaTypes(
    criterias,
    availableCriteriaTypes && availableCriteriaTypes.length > 0
      ? availableCriteriaTypes
      : undefined,
  );
  const hasAll = criterias.some(c => c.type === CriteriaType.ALL);

  return (
    <>
      {segmentationCriteriaDrawer}
      {individualCriteriaDrawer}
      {criterias.map((entry, index) => {
        if (entry.type === CriteriaType.ALL) {
          return (
            <AllSummaryCard
              key={`all-${index}`}
              onDelete={() => handleDelete(index)}
            />
          );
        }

        if (entry.type === CriteriaType.SEGMENTATION) {
          return (
            <SegmentationSummaryCard
              key={`segmentation-${index}`}
              description={getSegmentationDescription(entry)}
              onEdit={() => handleSegmentationClick(index)}
              onDelete={() => handleDelete(index)}
            />
          );
        }

        if (entry.type === CriteriaType.INDIVIDUAL) {
          return (
            <IndividualSummaryCard
              key={`individual-${index}`}
              description={getIndividualDescription(entry)}
              onEdit={() => handleIndividualClick(index)}
              onDelete={() => handleDelete(index)}
            />
          );
        }

        return null;
      })}
      {hasAll && showAllSelectedAlert && (
        <Alert
          severity="highlight"
          title={t('audience.all_selected_alert_title')}
          description={t('audience.all_selected_alert_description')}
        />
      )}
      {availableTypes.length > 0 && (
        <CriteriaAutocomplete
          onIndividual={
            availableTypes.includes(CriteriaType.INDIVIDUAL)
              ? () => handleIndividualClick()
              : undefined
          }
          onSegmentation={
            availableTypes.includes(CriteriaType.SEGMENTATION)
              ? () => handleSegmentationClick()
              : undefined
          }
        />
      )}
    </>
  );
};

export default CriteriaSummary;
