import { Button, Empty, Flex, Input, Select, Space, Tag, Typography } from 'antd';
import { DeleteOutlined, PlusOutlined } from '@ant-design/icons';
import { useMemo } from 'react';
import type {
  QueryFilterBuilderProps,
  QueryFilterCondition,
  QueryFilterField,
  QueryFilterOperator,
} from './types';
import './QueryFilterBuilderUI.css';

const { Text } = Typography;

function createCondition(
  fields: QueryFilterField[],
  operators: QueryFilterOperator[],
): QueryFilterCondition {
  return {
    id: `filter-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
    field: fields[0]?.value ?? '',
    operator: operators[0]?.value ?? '',
    value: '',
  };
}

function cloneConditions(conditions: QueryFilterCondition[]) {
  return conditions.map((condition) => ({ ...condition }));
}

export function QueryFilterBuilderUI({
  fields,
  operators,
  value,
  onChange,
  presets = [],
  compact = false,
  disabled = false,
  addLabel = '조건 추가',
  emptyText = '등록된 필터 조건이 없습니다.',
}: QueryFilterBuilderProps) {
  const fieldOptions = useMemo(
    () => fields.map((field) => ({ value: field.value, label: field.label })),
    [fields],
  );
  const operatorOptions = useMemo(
    () => operators.map((operator) => ({ value: operator.value, label: operator.label })),
    [operators],
  );
  const fieldMap = useMemo(
    () => new Map(fields.map((field) => [field.value, field])),
    [fields],
  );
  const operatorMap = useMemo(
    () => new Map(operators.map((operator) => [operator.value, operator])),
    [operators],
  );

  const updateCondition = (
    id: string,
    patch: Partial<Omit<QueryFilterCondition, 'id'>>,
  ) => {
    onChange(
      value.map((condition) =>
        condition.id === id ? { ...condition, ...patch } : condition,
      ),
    );
  };

  const removeCondition = (id: string) => {
    onChange(value.filter((condition) => condition.id !== id));
  };

  return (
    <Space direction="vertical" size={compact ? 8 : 12} className="query-filter-builder">
      <Flex wrap gap={8} align="center" justify="space-between" className="query-filter-builder__toolbar">
        <Space wrap size={8}>
          {presets.length ? (
            <Select
              allowClear
              disabled={disabled}
              className="query-filter-builder__preset"
              placeholder="프리셋 선택"
              options={presets.map((preset) => ({
                value: preset.value,
                label: preset.label,
              }))}
              onChange={(presetValue) => {
                const preset = presets.find((item) => item.value === presetValue);
                if (preset) {
                  onChange(cloneConditions(preset.conditions));
                }
              }}
            />
          ) : null}
          <Text type="secondary">{value.length}개 조건</Text>
        </Space>
        <Button
          type="primary"
          icon={<PlusOutlined />}
          disabled={disabled || fields.length === 0 || operators.length === 0}
          onClick={() => {
            onChange([...value, createCondition(fields, operators)]);
          }}
        >
          {addLabel}
        </Button>
      </Flex>

      {value.length ? (
        <Space direction="vertical" size={compact ? 6 : 8} className="query-filter-builder__rows">
          {value.map((condition) => {
            const field = fieldMap.get(condition.field);

            return (
              <div
                key={condition.id}
                className={[
                  'query-filter-builder__row',
                  compact ? 'query-filter-builder__row--compact' : '',
                ]
                  .filter(Boolean)
                  .join(' ')}
              >
                <Select
                  disabled={disabled}
                  className="query-filter-builder__field"
                  value={condition.field}
                  options={fieldOptions}
                  placeholder="필드"
                  onChange={(nextField) => updateCondition(condition.id, { field: nextField })}
                />
                <Select
                  disabled={disabled}
                  className="query-filter-builder__operator"
                  value={condition.operator}
                  options={operatorOptions}
                  placeholder="연산자"
                  onChange={(nextOperator) =>
                    updateCondition(condition.id, { operator: nextOperator })
                  }
                />
                <Input
                  disabled={disabled}
                  className="query-filter-builder__value"
                  value={condition.value}
                  placeholder={field?.placeholder ?? '값 입력'}
                  onChange={(event) =>
                    updateCondition(condition.id, { value: event.target.value })
                  }
                />
                <Button
                  danger
                  disabled={disabled}
                  aria-label="필터 조건 삭제"
                  icon={<DeleteOutlined />}
                  onClick={() => removeCondition(condition.id)}
                />
              </div>
            );
          })}
        </Space>
      ) : (
        <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description={emptyText} />
      )}

      {compact && value.length ? (
        <div className="query-filter-builder__summary">
          {value.map((condition) => (
            <Tag key={condition.id}>
              {fieldMap.get(condition.field)?.label ?? condition.field}{' '}
              {operatorMap.get(condition.operator)?.label ?? condition.operator}{' '}
              {condition.value || '값 없음'}
            </Tag>
          ))}
        </div>
      ) : null}
    </Space>
  );
}
