import React, { useCallback, useEffect, useRef, useState } from 'react'
import { Button, Col, DatePicker, Form, Input, Modal, Row, Select } from 'antd'
import TextArea from 'antd/es/input/TextArea'
import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons'
import dayjs from 'dayjs'
import Z3upFilesRef from '@/components/Z3upFilesRef'
import { FileListType } from '@/components/Z3upFiles/data'

const { RangePicker } = DatePicker

const EXHIBITION_TYPE_OPTIONS = [
  { label: '常设展', value: '常设展' },
  { label: '临时展', value: '临时展' },
  { label: '巡回展', value: '巡回展' },
  { label: '专题展', value: '专题展' },
  { label: '交流展', value: '交流展' },
  { label: '学术展', value: '学术展' },
  { label: '其他', value: '其他' }
]

export type ExhibitionFormValues = {
  name: string
  type: string
  dateOpen: string
  dateEnd: string
  planner: string
  remark: string
  fileIds: string
  region: string[]
}

export type ExhibitionInitialValues = {
  name?: string
  type?: string
  dateOpen?: string
  dateEnd?: string
  planner?: string
  remark?: string
  region?: string | string[]
}

type Props = {
  open: boolean
  onOk: (values: ExhibitionFormValues) => void | Promise<void>
  onCancel: () => void
  initialValues?: ExhibitionInitialValues
  initialFileList?: FileListType[]
}

function ExhibitionModal({ open, onOk, onCancel, initialValues, initialFileList }: Props) {
  const [form] = Form.useForm<ExhibitionFormValues>()
  const [confirmLoading, setConfirmLoading] = useState(false)
  const fileUploadRef = useRef<{
    sonResListFu: () => { list: FileListType[] }
    sonSetListFu: (list: FileListType[]) => void
  }>(null)

  const handleOk = useCallback(async () => {
    try {
      const values = await form.validateFields()
      const fileIds = fileUploadRef.current
        ?.sonResListFu()
        ?.list?.map(f => f.id)
        .join(',')
      const dateRange = (values as any).dateRange
      const submitData: ExhibitionFormValues = {
        ...values,
        dateOpen: dateRange?.[0] ? dayjs(dateRange[0]).format('YYYY-MM-DD') : '',
        dateEnd: dateRange?.[1] ? dayjs(dateRange[1]).format('YYYY-MM-DD') : '',
        fileIds: fileIds || '',
        region: (values.region || []).map((r: string) => (r || '').trim()).filter(Boolean)
      }
      delete (submitData as any).dateRange
      setConfirmLoading(true)
      await onOk(submitData)
      form.resetFields()
      onCancel()
    } catch (e) {
      // 校验失败
    } finally {
      setConfirmLoading(false)
    }
  }, [form, onOk, onCancel])

  const handleCancel = useCallback(() => {
    form.resetFields()
    onCancel()
  }, [form, onCancel])

  useEffect(() => {
    if (open) {
      if (initialValues) {
        const regionArr =
          typeof initialValues.region === 'string'
            ? initialValues.region.split(',').filter(Boolean)
            : Array.isArray(initialValues.region)
              ? initialValues.region
              : ['']
        form.setFieldsValue({
          name: initialValues.name ?? '',
          type: initialValues.type ?? undefined,
          planner: initialValues.planner ?? '',
          remark: initialValues.remark ?? '',
          region: regionArr.length ? regionArr : [''],
          dateRange:
            initialValues.dateOpen || initialValues.dateEnd
              ? [
                  initialValues.dateOpen ? dayjs(initialValues.dateOpen) : null,
                  initialValues.dateEnd ? dayjs(initialValues.dateEnd) : null
                ]
              : undefined
        } as ExhibitionFormValues & { dateRange?: any })
        fileUploadRef.current?.sonSetListFu(initialFileList || [])
      } else {
        form.resetFields()
        fileUploadRef.current?.sonSetListFu([])
      }
    }
  }, [open, initialValues, initialFileList, form])

  return (
    <Modal
      destroyOnClose
      title='展览信息'
      open={open}
      onOk={handleOk}
      onCancel={handleCancel}
      okText='提交'
      cancelText='取消'
      width={800}
      maskClosable={false}
      confirmLoading={confirmLoading}
    >
      <Form form={form} layout='vertical' initialValues={{ region: [''] }}>
        <Row gutter={16}>
          <Col span={12}>
            <Form.Item
              label='展览名称'
              name='name'
              rules={[
                { required: true, message: '请输入展览名称' },
                { max: 50, message: '不超过50个字' }
              ]}
            >
              <Input placeholder='请输入展览名称' maxLength={50} showCount />
            </Form.Item>
          </Col>
          <Col span={12}>
            <Form.Item
              label='展览类型'
              name='type'
              rules={[{ required: true, message: '请选择展览类型' }]}
            >
              <Select placeholder='请选择' options={EXHIBITION_TYPE_OPTIONS} allowClear />
            </Form.Item>
          </Col>
        </Row>

        <Row gutter={16}>
          <Col span={12}>
            <Form.Item label='起止日期' name='dateRange'>
              <RangePicker style={{ width: '100%' }} placeholder={['开始日期', '结束日期']} />
            </Form.Item>
          </Col>
          <Col span={12}>
            <Form.Item label='策展人' name='planner' rules={[{ max: 20, message: '不超过20个字' }]}>
              <Input placeholder='请输入策展人' maxLength={20} showCount />
            </Form.Item>
          </Col>
        </Row>

        <Form.Item label='备注' name='remark' rules={[{ max: 500, message: '不超过500个字' }]}>
          <TextArea placeholder='请输入备注' maxLength={500} showCount rows={4} />
        </Form.Item>

        <Form.Item label='附件'>
          <Z3upFilesRef
            ref={fileUploadRef}
            myUrl='cms/show/upload'
            dirCode='exhibits'
            moduleId={0}
          />
        </Form.Item>

        <Form.Item
          label='展区设置'
          name='region'
          rules={[
            {
              validator: (_, value) => {
                const list = value || []
                const names = list.map((v: string) => (v || '').trim()).filter(Boolean)
                if (names.length > 20) {
                  return Promise.reject(new Error('最多20个展区'))
                }
                const unique = new Set(names)
                if (unique.size !== names.length) {
                  return Promise.reject(new Error('同一展览内展区名称不能重复'))
                }
                return Promise.resolve()
              }
            }
          ]}
        >
          <Form.List name='region'>
            {(fields, { add, remove }) => (
              <>
                {fields.map(({ key, name, ...restField }) => (
                  <div key={key} style={{ display: 'flex', marginBottom: 8, gap: 8 }}>
                    <Form.Item {...restField} name={name} style={{ flex: 1, marginBottom: 0 }}>
                      <Input placeholder='请填写展厅或展区名称' />
                    </Form.Item>
                    <Form.Item style={{ marginBottom: 0 }}>
                      {fields.length > 1 ? (
                        <MinusCircleOutlined
                          onClick={() => remove(name)}
                          style={{ fontSize: 18, color: '#ff4d4f' }}
                        />
                      ) : null}
                    </Form.Item>
                  </div>
                ))}
                <Form.Item style={{ marginBottom: 0 }}>
                  <Button
                    type='dashed'
                    onClick={() => add()}
                    block
                    icon={<PlusOutlined rev={undefined} />}
                    disabled={fields.length >= 20}
                  >
                    添加展区
                  </Button>
                </Form.Item>
              </>
            )}
          </Form.List>
        </Form.Item>
      </Form>
    </Modal>
  )
}

export default ExhibitionModal
