import { SearchOutlined } from '@ant-design/icons'
import { Input, Select, Button, Tag, Space, message, DatePicker } from 'antd'
import moment, { Moment } from 'moment'
import React, { useState, useEffect, FC } from 'react'

const { Option } = Select

export interface SearchOption {
  key: string
  label: string
  inputType: string // 'text' | 'date' | 'enum'
  inputEnums?: { label: string; value: string }[]
  inputDefaultValue?: string
}

export interface SearchFilter extends SearchOption {
  value: string
}

interface MultiConditionSearchInputProps {
  options?: SearchOption[]
  onChange?: (filters: SearchFilter[]) => void
  dateFormat?: string // default monment.defaultFormat
}

export const MultiConditionSearchInput: FC<MultiConditionSearchInputProps> = ({
  options = [],
  onChange,
  dateFormat
}) => {
  const defaultFilters = options
    .map((opt) => {
      if (opt.inputDefaultValue) {
        return {
          ...opt,
          value: opt.inputDefaultValue
        }
      }
      return null
    })
    .filter((f) => f !== null) as SearchFilter[]

  const [filters, setFilters] = useState<SearchFilter[]>(defaultFilters)
  const [selectedKey, setSelectedKey] = useState<string>(options[0]?.key || '')
  const [inputValue, setInputValue] = useState<string>('')

  const availableOptions = options.filter(
    (opt) => !filters.some((f) => f.key === opt.key)
  )
  const selectedOption = options.find((opt) => opt.key === selectedKey)
  const useDateFormat: string = dateFormat || moment.defaultFormat

  useEffect(() => {
    if (availableOptions.length > 0) {
      if (!availableOptions.some((opt) => opt.key === selectedKey)) {
        setSelectedKey(availableOptions[0].key)
      }
    } else {
      setSelectedKey('')
    }
  }, [filters, availableOptions, selectedKey])

  useEffect(() => {
    setInputValue('')
  }, [selectedKey])

  useEffect(() => {
    if (onChange) {
      onChange(filters)
    }
  }, [filters, onChange])

  const handleAddFilter = () => {
    if (!selectedKey || !inputValue.trim()) {
      message.warning('Please select a filter and enter a value')
      return
    }

    if (filters.some((f) => f.key === selectedKey)) {
      message.warning(
        `Filter "${
          options.find((o) => o.key === selectedKey)?.label
        }" is existing`
      )
      return
    }

    if (!selectedOption) return

    const newFilter: SearchFilter = {
      key: selectedKey,
      value: inputValue.trim(),
      label: selectedOption.label,
      inputType: selectedOption.inputType
    }

    setFilters([...filters, newFilter])
    setInputValue('')
  }

  const handleRemoveFilter = (removedKey: string) => {
    setFilters(filters.filter((f) => f.key !== removedKey))
  }

  const renderInput = () => {
    if (!selectedOption) return

    switch (selectedOption.inputType) {
      case 'date':
        return (
          <DatePicker
            style={{ flex: 1 }}
            showTime
            value={inputValue ? moment(inputValue, useDateFormat) : undefined}
            onChange={(date) =>
              setInputValue(date ? date.format(useDateFormat) : '')
            }
          />
        )
      case 'enum':
        return (
          <Select
            style={{ flex: 1 }}
            showSearch={true}
            value={inputValue}
            onChange={(value) => setInputValue(value)}
            dropdownMatchSelectWidth={false}
          >
            {selectedOption.inputEnums?.map((enumOpt) => (
              <Option key={enumOpt.value} value={enumOpt.value}>
                {enumOpt.label}
              </Option>
            ))}
          </Select>
        )
      case 'text':
      default:
        return (
          <Input
            style={{ flex: 1 }}
            value={inputValue}
            onChange={(e) => setInputValue(e.target.value)}
            onPressEnter={handleAddFilter}
          />
        )
    }
  }

  return (
    <div
      style={{
        border: '1px solid #d9d9d9',
        borderRadius: '6px',
        padding: '4px 8px',
        display: 'flex',
        flexWrap: 'wrap',
        alignItems: 'center'
      }}
    >
      <Space wrap size={[0, 8]}>
        {filters.map((filter) => (
          <Tag
            key={filter.key}
            closable
            onClose={() => handleRemoveFilter(filter.key)}
            style={{ margin: '2px' }}
          >
            {filter.label}: {filter.value}
          </Tag>
        ))}
      </Space>

      {availableOptions.length > 0 && (
        <Input.Group
          compact
          style={{
            display: 'flex',
            flex: '1',
            minWidth: '250px',
            margin: '2px'
          }}
        >
          <Select
            value={selectedKey}
            onChange={(value) => setSelectedKey(value)}
            style={{ minWidth: '80px' }}
            dropdownMatchSelectWidth={false}
          >
            {availableOptions.map((opt) => (
              <Option key={opt.key} value={opt.key}>
                {opt.label}
              </Option>
            ))}
          </Select>
          {renderInput()}
          <Button
            type="default"
            icon={<SearchOutlined />}
            onClick={handleAddFilter}
          />
        </Input.Group>
      )}
    </div>
  )
}
