import { useTranslation } from 'react-i18next';

import ConditionLine from '@composed-components/ConditionLine';
import {
  type ConditionLineValues,
  ConditionOperator,
  type DefaultItemType,
  JoinOperator,
} from '@composed-components/ConditionLine/types';
import CardContainer from '@design-system/CardContainer';
import { Button, Stack, useTheme } from '@mui/material';
import { IconPlus } from '@tabler/icons-react';
import { insertIf } from '@utils/array';
import { mergeWith } from 'lodash';

import DynamicConditionLine from './components/DynamicConditionLine';
import { type ConditionGroupProps } from './types';

const ConditionGroup = <
  FieldItemType extends DefaultItemType,
  ValueItemType extends DefaultItemType,
>({
  onAdd,
  onDelete,
  onChange,
  disabled = false,
  value,
  slotProps = {},
  dynamicItems,
}: ConditionGroupProps<FieldItemType, ValueItemType>) => {
  const { t } = useTranslation('material_hu_only');
  const { palette } = useTheme();

  const { root, conditionLine, addButton } = slotProps;

  const handleDelete =
    (
      condition: ConditionLineValues<FieldItemType, ValueItemType>,
      index: number,
    ) =>
    () => {
      onDelete?.(condition, index);

      let newConditions = value.filter((_: unknown, i: number) => i !== index);

      if (newConditions.length === 0) {
        newConditions = [
          {
            joinOperator: value[0].joinOperator,
            field: null,
            conditionOperator: ConditionOperator.IS_IN,
            value: [],
          },
        ];
      }

      onChange?.(newConditions);
    };

  const handleAdd = () => {
    onAdd?.();

    const newCondition: ConditionLineValues<FieldItemType, ValueItemType> = {
      joinOperator: value[0].joinOperator,
      field: null,
      conditionOperator: ConditionOperator.IS_IN,
      value: [],
    };

    const newConditions = [...value, newCondition];

    onChange?.(newConditions);
  };

  const handleChange =
    (index: number) =>
    (newCondition: ConditionLineValues<FieldItemType, ValueItemType>) => {
      const newConditions = [...value];
      newConditions[index] = newCondition;
      onChange?.(newConditions);
    };

  const getOptions = (index: number) => {
    return [
      ...insertIf(index === 0, {
        label: t('condition_group.when'),
        value: JoinOperator.AND,
      }),
      {
        label: t('condition_group.and'),
        value: JoinOperator.AND,
      },
      {
        label: t('condition_group.or'),
        value: JoinOperator.OR,
      },
    ];
  };

  const getDefaultSlotProps = (index: number) =>
    mergeWith(
      {
        joinOperatorSelector: {
          title: index === 0 ? t('condition_group.when') : undefined,
          readOnly: index === 0,
          options: getOptions(index),
          slotProps: {
            button: {
              sx: {
                minWidth: '88px',
                padding: '0',
              },
            },
          },
        },
        conditionOperatorSelector: {
          children: t('condition_group.is_in'),
        },
        fieldSelector: {
          getTriggerTitle: (_value: DefaultItemType[]) => {
            return _value[0]?.name || t('condition_group.choose');
          },
        },
        valueSelector: {
          getTriggerTitle: (_value: DefaultItemType[]) => {
            return (
              _value.map(item => item.name).join(', ') ||
              t('condition_group.value')
            );
          },
        },
      },
      conditionLine?.slotProps,
      (_objValue, srcValue) => {
        if (Array.isArray(srcValue)) return srcValue;
      },
    );

  return (
    <CardContainer
      fullWidth
      {...root}
      sx={{
        backgroundColor: palette.new.background.layout.default,
        border: 'none',
        ...root?.sx,
      }}
    >
      <Stack sx={{ gap: 2 }}>
        {value.map(
          (
            condition: ConditionLineValues<FieldItemType, ValueItemType>,
            index: number,
          ) =>
            dynamicItems ? (
              <DynamicConditionLine
                key={index}
                condition={condition}
                allConditions={value}
                index={index}
                dynamicItems={dynamicItems}
                conditionLineProps={{
                  ...conditionLine,
                  slotProps: getDefaultSlotProps(index),
                }}
                onChange={handleChange(index)}
                onDelete={handleDelete(condition, index)}
                disabled={disabled}
              />
            ) : (
              <ConditionLine
                {...conditionLine}
                key={index}
                value={condition}
                disabled={disabled || conditionLine?.disabled}
                onDelete={handleDelete(condition, index)}
                onChange={handleChange(index)}
                fieldSelectorItems={conditionLine?.fieldSelectorItems ?? []}
                valueSelectorItems={conditionLine?.valueSelectorItems ?? []}
                slotProps={getDefaultSlotProps(index)}
              />
            ),
        )}
        <Button
          variant="tertiary"
          size="large"
          startIcon={<IconPlus size={16} />}
          {...addButton}
          disabled={disabled || addButton?.disabled}
          onClick={handleAdd}
        >
          {addButton?.children || t('condition_group.add_condition')}
        </Button>
      </Stack>
    </CardContainer>
  );
};

export default ConditionGroup;
