import { Button, message } from 'antd'
import LeftMenu from './Components/LeftMenu'
import { SortableContainer, SortableElement, SortableHandle } from 'react-sortable-hoc'
import { arrayMoveImmutable } from 'array-move'
import type { ColumnsType } from 'antd/lib/table'
import type { SortableContainerProps, SortEnd } from 'react-sortable-hoc'
import { useEffect, useRef, useState } from 'react'
import { useRequest } from 'umi'
import type { ProFormInstance } from '@ant-design/pro-form'
import { addDataSourceItem, queryDataSource, updateDataSourceItem } from '@/services/api/schema'
import { MenuOutlined, PlusOutlined } from '@ant-design/icons'
import classNames from 'classnames'
import './index.less'
import { ModalForm, ProFormRadio, ProFormText } from '@ant-design/pro-form'
import ProTable from '@ant-design/pro-table'
import { ModalType } from '@/utils/enum'
import { PageContainer } from '@ant-design/pro-layout'

enum OptionModalType {
  ADD,
  UPDATE
}

const DragHandle = SortableHandle(() => <MenuOutlined style={{ cursor: 'grab', color: '#999' }} />)

const SortableItem = SortableElement((props: React.HTMLAttributes<HTMLTableRowElement>) => (
  <tr {...props} />
))
const SortableBody = SortableContainer((props: React.HTMLAttributes<HTMLTableSectionElement>) => (
  <tbody {...props} />
))

type iState = {
  menuData: API.DataSourceMenuItem[]
  activeID: Nullable<string>
  menuDataTitle: Nullable<string>
  current: NonNullable<API.DataSourceItem>
  modalType: ModalType
  menuDataItems?: API.DataSourceItem[]
}
const Option = () => {
  const formRef = useRef<ProFormInstance>(null)
  const [state, setState] = useState<iState>({
    menuData: [],
    activeID: null,
    modalVisible: false,
    modalType: OptionModalType.ADD,
    menuDataItems: [],
    current: null,
    menuDataTitle: null
  })

  const { run: tryFetchList } = useRequest(queryDataSource, {
    onSuccess: (result: API.DataSourceMenuItem) => {
      setState({
        ...state,
        menuData: result,
        menuDataItems: result.find(i => i.ID === state.activeID)?.items
      })
    }
  })
  const { run: tryAddDataSourceItem } = useRequest(
    (params: API.DataSourceItem) => addDataSourceItem(params),
    {
      manual: true,
      onSuccess: async () => {
        await tryFetchList()
      }
    }
  )
  const { run: tryUpdateDataSourceItem } = useRequest(
    (params: API.DataSourceItem) => updateDataSourceItem(params),
    {
      manual: true,
      onSuccess: async () => {
        await tryFetchList()
      }
    }
  )

  const onSelect = (key: string, node) => {
    setState({ ...state, activeID: key, menuDataItems: node.node.items })
  }

  const columns: ColumnsType<API.DataSourceItem> = [
    {
      title: '排序',
      dataIndex: 'sort',
      width: 50,
      render: () => <DragHandle />
    },
    {
      title: '序号',
      dataIndex: 'num',
      width: 50,
      render: (num, record, index) => `${index + 1}`
    },
    {
      title: '选项名称',
      dataIndex: 'name'
    },
    {
      title: '状态',
      dataIndex: 'enable',
      render: text => (
        <div className="flex items-center">
          <span
            className={classNames(
              'w-3 h-3 rounded-1/2 inline-flex',
              text ? 'bg-green-500' : 'bg-red-500'
            )}
          />
          <span className="ml-1">{text ? '已启用' : '已停用'}</span>
        </div>
      )
    },
    {
      title: '操作',
      dataIndex: 'opreate',
      render: (_, record) => (
        <div
          className="text-primary cursor-pointer hover:text-hex-967bbd"
          onClick={() => {
            setTimeout(() => {
              formRef.current?.setFieldsValue({ ...record })
            }, 80)
            setState({
              ...state,
              modalType: ModalType.UPDATE,
              modalVisible: true,
              current: {
                ID: record.ID,
                name: record.name,
                enable: record.enable
              }
            })
          }}>
          编辑
        </div>
      )
    }
  ]

  const onSortEnd = ({ oldIndex, newIndex }: SortEnd) => {
    const { menuDataItems } = state
    if (oldIndex !== newIndex) {
      const newData = arrayMoveImmutable([].concat(menuDataItems), oldIndex, newIndex).filter(
        (el: DataType) => !!el
      )
      setState({ ...state, menuDataItems: newData })
      const oldIndexItem = menuDataItems?.find(item => item.index === oldIndex)
      const newIndexItem = menuDataItems?.find(item => item.index === newIndex)
      if (oldIndexItem && newIndexItem) {
        tryUpdateDataSourceItem({ ID: state.activeID, items: newData })
        message.success('编辑成功')
      }
    }
  }

  const DraggableContainer = (props: SortableContainerProps) => (
    <SortableBody
      useDragHandle
      disableAutoscroll
      helperClass="row-dragging"
      onSortEnd={onSortEnd}
      {...props}
    />
  )

  useEffect(() => {
    if (state.activeID) {
      setState({
        ...state,
        menuDataTitle:
          state.menuData.find(i => i.ID === state.activeID)?.name +
          `：/api/form/v1/ds/items?ID=${state.menuData.find(i => i.ID === state.activeID)?.ID}`
      })
    }
  }, [state.activeID])

  const DraggableBodyRow = ({ className, style, ...restProps }) => {
    if (state.menuDataItems?.length) {
      const index = state.menuDataItems?.findIndex(x => x.index === restProps['data-row-key'])
      return <SortableItem index={index} {...restProps} />
    }
    return <SortableItem index={0} {...restProps} />
  }

  const wrapHeight = document.querySelector('.ant-pro-page-container-warp')?.clientHeight || 0

  return (
    <PageContainer title={false}>
      <div className="h-full w-full flex flex-row">
        <LeftMenu
          onSelect={onSelect}
          showDelIcon={!state.menuDataItems?.length}
          options={state.menuData}
          initFn={() => tryFetchList()}
        />
        <div className="w-6/7 ml-8 bg-white p-4 rounded-20px shadow-hex-3e2c5a relative">
          <ProTable<API.DataSourceItem>
            columns={columns}
            search={false}
            scroll={{
              y: document.body.clientHeight - (287 + wrapHeight)
            }}
            dataSource={state.menuDataItems || []}
            rowKey="index"
            headerTitle={state.activeID ? state.menuDataTitle : null}
            toolbar={{
              actions: [
                <Button
                  key="btn-key"
                  size="small"
                  type="primary"
                  onClick={() => {
                    setState({
                      ...state,
                      modalType: OptionModalType.ADD,
                      modalVisible: true
                    })
                  }}
                  ghost>
                  <PlusOutlined />
                  添加选项
                </Button>
              ]
            }}
            components={{
              body: {
                wrapper: DraggableContainer,
                row: DraggableBodyRow
              }
            }}
          />
          <ModalForm
            labelCol={{ span: 6 }}
            key="form"
            width="30%"
            title={`${state.modalType === OptionModalType.ADD ? '添加' : '编辑'}选项`}
            formRef={formRef}
            layout="horizontal"
            visible={state.modalVisible}
            onVisibleChange={visible => {
              setState({ ...state, modalVisible: visible })
              setTimeout(() => {
                if (!visible) formRef.current?.resetFields()
              }, 80)
            }}
            initialValues={{ enable: true }}
            onFinish={async values => {
              try {
                if (state.modalType === OptionModalType.ADD) {
                  await tryAddDataSourceItem({ ...values, dataSourceID: state.activeID })
                } else {
                  const newItemData = state.menuDataItems?.map(item => {
                    if (item.ID === values.ID) {
                      const newItem = { ...values }
                      return newItem
                    }
                    return item
                  })
                  await tryUpdateDataSourceItem({
                    ID: state.activeID,
                    items: newItemData
                  })
                }
                message.success(`${state.modalType === OptionModalType.ADD ? '新增' : '编辑'}成功`)
                return true
              } catch (error) {
                message.error(error)
                return false
              }
            }}>
            <ProFormText name="ID" hidden />
            <ProFormText
              name="name"
              label="选项名称"
              rules={[{ required: true, message: '请输入选项名称' }]}
            />
            <ProFormRadio.Group
              name="enable"
              label="状态"
              options={[
                { label: '启用', value: true },
                { label: '停用', value: false }
              ]}
              rules={[{ required: true, message: '请选择启用/停用' }]}
            />
          </ModalForm>
        </div>
      </div>
    </PageContainer>
  )
}

export default Option
