import AllCriteriaCard from '@composed-components/audience/AllCriteriaCard';
import IndividualCriteriaCard from '@composed-components/audience/IndividualCriteriaCard';
import SegmentationCriteriaCard from '@composed-components/audience/SegmentationCriteriaCard';
import { type DefaultItemType } from '@composed-components/ConditionLine/types';

import useAudienceDrawers from '../hooks/useAudienceDrawers';
import {
  type AudienceFormValues,
  type CriteriaSelectorProps,
  CriteriaType,
} from '../types';

const ALL_TYPES = [
  CriteriaType.ALL,
  CriteriaType.SEGMENTATION,
  CriteriaType.INDIVIDUAL,
];

const CriteriaSelector = <
  FieldItemType extends DefaultItemType = DefaultItemType,
  ValueItemType extends DefaultItemType = DefaultItemType,
>({
  segmentationDrawerProps,
  individualDrawerProps,
  availableCriteriaTypes,
  showCriteriaInfo = true,
}: CriteriaSelectorProps<FieldItemType, ValueItemType>) => {
  const allowed =
    availableCriteriaTypes && availableCriteriaTypes.length > 0
      ? availableCriteriaTypes
      : ALL_TYPES;

  const {
    criterias,
    setValue,
    segmentationInputProps,
    segmentationCriteriaDrawer,
    showSegmentationCriteriaDrawer,
    individualCriteriaDrawer,
    showIndividualCriteriaDrawer,
  } = useAudienceDrawers<FieldItemType, ValueItemType>({
    segmentationDrawerProps,
    individualDrawerProps,
  });

  const addCriteria = (
    entry: AudienceFormValues<
      FieldItemType,
      ValueItemType
    >['criterias'][number],
  ) => {
    setValue('criterias', [...criterias, entry], { shouldDirty: true });
  };

  const handleSegmentationClick = () => {
    showSegmentationCriteriaDrawer({
      showInfo: showCriteriaInfo,
      onConfirm: values => {
        addCriteria({
          type: CriteriaType.SEGMENTATION,
          conditions: values.conditions,
        });
      },
      inputProps: segmentationInputProps,
    });
  };

  const handleIndividualClick = () => {
    showIndividualCriteriaDrawer({
      onConfirm: values => {
        addCriteria({
          type: CriteriaType.INDIVIDUAL,
          userIds: values.userIds ?? new Set(),
        });
      },
    });
  };

  const handleAllClick = () => {
    addCriteria({ type: CriteriaType.ALL });
  };

  return (
    <>
      {allowed.map(type => {
        switch (type) {
          case CriteriaType.SEGMENTATION:
            return (
              <SegmentationCriteriaCard
                key={type}
                onClick={handleSegmentationClick}
                showInfo={showCriteriaInfo}
              />
            );
          case CriteriaType.INDIVIDUAL:
            return (
              <IndividualCriteriaCard
                key={type}
                onClick={handleIndividualClick}
              />
            );
          case CriteriaType.ALL:
            return (
              <AllCriteriaCard
                key={type}
                onClick={handleAllClick}
                showInfo={showCriteriaInfo}
              />
            );
          default:
            return null;
        }
      })}
      {segmentationCriteriaDrawer}
      {individualCriteriaDrawer}
    </>
  );
};

export default CriteriaSelector;
