import { createContext, useReducer, useContext, useEffect, useRef, useState, useMemo } from "react";
import {
  Card,
  Collapse,
  List,
  Form,
  Input,
  InputNumber,
  Button,
  Select,
  Radio,
  Space,
  Table,
  Checkbox,
  Divider,
  Modal,
  Tree,
  message,
} from "antd";
import {
  PlusOutlined,
  MinusCircleOutlined,
  FileSearchOutlined,
  SettingOutlined,
} from "@ant-design/icons";
import { cloneDeep, cond, set } from "lodash";
import Sortable from "sortablejs";
import { FilterRules } from "dt-react-component";
import styles from "./index.less";

import type { InstructionItem, ContextType } from "./type";
import { shortid } from "../utils/utils";
import {
  CONDITION_DATA,
  CONDITION_DATA_TYPEB,
  CONDITION_DATA_TYPE_NOTB,
  INIT_ROW_VALUES,
  ROW_PRE_OPTIONS,
  PROPS_OPTIONS,
  SIMPLE_DATASET_FILTER_OPTIONS,
  RADIO_OPTIONS,
} from "../constants/common";

const initValues = {
  baseList: [
    {
      title: "条件判断",
      key: "ifdo",
      component: (props: any) => <FormIfdo {...props} />,
    },
    {
      title: "新增",
      key: "add",
      component: (props: any) => <FormAdd {...props} />,
    },
    {
      title: "修改",
      key: "edit",
      component: (props: any) => <FormEdit {...props} />,
      bFullMode: true,
    },
    {
      title: "删除",
      key: "del",
      component: (props: any) => <FormDel {...props} />,
      bFullMode: true,
    },
    {
      title: "复制",
      key: "copy",
      component: (props: any) => <FormCopy {...props} />,
      bFullMode: true,
    },
    {
      title: "保存",
      key: "save",
      component: (props: any) => <FormSave {...props} />,
    },
    {
      title: "过滤",
      key: "filter",
      component: (props: any) => <FormFilter {...props} />,
      bFullMode: true,
    },
    {
      title: "创建新数据集",
      key: "newempty",
      component: (props: any) => <FormNewempty {...props} />,
    },
    {
      title: "清空数据集",
      key: "emptyAll",
      component: (props: any) => <FormEmptyAll {...props} />,
    },
    {
      title: "刷新数据集",
      key: "refresh",
      component: (props: any) => <FormRefresh {...props} />,
    },
    {
      title: "清空选中行",
      key: "clearrowkey",
      component: (props: any) => <FormClearRowKey {...props} />,
    },
    {
      title: "选中表格第一行",
      key: "selectfirstline",
      component: (props: any) => <FormSelectFirstLine {...props} />,
    },
  ],
  funList: [
    {
      title: "打印",
      key: "print",
      component: (props: any) => <FormPrint {...props} />,
    },
    {
      title: "查询sql",
      key: "opensql",
      component: (props: any) => <FormOpenSql {...props} />,
    },
    {
      title: "执行sql",
      key: "exesql",
      component: (props: any) => <FormExesql {...props} />,
    },
    {
      title: "提示信息",
      key: "msg",
      component: (props: any) => <FormMsg {...props} />,
    },
  ],
  btnsList: [
    {
      title: "工具栏按钮配置",
      key: "btnhandle",
      component: (props: any) => <FormBtnHandle {...props} />,
    },
  ],
  instructionList: [], // 步骤列表
  settingPorps: {},
};

const myContext = createContext<ContextType>(null as any);
const reducer = (state: any, action: [any, any]) => {
  const [type, payload] = action;
  switch (type) {
    case "saveState":
      return {
        ...state,
        ...payload,
      };
    default:
      return {
        ...state,
        ...payload,
      };
  }
};

const oThis: any = {
  activeJson: {},
};

const convertData2Str = (dataValue: any, bList: boolean) => {
  const { type, children = [] } = dataValue;
  const childrenFilter = children.filter((child: any) => {
    if (child.children?.length) {
      return true;
    }
    if (child.rowValues) {
      const { pre1, value1, condition, pre2 } = child.rowValues;
      return (
        child.children ||
        (pre1 === "custom" && value1 !== undefined) ||
        (pre1 &&
          condition &&
          (pre2 ||
            condition?.includes("empty") ||
            condition?.includes("All") ||
            condition?.includes("One")))
      );
    }
    return false;
  });

  if (bList) {
    const result = [
      ...childrenFilter.map((child: any) => {
        if (child.children) {
          return convertData2Str(child, bList);
        } else {
          const { pre1, value1, condition, pre2, value2 } = child.rowValues;
          return [pre1, value1, condition, pre2, value2];
        }
      }),
      type,
    ];

    return result;
  }

  return childrenFilter
    .map((child: any) => {
      if (child.children) {
        return `(${convertData2Str(child, bList)})`;
      } else {
        const { pre1, value1, condition, pre2, value2 } = child.rowValues;
        let key1 = "";
        let key2 = "";
        if (pre1 === "number" || pre1 === "boolean") {
          key1 = value1;
        } else if (pre1 === "string") {
          key1 = `'${value1}'`;
        } else {
          if (
            value1?.startsWith("i") ||
            value1?.startsWith("d") ||
            value1?.startsWith("b") ||
            value1 === "enabled"
          ) {
            key1 = `\${${pre1}.${value1}}`;
          } else {
            key1 = `'\${${pre1}.${value1}}'`;
          }
        }

        if (pre2 === "number" || pre2 === "boolean") {
          key2 = value2;
        } else if (pre2 === "string") {
          key2 = `'${value2}'`;
        } else {
          if (
            value2?.startsWith("i") ||
            value2?.startsWith("d") ||
            value2?.startsWith("b") ||
            value2 === "enabled"
          ) {
            key2 = `\${${pre2}.${value2}}`;
          } else {
            key2 = `'\${${pre2}.${value2}}'`;
          }
        }

        if (condition === "includes") {
          return `${key1}.includes(${key2})`;
        } else if (condition === "!includes") {
          return `!${key1}.includes(${key2})`;
        } else if (condition === "empty") {
          return `!${key1}`;
        } else if (condition === "!empty") {
          return `!!${key1}`;
        } else if (condition === "trueAll") {
          return `$\{${pre1}@all.${value1}.===.true\}`;
        } else if (condition === "trueOne") {
          return `$\{${pre1}@one.${value1}.===.true\}`;
        } else if (condition === "falseAll") {
          return `$\{${pre1}@all.${value1}.===.false\}`;
        } else if (condition === "falseOne") {
          return `$\{${pre1}@one.${value1}.===.false\}`;
        } else if (condition.includes("All")) {
          let conditionNew = condition.replace("All", "");
          if (conditionNew === "!empty") {
            conditionNew = "!=";
          } else if (conditionNew === "empty") {
            conditionNew = "==";
          }
          return `$\{${pre1}@all.${value1}.${conditionNew}.${value2}\}`;
        } else if (condition.includes("One")) {
          let conditionNew = condition.replace("One", "");
          if (conditionNew === "!empty") {
            conditionNew = "!=";
          } else if (conditionNew === "empty") {
            conditionNew = "==";
          }
          return `$\{${pre1}@one.${value1}.${conditionNew}.${value2}\}`;
        } else if (pre1 === "custom") {
          return value1;
        } else {
          return `${key1} ${condition} ${key2}`;
        }
      }
    })
    .join(` ${type === 1 ? "&&" : "||"} `);
};

const convertStr2Data = (arr: any, level: number = 1) => {
  const type = arr.find((item: any) => typeof item === "number");
  const restArr = arr.filter((item: any) => typeof item !== "number");

  return {
    key: shortid(),
    level: level,
    type,
    children: restArr.map((child: any) => {
      if (child.some((item: any) => typeof item === "number")) {
        return convertStr2Data(child, level + 1);
      } else {
        return {
          rowValues: {
            pre1: child[0],
            value1: child[1],
            condition: child[2],
            pre2: child[3],
            value2: child[4],
          },
          key: shortid(),
          level: level,
        };
      }
    }),
  };
};

// 入口
const Index = () => {
  const [state, dispatch] = useReducer(reducer, initValues);
  const setState = (payload: any) => {
    dispatch(["saveState", payload]);
  };

  return (
    <myContext.Provider
      value={{
        setState,
        ...state,
      }}
    >
      <Card
        title={
          <div>
            指令集可视化{" "}
            <FileSearchOutlined
              onClick={() => {
                const screenWidth = window.screen.width;
                const screenHeight = window.screen.height;
                window.open(
                  location.origin + "/InsSet/指令集说明文档.html",
                  "指令集说明文档",
                  `width=${screenWidth},height=${screenHeight},left=0,top=0`
                );
              }}
            />
          </div>
        }
        className={styles.indexCard}
      >
        <Card title="指令集列表" className={styles.instructionSet}>
          <InstructionSetList />
        </Card>
        <Card title="指令集内容" className={styles.instructionContent}>
          <InstructionContent />
        </Card>
        <Card title="指令集结果" className={styles.instructionResult}>
          <InstructionResult />
        </Card>
      </Card>
      <SettingModal />
    </myContext.Provider>
  );
};

// 左侧列表区域
const InstructionSetList = () => {
  const { tableName, sFieldName, baseList, funList, btnsList, instructionList, setState } =
    useContext(myContext);

  const addInstruction = (item: any) => {
    instructionList.push({ ...item, type: item.key, key: shortid(), mode: "easy" });
    setState({ instructionList });
  };

  const ListItem = (item: any) => {
    return (
      <List.Item style={{ cursor: "default" }} onClick={addInstruction.bind(this, item)}>
        {item.title}
      </List.Item>
    );
  };

  let items = [];

  if (tableName === "master" && sFieldName === "sInstruct") {
    items = [
      {
        key: "3",
        label: "按钮指令集",
        children: <List split={false} dataSource={btnsList} renderItem={item => ListItem(item)} />,
        className: styles.collapseItem,
      },
    ];
  } else {
    items = [
      {
        key: "1",
        label: " 基础指令集",
        children: <List split={false} dataSource={baseList} renderItem={item => ListItem(item)} />,
        className: styles.collapseItem,
      },
      {
        key: "2",
        label: "功能指令集",
        children: <List split={false} dataSource={funList} renderItem={item => ListItem(item)} />,
        className: styles.collapseItem,
      },
    ];
  }

  return (
    <Collapse
      bordered={false}
      defaultActiveKey={["1", "2", "3"]}
      style={{ background: "transparent", overflow: "auto", width: "100%" }}
      items={items}
    />
  );
};

const getTargetParentAndIndex = (
  arr: InstructionItem[],
  path: number[]
): { parentArr: InstructionItem[]; targetIndex: number; targetItem: InstructionItem } | null => {
  let current: any = { children: arr };
  for (let i = 0; i < path.length - 1; i++) {
    const index = path[i];
    if (!Array.isArray(current.children) || !current.children[index]) return null;
    current = current.children[index];
  }
  const targetIndex = path[path.length - 1];
  const parentArr = current.children || [];
  const targetItem = parentArr[targetIndex];
  return { parentArr, targetIndex, targetItem };
};

const updateInstructionListByMove = (
  instructionList: InstructionItem[],
  fromPath: number[], // 被移动项的原始路径，如 [0, 1, 1]
  toPath: number[], // 目标插入位置路径，如 [0, 1, 2]
  insertIndex: number // 插入到该层级下的哪个索引
): InstructionItem[] => {
  const deepClone = cloneDeep(instructionList) as InstructionItem[];

  // Step 1: 获取要删除的节点及其父级数组和索引
  const deleteInfo = getTargetParentAndIndex(deepClone, fromPath);

  if (!deleteInfo) return instructionList;

  const { parentArr: deleteParent, targetIndex: deleteIndex, targetItem } = deleteInfo;

  // Step 2: 删除节点
  const deletedItem = deleteParent.splice(deleteIndex, 1)[0];

  // Step 3: 获取插入位置的父级数组
  const insertInfo = getTargetParentAndIndex(deepClone, toPath);
  if (!insertInfo) return instructionList;

  const { parentArr: insertParent } = insertInfo;

  // Step 4: 插入节点到指定位置
  insertParent.splice(insertIndex, 0, deletedItem);

  return deepClone;
};

const InstructionContent = () => {
  const { instructionList, setState } = useContext(myContext);

  const [treeData, setTreeData] = useState([]);
  useEffect(() => {
    const treeData = instructionList.map(item => {
      // 递归处理子节点
      const processChildren = (nodeItem: any): any => {
        const treeNode: any = {
          title: <InstructionDetail item={nodeItem} />,
          key: nodeItem.key,
          // 只有特定类型的节点才允许添加子节点，比如"条件判断"
          bDropTo: nodeItem.title === "条件判断" || nodeItem.type === "ifdo",
        };

        // 如果有子节点，递归处理
        if (nodeItem.children && nodeItem.children.length > 0) {
          treeNode.children = nodeItem.children.map((child: any) => processChildren(child));
        }

        return treeNode;
      };

      return processChildren(item);
    }) as any;

    setTreeData(treeData);
  }, [JSON.stringify(instructionList)]);

  const [expandedKeys, setExpandedKeys] = useState<any[]>([]);
  const onDrop = (info: any) => {
    const dropKey = info.node.key;
    const dragKey = info.dragNode.key;
    const dropPos = info.node.pos.split("-");
    const dropPosition = info.dropPosition - Number(dropPos[dropPos.length - 1]);

    // 如果节点被放入另一个节点内部，则将其加入展开列表
    if (!info.dropToGap) {
      setExpandedKeys(prev => [...new Set([...prev, dropKey])]);
    }

    // 克隆当前 instructionList
    const newData = cloneDeep(instructionList);

    // 查找拖拽节点和目标节点
    let dragItem: any = null;
    let dragParent: any[] = newData;
    let dragIndex = -1;

    const findDragItem = (items: any[], parent: any[], index: number) => {
      for (let i = 0; i < items.length; i++) {
        if (items[i].key === dragKey) {
          dragItem = items[i];
          dragParent = parent;
          dragIndex = i;
          return true;
        }
        if (items[i].children) {
          if (findDragItem(items[i].children, items[i].children, i)) {
            return true;
          }
        }
      }
      return false;
    };

    findDragItem(newData, newData, -1);

    // 从原位置删除拖拽节点
    if (dragItem) {
      dragParent.splice(dragIndex, 1);
    }

    // 查找目标节点并插入
    if (!info.dropToGap) {
      // 插入为子节点
      const insertIntoChildren = (items: any[]) => {
        for (let i = 0; i < items.length; i++) {
          if (items[i].key === dropKey) {
            if (!items[i].children) {
              items[i].children = [];
            }
            items[i].children.unshift(dragItem);
            return true;
          }
          if (items[i].children) {
            if (insertIntoChildren(items[i].children)) {
              return true;
            }
          }
        }
        return false;
      };

      insertIntoChildren(newData);
    } else {
      // 插入为兄弟节点
      const insertAsSibling = (items: any[]) => {
        for (let i = 0; i < items.length; i++) {
          if (items[i].key === dropKey) {
            const parent = items === newData ? newData : items;
            const dropIndex = parent.indexOf(items[i]);
            const insertIndex = dropPosition === -1 ? dropIndex : dropIndex + 1;
            parent.splice(insertIndex, 0, dragItem);
            return true;
          }
          if (items[i].children) {
            if (insertAsSibling(items[i].children)) {
              return true;
            }
          }
        }
        return false;
      };

      insertAsSibling(newData);
    }

    // 更新 instructionList
    setState({ instructionList: newData });
  };

  return (
    <Tree
      className={styles.draggableTree}
      defaultExpandAll
      expandedKeys={expandedKeys}
      onExpand={setExpandedKeys}
      draggable={{
        icon: false,
      }}
      allowDrop={info => {
        // 根据节点的自定义属性判断
        if (info.dropPosition === 0) {
          const { bDropTo } = info.dropNode;
          return !!bDropTo;
        }
        return true;
      }}
      blockNode
      showLine
      onDrop={onDrop}
      treeData={treeData}
    />
  );
};

// 中间内容区域
const InstructionContent1 = () => {
  const { instructionList, setState } = useContext(myContext);

  const listRef = useRef<any>(null);
  const instructionListRef = useRef<any>(null);

  useEffect(() => {
    instructionListRef.current = instructionList;
  }, [JSON.stringify(instructionList)]);

  useEffect(() => {
    const oDom = listRef.current as HTMLElement;
    new Sortable(oDom, {
      group: "instructionGroup", // 分组
      animation: 150, // 动画时间
      ghostClass: styles.draggableItemSelected, // 移动行样式
      handle: ".ant-collapse-header",
      draggable: ".draggable-item",
      onEnd: evt => {
        const { from, to, oldIndex, newIndex, item } = evt;

        // 根据item的data-id获取数据并删除
        const dataId = item.getAttribute("data-id") as String;
        const fromPath = dataId
          .split("-")
          .filter((_, index) => index > 0)
          .map(Number);

        // 根据to的data-id获取数据并添加到newIndex位置
        const toDataId = to.getAttribute("data-id") as String;
        const toPath = toDataId.split("-").map(Number);

        const instructionListNew = updateInstructionListByMove(
          instructionListRef.current,
          fromPath,
          toPath,
          newIndex as number
        );
        setState({ instructionList: instructionListNew });
      },
    });
  }, []);

  const RecursiveItem = ({ item, level, index }: { item: any; level: number; index: number }) => {
    const currentLevelClass = `draggable-item lv${level}`;
    const dataId = `${level - 1}-${index}`;

    return (
      <div className={currentLevelClass} data-id={dataId}>
        <InstructionDetail item={item} dataId={dataId} />
        {item.children && item.children.length > 0 && (
          <div>
            {item.children.map((child: any, index1: number) => (
              <RecursiveItem key={child.key} item={child} level={level + 1} index={index1} />
            ))}
          </div>
        )}
      </div>
    );
  };

  return (
    <div className={styles.draggableList} data-id="0" ref={listRef}>
      {instructionList.map((item: any, index) => (
        <RecursiveItem key={item.key} item={item} level={1} index={index} />
      ))}
    </div>
  );
};

// 中间内容区域-具体组件
const InstructionDetail = (props: any) => {
  const { item, dataId } = props;

  const contentData = useContext(myContext);
  const { instructionList, setState } = contentData;

  const [activeKey, setActiveKey] = useState(oThis.activeJson[item.key] || [item.key]);
  const setInstructionMode = (value: string) => {
    const { instructionListNew, targetItem } = handleGetChangeData({ ...contentData, ...props });
    targetItem.mode = value;
    setState({ instructionList: instructionListNew });
  };
  let lableTitle = item.content?.desDataset || item.content?.srcDataset;
  if (item.type === "print") {
    lableTitle = `${item.content?.reportName || ""}${item.content?.reportType || ""}`;
  }
  let label = `${item.title}${lableTitle ? `【${lableTitle}】` : ""}`;

  if (item.type === "opensql") {
    label = `${item.title}${
      item.content?.newDataset ? `-> 保存到【${item.content.newDataset}】` : ""
    }`;
  }

  return (
    <div className={styles.collapseItem} key={item.key}>
      <Collapse
        activeKey={activeKey}
        onChange={(keys: string[]) => {
          setTimeout(() => {
            if (oThis.changeMode) {
              oThis.changeMode = false;
              return;
            }
            setActiveKey(keys);
            oThis.activeJson[item.key] = keys;
          }, 10);
        }}
        items={[
          {
            key: item.key,
            label,
            extra: (
              <Space>
                {item.bFullMode && (
                  <Radio.Group
                    value={item.mode}
                    options={[
                      { value: "easy", label: "简易模式" },
                      { value: "full", label: "高级模式" },
                    ]}
                    onChange={e => {
                      oThis.changeMode = true;
                      setInstructionMode(e.target.value);
                    }}
                  />
                )}

                <Button
                  type="link"
                  onClick={event => {
                    event.stopPropagation();
                    handleUpdateData({ ...props, ...contentData }, "delete");
                  }}
                >
                  删除
                </Button>
              </Space>
            ),
            children: item.component(props),
          },
        ]}
      />
    </div>
  );
};

// 右侧结果区域
const InstructionResult = () => {
  const {
    instructionList,
    setState,
    baseList,
    funList,
    btnsList,
    configList = [],
    srcModelsList = [],
  } = useContext(myContext);

  const outputContent = instructionList
    .filter(item => item.content)
    .map(item => {
      if (item.children && item.children.length > 0) {
        const processChildren = (children: any[]): any[] => {
          return children
            .map(child => {
              if (child.content) {
                if (child.children && child.children.length > 0) {
                  return {
                    ...child.content,
                    conditions: [
                      {
                        condition: child.content.condition,
                        commands: processChildren(child.children),
                      },
                    ],
                  };
                }
                return child.content;
              }
              return null;
            })
            .filter(Boolean);
        };

        return {
          ...item.content,
          conditions: [
            {
              condition: item.content.condition,
              commands: processChildren(item.children),
            },
          ],
        };
      }

      return item.content;
    });

  useEffect(() => {
    if (!configList.length) return;

    const configOptions = configList.map((item: any) => ({
      label: item.showName,
      value: item.tableName,
      tableName: item.sTbName,
    }));
    const configValueOptions = configList.reduce((pre: any, cur: any) => {
      pre[cur.tableName] = cur.gdsconfigformslave
        .filter((x: any) => x.sName && x.showName && !x.sControlName?.startsWith("Btn"))
        .map((x: any) => ({ label: x.showName, value: x.sName }));
      return pre;
    }, {});

    const propsOptions = [
      {
        label: "是否可编辑",
        value: "enabled",
      },
      {
        label: "模块id",
        value: "sSrcModelsId",
      },
    ];

    configValueOptions.props = propsOptions;

    let srcModelsOptions = [];
    if (srcModelsList.length) {
      const showKey = Object.keys(srcModelsList[0])[0];
      srcModelsOptions = srcModelsList.map((x: any) => ({
        label: x[showKey],
        value: x.sId,
      }));
    }

    setState({ configOptions, configValueOptions, srcModelsOptions });
  }, [configList.length]);

  const onReceiveData = (event: any) => {
    // 验证来源
    if (!document.referrer.includes(event.origin)) {
      return;
    }

    // 处理接收到的命令
    if (event.data.command === "initData") {
      const value = event.data.value || [];

      // 执行相应操作
      setState({
        tableName: event.data.tableName,
        sFieldName: event.data.sFieldName,
        slave0Data: event.data.slave0Data,
        configList: event.data.configList,
        srcModelsList: event.data.srcModelsList,
        instructionList: value.map((item: any) => {
          const allList = [...baseList, ...funList, ...btnsList];
          const config = allList.find(listItem => listItem.key === item.opr);
          // const bFullMode = item.bFullMode;
          // delete item.bFullMode;
          const result = {
            ...config,
            type: config?.key,
            key: shortid(),
            mode: "full",
            content: item,
          };
          // if (bFullMode) {
          //   result.bFullMode = true;
          // }
          return result;
        }),
      });
    }
  };

  useEffect(() => {
    window.addEventListener("message", onReceiveData);
    try {
      window.parent.postMessage(
        {
          command: "initData",
        },
        document.referrer
      );
    } catch (error) {}
    return () => {
      window.removeEventListener("message", onReceiveData);
    };
  }, []);
  // 复制到剪贴板
  const handleCopy = (bZip: boolean) => {
    const value = bZip ? JSON.stringify(outputContent) : JSON.stringify(outputContent, null, 2);
    navigator.clipboard.writeText(value);
  };

  const handleSave = () => {
    window.parent.postMessage(
      {
        command: "saveData",
        data: outputContent,
      },
      document.referrer
    );
  };

  return (
    <div
      style={{
        width: "100%",
        height: "100%",
        display: "flex",
        flexDirection: "column",
        alignItems: "center",
        justifyContent: "center",
      }}
    >
      <Input.TextArea
        style={{ height: "calc(100% - 40px)" }}
        value={JSON.stringify(outputContent, null, 2)}
        readOnly
      />
      <Space align="center" style={{ height: 40 }}>
        <Button type="primary" onClick={handleCopy.bind(this, true)}>
          压缩复制
        </Button>
        {/* <Button type="primary" onClick={handleCopy.bind(this, false)}>
          格式化复制
        </Button> */}
        <Button type="primary" onClick={handleSave.bind(this)}>
          保存
        </Button>
      </Space>
    </div>
  );
};

const FormIfdo = (props: any) => {
  const [formProps, commonProps] = useFormCommon(props);
  const { form } = commonProps;
  const conditionType = Form.useWatch("conditionType", form) || "0";

  return (
    <>
      <Form {...formProps}>
        <Form.Item name="conditionType" label=" " colon={false}>
          <Radio.Group
            defaultValue={"0"}
            options={[
              { value: "0", label: "自定义规则" },
              { value: "1", label: "数据集为空" },
              { value: "2", label: "数据集不为空" },
            ]}
          />
        </Form.Item>
        {conditionType === "0" && <CommonDataset {...commonProps} />}
        {conditionType === "0" ? (
          <CommonCondition {...commonProps} dependsWith="dataset" />
        ) : conditionType === "1" ? (
          <CommonDataset
            {...commonProps}
            sName="conditionEmpty"
            sLabel="为空数据集"
            onlyAllData
            bMust
          />
        ) : (
          <CommonDataset
            {...commonProps}
            sName="conditionNotEmpty"
            sLabel="不为空数据集"
            onlyAllData
            bMust
          />
        )}
        <CommonSaveBtn {...commonProps} />
      </Form>
    </>
  );
};

// 新增
const FormAdd = (props: any) => {
  const [formProps, commonProps] = useFormCommon(props);
  return (
    <Form {...formProps}>
      <CommonInput {...commonProps} />
      <CommonDataset {...commonProps} />
      <CommonSValue {...commonProps} />
      <CommonSaveBtn {...commonProps} />
    </Form>
  );
};

// 编辑
const FormEdit = (props: any) => {
  const [formProps, commonProps] = useFormCommon(props);
  const bFullMode = props.item.mode === "full";
  return (
    <Form {...formProps}>
      <CommonInput {...commonProps} bFilter />
      <CommonDataset {...commonProps} />
      {bFullMode && <CommonCondition {...commonProps} />}
      <CommonSValue {...commonProps} />
      <CommonSaveBtn {...commonProps} />
    </Form>
  );
};

// 删除
const FormDel = (props: any) => {
  const [formProps, commonProps] = useFormCommon(props);
  const bFullMode = props.item.mode === "full";
  return (
    <Form {...formProps}>
      <CommonInput {...commonProps} bFilter />
      {bFullMode && <CommonDataset {...commonProps} />}
      {bFullMode && <CommonCondition {...commonProps} />}
      <CommonSaveBtn {...commonProps} />
    </Form>
  );
};

// 复制
const FormCopy = (props: any) => {
  const [formProps, commonProps] = useFormCommon(props);
  const bFullMode = props.item.mode === "full";
  return (
    <Form {...formProps}>
      <CommonInput {...commonProps} sName="srcDataset" sLabel="数据源(复制从)" bFilter />
      <CommonInput {...commonProps} sName="newDataset" sLabel="数据源(复制到)" />
      {bFullMode && <CommonDataset {...commonProps} />}
      {bFullMode && <CommonSValue {...commonProps} />}
      <CommonSaveBtn {...commonProps} />
    </Form>
  );
};

// 保存
const FormSave = (props: any) => {
  const [formProps, commonProps] = useFormCommon(props);
  const { form, configOptions = [] } = commonProps;
  const saveType = Form.useWatch("saveType", form);
  const data = Form.useWatch("data", form) || [];

  return (
    <Form {...formProps}>
      <Form.Item name="saveType" label=" " colon={false}>
        <Radio.Group
          defaultValue={"saveAll"}
          options={[
            { value: "saveAll", label: "保存全部数据集" },
            { value: "saveCustom", label: "保存指定数据集" },
          ]}
        />
      </Form.Item>
      {saveType === "saveCustom" && (
        <>
          <Form.List name="data">
            {(fields, { add, remove }) => (
              <>
                {fields.map(field => {
                  const srcDataset = data[field.name]?.srcDataset;
                  const selectValue = configOptions.some((item: any) => item.value === srcDataset)
                    ? srcDataset
                    : "custom";
                  return (
                    <Space key={field.key} align="baseline">
                      <Form.Item
                        {...field}
                        label="数据集名称"
                        name={[field.name, "srcDataset"]}
                        rules={[{ required: true, message: "请输入数据集名称" }]}
                      >
                        <Input
                          addonBefore={
                            <Select
                              options={[...configOptions, { label: "自定义", value: "custom" }]}
                              value={selectValue}
                              style={{ minWidth: 100 }}
                              popupMatchSelectWidth={false}
                              onChange={(value, option) => {
                                // 给Input赋值
                                form.setFieldsValue({
                                  data: form.getFieldValue("data").map((item: any, index: number) =>
                                    index === field.name
                                      ? {
                                          ...item,
                                          srcDataset: value === "custom" ? "" : value,
                                          tablename: option.tableName || "",
                                        }
                                      : item
                                  ),
                                });
                              }}
                            />
                          }
                        />
                      </Form.Item>
                      <Form.Item
                        {...field}
                        label="数据库表名"
                        name={[field.name, "tablename"]}
                        rules={[{ required: true, message: "请输入数据库表名" }]}
                      >
                        <Input />
                      </Form.Item>
                      <MinusCircleOutlined onClick={() => remove(field.name)} />
                    </Space>
                  );
                })}

                <Form.Item label=" " colon={false}>
                  <Button
                    type="dashed"
                    style={{ width: 502 }}
                    onClick={() => add()}
                    block
                    icon={<PlusOutlined />}
                  >
                    新增
                  </Button>
                </Form.Item>
              </>
            )}
          </Form.List>

          <CommonCheckBox {...commonProps} sName="doNotValidate" sLabel="保存不进行校验" />
          <CommonCheckBox {...commonProps} sName="doNotRefresh" sLabel="保存后不刷新表格" />
        </>
      )}
      <CommonSaveBtn {...commonProps} />
    </Form>
  );
};

// 过滤
const FormFilter = (props: any) => {
  const [formProps, commonProps] = useFormCommon(props);
  const bFullMode = props.item.mode === "full";
  return (
    <Form {...formProps}>
      <CommonInput {...commonProps} sName="srcDataset" sLabel="数据源(过滤从)" bFilter />
      <CommonInput {...commonProps} sName="newDataset" sLabel="数据源(过滤到)" />
      {bFullMode && <CommonDataset {...commonProps} />}
      {bFullMode && <CommonCondition {...commonProps} />}
      <CommonSaveBtn {...commonProps} />
    </Form>
  );
};

// 创建新数据集
const FormNewempty = (props: any) => {
  const [formProps, commonProps] = useFormCommon(props);
  const radioValue =
    Form.useWatch("radioValue", formProps.form) ||
    (props.item.content?.desDataset ? "desDataset" : "") ||
    "srcDataset";
  return (
    <Form {...formProps}>
      <Form.Item name="radioValue" label=" " colon={false}>
        <Radio.Group
          value={radioValue}
          options={[
            { value: "srcDataset", label: "新增临时数据集" },
            { value: "desDataset", label: "覆盖已有数据集" },
          ]}
          onChange={e => {
            formProps.form.setFieldValue("radioValue", e.target.value);
          }}
        />
        <Input style={{ display: "none" }} />
      </Form.Item>
      {radioValue === "srcDataset" ? (
        <CommonInput {...commonProps} sName="srcDataset" />
      ) : (
        <CommonInput {...commonProps} />
      )}
      <CommonSaveBtn {...commonProps} />
    </Form>
  );
};

// 清空数据集
const FormEmptyAll = (props: any) => {
  const [formProps, commonProps] = useFormCommon(props);
  return (
    <Form {...formProps}>
      <CommonInput {...commonProps} bMuti sLabel="数据集名称" />
      <CommonSaveBtn {...commonProps} />
    </Form>
  );
};

// 刷新数据集
const FormRefresh = (props: any) => {
  const [formProps, commonProps] = useFormCommon(props);
  return (
    <Form {...formProps}>
      <CommonInput {...commonProps} bMuti sLabel="数据集名称" sName="dataset" />
      <CommonSaveBtn {...commonProps} />
    </Form>
  );
};

// 清空选中行
const FormClearRowKey = (props: any) => {
  const [formProps, commonProps] = useFormCommon(props);
  return (
    <Form {...formProps}>
      <CommonInput {...commonProps} bMuti sLabel="数据集名称" sName="dataset" />
      <CommonSaveBtn {...commonProps} />
    </Form>
  );
};

// 选中表格第一行
const FormSelectFirstLine = (props: any) => {
  const [formProps, commonProps] = useFormCommon(props);
  return (
    <Form {...formProps}>
      <CommonInput {...commonProps} bMuti sLabel="表格名称" sName="dataset" />
      <CommonSaveBtn {...commonProps} />
    </Form>
  );
};

// 打印
const FormPrint = (props: any) => {
  const [formProps, commonProps] = useFormCommon({
    ...props,
    formPreFuc: (values: any) => {
      return {
        ...values,
        srcDataset: values.srcDataset?.split(",").filter((item: any) => item),
      };
    },
  });
  return (
    <Form {...formProps}>
      <CommonInput
        {...commonProps}
        sName="reportName"
        sLabel="报表名称"
        noAddonBefore
        extraProps={{ placeholder: "请输入报表名称(举例:生产工单报表)" }}
      />
      <CommonSelect
        {...commonProps}
        sName="reportType"
        sLabel="报表类型"
        options={[
          { label: "PDF", value: ".pdf" },
          { label: "Execl", value: ".xlsx" },
        ]}
      />
      <CommonDataset {...commonProps} sName="srcDataset" sLabel="数据源" bMust />
      <CommonSingleChoice {...commonProps} sName="bPreviewOnly" sLabel="不显示打印" />
      <CommonSaveBtn {...commonProps} />
    </Form>
  );
};

// 查询sql
const FormOpenSql = (props: any) => {
  const [formProps, commonProps] = useFormCommon(props);
  return (
    <Form {...formProps}>
      <CommonDataset {...commonProps} sName="srcDataset" sLabel="数据源" bMust />
      <CommonInput {...commonProps} sName="newDataset" sLabel="数据集(保存到)" bMust />
      <CommonInput
        {...commonProps}
        sName="sql"
        sLabel="sql查询语句"
        bMust
        bArea
        extraProps={{
          placeholder:
            "举例：select sBoardNo FROM plc_machinedate_tray WHERE sWorkOrderId = ${sWorkOrderId} limit 1",
        }}
      />
      <CommonInput
        {...commonProps}
        sName="sSqlCondition"
        sLabel="sql条件"
        bMust
        bArea
        extraProps={{ placeholder: "举例：slave.sWorkOrderId.sWorkOrderId" }}
      />
      <CommonSaveBtn {...commonProps} />
    </Form>
  );
};

// 执行sql
const FormExesql = (props: any) => {
  const [formProps, commonProps] = useFormCommon(props);
  return (
    <Form {...formProps}>
      <CommonDataset {...commonProps} sName="srcDataset" sLabel="数据源" bMust />
      <CommonInput
        {...commonProps}
        sName="sSqlCondition"
        sLabel="sql执行语句"
        bMust
        bArea
        extraProps={{
          placeholder: "举例：update plc_machinedate_tray SET bWlStatus= 1 WHERE sId=${sParentId}",
        }}
      />
      <CommonSaveBtn {...commonProps} />
    </Form>
  );
};

// 消息提示
const FormMsg = (props: any) => {
  const [formProps, commonProps] = useFormCommon(props);
  const { form } = commonProps;
  const codeValue = Form.useWatch("code", form);

  return (
    <Form {...formProps}>
      <Form.Item
        label="消息类型"
        name="code"
        rules={[{ required: true, message: "请选择消息类型" }]}
      >
        <Select
          value={codeValue}
          options={[
            {
              label: "成功(code:1)",
              value: 1,
              className: styles.code1,
            },
            {
              label: "错误(code:-1)",
              value: -1,
              className: styles.code_1,
            },
            {
              label: "错误(code:-8)",
              value: -8,
              className: styles.code_8,
            },
            {
              label: "提示(code:2)",
              value: 2,
              className: styles.code2,
            },
            {
              label: "确认(code:-7)",
              value: -7,
              className: styles.code_7,
            },
          ]}
        />
      </Form.Item>
      <CommonInput {...commonProps} sName="msg" sLabel="消息内容" bMust bArea />
      <CommonInputNumber
        {...commonProps}
        sName="time"
        sLabel="弹窗持续时间"
        extraProps={{ addonAfter: "秒", placeholder: "2" }}
      />
      <CommonSaveBtn {...commonProps} />
    </Form>
  );
};

// 按钮组件
const FormBtnHandle = (props: any) => {
  const [formProps, commonProps] = useFormCommon(props);
  const { slave0Data, setState, settingPorps = {} } = useContext(myContext);
  const { form } = commonProps;

  const selectData = useMemo(
    () =>
      slave0Data
        ?.filter((item: any) => item.bVisible && item.sControlName?.startsWith("Btn"))
        .map((item: any) => ({
          label: item.sChinese,
          value: item.sControlName,
        })) || [],
    [!!slave0Data]
  );

  const { open, condition, conditionData, index, name } = settingPorps;
  useEffect(() => {
    if (!open) {
      const data = [...(form.getFieldValue("data") || [])];
      if (condition && conditionData) {
        data[index][name] = condition;
        data[index][`${name}Data`] = conditionData;
        form.setFieldValue("data", data);
      } else if (conditionData == "[1]") {
        delete data[index][name];
        delete data[index][`${name}Data`];
      }
      setTimeout(() => {
        setState({
          settingPorps: {},
        });
        form.submit();
      }, 100);
    }
  }, [open]);

  const handleOpenSettingModal = (index: number, name: string) => {
    const itemData = form.getFieldValue("data")[index];
    if (!itemData) {
      message.error("请先选择按钮名称！");
      return;
    }
    setState({
      settingPorps: {
        open: true,
        index,
        name,
        conditionData: form.getFieldValue("data")[index][`${name}Data`],
      },
    });
  };

  const removeLine = (index: number) => {
    const data = [...form.getFieldValue("data")];
    data.splice(index, 1);
    form.setFieldValue("data", data);
    form.submit();
  };

  return (
    <Form {...formProps}>
      <Form.List name="data">
        {(fields, { add, remove }) => (
          <>
            {fields.map((field, index) => (
              <>
                <Divider orientation="left" style={{ position: "relative" }}>
                  配置{index + 1}
                  <MinusCircleOutlined
                    style={{ position: "absolute", right: 8, top: 5, color: "red" }}
                    onClick={() => removeLine(index)}
                  />
                </Divider>
                <Form.Item
                  {...field}
                  label="按钮名称"
                  name={[field.name, "name"]}
                  rules={[{ required: true, message: "请输入按钮名称" }]}
                >
                  <Select
                    options={selectData}
                    mode="tags"
                    onBlur={() => {
                      form.submit();
                    }}
                  />
                </Form.Item>
                <Form.Item
                  {...field}
                  label="可点击条件"
                  name={[field.name, "enabled"]}
                  extra={
                    <Button
                      type="primary"
                      className={styles.settingBtn}
                      onClick={handleOpenSettingModal.bind(this, index, "enabled")}
                    >
                      <span>配</span>
                      <span>置</span>
                    </Button>
                  }
                >
                  <Input.TextArea readOnly style={{ width: "calc(100% - 30px)" }}></Input.TextArea>
                </Form.Item>
                <Form.Item
                  {...field}
                  label="可显示条件"
                  name={[field.name, "show"]}
                  extra={
                    <Button
                      type="primary"
                      className={styles.settingBtn}
                      onClick={handleOpenSettingModal.bind(this, index, "show")}
                    >
                      <span>配</span>
                      <span>置</span>
                    </Button>
                  }
                >
                  <Input.TextArea readOnly style={{ width: "calc(100% - 30px)" }} />
                </Form.Item>
              </>
            ))}

            <Form.Item label=" " colon={false}>
              <Button
                type="dashed"
                style={{ width: "100%" }}
                onClick={() => add()}
                block
                icon={<PlusOutlined />}
              >
                新增
              </Button>
            </Form.Item>
          </>
        )}
      </Form.List>
      <CommonSaveBtn {...commonProps} />
    </Form>
  );
};

const SettingModal = () => {
  const { setState, settingPorps } = useContext(myContext);
  const { open, index, name, conditionData } = settingPorps;

  if (!open) return "";

  const initData = {
    key: shortid(),
    level: 1,
    type: 1,
    children: [
      {
        rowValues: INIT_ROW_VALUES,
        key: shortid(),
        level: 1,
      },
    ],
  };

  const [data, setData] = useState(
    conditionData ? convertStr2Data(JSON.parse(conditionData)) : initData
  );
  const onCancel = () => {
    setState({ settingPorps: { open: false } });
  };

  const onOk = () => {
    const condition = convertData2Str(data, false);

    const conditionData = JSON.stringify(convertData2Str(data, true));
    setState({ settingPorps: { open: false, condition, conditionData, index, name } });
  };

  return (
    <Modal
      title="配置"
      open={open}
      className={styles.settingModal}
      footer={
        <Space style={{ position: "fixed", bottom: 42, right: 40 }}>
          <Button type="primary" onClick={onOk}>
            确认
          </Button>
          <Button onClick={onCancel}>取消</Button>
        </Space>
      }
      onCancel={onCancel}
    >
      <FilterRules
        component={props => <MyFilterRulesGroup {...props} dataSetList={[]} />}
        value={data}
        onChange={(value: any) => {
          let valueNew = cloneDeep(value);
          if (!valueNew) {
            valueNew = initData;
          } else if (!valueNew.children) {
            valueNew = {
              key: shortid(),
              level: 1,
              type: 1,
              children: [value],
            };
          } else if (!valueNew.children.length) {
            valueNew = initData;
          }
          setData(valueNew);
        }}
        initValues={INIT_ROW_VALUES}
        notEmpty={{ data: false }}
      />
    </Modal>
  );
};

const useFormCommon = (props: any) => {
  const { ...rest } = useContext(myContext);
  const [form] = Form.useForm();
  useEffect(() => {
    const { item, formPreFuc } = props;
    const { content = {} } = item;
    const { dataset, data } = content;
    let initValue = {
      ...content,
      dataset: dataset?.split(",").filter((item: any) => item),
    };
    if (data?.length) {
      initValue.data = data.map((item: any) => {
        if (item.name && typeof item.name === "string") {
          return { ...item, name: item.name.split(",").filter((item: any) => item) };
        }
        return item;
      });
    }
    if (formPreFuc) {
      initValue = formPreFuc(initValue);
    }
    form.setFieldsValue(initValue);
  }, []);

  const commonProps = {
    ...props,
    ...rest,
    form,
  };
  const onFinish = () => {
    handleUpdateData({ ...commonProps });
  };

  const formProps = {
    form,
    labelCol: { flex: "150px" },
    wrapperCol: { flex: "auto" },
    autoComplete: "off",
    onFinish,
  };
  return [formProps, commonProps];
};

const CommonInput = (props: any) => {
  const {
    form,
    sName = "desDataset",
    sLabel = "数据集名称",
    bMuti,
    bFilter,
    bArea,
    noAddonBefore,
    extraProps = {},
    configOptions = [],
  } = props;

  let inputValue = Form.useWatch(sName, form) || [];
  inputValue = inputValue.toString() || "";

  const [valueFilter, afterValue = ""] = inputValue.split("@");

  return (
    <>
      {bMuti && (
        <Form.Item label={sLabel}>
          <Select
            options={[...configOptions]}
            value={inputValue ? inputValue.split(",") : []}
            mode="tags"
            onChange={value => form.setFieldsValue({ [sName]: value.join(",") })}
            {...extraProps}
          />
        </Form.Item>
      )}
      <Form.Item
        label={sLabel}
        name={sName}
        rules={[{ required: true, message: `请输入${sLabel}` }]}
        hidden={bMuti}
      >
        {bArea ? (
          <Input.TextArea {...extraProps} />
        ) : (
          <Input
            addonBefore={
              !noAddonBefore && (
                <Space size={20} split={<span style={{ color: "rgba(0,0,0,0.25)" }}>{">>"}</span>}>
                  <Select
                    style={{ width: 100 }}
                    popupMatchSelectWidth={false}
                    options={[...configOptions, { label: "自定义", value: "custom" }]}
                    optionRender={({ label, value }) => {
                      return (
                        <span>
                          {label}({value})
                        </span>
                      );
                    }}
                    value={
                      configOptions.some((item: any) => item.value === valueFilter)
                        ? valueFilter
                        : "custom"
                    }
                    onChange={value => {
                      let result = value === "custom" ? "" : value;
                      if (afterValue) {
                        result += `@${afterValue}`;
                      }
                      form.setFieldValue(sName, result);
                    }}
                  />
                  {bFilter && (
                    <Select
                      style={{ width: 100 }}
                      value={afterValue}
                      options={[...SIMPLE_DATASET_FILTER_OPTIONS]}
                      onChange={value => {
                        let result = valueFilter;
                        if (value) {
                          result += `@${value}`;
                        }
                        form.setFieldValue(sName, result);
                      }}
                    />
                  )}
                </Space>
              )
            }
            // addonAfter={

            // }
            {...extraProps}
          />
        )}
      </Form.Item>
    </>
  );
};

const CommonInputNumber = (props: any) => {
  const { sName = "time", sLabel = "时间", bMust = false, extraProps = {} } = props;
  return (
    <Form.Item
      label={sLabel}
      name={sName}
      rules={[{ required: bMust, message: `请输入${sLabel}` }]}
    >
      <InputNumber {...extraProps} />
    </Form.Item>
  );
};

const CommonCheckBox = (props: any) => {
  const { sName = "", sLabel = "", extraProps = {} } = props;
  return (
    <Form.Item name={sName} valuePropName="checked" label=" " colon={false} {...extraProps}>
      <Checkbox>{sLabel}</Checkbox>
    </Form.Item>
  );
};

const CommonSelect = (props: any) => {
  const { sName = "reportType", sLabel = "报表类型", options = [] } = props;
  return (
    <Form.Item label={sLabel} name={sName}>
      <Select options={options} />
    </Form.Item>
  );
};

const CommonSingleChoice = (props: any) => {
  const { sName = "bPreviewOnly", sLabel = "不显示打印" } = props;
  return (
    <Form.Item label=" " colon={false} name={sName} valuePropName="checked">
      <Checkbox>{sLabel}</Checkbox>
    </Form.Item>
  );
};

const CommonDataset = (props: any) => {
  const {
    form,
    sName = "dataset",
    sLabel = "辅助数据集",
    onlyAllData,
    bMust,
    configOptions = [],
  } = props;

  const searchRef = useRef<any>(null);
  const [searchValue, setSearchValue] = useState("");

  // 获取当前已选择的值
  const selectedValues = Form.useWatch(sName, form) || [];

  if (typeof selectedValues === "string" && selectedValues) {
    form.setFieldsValue({ [sName]: selectedValues.split(",") });
    return null;
  }

  const option0 = configOptions.map((item: { label: any; value: any }) => ({
    ...item,
    label: `${item.label}(${item.value})`,
  }));

  // 根据已选择的值动态生成选项
  const options = useMemo(() => {
    return option0.filter(
      (item: { value: string }) =>
        !selectedValues.some((i: string) => i.split("@")[0] === item.value)
    );
  }, [selectedValues]);

  return (
    <Form.Item
      label={sLabel}
      name={sName}
      rules={bMust ? [{ required: true, message: `请填写${sLabel}` }] : []}
    >
      <Select
        ref={searchRef}
        mode="tags"
        searchValue={searchValue}
        onSearch={value => setSearchValue(value)}
        onChange={() => {
          setSearchValue("");
        }}
        options={options}
        filterSort={(optionA: any, optionB: any) => {
          const valueA = optionA.value.split("@")[0];
          const valueB = optionB.value.split("@")[0];
          const bType1 = option0.some((item: any) => item.value === valueA);
          const bType2 = option0.some((item: any) => item.value === valueB);

          if (bType1 && !bType2) {
            return -1;
          }

          if (bType2 && !bType1) {
            return 1;
          }

          if (bType1 && bType2) {
            return (
              option0.findIndex((item: any) => item.value === valueA) -
              option0.findIndex((item: any) => item.value === valueB)
            );
          }

          if (!bType1 && !bType2) {
            return (
              selectedValues.findIndex((item: any) => item === optionA.value) -
              selectedValues.findIndex((item: any) => item === optionB.value)
            );
          }

          return 1;
        }}
        optionRender={option => {
          const value0 = option.value as string;
          const [label, type = ""] = value0.split("@");
          const labelNew =
            option0.find((item: { value: string }) => item.value === label)?.label || label;

          return (
            <Space>
              <div>{labelNew}</div>
              {SIMPLE_DATASET_FILTER_OPTIONS.filter(item => !onlyAllData || !item.value)
                .map(item => ({
                  title: item.label,
                  type: item.value,
                }))
                .map(item => (
                  <Button
                    type={type === item.type ? "primary" : "default"}
                    onClick={event => {
                      event.stopPropagation();
                      const selectValue = form.getFieldValue(sName) || [];
                      form.setFieldValue(sName, [
                        ...selectValue.filter((x: string) => x.split("@")[0] !== label),
                        `${label}${item.type ? "@" : ""}${item.type}`,
                      ]);
                      setSearchValue("");
                    }}
                  >
                    {item.title}
                  </Button>
                ))}
            </Space>
          );
        }}
      />
    </Form.Item>
  );
};

const CommonSValue = (props: any) => {
  const { form } = props;

  const dataset = Form.useWatch("dataset", form);
  const datasetList = dataset
    ? dataset.map((item: any) => ({
        value: item.split("@")[0],
        label: item.split("@")[0],
      }))
    : [];

  const sValue = Form.useWatch("sValue", form);
  const tableData = sValue
    ? sValue.split(",").map((item: any, index: number) => {
        if (item === "*") {
          return {
            iRowNum: index + 1,
            sFieldNameNew: "",
            sFieldNameOldPre: "*",
            sFieldNameOld: "",
          };
        }

        if (item.includes(".*")) {
          const sFieldNameOldPre = item.split(".*")[0];
          return {
            iRowNum: index + 1,
            sFieldNameNew: "",
            sFieldNameOldPre,
            sFieldNameOld: "*",
          };
        }

        const [sFieldNameNew, sFieldNameOld0 = ""] = item.split(":");
        let [sFieldNameOldPre, sFieldNameOld] = [undefined as any, ""];
        if (sFieldNameOld0.includes("$") || sFieldNameOld0.includes("var")) {
          [sFieldNameOldPre, sFieldNameOld] = ["var", sFieldNameOld0];
        } else if (sFieldNameOld0.includes(".")) {
          [sFieldNameOldPre, sFieldNameOld] = sFieldNameOld0.split(".");
        } else if (sFieldNameOld0.includes("'")) {
          [sFieldNameOldPre, sFieldNameOld] = ["string", sFieldNameOld0.replace(/'/g, "")];
        } else if (sFieldNameOld0 !== "") {
          [sFieldNameOldPre, sFieldNameOld] = ["number", sFieldNameOld0];
        } else {
          [sFieldNameOldPre, sFieldNameOld] = [undefined, ""];
        }

        return {
          iRowNum: index + 1,
          sFieldNameNew,
          sFieldNameOldPre,
          sFieldNameOld,
        };
      })
    : [];

  const handleChangeValue = (record: any) => {
    const sValueList = sValue.split(",");
    const { sFieldNameOldPre, index } = record;

    if (sFieldNameOldPre === "*") {
      sValueList[index] = "*";
    } else if (sFieldNameOldPre === "number") {
      sValueList[index] = `${record.sFieldNameNew || ""}:${Number(record.sFieldNameOld) || 0}`;
    } else if (sFieldNameOldPre === "string") {
      sValueList[index] = `${record.sFieldNameNew || ""}:'${record.sFieldNameOld || ""}'`;
    } else if (sFieldNameOldPre === "var") {
      sValueList[index] = `${record.sFieldNameNew || ""}:${record.sFieldNameOld || "${}"}`;
    } else if (sFieldNameOldPre) {
      sValueList[index] = `${record.sFieldNameNew || ""}${
        record.sFieldNameOld !== "*" ? ":" : ""
      }${sFieldNameOldPre}.${record.sFieldNameOld || ""}`;
    } else {
      sValueList[index] = `${record.sFieldNameNew || ""}:`;
    }
    form.setFieldValue("sValue", sValueList.toString());
  };

  return (
    <>
      <Form.Item label="赋值" name="sValue" rules={[{ required: true, message: "请输入赋值内容" }]}>
        <Input.TextArea />
      </Form.Item>
      <Form.Item label=" " colon={false} wrapperCol={{ flex: "calc(100% - 150px)" }}>
        <Table
          bordered
          dataSource={tableData}
          columns={[
            {
              title: "#",
              width: 50,
              dataIndex: "iRowNum",
            },
            {
              title: "现字段",
              width: "auto",
              dataIndex: "sFieldNameNew",
              render: (text: string, record: any, index: number) => {
                return (
                  <Input
                    value={text}
                    disabled={[record.sFieldNameOldPre, record.sFieldNameOld].includes("*")}
                    onChange={event => {
                      handleChangeValue({ ...record, sFieldNameNew: event.target.value, index });
                    }}
                  />
                );
              },
            },
            {
              title: "源字段",
              width: "auto",
              dataIndex: "sFieldNameOld",
              render: (text: string, record: any, index: number) => {
                return (
                  <Input
                    value={text}
                    disabled={record.sFieldNameOldPre === "*"}
                    onChange={event => {
                      handleChangeValue({ ...record, sFieldNameOld: event.target.value, index });
                    }}
                    addonBefore={
                      <Select
                        value={record.sFieldNameOldPre}
                        placeholder="类型"
                        style={{ minWidth: 80 }}
                        popupMatchSelectWidth={false}
                        options={[
                          { label: "全部(*)", value: "*" },
                          ...ROW_PRE_OPTIONS,
                          ...datasetList,
                          { label: "自定义计算", value: "var" },
                        ]}
                        onChange={value => {
                          handleChangeValue({
                            ...record,
                            sFieldNameOldPre: value,
                            sFieldNameOld: "",
                            index,
                          });
                        }}
                      />
                    }
                  />
                );
              },
            },
            {
              title: () => {
                return (
                  <Space>
                    <div>操作</div>
                    <Button
                      type="link"
                      onClick={() => {
                        const sValue = form.getFieldValue("sValue") || "";
                        form.setFieldValue("sValue", sValue ? `${sValue},` : ":");
                      }}
                    >
                      新增
                    </Button>
                  </Space>
                );
              },
              width: 150,
              dataIndex: "operation",
              render: (_, _1, index) => {
                return (
                  <Button
                    type="primary"
                    onClick={() => {
                      const sValue = form.getFieldValue("sValue");
                      const sValueList = sValue.split(",");
                      sValueList.splice(index, 1);
                      form.setFieldValue("sValue", sValueList.toString());
                    }}
                  >
                    删除
                  </Button>
                );
              },
            },
          ]}
          locale={{ emptyText: "暂无数据" }}
          pagination={false}
          scroll={{ y: 410 }}
        />
      </Form.Item>
    </>
  );
};

const MyFilterRulesGroup = ({ dataSetList, rowValues, rowKey, onChange, form }: any) => {
  const {
    configOptions = [],
    configValueOptions = {},
    srcModelsOptions = [],
  } = useContext(myContext);
  const { pre1, value1, condition, pre2, value2 } = rowValues;
  const bHasDataset = !!form?.getFieldValue("dataset");

  let conditionOption = CONDITION_DATA; // 条件下拉
  let hide2 = false; // pre2、value2隐藏
  let showRaido = false; // 显示raido选择框
  let bModelsId = value1 === "sSrcModelsId"; // 是否模块id
  let bCustom = pre1 === "custom"; // 自定义代码

  //如果pre1为slave之类
  if (
    pre1 &&
    value1 &&
    pre1 !== "master" &&
    configOptions.some((item: any) => item.value === pre1) &&
    !bHasDataset
  ) {
    // value1为b开头
    if (value1.startsWith("b")) {
      hide2 = true;
      conditionOption = CONDITION_DATA_TYPEB;
    } else {
      conditionOption = CONDITION_DATA_TYPE_NOTB;
    }
  }

  // 如果是模块id且pre1为props|master,condition取前两个
  if (bModelsId && ["props", "master"].includes(pre1)) {
    conditionOption = [conditionOption[0], conditionOption[1]];
  }

  // 如果条件包含empty字段
  if (condition?.includes("empty")) {
    hide2 = true;
  }

  if (["props", "master"].includes(pre1) && (value1?.startsWith("b") || value1 === "enabled")) {
    showRaido = true;
  }

  // condition默认为第一个
  useEffect(() => {
    if (!condition || !conditionOption.some((item: any) => item.value === condition)) {
      onChange(rowKey, { ...rowValues, condition: conditionOption[0].value });
    }
  }, [pre1]);

  // 如果hide2为true，保证pre2、value2为空
  useEffect(() => {
    if (hide2 && (pre2 || value2)) {
      onChange(rowKey, { ...rowValues, pre2: undefined, value2: "" });
    }
  }, [hide2]);

  // 如果显示raido选择框且condition不包含empty字段时，默认condition为是
  useEffect(() => {
    if (showRaido && !condition?.includes("empty")) {
      onChange(rowKey, { ...rowValues, condition: "!empty", pre2: undefined, value2: "" });
    }
  }, [showRaido]);

  // 如果value1为s|i|d|t开头且hide2为false
  useEffect(() => {
    let addState = {} as any;
    // condition默认为第一个
    if (!condition || !conditionOption.some((item: any) => item.value === condition)) {
      addState.condition = conditionOption[0].value;
    }
    if (
      value1?.startsWith("s") ||
      value1?.startsWith("i") ||
      value1?.startsWith("d") ||
      value1?.startsWith("t")
    ) {
      if (!hide2 && (value1?.startsWith("s") || value1?.startsWith("t"))) {
        // 如果pre2不是string，设置为string
        if (pre2 !== "string") {
          addState.pre2 = "string";
        }
      }
      if (!hide2 && (value1?.startsWith("i") || value1?.startsWith("d"))) {
        // 如果pre2不是number，设置为number
        if (pre2 !== "number") {
          addState.pre2 = "number";
        }
      }
    }
    if (JSON.stringify(addState) !== "{}") {
      onChange(rowKey, { ...rowValues, ...addState });
    }
  }, [value1, condition]);

  // 自定义时多余字段清空
  useEffect(() => {
    if (bCustom) {
      onChange(rowKey, { ...rowValues, condition: undefined, pre2: undefined, value2: "" });
    }
  }, [bCustom]);

  const handleChangeValue = (value: any, key: string) => {
    let changeValue = { pre1, value1, condition, pre2, value2, [key]: value };
    onChange(rowKey, changeValue);
  };

  const options = [
    ...dataSetList,
    ...PROPS_OPTIONS,
    ...(!bHasDataset ? configOptions : []),
    { label: "自定义", value: "custom" },
  ];

  return (
    <Space>
      <Input
        style={{ width: bCustom ? 800 : "auto" }}
        placeholder={bCustom ? "请输入自定义内容" : "字段名"}
        addonBefore={
          <Select
            style={{ minWidth: 80 }}
            popupMatchSelectWidth={false}
            placeholder="表名"
            options={options}
            optionRender={({ label, value }) => {
              return (
                <span>
                  {label}({value})
                </span>
              );
            }}
            value={pre1}
            showSearch
            filterOption={(inputValue, option) => {
              const condition1 =
                option?.value?.toUpperCase().indexOf(inputValue.toUpperCase()) !== -1;
              const condition2 =
                option?.label?.toUpperCase().indexOf(inputValue.toUpperCase()) !== -1;
              return condition1 || condition2;
            }}
            onChange={value => handleChangeValue(value, "pre1")}
          />
        }
        addonAfter={
          !bCustom && (
            <Select
              // style={{ minWidth: 80 }}
              popupMatchSelectWidth={false}
              // placeholder="表字段"
              options={[...(configValueOptions[pre1] || [])]}
              value={
                configValueOptions[pre1]?.some((item: any) => item.value === value1) ? value1 : null
              }
              showSearch
              filterOption={(inputValue, option) => {
                const condition1 =
                  option?.value?.toUpperCase().indexOf(inputValue.toUpperCase()) !== -1;
                const condition2 =
                  option?.label?.toUpperCase().indexOf(inputValue.toUpperCase()) !== -1;
                return condition1 || condition2;
              }}
              optionRender={({ label, value }) => {
                return (
                  <span>
                    {label}({value})
                  </span>
                );
              }}
              onChange={value => handleChangeValue(value, "value1")}
            />
          )
        }
        value={value1}
        onChange={e => handleChangeValue(e.target.value, "value1")}
      />
      {(() => {
        if (bCustom) return "";
        if (showRaido) {
          return (
            <Radio.Group
              options={RADIO_OPTIONS}
              onChange={e => handleChangeValue(e.target.value, "condition")}
              value={condition}
              optionType="button"
              buttonStyle="solid"
            />
          );
        }
        return (
          <>
            <Select
              value={condition}
              style={{ width: "auto", minWidth: 140 }}
              placeholder="判断条件"
              options={conditionOption}
              showSearch
              filterOption={(inputValue, option) => {
                const condition1 =
                  option?.value?.toUpperCase().indexOf(inputValue.toUpperCase()) !== -1;
                const condition2 =
                  option?.label?.toUpperCase().indexOf(inputValue.toUpperCase()) !== -1;
                return condition1 || condition2;
              }}
              onChange={value => handleChangeValue(value, "condition")}
            />
            <Input
              style={{ width: "auto", ...(hide2 ? { display: "none" } : {}) }}
              placeholder="字段值"
              addonBefore={
                <Select
                  style={{ minWidth: 80 }}
                  popupMatchSelectWidth={false}
                  placeholder="表名"
                  options={[...ROW_PRE_OPTIONS, ...dataSetList]}
                  value={pre2}
                  onChange={value => handleChangeValue(value, "pre2")}
                />
              }
              value={value2}
              onChange={e => handleChangeValue(e.target.value, "value2")}
              {...(() => {
                if (bModelsId) {
                  return {
                    addonAfter: (
                      <Select
                        // style={{ minWidth: 80 }}
                        popupMatchSelectWidth={300}
                        // placeholder="表字段"
                        virtual={true}
                        options={[...srcModelsOptions]}
                        value={
                          srcModelsOptions.some((item: any) => item.value === value2)
                            ? value2
                            : null
                        }
                        showSearch
                        filterOption={(inputValue, option) => {
                          const condition1 =
                            option?.value?.toUpperCase().indexOf(inputValue.toUpperCase()) !== -1;
                          const condition2 =
                            option?.label?.toUpperCase().indexOf(inputValue.toUpperCase()) !== -1;
                          return condition1 || condition2;
                        }}
                        onChange={value => handleChangeValue(value, "value2")}
                      />
                    ),
                  };
                }
                return {};
              })()}
            />
          </>
        );
      })()}
    </Space>
  );
};
const CommonCondition = (props: any) => {
  const { form, item, dependsWith } = props;

  const typeJson = SIMPLE_DATASET_FILTER_OPTIONS.reduce((pre: any, item) => {
    pre[item.value] = item.label;
    return pre;
  }, {});

  const desDataset = Form.useWatch("desDataset", form) || "";
  const dataset = Form.useWatch("dataset", form) || [];
  const dataSetList = dataset.map((item: any) => ({
    label: item.split("@")[0] + typeJson[item.split("@")[1] || ""],
    value: item.split("@")[0],
  }));

  const initData = {
    key: shortid(),
    level: 1,
    type: 1,
    children: [
      {
        rowValues: INIT_ROW_VALUES,
        key: shortid(),
        level: 1,
      },
    ],
  };

  const [data, setData] = useState(initData);

  const conditionData = Form.useWatch("conditionData", form);
  const flag = useRef(0);
  useEffect(() => {
    if (flag.current > 2) return;
    if (conditionData) {
      const dataNew = JSON.parse(conditionData);
      if (dataNew.length >= 2) {
        setData(convertStr2Data(dataNew));
      }
    }
  }, [conditionData]);

  let preDataSetList = desDataset
    ? [{ label: `${desDataset}每条数据`, value: `${desDataset}One` }]
    : [];
  if (item.type === "filter") {
    const srcDataset = Form.useWatch("srcDataset", form) || "";
    const srcDatasetNew = srcDataset.split("@")[0];
    preDataSetList = srcDataset
      ? [{ label: `${srcDatasetNew}每条数据`, value: `${srcDatasetNew}One` }]
      : [];
  } else if (item.type === "edit") {
    const desDatasetNew = desDataset.split("@")[0];
    preDataSetList = desDataset
      ? [{ label: `${desDatasetNew}每条数据`, value: `${desDatasetNew}One` }]
      : [];
  } else if (dependsWith) {
    // const dataset = Form.useWatch(dependsWith, form) || [];
    // preDataSetList = dataset.length ? [{ label: `${dataset[0].split("@")[0]}One`, value: `${dataset[0].split("@")[0]}One` }] : [];
  }

  return (
    <>
      <Form.Item label="筛选条件" name="condition">
        <Input.TextArea readOnly />
      </Form.Item>
      <Form.Item label="筛选数据" name="conditionData" style={{ display: "none" }}>
        <Input.TextArea />
      </Form.Item>
      <div style={{ paddingLeft: 150, marginBottom: 10 }}>
        <FilterRules
          component={props => (
            <MyFilterRulesGroup
              {...props}
              form={form}
              dataSetList={[...preDataSetList, ...dataSetList]}
            />
          )}
          value={data}
          onChange={(value: any) => {
            let valueNew = cloneDeep(value);
            if (!valueNew) {
              valueNew = initData;
            } else if (!valueNew.children) {
              valueNew = {
                key: shortid(),
                level: 1,
                type: 1,
                children: [value],
              };
            } else if (!valueNew.children.length) {
              valueNew = initData;
            }
            setData(valueNew);
            flag.current++;
            form.setFieldValue("condition", convertData2Str(valueNew, false));
            form.setFieldValue("conditionData", JSON.stringify(convertData2Str(valueNew, true)));
          }}
          initValues={INIT_ROW_VALUES}
          notEmpty={{ data: false }}
        />
      </div>
    </>
  );
};

const CommonSaveBtn = (props: any) => {
  return (
    <Form.Item label=" " colon={false}>
      <Button type="primary" htmlType="submit">
        更新指令集
      </Button>
    </Form.Item>
  );
};

const handleGetChangeData = (props: any) => {
  const { instructionList, item } = props;

  const instructionListNew = cloneDeep(instructionList) as InstructionItem[];

  const findNodePath = (treeData: any[], key: string, path: number[] = []): number[] | null => {
    for (let i = 0; i < treeData.length; i++) {
      const node = treeData[i];
      // 如果当前节点匹配key，返回当前路径
      if (node.key === key) {
        return [...path, i];
      }

      // 如果当前节点有子节点，递归查找
      if (node.children && node.children.length > 0) {
        const foundPath = findNodePath(node.children, key, [...path, i]);
        if (foundPath) {
          return foundPath;
        }
      }
    }

    // 未找到返回null
    return null;
  };

  const targetNodePath = findNodePath(instructionListNew, item.key) || [];

  let targetItem = instructionListNew as any;
  for (let i = 0; i < targetNodePath.length; i++) {
    if (i === targetNodePath.length - 1) {
      targetItem = targetItem[targetNodePath[i]];
    } else {
      targetItem = targetItem[targetNodePath[i]].children;
    }
  }

  return {
    instructionListNew,
    targetItem,
    targetNodePath,
  };
};

const handleUpdateData = (props: any, handleType = "update") => {
  const { setState, form, item } = props;

  const { instructionListNew, targetItem, targetNodePath } = handleGetChangeData(props);

  if (handleType == "update") {
    // Step 2: 修改节点
    const values = form.getFieldsValue();
    targetItem.content = Object.keys(values).reduce(
      (pre: { opr: any; [key: string]: any }, key) => {
        if (key === "data" && values[key].length) {
          pre[key] = values[key].map((item: any) => {
            if (item.name && typeof item.name === "object") {
              return {
                ...item,
                name: item.name.join(","),
              };
            } else {
              return item;
            }
          });
        } else if (typeof values[key] === "object" && key !== "data") {
          pre[key] = values[key].join(",");
        } else if (values[key]) {
          pre[key] = values[key];
        }
        return pre;
      },
      { opr: item.type }
    ) as any;
  } else if (handleType == "delete") {
    // Step 2: 删除节点
    let evalStr = "instructionListNew";
    for (let i = 0; i < targetNodePath.length; i++) {
      if (i === targetNodePath.length - 1) {
        evalStr += `.splice(${targetNodePath[i]}, 1)`;
      } else {
        evalStr += `[${targetNodePath[i]}].children`;
      }
    }

    eval(evalStr);
  }

  setState({ instructionList: instructionListNew });
};

export default Index;
