import React, { useEffect, useMemo } from 'react';
import { observer } from 'mobx-react-lite';
import {
  Box,
  DropdownBase,
  Input,
  FormField,
  listItemSelectBuilder,
  TextButton,
} from '@wix/design-system';
import {
  FilterOperator,
  OperatorFilterValue,
  getOperatorLabel,
  operatorNeedsValue,
  OperatorFilterState,
} from '@wix/bex-core';
import { useWixPatternsContainer } from '@wix/bex-core/react';
import { useOperatorFilterState } from '../../hooks/useOperatorFilterState';
import { FilterProps } from '../../model';
import { ChevronDown } from '@wix/wix-ui-icons-common';
import { renderOperatorFilterToolbarTag } from './renderOperatorFilterToolbarTag';

export interface OperatorPickerProps<T>
  extends FilterProps<OperatorFilterValue<T>> {}

function _OperatorFilterPicker<T>(props: OperatorPickerProps<T>) {
  const { filter } = props;
  const { translate: t } = useWixPatternsContainer();

  const filterState = filter as OperatorFilterState<T>;
  const allowedOperators = filterState.allowedOperators;
  const hasOperatorWithValue = useMemo(
    () => allowedOperators.some((op) => operatorNeedsValue(op)),
    [allowedOperators],
  );

  if (!hasOperatorWithValue) {
    throw new Error(
      `[OperatorFilterPicker] Invalid configuration for filter "${filter.name}": ` +
        `All operators in allowedOperators [${allowedOperators.join(
          ', ',
        )}] don't require a value. ` +
        `When using only value-less operators like EXISTS, IS_EMPTY, or NOT_EXISTS, ` +
        `you should use a Checkbox filter component instead of OperatorFilterPicker. ` +
        `OperatorFilterPicker is designed for operators that require user input (e.g., EQUALS, CONTAINS, STARTS_WITH).`,
    );
  }

  const state = useOperatorFilterState<T>({ filter });

  useEffect(() => state.init(), [state]);

  const operatorOptions = allowedOperators.map((op) =>
    listItemSelectBuilder({
      id: op,
      title: t(getOperatorLabel(op)),
      label: t(getOperatorLabel(op)),
    }),
  );

  const showValueInput = state.operatorNeedsValue();

  return (
    <Box
      dataHook={`operator-picker-${filter.name}`}
      direction="vertical"
      gap="12px"
    >
      <FormField>
        <DropdownBase
          options={operatorOptions}
          selectedId={state.operator}
          onSelect={(option) => state.setOperator(option.id as FilterOperator)}
          dataHook="operator-picker-operator-dropdown"
          appendTo="window"
          flip
          placement="bottom-start"
        >
          {({ toggle }) => (
            <TextButton
              skin="dark"
              onClick={toggle}
              suffixIcon={<ChevronDown />}
              size="small"
              dataHook="operator-picker-trigger"
            >
              {t(getOperatorLabel(state.operator))}
            </TextButton>
          )}
        </DropdownBase>
      </FormField>

      {showValueInput && (
        <FormField>
          <Input
            border="round"
            value={state.value?.toString() || ''}
            placeholder={t('cairo.filterOperator.valuePlaceholder')}
            onChange={(e) => state.setValue(e.target.value as T)}
            onBlur={() => state.applyImmediately()}
            onKeyDown={(e) => {
              if (e.key === 'Enter') {
                state.applyImmediately();
              }
            }}
            dataHook="operator-picker-value-input"
          />
        </FormField>
      )}
    </Box>
  );
}

export const OperatorFilterPicker = observer(
  _OperatorFilterPicker,
) as typeof _OperatorFilterPicker & {
  displayName?: string;
  renderPresetToolbarTag?: typeof renderOperatorFilterToolbarTag;
};

OperatorFilterPicker.displayName = 'OperatorFilterPicker';
OperatorFilterPicker.renderPresetToolbarTag = renderOperatorFilterToolbarTag;
