import { useClearField } from '@/object-record/record-field/hooks/useClearField';
import { useSelectField } from '@/object-record/record-field/meta-types/hooks/useSelectField';
import { FieldInputEvent } from '@/object-record/record-field/types/FieldInputEvent';
import { SINGLE_ENTITY_SELECT_BASE_LIST } from '@/object-record/relation-picker/constants/SingleEntitySelectBaseList';
import { SelectOption } from '@/spreadsheet-import/types';
import { SelectInput } from '@/ui/input/components/SelectInput';
import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList';
import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectableList';
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
import { useState } from 'react';
import { Key } from 'ts-key-enum';
import { isDefined } from 'twenty-ui';

type SelectFieldInputProps = {
  onSubmit?: FieldInputEvent;
  onCancel?: () => void;
};

export const SelectFieldInput = ({
  onSubmit,
  onCancel,
}: SelectFieldInputProps) => {
  const { persistField, fieldDefinition, fieldValue, hotkeyScope } =
    useSelectField();
  const [selectWrapperRef, setSelectWrapperRef] =
    useState<HTMLDivElement | null>(null);

  const [filteredOptions, setFilteredOptions] = useState<SelectOption[]>([]);

  const { handleResetSelectedPosition } = useSelectableList(
    SINGLE_ENTITY_SELECT_BASE_LIST,
  );
  const clearField = useClearField();

  const selectedOption = fieldDefinition.metadata.options.find(
    (option) => option.value === fieldValue,
  );
  // handlers
  const handleClearField = () => {
    clearField();
    onCancel?.();
  };

  const handleSubmit = (option: SelectOption) => {
    onSubmit?.(() => persistField(option?.value));

    handleResetSelectedPosition();
  };

  useScopedHotkeys(
    Key.Escape,
    () => {
      onCancel?.();
      handleResetSelectedPosition();
    },
    hotkeyScope,
    [onCancel, handleResetSelectedPosition],
  );

  const optionIds = [
    `No ${fieldDefinition.label}`,
    ...filteredOptions.map((option) => option.value),
  ];

  return (
    <div ref={setSelectWrapperRef}>
      <SelectableList
        selectableListId={SINGLE_ENTITY_SELECT_BASE_LIST}
        selectableItemIdArray={optionIds}
        hotkeyScope={hotkeyScope}
        onEnter={(itemId) => {
          const option = filteredOptions.find(
            (option) => option.value === itemId,
          );
          if (isDefined(option)) {
            onSubmit?.(() => persistField(option.value));
            handleResetSelectedPosition();
          }
        }}
      >
        <SelectInput
          parentRef={selectWrapperRef}
          onOptionSelected={handleSubmit}
          options={fieldDefinition.metadata.options}
          onCancel={onCancel}
          defaultOption={selectedOption}
          onFilterChange={setFilteredOptions}
          onClear={
            fieldDefinition.metadata.isNullable ? handleClearField : undefined
          }
          clearLabel={fieldDefinition.label}
        />
      </SelectableList>
    </div>
  );
};
