import type { TableItemType, ColumnItem } from "@/type";
import React, { useEffect, useState } from "react";
import {
  ProDescriptions,
  ProDescriptionsProps,
} from "@ant-design/pro-components";
import LangInput from "@/components/LangInput";
import LangInputTextarea from "@/components/LangInputTextarea";
import { Button, Table, Tooltip, TableProps, Spin } from "antd";
import { validateAliasName, validateTableCode } from "@/utils/validator";
import { GetBusinessTablesByTableId, GetAllBusinessTableColumns, ListLangByKey } from "@/api";
import { useRequest } from "umi";
import { DoubleLeftOutlined } from "@ant-design/icons";
import { createColumn } from "@/utils";
import { pick } from "lodash-es";

const baseColumns: TableProps["columns"] = [
  {
    title: "字段代码",
    dataIndex: "schemaName",
  },
  {
    title: "字段名称",
    dataIndex: "name",
    render: (_dom, entity) => {
      return entity.langNameList
        ? entity.langNameList.find(
            (item: Record<string, string>) => item.name === "zh-CN"
          )?.value || "-"
        : entity.name;
    },
  },
  {
    title: "类型",
    dataIndex: "type",
  },
  {
    title: "长度",
    dataIndex: "maxLength",
  },
  {
    title: "必填",
    dataIndex: "isRequired",
  },
  {
    title: "唯一",
    dataIndex: "isUnique",
  },
  {
    title: "默认值",
    dataIndex: "defaultValue",
  },
  {
    title: "字符集",
    dataIndex: "chartset",
  },
  {
    title: "内容",
    dataIndex: "whereInputContent",
  },
  {
    title: "描述",
    dataIndex: "memo",
  },
];

// 表详情组件
const DescComp = function ({
  detail,
  editable,
  title,
}: {
  detail: TableItemType["table"];
  editable?: ProDescriptionsProps["editable"];
  title?: string;
}) {
  return (
    <ProDescriptions
      title={title}
      dataSource={detail}
      editable={editable}
      columns={[
        {
          label: "类型",
          dataIndex: "type",
          valueType: "select",
          valueEnum: {
            3: "业务表",
            2: "流程表",
          },
          editable: false,
        },
        {
          label: "编码",
          dataIndex: "schemaName",
          valueType: "text",
          formItemProps: {
            rules: [
              { required: true, message: "请输入编码" },
              validateTableCode,
            ],
          },
        },
        {
          label: "别名",
          dataIndex: "aliasName",
          valueType: "text",
          formItemProps: {
            rules: [
              { required: true, message: "请输入别名" },
              validateAliasName,
            ],
          },
        },
        {
          label: "名称",
          dataIndex: "langNameList",
          render: (_, record) => {
            return (
              record.langNameList?.find((item: any) => item.name === "zh-CN")
                ?.value || "-"
            );
          },
          renderFormItem: (_schema, config, form) => {
            return (
              <LangInput
                style={{ width: 200 }}
                onChange={(val) => form.setFieldValue("langNameList", val)}
              />
            );
          },
        },
        {
          label: "描述",
          dataIndex: "langDescriptionList",
          render: (_, record) => {
            return (
              record?.langDescriptionList?.find(
                (item: any) => item.name === "zh-CN"
              )?.value || "-"
            );
          },
          renderFormItem: (_schema, config, form) => {
            return (
              <>
                <LangInputTextarea
                  value={form.getFieldValue("langDescriptionList")}
                  onChange={(val) =>
                    form.setFieldValue("langDescriptionList", val)
                  }
                />
              </>
            );
          },
        },
      ]}
    ></ProDescriptions>
  );
};
export default function DiffTable({
  sourceTable,
  targetTableId,
  onChange
}: {
  sourceTable: TableItemType;
  targetTableId?: string;
  onChange: (tableItem: TableItemType) => void;
}) {
  const [selectedKeys, setSelectedKeys] = useState<React.Key[]>([]);
  const [selectedRows, setSelectedRows] = useState<any[]>([]);

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

  const {
    data: tableColumnRes,
    run: run2,
    loading: loading2,
  } = useRequest(GetAllBusinessTableColumns, { manual: true });

  useEffect(() => {
    if (targetTableId) {
      run1(targetTableId);
      run2({
        currentPage: 1,
        pageSize: 2000,
        orderByProperty: "isPreDefined DESC, DisplayOrder",
        Ascending: true,
        totalPage: 1,
        totalCount: 1,
        filters: [
          {
            name: "BusinessTableId",
            value: targetTableId,
          },
        ],
      });
    }
  }, []);

  // 右侧选中数据覆盖左侧数据
  const handleCoverTable = async () => {
    if(!selectedRows.length) return;
    const arr = [...sourceTable.tableColumnList];

    // 获取全部多语言数据
    const langList = await Promise.all(
      [...new Set(selectedRows.map(item => item.langName))].map((key) =>
        ListLangByKey({ key }).then((res) => res.result)
      )
    );

    // 1、存在的数据进行更新
    // 2、不存在的数据进行新增
    selectedRows.forEach((item) => {
      const index = arr.findIndex(
        (item2: any) => item2.schemaName === item.schemaName
      );
      const newColumn = createColumn(sourceTable.table.id);
      const langName = langList.find((lang) => lang.key === item.langName);

      const column = {
        ...newColumn,
        ...pick(item, Object.keys(newColumn)),
        langNameList: [
          { name: "zh-CN", value: langName?.["zh-CN"] || "" },
          { name: "en", value: langName?.["en"] || "" },
        ],
      };
      if (index !== -1) {
        arr[index] = column;
      } else {
        arr.push(column);
      }
    });

    onChange({
      ...sourceTable,
      tableColumnList: arr,
    });

    setSelectedKeys([]);
    setSelectedRows([]);
  };

  return (
    <Spin spinning={loading1 || loading2}>
      <div className="flex">
        <div className="left rounded-8px border border-1px border-solid border-#979797 overflow-hidden">
          <div className="h-120px p-y-10px p-l-20px">
            <DescComp
              title="当前模型表"
              detail={sourceTable.table}
              editable={{
                onSave: async (keypath, newInfo, oriInfo) => {
                  onChange({
                    ...sourceTable,
                    table: {
                      ...sourceTable.table,
                      ...newInfo
                    }
                  });
                  return true;
                },
              }}
            />
          </div>
          <Table
            pagination={false}
            columns={baseColumns}
            dataSource={sourceTable.tableColumnList || []}
          />
        </div>
        <div className="middle w-100px flex-shrink-0">
          <Tooltip title="使用右侧数据">
            <Button
              className="block m-x-auto m-y-0 m-t-140px"
              icon={<DoubleLeftOutlined />}
              disabled={!selectedKeys.length}
              onClick={handleCoverTable}
            />
          </Tooltip>
        </div>
        <div className="right rounded-8px border border-1px border-solid border-#979797 overflow-hidden">
          <div className="h-120px p-y-10px p-l-20px">
            <DescComp
              title="远程数据表"
              detail={tableDetailRes?.result?.[0] || {}}
            />
          </div>
          <Table
            pagination={false}
            columns={baseColumns}
            dataSource={tableColumnRes?.result?.model || []}
            rowSelection={{
              type: "checkbox",
              selectedRowKeys: selectedKeys,
              onChange: (keys, selectedRows) => {
                setSelectedKeys(keys);
                setSelectedRows(selectedRows);
              },
            }}
          />
        </div>
      </div>
    </Spin>
  );
}
