import DatePicker from '@/components/DatePicker'
import FileModal from '@/components/FileModal'
import { contractStore } from '@/store/mobx'
import { ContractType } from '@/store/mobx/contract'
import { iReceivableState, iEditableCellProps } from '@/types/contract'
import { iFileModal } from '@/types/file'
import consts from '@/utils/consts'
import { dayjsFormat, formatMoney } from '@/utils/util'
import { DisconnectOutlined } from '@ant-design/icons'
import { Form, Input, Popconfirm, Table } from 'antd'
// import locale from 'antd/es/date-picker/locale/zh_CN'
import dayjs from 'dayjs'
import { observer } from 'mobx-react'
import React, { useEffect, useState } from 'react'
import { apiDelReturn, apiGetReturns, apiUpdateReturn } from './api'


const EditableCell: React.FC<iEditableCellProps> = ({
  editing,
  dataIndex,
  title,
  cellType,
  children,
  record,
  index,
  ...restProps
}) => {

  const cellNode = cellType === 'text' ? <Input size="small" allowClear autoComplete="off"/> : <DatePicker size="small" allowClear />

  // const isDate = useMemo(() => {
  //   return dataIndex === 'createTime' || dataIndex === 'time'
  // }, [ dataIndex ])


  return (
    <td {...restProps}>
      {editing ? (
        <Form.Item name={dataIndex} style={{ margin: 0 }} rules={[ dataIndex === 'remarks' ? {} : { required: true, message: `请输入${title}!` } ]}>
          {cellNode}
        </Form.Item>
      ) : (
          children
        )}
    </td>
  )
}

interface ReceivableProps {
  updateTreeAndContract: () => Promise<void>
  type : 'income' | 'expenditure'
}
const Receivable: React.FC<ReceivableProps> = ({ updateTreeAndContract, type }) => {
  const [ form ] = Form.useForm()
  const [ data, setData ] = useState<Array<iReceivableState>>([])
  const [ id, setId ] = useState<string>('')
  const [ fileModal, setFileModal ] = useState<iFileModal>({
    visible: false,
    dataType: consts.DATA_TYPE.RETURN,
    dataId: ''
  })
  const [ editingKey, setEditingKey ] = useState<string>('')

  const delConfirm = async (id: string, contractsId: string, bidsectionId: string) => {
    const { code = -1 } = await apiDelReturn(type, id, contractsId, bidsectionId)
    if (code === consts.RET_CODE.SUCCESS) {
      const newData = data.filter(item => item.id !== id)
      setData(newData)
      updateTreeAndContract()
    }
  }

  useEffect(() => {
    if (contractStore.contract.id) {
      if (contractStore.contract.id !== id) {
        setId(contractStore.contract.id)
        initData()
      } else if (contractStore.shouldUpdate && contractStore.shouldUpdate === '2') {
        initData()
      }
      contractStore.shouldUpdate && (contractStore.changeUpdate(''))
    }
  }, [ contractStore.contract.id, contractStore.shouldUpdate ])

  const initData = async () => {
    const { code = -1, data = [] } = await apiGetReturns(type, contractStore.contract.id, contractStore.contract.bidsectionId)
    if (code === consts.RET_CODE.SUCCESS) {
      setData(data)
    }
  }
  const save = async (key: React.Key) => {
    try {
      const row = (await form.validateFields()) as iReceivableState

      const newData = [ ...data ]
      const index = newData.findIndex(item => key === item.id)
      if (index > -1) {
        const item = newData[index]
        const payload = { ...row, time: dayjsFormat(row.time, 'YYYY-MM-DD'), createTime: dayjsFormat(row.createTime, 'YYYY-MM-DD'), id: item.id, bidsectionId: item.bidsectionId, contractsId: item.contractsId }
        const { code = -1 } = await apiUpdateReturn(type, payload)
        if (code === consts.RET_CODE.SUCCESS) {
          newData.splice(index, 1, {
            ...item,
            ...row
          })
          setData(newData)
          await updateTreeAndContract()
        }
      }
      setEditingKey('')
    } catch (errInfo) {
      console.log('Validate Failed:', errInfo)
    }
  }

  const isEditing = (record: iReceivableState) => record.id === editingKey
  const columns = [
    {
      dataIndex: 'sort',
      width: '5%',
      // eslint-disable-next-line react/display-name
      render: (_: any, record: any, index: number) => {
        return <span>{index + 1}</span>
      }
    },
    {
      title: type === ContractType.INCOME ? '回款日期' : '支付日期',
      dataIndex: 'time',
      editable: true,
      width: '12%',
      // eslint-disable-next-line react/display-name
      render: (text: string) => <span>{dayjsFormat(text, 'YYYY-MM-DD')}</span>
    },
    {
      title:  type === ContractType.INCOME ? '回款金额' : '支付金额',
      dataIndex: 'price',
      editable: true,
      width: '12%',
      // eslint-disable-next-line react/display-name
      render: (text: string) => <span className="pi-text-right pi-width-100P">{formatMoney(text)}</span>
    },
    {
      title:  type === ContractType.INCOME ? '回款方式' : '支付方式',
      dataIndex: 'way',
      editable: true,
      width: '12%'
    },
    {
      title: '创建人',
      dataIndex: 'createUser',
      editable: false,
      width: '12%'
    },
    {
      title: '创建时间',
      dataIndex: 'createTime',
      editable: true,
      width: '12%',
      // eslint-disable-next-line react/display-name
      render: (text: any) => <span>{dayjsFormat(text, 'YYYY-MM-DD')}</span>
    },
    {
      title: '备注',
      dataIndex: 'remarks',
      editable: true,
      width: '12%'
    },
    {
      title: '附件',
      dataIndex: 'fileCounts',
      // eslint-disable-next-line react/display-name
      render: (text: number, record: iReceivableState) => <span className="pi-pointer" onClick={() => setFileModal({ ...fileModal, dataId: record.id, visible: true })}><DisconnectOutlined style={{ color: '#007bff' }}/> {text}</span>
    },
    {
      title: '操作',
      dataIndex: 'opreate',
      width: '10%',
      // eslint-disable-next-line react/display-name
      render: (text: any, record: iReceivableState) => {
        const editable = isEditing(record)
        return (
          <div>
            {
              editable ?
                (<><span className="pi-link-blue pi-mg-right-5" onClick={() => save(record.id)}>保存</span><span className="pi-link-blue" onClick={() => setEditingKey('')}>取消</span></>)
                :
                <span className="pi-link-blue" onClick={() => handleRowEdit(record.id)}>编辑</span>
            }
            <Popconfirm title="确认删除?" cancelText="取消" okText="确认" okButtonProps={{ danger: true }} onConfirm={() => delConfirm(record.id, record.contractsId, record.bidsectionId)}>
              <span className="pi-link-red pi-mg-left-5">删除</span>
            </Popconfirm>
          </div>
        )
      }
    }
  ]

  const handleRowEdit = (id: string) => {
    const formItem = data.find(item => item.id === id)
    if (formItem) {
      const newFormItem = { ...formItem, createTime: dayjs(formItem.createTime), time: dayjs(formItem.time) }
      form.setFieldsValue(newFormItem)
      setEditingKey(id)

    }
  }

  const cancel = () => {
    setEditingKey('')
  }


  const mergedColumns = columns.map(col => {
    if (!col.editable) {
      return col
    }
    return {
      ...col,
      onCell: (record: iReceivableState) => ({
        record,
        cellType: col.dataIndex === 'createTime' || col.dataIndex === 'time' ? 'DatePicker' : 'text',
        dataIndex: col.dataIndex,
        title: col.title,
        editing: isEditing(record)
      })
    }
  })

  return (
    <>
      <Form form={form} component={false}>
        <Table
          components={{ body: { cell: EditableCell } }}
          dataSource={data}
          columns={mergedColumns}
          bordered
          rowClassName="editable-row"
          pagination={{ onChange: cancel, size: "small", pageSize: 7 }}
          rowKey={record => record.id}
        />
      </Form>
      <FileModal
        visible={fileModal.visible}
        dataType={fileModal.dataType}
        dataId={fileModal.dataId}
        onCancel={() => setFileModal({ ...fileModal, visible: false })}
        showUpload={true}
        uploadCallBack={() => initData()}
      />
    </>
  )
}
export default observer(Receivable)
