import { Form, message, Modal } from "antd";
import { useEffect, useState } from "react";
import Search from "zy-react-library/components/Search";
import Table from "zy-react-library/components/Table";
import { FORM_ITEM_RENDER_ENUM } from "zy-react-library/enum/formItemRender";
import useTable from "zy-react-library/hooks/useTable";
import { getLabelName } from "zy-react-library/utils";
import { SENSOR_ATTR_OPTIONS, SENSOR_STATUS_OPTIONS } from "~/enumerate/constant";

function BindSensorModal(props) {
  const [form] = Form.useForm();
  const [loading, setLoading] = useState(false);
  const [tableReady, setTableReady] = useState(false);

  const [selectedSensorIds, setSelectedSensorIds] = useState([]);
  const { tableProps, getData } = useTable(props.sensorDeviceList, { form });
  const currentFireRegionId = props.currentRecord?.fireRegionId;

  const hasFireRegionField = record => Object.prototype.hasOwnProperty.call(record || {}, "fireRegionId");
  const hasBoundFireRegion = record => hasFireRegionField(record) && record.fireRegionId !== null && record.fireRegionId !== undefined;
  const isSameFireRegion = record => hasBoundFireRegion(record) && String(record.fireRegionId) === String(currentFireRegionId);
  const isDisabledRow = record => hasBoundFireRegion(record) && !isSameFireRegion(record);
  // The default selection depends on asynchronously loaded table data, so we sync it after each load.
  // eslint-disable-next-line react-hooks-extra/no-direct-set-state-in-use-effect
  const mergeSelectedSensorIds = sensorIds => setSelectedSensorIds(prev => Array.from(new Set([...prev, ...sensorIds])));

  useEffect(() => {
    const matchedSensorIds = (tableProps.dataSource || [])
      .filter(isSameFireRegion)
      .map(item => item.sensorDeviceId)
      .filter(item => item !== undefined && item !== null);

    if (matchedSensorIds.length === 0) {
      return;
    }

    mergeSelectedSensorIds(matchedSensorIds);
  }, [currentFireRegionId, tableProps.dataSource]);

  const handleReset = () => {
    form.resetFields();
    getData();
  };
  const handleSubmit = async () => {
    setLoading(true);
    try {
      const res = await props.deviceRegionBindSensor({
        fireRegionId: props.currentRecord.fireRegionId,
        deviceIdList: selectedSensorIds,
      });
      if (res.success) {
        message.success("关联传感器已更新");
        props.onCancel();
        props.getData();
      }
    }
    finally {
      setLoading(false);
    }
  };

  return (
    <Modal
      destroyOnClose
      open={props.open}
      title="关联传感器"
      onCancel={props.onCancel}
      onOk={handleSubmit}
      afterOpenChange={open => setTableReady(open)}
      confirmLoading={loading}
      maskClosable={false}
      width={1200}
    >
      <Search
        form={form}
        labelCol={{ span: 8 }}
        onFinish={getData}
        onReset={handleReset}
        options={[
          {
            name: "sensorName",
            label: "传感器名称",
          },
          {
            name: "sensorAttr",
            label: "传感器属性",
            render: FORM_ITEM_RENDER_ENUM.SELECT,
            items: SENSOR_ATTR_OPTIONS,
          },
        ]}
      />

      {tableReady && (
        <Table
          {...tableProps}
          options={false}
          rowKey="sensorDeviceId"
          disabledResizer={true}
          scroll={{ y: 360 }}
          pagination={tableProps.pagination ? { ...tableProps.pagination, showSizeChanger: true } : false}
          rowSelection={{
            preserveSelectedRowKeys: true,
            selectedRowKeys: selectedSensorIds,
            onChange: keys => setSelectedSensorIds(keys),
            getCheckboxProps: record => ({
              disabled: isDisabledRow(record),
            }),
          }}

          columns={[
            { title: "传感器编码", dataIndex: "sensorCode" },
            { title: "传感器名称", dataIndex: "sensorName" },
            { title: "传感器类型", dataIndex: "sensorTypeName" },
            {
              title: "传感器属性",
              dataIndex: "sensorAttr",
              render: (_, record) => getLabelName({ status: record.sensorAttr, list: SENSOR_ATTR_OPTIONS }) || "-",
            },
            {
              title: "传感器状态",
              dataIndex: "sensorStatus",
              render: (_, record) => getLabelName({ status: record.sensorStatus, list: SENSOR_STATUS_OPTIONS }) || "-",
            },
          ]}
        />
      )}
    </Modal>
  );
}

export default BindSensorModal;
