import React, { useRef, useState } from 'react';
import { useAccess } from '@umijs/max';
import { Button, Modal, message, Typography } from 'antd';
import {
  ActionType,
  ProColumns,
  ProTable,
  ModalForm,
  ProFormText,
  ProFormSelect,
} from '@ant-design/pro-components';
import { PlusOutlined, DeleteOutlined, LinkOutlined, DisconnectOutlined } from '@ant-design/icons';
import {
  getOutdoorFairDeviceList,
  addOutdoorFairDevice,
  bindOutdoorFairDevice,
  deleteOutdoorFairDevice,
  getOutdoorFairCompanyOptions,
} from '@/services/jobportal/outdoorFairDevice';
import type { OutdoorFairDeviceItem } from '@/services/jobportal/outdoorFairDevice';

interface Props {
  fairId: number;
}

const DeviceTab: React.FC<Props> = ({ fairId }) => {
  const access = useAccess();
  const actionRef = useRef<ActionType>();
  const [addVisible, setAddVisible] = useState(false);
  const [bindVisible, setBindVisible] = useState(false);
  const [currentRow, setCurrentRow] = useState<OutdoorFairDeviceItem>();

  const handleDelete = (id: number) => {
    Modal.confirm({
      title: '确认删除',
      content: '确定要删除该设备码吗？',
      onOk: async () => {
        const res = await deleteOutdoorFairDevice(id);
        if (res.code === 200) {
          message.success('删除成功');
          actionRef.current?.reload();
        } else {
          message.error(res.msg || '删除失败');
        }
      },
    });
  };

  const handleUnbind = (record: OutdoorFairDeviceItem) => {
    Modal.confirm({
      title: '确认解绑',
      content: `确定要解除设备码与「${record.companyName}」的绑定吗？`,
      onOk: async () => {
        const res = await bindOutdoorFairDevice(record.id, undefined);
        if (res.code === 200) {
          message.success('解绑成功');
          actionRef.current?.reload();
        } else {
          message.error(res.msg || '解绑失败');
        }
      },
    });
  };

  const columns: ProColumns<OutdoorFairDeviceItem>[] = [
    {
      title: '设备码',
      dataIndex: 'deviceCode',
      ellipsis: true,
      render: (_, record) => (
        <Typography.Text copyable code>
          {record.deviceCode}
        </Typography.Text>
      ),
    },
    {
      title: '绑定企业',
      dataIndex: 'companyName',
      ellipsis: true,
      hideInSearch: true,
      render: (_, record) => (record.companyName ? record.companyName : '— 未绑定 —'),
    },
    {
      title: '绑定时间',
      dataIndex: 'bindTime',
      valueType: 'dateTime',
      hideInSearch: true,
    },
    {
      title: '操作',
      valueType: 'option',
      width: 200,
      fixed: 'right',
      render: (_, record) => [
        record.companyId ? (
          <Button
            key="unbind"
            type="link"
            size="small"
            icon={<DisconnectOutlined />}
            hidden={!access.hasPerms('cms:outdoorFair:edit')}
            onClick={() => handleUnbind(record)}
          >
            解绑
          </Button>
        ) : (
          <Button
            key="bind"
            type="link"
            size="small"
            icon={<LinkOutlined />}
            hidden={!access.hasPerms('cms:outdoorFair:edit')}
            onClick={() => {
              setCurrentRow(record);
              setBindVisible(true);
            }}
          >
            绑定企业
          </Button>
        ),
        <Button
          key="delete"
          type="link"
          size="small"
          danger
          icon={<DeleteOutlined />}
          hidden={!access.hasPerms('cms:outdoorFair:remove')}
          onClick={() => handleDelete(record.id)}
        >
          删除
        </Button>,
      ],
    },
  ];

  return (
    <>
      <ProTable<OutdoorFairDeviceItem>
        actionRef={actionRef}
        rowKey="id"
        headerTitle="设备管理"
        search={{ labelWidth: 'auto' }}
        options={false}
        pagination={{ pageSize: 10 }}
        scroll={{ x: 'max-content' }}
        toolBarRender={() => [
          <Button
            key="add"
            type="primary"
            icon={<PlusOutlined />}
            hidden={!access.hasPerms('cms:outdoorFair:add')}
            onClick={() => setAddVisible(true)}
          >
            新增设备码
          </Button>,
        ]}
        request={async (params) => {
          const res = await getOutdoorFairDeviceList({
            fairId,
            current: params.current,
            pageSize: params.pageSize,
            deviceCode: params.deviceCode,
            companyName: params.companyName,
          });
          return { data: res.rows || [], total: res.total || 0, success: res.code === 200 };
        }}
        columns={columns}
      />

      <ModalForm<{ deviceCode: string; companyId?: number }>
        title="新增设备码"
        open={addVisible}
        modalProps={{ destroyOnClose: true, onCancel: () => setAddVisible(false) }}
        onFinish={async (values) => {
          const res = await addOutdoorFairDevice({
            fairId,
            deviceCode: values.deviceCode.trim(),
            companyId: values.companyId,
          });
          if (res.code === 200) {
            message.success('新增成功');
            setAddVisible(false);
            actionRef.current?.reload();
            return true;
          }
          message.error(res.msg || '新增失败');
          return false;
        }}
      >
        <ProFormText
          name="deviceCode"
          label="设备码"
          placeholder="请输入设备码"
          fieldProps={{ maxLength: 64 }}
          rules={[
            { required: true, message: '请输入设备码' },
            { max: 64, message: '设备码长度不能超过64个字符' },
          ]}
        />
        <ProFormSelect
          name="companyId"
          label="绑定企业"
          placeholder="选填，不选则创建未绑定的设备码"
          showSearch
          allowClear
          request={async () => {
            const [companies, devicesRes] = await Promise.all([
              getOutdoorFairCompanyOptions(fairId),
              getOutdoorFairDeviceList({ fairId, current: 1, pageSize: 1000 }),
            ]);
            // 排除已绑定到其他设备的企业
            const boundIds = new Set(
              (devicesRes.rows || [])
                .map((d) => d.companyId)
                .filter((cid): cid is number => cid != null),
            );
            return companies
              .filter((item) => !boundIds.has(item.companyId))
              .map((item) => ({
                label: item.companyName,
                value: item.companyId,
              }));
          }}
        />
      </ModalForm>

      <ModalForm<{ companyId: number }>
        title="绑定参会企业"
        open={bindVisible}
        modalProps={{ destroyOnClose: true, onCancel: () => setBindVisible(false) }}
        onFinish={async (values) => {
          if (!currentRow) return false;
          const res = await bindOutdoorFairDevice(currentRow.id, values.companyId);
          if (res.code === 200) {
            message.success('绑定成功');
            setBindVisible(false);
            setCurrentRow(undefined);
            actionRef.current?.reload();
            return true;
          }
          message.error(res.msg || '绑定失败');
          return false;
        }}
      >
        <ProFormSelect
          name="companyId"
          label="参会企业"
          placeholder="请选择参会企业"
          showSearch
          request={async () => {
            const [companies, devicesRes] = await Promise.all([
              getOutdoorFairCompanyOptions(fairId),
              getOutdoorFairDeviceList({ fairId, current: 1, pageSize: 1000 }),
            ]);
            // 排除已绑定到其他设备的企业
            const boundIds = new Set(
              (devicesRes.rows || [])
                .map((d) => d.companyId)
                .filter((cid): cid is number => cid != null),
            );
            return companies
              .filter((item) => !boundIds.has(item.companyId))
              .map((item) => ({
                label: item.companyName,
                value: item.companyId,
              }));
          }}
          rules={[{ required: true, message: '请选择参会企业' }]}
        />
      </ModalForm>
    </>
  );
};

export default DeviceTab;
