import React, { forwardRef, useEffect, useImperativeHandle, useRef, useState } from 'react'
import Checkbox from 'antd/lib/checkbox'
import message from 'antd/lib/message'
import Button from 'antd/lib/button'
import Select from 'antd/lib/select'
import InputNumber from 'antd/lib/input-number'
import { isMobile } from '../../utils/helper'
import Input, { InputRef } from 'antd/lib/input'
import { debounce, flatMap } from 'lodash'
import Sortable from 'sortablejs'
import { CloseOutlined } from '@ant-design/icons'
import { Icon } from '../icons'

interface Field {
  name: string
  label: string
  comparable: boolean
  isNumerical?: boolean
  type: string
}

interface ShowField extends Field {
  checked: boolean
  disabled: boolean
}

interface SortField extends Field {
  order: number
}

type OptionsParam = {
  showFields: string[] //显示字段
  sortFields: string[] //排序字段
  groupByFields: string[] //分组字段
  itemCount: boolean //仅查项数
  itemRepeat: boolean  //数据去除
  itemSumCount: boolean   //仅查总数
  section: boolean //是否勾选分段查询
  sectionParams: SectionParam
}

type SectionParam = {
  leftOpenRightClose: boolean//区间左开右闭
  sectionField: string //分段字段
  avgSection: boolean //类型  false:自定义段位  true:平均段位
  sections: number[] //段位
  sectionNorm: string //分段标准
}

interface ChangeData {
  optionsParam: OptionsParam | undefined
  rawShowFields: string[]  //后端要求显示字段全选时showFields传空数组,设置默认值的时候用
  rawOptionsParams: OptionsParam
}

interface OptionTransferProps {
  allFields: Field[]
  defaultOptionsParam?: OptionsParam
  onChange: (data: ChangeData) => void
}

enum CheckOption {
  SELECT_ALL = '全选',
  SELECT_REVERSE = '反选',
  CLEAR_ALL = '全清'
}

const segmentStandardList = [
  { title: "年", value: "year" },
  { title: "季度", value: "quarter" },
  { title: "月", value: "month" },
  { title: "周", value: "week" },
  { title: "日", value: "day" },
  { title: "时", value: "hour" },
  { title: "分", value: "minute" },
  { title: "秒", value: "second" },
]

const OptionTransfer = forwardRef((props: OptionTransferProps, ref) => {

  const { allFields, defaultOptionsParam, onChange } = props

  const segmentFields = allFields.filter(field => field.type == 'number' || field.type == 'date' || field.type == 'progress')

  const [itemRepeat, setItemRepeat] = useState(defaultOptionsParam?.itemRepeat ?? false)

  const [itemCount, setItemCount] = useState(defaultOptionsParam?.itemCount ?? false)

  const [itemSumCount, setItemSumCount] = useState(defaultOptionsParam?.itemSumCount ?? false)

  const [showSegment, setShowSegment] = useState(defaultOptionsParam?.section ?? false)

  const [showFields, setShowFields] = useState<ShowField[]>(allFields.map(field => {
    const checked = defaultOptionsParam ? (defaultOptionsParam.showFields.length == 0 ? true : defaultOptionsParam.showFields.includes(field.name)) : true
    const disabled = defaultOptionsParam?.groupByFields.includes(field.name) ?? false
    return { ...field, checked, disabled }
  }))

  useEffect(() => {
    if (!!defaultOptionsParam)
      handleReset()
  }, [defaultOptionsParam])

  const [sortFields, setSortFields] = useState<SortField[]>(flatMap(defaultOptionsParam?.sortFields ?? [], field => {
    const fields = field.split(',')
    const fieldName = fields[0]
    const order = fields.includes('desc') ? 1 : 0
    const targetField = allFields.find(item => item.name == fieldName)
    if (targetField) {
      return { ...targetField, order }
    }
    return []
  }) ?? [])

  const [groupByFields, setGroupByFields] = useState<Field[]>(allFields.filter(field => defaultOptionsParam?.groupByFields.includes(field.name)))

  const [selectedShowField, setSelectedShowField] = useState<Field>()

  const [leftOpenRightClose, setLeftOpenRightClose] = useState(defaultOptionsParam?.sectionParams.leftOpenRightClose ?? false)

  const [sectionField, setSectionField] = useState<string>(defaultOptionsParam?.sectionParams.sectionField ?? segmentFields[0]?.name)

  const [avgSection, setAvgSection] = useState(defaultOptionsParam?.sectionParams.avgSection ?? true)

  const [sectionWidthValue, setSectionWidthValue] = useState(defaultOptionsParam?.sectionParams.sections?.[0] ?? 1)

  const [sectionValue, setSectionValue] = useState(1)

  const [sections, setSections] = useState<number[]>(defaultOptionsParam?.sectionParams.sections ?? [])

  const [sectionNorm, setSectionNorm] = useState<string>(defaultOptionsParam?.sectionParams.sectionNorm ?? '')

  const [searchValue, setSearchValue] = useState<string>('')

  const innerRef = useRef<HTMLDivElement>(null);

  const inputRef = useRef<InputRef>(null);

  useEffect(() => {
    const sortable = new Sortable(document.getElementById(`transfer-target-0`)!, {
      group: '.transfer-target-content',
      handle: '.item-label',
      animation: 150,
      onEnd: (e) => {
        const oldIndex = e.oldIndex
        const newIndex = e.newIndex
        if (oldIndex != undefined && newIndex != undefined) {
          setSortFields(fields => {
            const newFields = [...fields]
            const tempField = fields[oldIndex]
            newFields[oldIndex] = newFields[newIndex]
            newFields[newIndex] = tempField
            return newFields
          })
        }
      }
    })

    return () => {
      sortable.destroy()
    }
  }, [])

  useEffect(() => {
    if (searchValue) {
      debounceHandleSearch(searchValue)
    }
  }, [searchValue, showFields])

  const handleSearch = (searchValue: string) => {
    //匹配规则，1.全匹配 2.以关键字开头匹配 3.模糊匹配
    let target = showFields.find(item => item.label === searchValue);
    !target && (target = showFields.find(item => item.label.startsWith(searchValue)));
    !target && (target = showFields.find(item => item.label?.includes(searchValue)));
    if (target) {
      setSelectedShowField(target)
      if (target.name === selectedShowField?.name) {
        const activeDom = innerRef.current?.querySelector('.display-field-active')
        activeDom?.scrollIntoView({ behavior: 'smooth', block: 'start' })
      }
    }
  }

  const debounceHandleSearch = debounce(handleSearch, 100)

  useEffect(() => {
    if (selectedShowField && searchValue) {
      const activeDom = innerRef.current?.querySelector('.display-field-active')
      activeDom?.scrollIntoView({ behavior: 'smooth', block: 'start' })
      setSearchValue('')
    }
  }, [selectedShowField])

  useEffect(() => {
    const show = showFields.filter(field => field.checked).map(field => field.name)
    const sort = sortFields.map(field => `${field.name}${field.order === 1 ? ',desc' : ''}`)
    const group = groupByFields.map(field => field.name)
    const checkedAll = showFields.every(field => field.checked)
    const retShowField = (itemCount || itemRepeat || itemSumCount || groupByFields.length > 0) ? show : checkedAll ? [] : show
    const ellipsis = !itemRepeat && !itemCount && !itemSumCount && !showSegment && retShowField.length == 0 && sort.length == 0 && group.length == 0
    const options = {
      itemRepeat,
      itemCount,
      itemSumCount,
      showFields: retShowField,
      sortFields: sort,
      groupByFields: group,
      section: showSegment,
      sectionParams: {
        leftOpenRightClose,
        sectionField,
        avgSection,
        sections: avgSection ? [sectionWidthValue] : sections,
        sectionNorm: sectionNorm ?? ''
      }
    }
    onChange({ rawShowFields: show, rawOptionsParams: options, optionsParam: !ellipsis ? options : undefined })
  }, [itemRepeat, itemCount, itemSumCount, showFields, showSegment, sortFields, groupByFields, leftOpenRightClose, sectionField, avgSection, sectionWidthValue, sections, sectionNorm])

  useImperativeHandle(ref, () => ({ handleReset }))

  const handleReset = () => {
    setItemRepeat(defaultOptionsParam?.itemRepeat ?? false)
    setItemCount(defaultOptionsParam?.itemCount ?? false)
    setItemSumCount(defaultOptionsParam?.itemSumCount ?? false)
    setShowFields(allFields.map(field => {
      const checked = (defaultOptionsParam?.itemCount === true && !defaultOptionsParam.showFields.includes(field.name)) ? false : defaultOptionsParam ? (defaultOptionsParam.showFields.length == 0 ? true : defaultOptionsParam.showFields.includes(field.name)) : true
      const disabled = defaultOptionsParam?.groupByFields.includes(field.name) ?? false
      return { ...field, checked, disabled }
    }))
    setSortFields(flatMap(defaultOptionsParam?.sortFields ?? [], field => {
      const fields = field.split(',')
      const fieldName = fields[0]
      const order = fields.includes('desc') ? 1 : 0
      const targetField = allFields.find(item => item.name == fieldName)
      if (targetField) {
        return { ...targetField, order }
      }
      return []
    }) ?? [])
    setGroupByFields(flatMap(defaultOptionsParam?.groupByFields ?? [], groupField => allFields.find(field => field.name == groupField) ?? []) ?? [])
    setSelectedShowField(undefined)
    setLeftOpenRightClose(defaultOptionsParam?.sectionParams.leftOpenRightClose ?? false)
    setSectionField(defaultOptionsParam?.sectionParams.sectionField ?? segmentFields[0]?.name)
    setAvgSection(defaultOptionsParam?.sectionParams.avgSection ?? true)
    setSectionWidthValue(defaultOptionsParam?.sectionParams.sections?.[0] ?? 1)
    setSectionValue(1)
    setSections(defaultOptionsParam?.sectionParams.sections ?? [])
    setSectionNorm(defaultOptionsParam?.sectionParams.sectionNorm ?? '')
  }

  const handleCheckedChange = (showField: ShowField, checked: boolean) => {
    checked ? setSelectedShowField(showField) : setSelectedShowField(field => field?.name === showField.name ? undefined : field)
    const fields = showFields.map(field => {
      if (field.name === showField.name) {
        return { ...field, checked }
      }
      return field
    })
    setShowFields(fields)
    inputRef.current?.focus()
  }

  const handleCheckedOption = (option: CheckOption) => {
    let fields: ShowField[]
    switch (option) {
      case CheckOption.SELECT_ALL:
        fields = (itemRepeat || itemCount || itemSumCount) ? showFields.slice().map(field => {
          if (field.comparable === true && !field.disabled) {
            return { ...field, checked: true }
          }
          return field
        }) : showFields.slice().map(field => ({ ...field, checked: true }))
        break
      case CheckOption.CLEAR_ALL:
        fields = showFields.slice().map(field => ({ ...field, checked: field.disabled ? field.checked : (itemRepeat || itemCount || itemSumCount ? false : field.disabled) }))
        break
      case CheckOption.SELECT_REVERSE:
        fields = showFields.slice().map(field => ({ ...field, checked: !field.disabled ? !field.checked : field.checked }))
        break
    }
    setShowFields(fields)
  }

  const handleAddField = (type: 0 | 1, fields: SortField[] | Field[]) => {
    if (selectedShowField) {
      if (type === 0) {
        const tempFields = fields.slice() as SortField[]
        if (itemCount || itemSumCount) {
          message.warning('仅查项数,仅查总数不能使用字段排序')
          return
        }

        if (showSegment && (selectedShowField.type != 'number' && selectedShowField.type != 'date' && selectedShowField.type != 'progress')) {
          message.warning('分段查询,非数字时间类型不能使用字段排序')
          return
        }

        if (!tempFields.some(field => field.name === selectedShowField.name)) {
          tempFields.push({ ...selectedShowField, order: 0 })
          setSortFields(tempFields)
        } else {
          message.warning('已添加过该字段')
        }

      } else {
        const tempFields = fields.slice() as Field[]
        if (!tempFields.some(field => field.name === selectedShowField.name)) {
          tempFields.push(selectedShowField)
          setGroupByFields(tempFields)
        } else {
          message.warning('已添加过该字段')
          return
        }
        setShowFields(fields => fields.map(field => {
          if (field.name === selectedShowField.name) {
            return { ...field, checked: true, disabled: true }
          }
          if (fields.every(field => field.checked)) {
            return { ...field, checked: field.isNumerical ?? false }
          }
          return field
        }))
      }
    }
  }

  const handleDeleteField = (type: 0 | 1, names: string[], fields: SortField[] | Field[]) => {
    if (type === 0) {
      const tempFields = fields.slice() as SortField[]
      setSortFields(tempFields.filter(field => !names.includes(field.name)))
    } else {
      const tempFields = fields.slice() as Field[]
      setGroupByFields(tempFields.filter(field => !names.includes(field.name)))
      const tempShowFields = showFields.slice().map(field => {
        const target = names.find(name => name === field.name)
        if (target) {
          return { ...field, checked: false, disabled: false }
        }
        return field
      })
      setShowFields(tempShowFields)
    }
  }

  const handleSortFields = (field: SortField, sortfields: SortField[]) => {
    const tempFields = sortfields.slice().map(sortField => {
      if (field.name === sortField.name) {
        return { ...sortField, order: 1 ^ sortField.order }
      }
      return sortField
    })
    setSortFields(tempFields)
  }

  // 勾选数据去重
  const handleCheckedItemRepeat = (checked: boolean) => {
    setItemRepeat(checked)
    if (checked) {
      setShowFields(fields => fields.map(field => {
        if (field.comparable === false) {
          return { ...field, checked: false }
        }
        return field
      }))
    }
  }

  // 勾选仅查项数
  const handleCheckedItemCount = (checked: boolean) => {
    setItemCount(checked);
    setSortFields([]);
    if (checked && showFields.every(item => item.checked)) {
      setShowFields(fields => fields.map(field => ({ ...field, checked: false })))
    }
  }

  //勾选仅查总数
  const handleCheckedItemSumCount = (checked: boolean) => {
    if (checked && showFields.every(item => item.checked)) {
      setGroupByFields([])
      setSortFields([])
      setShowFields(fields => fields.map(field => {
        const isChecked = field.type == 'number' || field.type == 'progress'
        return { ...field, checked: isChecked }
      }))
    }
    setItemSumCount(checked)
  }

  //勾选分段字段
  const handleCheckedSegment = (checked: boolean) => {
    if (checked) {
      setShowFields(fields => {
        if (fields.every(field => field.checked)) {
          return fields.map(field => {
            const isChecked = field.type == 'number' || field.type == 'date' || field.type == 'progress'
            if (!field.disabled) {
              return { ...field, checked: isChecked }
            }
            return field
          })
        }
        return fields
      })
    }
    setShowSegment(checked)
  }

  //修改分段字段
  const handleChangeSectionField = (value: string) => {
    const field = segmentFields.find(field => field.name == value)
    if (field?.type !== 'date') {
      setSectionNorm('')
    } else {
      setSectionNorm('year')
    }
    setSectionField(value)
  }

  //添加段位列表
  const handleAddSections = (section: number) => {
    if (!sections.includes(section)) {
      setSections(sections => sections.concat(section))
    } else {
      message.info('已添加过该段位')
    }
  }

  const renderTarget = (type: 0 | 1, fields: SortField[] | Field[]) => {
    const sortDisabled = !!!selectedShowField?.comparable || itemSumCount || itemCount
    const groupDisabled = !!!selectedShowField?.comparable || itemSumCount
    // || fields.length >= 8
    const disabledBtn = type == 0 ? sortDisabled : groupDisabled

    return (
      <div className={`target-box`}>
        <div className="btn-group">
          <div style={{ cursor: disabledBtn ? 'not-allowed' : 'pointer' }} className={` btn`} onClick={disabledBtn ? undefined : () => handleAddField(type, fields)}>
            <i className='fa fa-chevron-right' />
          </div>
        </div>
        <div className="transfer-target">
          <div className="transfer-target-heander">
            <span className="title">{type === 0 ? '排序字段' : '分组字段'}</span>
            <Button type='link' onClick={() => handleDeleteField(type, fields.map(field => field.name), fields)}>清空</Button>
          </div>
          <div id={`transfer-target-${type}`} className={`transfer-target-content`}>
            <div className='option'>
              {type === 0 && (fields as SortField[]).map((field, index) => (
                <span className='option-item' key={field.name}>
                  <span className='item-title'>{index + 1}</span>
                  <span onClick={() => handleSortFields(field, sortFields)}>
                    <Icon icon={`${field.order === 0 ? '#icon-toolshunxu' : '#icon-tooldaoxu'}`} symbol ></Icon>
                  </span>
                  {/* <i className={`fa fa-arrow-${field.order === 0 ? 'up' : 'down'}`} onClick={() => handleSortFields(field, sortFields)} /> */}
                  <span className='item-label'>{field.label}</span>
                  <CloseOutlined onClick={() => handleDeleteField(type, [field.name], fields)} />
                </span>
              ))}
              {type === 1 && (fields as Field[]).map((field, index) => (
                <div className='option-item' key={field.name}>
                  <span className='item-title'>{index + 1}</span>
                  <span className='item-label'>{field.label}</span>
                  <CloseOutlined onClick={() => handleDeleteField(type, [field.name], fields)} />
                </div>
              ))}
            </div>

            {type === 1 && <div className='transfer-target-footer'>建议选择少于8个分组字段 </div>}
          </div>
        </div>
      </div>
    )
  }

  return (
    <div className='transfer-check'>
      <div className='transfer-check-group'>
        {isMobile() ? <>
          <Button
            type="text"
            className={`transfer-check-bat ${itemRepeat ? 'transfer-check-bat-true' : ''}`}
            onClick={() => handleCheckedItemRepeat(!itemRepeat)}>
            数据去重
            {itemRepeat && <span className='transfer-check-bat-icon'></span>}
          </Button>
          <Button
            type="text"
            className={`transfer-check-bat ${itemCount ? 'transfer-check-bat-true' : ''}'`}
            disabled={itemSumCount}
            onClick={() => handleCheckedItemCount(!itemCount)}>
            仅查项数
            {itemCount && <span className='transfer-check-bat-icon'></span>}
          </Button>
          <Button
            type="text"
            className={`transfer-check-bat ${itemSumCount ? 'transfer-check-bat-true' : ''}`}
            disabled={itemCount}
            onClick={() => handleCheckedItemSumCount(!itemSumCount)}>
            仅查总数
            {itemSumCount && <span className='transfer-check-bat-icon'></span>}
          </Button>
        </>
          :
          <>
            <Checkbox checked={itemRepeat} onChange={e => handleCheckedItemRepeat(e.target.checked)}>数据去重</Checkbox>
            <Checkbox
              checked={itemCount}
              disabled={itemSumCount}
              onChange={e => handleCheckedItemCount(e.target.checked)}
            >
              仅查项数
            </Checkbox>
            <Checkbox checked={itemSumCount} disabled={itemCount} onChange={e => handleCheckedItemSumCount(e.target.checked)}>仅查总数</Checkbox>
          </>
        }
      </div>
      <div className='transfer-container'>
        <div className='transfer-source'>
          <div className="transfer-source-header">
            <span className="title">显示字段</span>
            <div className="option-group">
              {
                isMobile() ? <>
                  <div >
                    <span className="option" onClick={() => {
                      handleCheckedOption(CheckOption.SELECT_REVERSE)
                    }}>
                      {CheckOption.SELECT_REVERSE}
                    </span>
                  </div>
                </>
                  :
                  <>
                    {Object.values(CheckOption).map((value, index) => (
                      <div key={index}>
                        <span className="option" onClick={() => handleCheckedOption(value)}>{value}</span>&nbsp;&nbsp;
                      </div>
                    ))}
                  </>

              }


            </div>
          </div>
          <div className='transfer-source-position'>
            <Input ref={inputRef} onKeyDown={(e) => {
              //键盘事件后清空值，后续重新输入
              e.stopPropagation()
              if (e.key === 'Enter') {
                setTimeout(() => {
                  setSearchValue('')
                }, 500)
              }
            }}
              onCompositionEnd={(e) => {
                setTimeout(() => {
                  setSearchValue('')
                }, 500)
              }}
              onBlur={() => setSearchValue('')} value={searchValue}
              onChange={(e) => setSearchValue(e.target.value)} />
          </div>
          <div className="transfer-source-content">
            <div className="source-content-inner" ref={innerRef}>
              {showFields.map(field => (
                <section className={selectedShowField?.name === field.name ? 'display-field display-field-active' : 'display-field'} key={field.name}>
                  <Checkbox
                    disabled={field.disabled}
                    checked={field.checked}
                    onChange={e => handleCheckedChange(field, e.target.checked)}
                  />
                  <span className='display-field-label' onClick={() => {
                    setSelectedShowField(selectedShowField?.name === field.name ? undefined : field);
                    inputRef.current?.focus()
                  }
                  }>
                    {field.label}
                  </span>
                </section>
              ))}
            </div>
          </div>
        </div>
        <div className='transfer-target-group'>
          {renderTarget(0, sortFields)}
          {renderTarget(1, groupByFields)}
        </div>
      </div>
      <div className='transfer-check-group'>
        <Checkbox disabled={itemSumCount} checked={showSegment} onChange={e => handleCheckedSegment(e.target.checked)}>分段查询</Checkbox>
        {showSegment && <Checkbox checked={leftOpenRightClose} onChange={e => setLeftOpenRightClose(e.target.checked)}>区间左开右闭</Checkbox>}
      </div>
      {showSegment && (
        <div className='transfer-segment-container'>
          <div className='left-content'>
            <div className='segment-select'>
              <div className='segment-select-item'>
                <span>分段字段</span>
                <Select value={sectionField} onChange={value => handleChangeSectionField(value)} style={{ width: 150, marginLeft: 10 }} dropdownClassName={`dropdown-select-style`}>
                  {segmentFields.map(field => (
                    <Select.Option key={field.name} value={field.name}>{field.label}</Select.Option>
                  ))}
                </Select>
              </div>
              <div className='segment-select-item'>
                <span>类型</span>
                <Select<boolean> style={{ width: 150, marginLeft: 10 }} value={avgSection} onChange={value => setAvgSection(value)} dropdownClassName={`dropdown-select-style`}>
                  <Select.Option value={true}>平均段位</Select.Option>
                  <Select.Option value={false}>自定义段位</Select.Option>
                </Select>
              </div>
              <div className='segment-select-item'>
                <span>分段标准</span>
                <Select onChange={value => setSectionNorm(value)} value={sectionNorm} disabled={segmentFields.find(field => field.name == sectionField)?.type !== 'date'} style={{ width: 150, marginLeft: 10 }} dropdownClassName={`dropdown-select-style`}>
                  {segmentStandardList.map(item => (
                    <Select.Option key={item.value} value={item.value}>{item.title}</Select.Option>
                  ))}
                </Select>
              </div>
              <div className='segment-select-item'>
                <span>{avgSection ? '宽度' : '段位'}</span>
                {avgSection ?
                  <InputNumber value={sectionWidthValue} onChange={value => setSectionWidthValue(value ?? 0)} min={0} type={'number'} style={{ width: 150, marginLeft: 10 }} /> :
                  <InputNumber value={sectionValue} onChange={value => setSectionValue(value ?? 0)} type={'number'} style={{ width: 150, marginLeft: 10 }} />}
              </div>
            </div>
          </div>
          {!avgSection && (
            <div className='right-content'>
              <div className='target-box'>
                <div className="btn-group">
                  <div style={{ cursor: false ? 'not-allowed' : 'pointer' }} className="btn" onClick={() => handleAddSections(sectionValue)}>
                    <i className='fa fa-chevron-right' />
                  </div>
                </div>
                <div className="transfer-target">
                  <div className="transfer-target-heander">
                    <span className="title">段位列表</span>
                  </div>
                  <div className="transfer-target-content">
                    <div className="target-content-inner">
                      {sections.map(section => (
                        <div className='option-item' key={section}>
                          <span className='item-label'>{section}</span>
                          <i className='fa fa-times' onClick={() => setSections(sections => sections.filter(item => item != section))} />
                        </div>
                      ))}
                    </div>
                  </div>
                </div>
              </div>
            </div>
          )}
        </div>
      )}
    </div >
  )
})

export default OptionTransfer