import { useRef, useState } from 'react';

import PlusIconWrapper from '~/src/components/Icon/PlusIcon';
import { useI18n } from '~/src/lib/i18n';
import {
  Form,
  FormConfig,
  FormConfigField,
  FormFieldOption,
  useFieldDefaults,
} from '~/src/ui/components/form';
import { Layout } from '~/src/ui/layouts/layout';
import { Button } from '~/src/ui/primitives/button';
import { Text } from '~/src/ui/primitives/text';
import { FormInputEdit } from './FormInputEdit';

interface FormFieldOptionItem extends FormFieldOption {
  id: number;
}

interface FormSelectEditProps {
  field: FormConfigField;
  onChange: (data: {
    label?: string;
    placeholder?: string;
    description?: string;
    options?: FormFieldOption[];
  }) => void;
}

export const FormSelectEdit = ({ field, onChange }: FormSelectEditProps) => {
  const { t } = useI18n('formBuilder');
  const defaults = useFieldDefaults(field);

  const defaultOptions = field.options ??
    defaults.options ?? [{ value: 'Option 1' }, { value: 'Option 2' }];

  const counter = useRef(defaultOptions.length);

  const [options, setOptions] = useState<FormFieldOptionItem[]>(() =>
    defaultOptions.map((option, index) => ({
      id: index,
      ...option,
    }))
  );

  const reportChange = (updatedOptions: FormFieldOptionItem[]) => {
    onChange({ options: updatedOptions.map(({ id, ...option }) => option) });
  };

  const handleAddOption = () => {
    const newOption: FormFieldOptionItem = {
      id: counter.current++,
      value: `Option ${counter.current}`,
    };

    setOptions((prevOptions) => {
      const updatedOptions = [...prevOptions, newOption];

      reportChange(updatedOptions);
      return updatedOptions;
    });
  };

  const handleChange = (data: Record<string, string>) => {
    const updatedOptions = options.map((option) => {
      const key = `option_${option.id}`;
      const value = data[key];

      return {
        ...option,
        label: undefined,
        value: value || option.value,
      };
    });

    setOptions(updatedOptions);
    reportChange(updatedOptions);
  };

  const handleRemoveOption = (optionToRemove: FormFieldOption) => {
    setOptions((prevOptions) => {
      const updatedOptions = prevOptions.filter(
        (option) => option !== optionToRemove
      );

      reportChange(updatedOptions);
      return updatedOptions;
    });
  };

  const config: FormConfig = {
    fields: [
      ...options.map((option, index) => ({
        name: `option_${option.id}`,
        label: `Option ${index + 1}`,
        placeholder: t('enterValue'),
        type: 'text' as const,
        defaultValue: option.label || option.value,
        required: true,
        onRemove:
          options.length > 2 ? () => handleRemoveOption(option) : undefined,
      })),
    ],
  };

  return (
    <Layout column gap="5">
      <FormInputEdit field={field} onChange={onChange} />
      {!field.hasFixedOptions && (
        <>
          <Text variant="body-small">{t('selectableOptions')}</Text>
          <Form mode="onChange" onChange={handleChange} config={config} />
          <Button onClick={handleAddOption} variant="text">
            <Layout align="center" gap="2">
              <PlusIconWrapper size={24} /> {t('addOption')}
            </Layout>
          </Button>
        </>
      )}
    </Layout>
  );
};
