import {
  forwardRef,
  Key,
  useEffect,
  useImperativeHandle,
  useMemo,
  useState,
} from "react";
import {
  Modal,
  Collapse,
  Empty,
  Steps,
  Result,
  Button,
  Spin,
  Form,
  TreeSelect,
  Tabs,
  message,
} from "antd";
import { ProTable } from "@ant-design/pro-components";
import DiffTable from "./DiffTable";
import { useModel, useRequest } from "umi";
import { PushDataModelTable, GetCanUseTableList } from "@/api/dataModel";
import {
  GetAllDesignTables,
  SaveDataModel,
  ImportFromBusinessTables,
} from "@/api";
import { TableItemType } from "@/type";
import NoData from "@/assets/no-data.png";
import CustomColorPicker from "./CustomColorPicker";
import { pick, set } from "lodash-es";

export default forwardRef(function SyncModal(
  props: { onPush: () => void },
  ref
) {
  const [open, setOpen] = useState(false);
  const { project } = useModel("erModel");
  const [color, setColor] = useState<string>();
  const { data, loading, run } = useRequest(GetAllDesignTables, {
    manual: true,
  });
  const [tableList, setTableList] = useState<TableItemType[]>(project?.tables);
  const [step, setStep] = useState(0);
  const [tabActiveKey, setTabActiveKey] = useState<string>("1");

  // 选中需要同步的表
  const [selectedRowKeys, setSelectedRowKeys] = useState<Key[]>([]);
  const [selectedRows, setSelectedRows] = useState<any[]>([]);
  const [okLoading, setOkLoading] = useState(false);
  const [resultStatus, setResultStatus] = useState<"success" | "error">(
    "success"
  );
  const [importTables, setImportTables] = useState<Key[]>([]);

  useEffect(() => {
    if (step === 0 && tableList.length) {
      setSelectedRowKeys(tableList.map((item) => item.table.id));
      setSelectedRows(tableList);
    }
  }, [tableList, step]);

  useImperativeHandle(ref, () => ({
    open: () => {
      setTabActiveKey("1");
      setColor(undefined);
      setStep(0);
      setOpen(true);
      run();
      run1({ type: project.type });
    },
    close: () => setOpen(false),
  }));

  useEffect(() => {
    setTableList(project.tables);
  }, [project.tables]);

  useEffect(() => {
    setStep(0);
  }, [tabActiveKey]);

  const {
    data: data1,
    loading: loading1,
    run: run1,
  } = useRequest(GetCanUseTableList, {
    manual: true,
  });

  // 可引入表列表
  const treeData = useMemo(() => {
    const tableMap: Record<string, any> = {};
    data1?.result
      ?.filter(
        (item: any) =>
          // 过滤当前数据表类型及存在相同schemaName、aliasName的表
          item?.type == project?.type
        // && !project.tables.find(
        //   (tableItem) =>
        //     tableItem.table.schemaName === item.schemaName ||
        //     tableItem.table.aliasName === item.aliasName
        // )
      )
      ?.forEach((item: any) => {
        // 判断是否存在已引入的表
        const hasTable = project.tables.find(
          (tableItem: TableItemType) =>
            tableItem.table.schemaName === item.schemaName ||
            tableItem.table.aliasName === item.aliasName
        );

        const option = {
          key: item.id,
          title: `${item?.schemaName}(${item.name})`,
          value: item?.id,
          disabled: hasTable,
          selectable: !item.parentBusinessTableId,
        };
        // 子表
        if (item.parentBusinessTableId) {
          if (tableMap[item.parentBusinessTableId]) {
            tableMap[item.parentBusinessTableId].children.push(option);
          } else {
            tableMap[item.parentBusinessTableId] = {
              children: [option],
            };
          }
        } else {
          // 主表
          if (tableMap[item.id]) {
            tableMap[item.id] = {
              ...tableMap[item.id],
              ...option,
            };
          } else {
            tableMap[item.id] = {
              ...option,
              children: [],
            };
          }
        }
        return;
      });
    return Object.keys(tableMap).map((key) => tableMap[key]);
  }, [data1]);

  // 已存在的数据表
  const existTableList = useMemo(() => {
    const list: {
      modelTable: TableItemType;
      dataTable: any;
    }[] = [];
    const tables = data?.result?.appBusinessTables || [];
    selectedRows.forEach((tableItem) => {
      const dataTable = tables.find(
        (item: any) => item.id === tableItem.table?.businessTableId
        // item.schemaName === tableItem.table.schemaName ||
        // item.aliasName === tableItem.table.aliasName
      );
      if (dataTable) {
        list.push({
          modelTable: tableItem,
          dataTable,
        });
      }
    });

    return list;
  }, [selectedRows, data]);

  // 差异对比更新当前模型数据
  const handleUpdateTable = (tableItem: TableItemType) => {
    setSelectedRows(
      selectedRows.map((item) =>
        item.table.id === tableItem.table.id ? tableItem : item
      )
    );
  };

  const Step1Comp = () => {
    return (
      <>
        <ProTable
          title={() => "请选择模型表"}
          dataSource={tableList.map((item) => item.table)}
          rowKey="id"
          search={false}
          pagination={false}
          options={false}
          size="small"
          rowSelection={{
            selectedRowKeys,
            onChange(selectedRowKeys) {
              setSelectedRowKeys(selectedRowKeys);
              setSelectedRows(
                tableList.filter((item) =>
                  selectedRowKeys.includes(item.table.id)
                )
              );
            },
          }}
          columns={[
            {
              title: "类型",
              dataIndex: "type",
              valueType: "select",
              valueEnum: {
                3: "业务表",
                2: "流程表",
              },
            },
            {
              title: "编码",
              dataIndex: "schemaName",
              valueType: "text",
            },
            {
              title: "别名",
              dataIndex: "aliasName",
              valueType: "text",
            },
            {
              title: "名称",
              dataIndex: "langNameList",
              render: (_, record) => {
                return (
                  record.langNameList?.find(
                    (item: any) => item.name === "zh-CN"
                  )?.value || "-"
                );
              },
            },
            {
              title: "描述",
              dataIndex: "langDescriptionList",
              render: (_, record) => {
                return (
                  record?.langDescriptionList?.find(
                    (item: any) => item.name === "zh-CN"
                  )?.value || "-"
                );
              },
            },
          ]}
        />
      </>
    );
  };

  const Step2Comp = () => {
    const list = selectedRows.filter(({ table }) =>
      existTableList.find((item) => item.modelTable.table.id === table.id)
    );
    return (
      <>
        <div className="text-14px font-bold m-y-12px">
          提示：共选择了
          <span className="color-green">{selectedRows.length}</span>
          张表格数据。
          {existTableList.length ? (
            <>
              其中有
              <span className="color-#faad14">{existTableList.length}</span>
              张表已存在，可对比调整差异后开始操作。
            </>
          ) : null}
        </div>

        <Collapse
          items={list.map((item) => {
            const { table } = item;
            const name = table.langNameList?.find(
              (item: any) => item.name === "zh-CN"
            )?.value;
            const existTable = existTableList.find(
              (item) => item.modelTable.table.id === table.id
            );
            return {
              key: table.id,
              label: (
                <span
                  style={{
                    color: existTable ? "#faad14" : "",
                  }}
                >{`${table.schemaName}${name ? `(${name})` : ""}`}</span>
              ),
              children: (
                <DiffTable
                  sourceTable={item}
                  targetTableId={existTable?.dataTable?.id}
                  onChange={handleUpdateTable}
                />
              ),
            };
          })}
        />
      </>
    );
  };

  const Step3Comp = () => {
    return (
      <div className="flex justify-center items-center h-full">
        {okLoading ? (
          <Spin spinning={okLoading} tip="正在同步数据...">
            <div className="w-500px h-full"></div>
          </Spin>
        ) : (
          <>
            {resultStatus === "success" ? (
              <Result
                status="success"
                title={`数据${tabActiveKey === '1' ? '拉取' : '推送'}完成！`}
                subTitle="请查看数据表的数据信息"
              />
            ) : (
              <Result
                status="error"
                title={`数据${tabActiveKey === '1' ? '拉取' : '推送'}失败！`}
                subTitle="请检查数据表的数据信息"
              />
            )}
          </>
        )}
      </div>
    );
  };

  const handlePush = async () => {
    setStep(2);
    try {
      setOkLoading(true);
      await PushDataModelTable(selectedRows);
      // message.success("同步推送完成");

      setResultStatus("success");
    } catch (err) {
      setResultStatus("error");
    } finally {
      setOkLoading(false);
    }
  };

  const handlePull = async () => {
    setOkLoading(true);
    try {
      // 1、更新原有表的数据
      const tableIds = selectedRows.map(({ table }) => table.id);
      await SaveDataModel({
        erDataModel: {
          ...project,
          tables: project.tables.map((item) => {
            if (tableIds.includes(item.table.id)) {
              return (
                selectedRows.find((t) => t.table.id === item.table.id) ||
                item
              );
            }
            return item;
          }),
        },
      });
    } catch (err) {
      console.log(err);
      message.error("拉取失败");
      setResultStatus("error");
    }

    // 2、添加引入数据
    try {
      const businessTables =
        data1?.result
          ?.filter((item: any) => importTables?.includes(item.id))
          ?.map((item: any) => {
            return pick(item, [
              "aliasName",
              "schemaName",
              "id",
              "parentBusinessTableId",
            ]);
          }) || [];
      if (!businessTables.length) {
        setResultStatus("success");
        setStep(2);
        return;
      }
      await ImportFromBusinessTables({
        dataModelId: project.id,
        color,
        businessTables,
      });
    } catch (err) {
      console.log(err);
      message.error("引入失败");
      setResultStatus("error");
    } finally {
      setOkLoading(false);
      setStep(2);
    }
  };

  const handleDone = () => {
    setOpen(false);
    props.onPush?.();
  };

  return (
    <Modal
      title="数据同步"
      width={"100%"}
      open={open}
      loading={loading}
      style={{
        top: 10,
        padding: 0,
      }}
      bodyProps={{
        style: {
          height: "80vh",
          overflowY: "auto",
        },
      }}
      okButtonProps={{
        loading: okLoading,
        disabled: !selectedRows.length,
      }}
      onCancel={() => setOpen(false)}
      footer={(_, { CancelBtn }) => {
        return (
          <>
            <CancelBtn />
            {step === 0 && (
              <Button
                type="primary"
                disabled={!selectedRows.length}
                onClick={() => setStep(step + 1)}
              >
                下一步
              </Button>
            )}
            {step > 0 && (
              <Button onClick={() => setStep(step - 1)}>上一步</Button>
            )}
            {step === 2 && resultStatus === "success" && (
              <Button type="primary" onClick={handleDone}>
                完成
              </Button>
            )}
            {step === 1 && tabActiveKey === "1" && (
              <Button type="primary" onClick={handlePull}>
                开始
              </Button>
            )}
            {step === 1 && tabActiveKey === "2" && (
              <Button type="primary" onClick={handlePush}>
                开始
              </Button>
            )}
          </>
        );
      }}
    >
      <Tabs
        activeKey={tabActiveKey}
        onChange={setTabActiveKey}
        items={[
          {
            key: "1",
            label: "拉取",
            children: (
              <div className="h-full flex flex-col overflow-hidden">
                <div className="py-12px px-30px">
                  <Steps
                    current={step}
                    // progressDot
                    items={[
                      {
                        title: "选择数据表",
                        description: "选择需要拉取的表",
                      },
                      {
                        title: "差异对比",
                        description: "数据模型与数据表进行对比",
                      },
                      {
                        title: "结果",
                        description: "拉取到模型",
                      },
                    ]}
                  />
                </div>
                {step === 0 && (
                  <>
                    <Form>
                      <Form.Item label="引入表" name="table">
                        <TreeSelect
                          multiple
                          treeCheckable
                          allowClear
                          placeholder="请选择"
                          loading={loading1}
                          treeData={treeData}
                          value={importTables}
                          onChange={(value) => {
                            setImportTables(value);
                          }}
                        />
                      </Form.Item>
                      <Form.Item label="颜色" name="color">
                        <CustomColorPicker onChange={setColor}>
                          {color ? (
                            <div
                              className="rounded-4px cus-btn w-32px h-32px bg-#eee flex-none cursor-pointer shadow-inner"
                              style={{ background: color || "#eee" }}
                            ></div>
                          ) : (
                            <span className="bg-#eee px-5px py-3px rounded-4px cursor-pointer text-12px text-#666">
                              随机生成,点击可选择颜色
                            </span>
                          )}
                        </CustomColorPicker>
                      </Form.Item>
                    </Form>
                    <Step1Comp />
                  </>
                )}
                {step === 1 && <Step2Comp />}
                {step === 2 && <Step3Comp />}
              </div>
            ),
          },
          {
            key: "2",
            label: "推送",
            children: (
              <div className="h-full flex flex-col overflow-hidden">
                <div className="py-12px px-30px">
                  <Steps
                    current={step}
                    // progressDot
                    items={[
                      {
                        title: "选择数据表",
                        description: "选择需要同步的表",
                      },
                      {
                        title: "差异对比",
                        description: "数据模型与数据表进行对比",
                      },
                      {
                        title: "结果",
                        description: "推送到数据表",
                      },
                    ]}
                  />
                </div>
                <div className="flex-1 overflow-auto">
                  {step === 0 && <Step1Comp />}
                  {step === 1 && <Step2Comp />}
                  {step === 2 && <Step3Comp />}
                </div>
              </div>
            ),
          },
        ]}
      />
      {!tableList.length && (
        <Empty
          image={NoData}
          description="当前模型表为空，请添加后再进行同步！"
        />
      )}
    </Modal>
  );
});
