import {
  forwardRef,
  useImperativeHandle,
  useMemo,
  useRef,
  useState,
} from "react";
import {
  Col,
  Form,
  Input,
  message,
  Modal,
  Row,
  Select,
  Tabs,
  TabsProps,
  TreeSelect,
} from "antd";
import LangInput from "@/components/LangInput";
import LangInputTextarea from "@/components/LangInputTextarea";
import { TableType } from "@/enum";
import { createColumn, createTable } from "@/utils";
import { TableItemType } from "@/type";
import { useModel, useRequest } from "umi";
import {
  // GetAllDesignTables,
  // GetAllBusinessTableColumns,
  // GetBusinessTablesByTableId,
  // ListLangByKey,
  GetCanUseTableList,
  ImportFromBusinessTables,
} from "@/api";
import { validateTableCode, validateAliasName } from "@/utils/validator";
import { pick } from "lodash-es";
import CustomColorPicker from "@/components/CustomColorPicker";

export default forwardRef(function AddTable(
  props: {
    onChange: (tables: TableItemType[]) => void;
  },
  ref
) {
  const [open, setOpen] = useState(false);
  const tableItemRef = useRef<TableItemType>();
  const { project, graph } = useModel("erModel");
  const [tabActiveKey, setTabActiveKey] = useState("1");
  const [form] = Form.useForm();
  const [form1] = Form.useForm();
  const [formModel, setFormModel] = useState<TableItemType["table"]>();
  const [hideAddTab, setHideAddTab] = useState(false);
  const [color, setColor] = useState<string>();

  useImperativeHandle(ref, () => ({
    open: () => {
      // 获取当前模型类型
      tableItemRef.current = createTable(project.type, project.id);
      setFormModel(tableItemRef.current.table);
      setOpen(true);
      setColor(undefined);
    },
    openImportMode: () => {
      setTabActiveKey("2");
      run({ type: project?.type });
      setHideAddTab(true);
      setOpen(true);
    },
    close: () => {
      setOpen(false);
    },
  }));

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

  // 可引入表列表
  const treeData = useMemo(() => {
    const tableMap: Record<string, any> = {};
    data?.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.parentBusinessTableId],
              ...option,
            };
          } else {
            tableMap[item.id] = {
              ...option,
              children: [],
            };
          }
        }
        return;
      });
    return Object.keys(tableMap).map((key) => tableMap[key]);
  }, [data]);

  const items: TabsProps["items"] = [
    {
      key: "1",
      label: `新建`,
      children: (
        <div>
          <Form labelCol={{ span: 8 }} form={form}>
            <Row gutter={16}>
              <Col span={12}>
                <Form.Item
                  label="编码"
                  name="schemaName"
                  rules={[
                    { required: true, message: "请输入编码" },
                    validateTableCode,
                  ]}
                  tooltip="包含字母、下划线、数字, 必须小写字母开头，且必须有下划线！ 如：user_info"
                >
                  <Input
                    placeholder="请输入"
                    value={formModel?.schemaName}
                    onChange={(e) => handleChange("schemaName", e.target.value)}
                  />
                </Form.Item>
              </Col>
              <Col span={12}>
                <Form.Item label="表类型" name="type">
                  <Input
                    placeholder="请输入"
                    value={
                      formModel?.type == TableType.BusinessTable
                        ? "业务表"
                        : "视图表"
                    }
                    disabled
                  />
                </Form.Item>
              </Col>
            </Row>
            <Row gutter={16}>
              <Col span={12}>
                <Form.Item
                  label="别名"
                  name="aliasName"
                  rules={[
                    { required: true, message: "请输入别名" },
                    validateAliasName,
                  ]}
                  tooltip="包含字母、数字, 必须小写字母开头！ 如：userinfo"
                >
                  <Input
                    placeholder="请输入"
                    value={formModel?.aliasName}
                    onChange={(e) => handleChange("aliasName", e.target.value)}
                  />
                </Form.Item>
              </Col>
              <Col span={12}>
                <Form.Item label="表名" name="langNameList">
                  <LangInput
                    value={formModel?.langNameList}
                    onChange={(lang) => handleChange("langNameList", lang)}
                  />
                </Form.Item>
              </Col>
            </Row>
            <Row gutter={16}>
              <Col span={24}>
                <Form.Item
                  label="描述"
                  labelCol={{ span: 4 }}
                  name="langDescriptionList"
                >
                  <LangInputTextarea
                    value={formModel?.langDescriptionList}
                    onChange={(lang) =>
                      handleChange("langDescriptionList", lang)
                    }
                  />
                </Form.Item>
              </Col>
            </Row>
          </Form>
        </div>
      ),
    },
    {
      key: "2",
      label: `引入`,
      children: (
        <div>
          <Form labelCol={{ span: 4 }} form={form1}>
            <Form.Item
              label="选择表"
              name="table"
              rules={[{ required: true, message: "请选择表" }]}
            >
              <TreeSelect
                multiple
                treeCheckable
                allowClear
                placeholder="请选择"
                loading={loading}
                treeData={treeData}
              />
            </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>
        </div>
      ),
    },
  ];

  const handleChange = (key: string, value: any) => {
    formModel &&
      setFormModel({
        ...formModel,
        [key]: value,
      });
  };

  const [loadingColumns, setLoadingColumns] = useState(false);
  const handleOk = () => {
    // 新建
    if (tabActiveKey === "1") {
      form.validateFields().then(() => {
        if (tableItemRef.current && formModel) {
          props.onChange([
            {
              ...tableItemRef.current,
              table: formModel,
            },
          ]);
        }
        form.resetFields();
        setOpen(false);
      });
    }
    // 引入
    if (tabActiveKey === "2") {
      form1.validateFields().then(async () => {
        // 加载表格字段
        const values = form1.getFieldsValue();
        try {
          setLoadingColumns(true);

          if (values.table.length === 0) {
            message.error("请选择要引入的表");
            return;
          }

          const businessTables =
            data?.result
              ?.filter((item: any) => values.table.includes(item.id))
              ?.map((item: any) => {
                return pick(item, [
                  "aliasName",
                  "schemaName",
                  "id",
                  "parentBusinessTableId",
                ]);
              }) || [];
          const res = await ImportFromBusinessTables({
            dataModelId: project.id,
            color,
            businessTables,
          });
          console.log("导入结果：", res);
          const rect = graph?.getAllCellsBBox();
          // 计算起始位置 默认往最后加
          const startY = (rect?.height || 0) + (rect?.y || 0) + 20;
          props.onChange(res.result?.map((item: any) => {
            item.table.style = JSON.parse(item.table.style || '{}');
            item.table.style.y = startY;
            return item
          }));
          form1.resetFields();
          setOpen(false);
        } catch (err) {
          console.error(err);
          message.warning("引入失败");
        } finally {
          setLoadingColumns(false);
        }
      });
    }
  };

  const handleChangeTableActiveKey = (key: string) => {
    setTabActiveKey(key);
    if (key === "2") {
      run({ type: project.type });
    }
  };

  return (
    <Modal
      open={open}
      title="添加表"
      okText={loadingColumns ? "加载中..." : "确定"}
      cancelText="取消"
      onCancel={() => setOpen(false)}
      onOk={handleOk}
      okButtonProps={{
        loading: loadingColumns,
      }}
    >
      <Tabs
        items={items.filter((item) => (hideAddTab ? item.key === "2" : true))}
        activeKey={tabActiveKey}
        onChange={handleChangeTableActiveKey}
      />
    </Modal>
  );
});
