/* eslint-disable */
import React, {
  useContext,
  useEffect,
  useReducer,
  useRef,
  useState
} from "react";
// import "@ant-design/compatible/assets/index.css";
import { Tabs, Tooltip, message } from "antd-v4";
import ShowType from "@/components/Common/CommonComponent";
import * as commonBusiness from "@/components/Common/commonBusiness";
import StaticEditTable from "@/components/Common/CommonTable";
import * as commonUtils from "@/utils/utils";
import * as rglUtils from "./rglUtils";
import RGL, { WidthProvider } from "react-grid-layout";
import styles from "./index.less";

const ReactGridLayout = WidthProvider(RGL);
const { myContext, reducer } = commonUtils;

const initialState = {
  // sParamList: ["sProcess", "sReport", "sWorkOrder", "sNorm", "sTest"],
  // sParamNameList: ["工序参数", "上报参数", "工单参数", "标准书参数", "测试参数"],
  selectedData: {} // 当前选中数据
};

// 可拖拽组件
const CommonViewDragable = props => {
  const { tableName } = props;
  const [state, dispatch] = useReducer(reducer, initialState);

  let selectedRowKeys = props[`${tableName}SelectedRowKeys`] || [];
  if(commonUtils.isEmptyArr(selectedRowKeys) && commonUtils.isNotEmptyArr(props[`${tableName}Data`]) ) {
    selectedRowKeys =  [props[`${tableName}Data`][0]]
  }
  const key = selectedRowKeys[0] || commonUtils.createSid();
  const selectedData = handleGetSelectedData(props);

  // 根据选中节点获取选中数据
  useEffect(
    () => {
      dispatch(["saveState", { selectedData }]);
    },
    [selectedRowKeys[0], JSON.stringify(selectedData)]
  );

  return (
    <myContext.Provider
      value={{
        props,
        hooksProps: { ...state, dispatch }
      }}
    >
      <div className={`viewStyle ${styles.commonViewDragable}`} key={key}>
        <TabComponent />
      </div>
    </myContext.Provider>
  );
};

const TabComponent = () => {
  const { props } = useContext(myContext);
  const { hideTabsNav, sParamData = [] } = props;
  return (
    <Tabs
      className={hideTabsNav ? "hideTabsNav" : ""}
      items={sParamData.map(({ sParamType, sParamName }) => ({
        label: sParamName,
        key: sParamType,
        children: <TabPaneComponent sParamType={sParamType} />
      }))}
    />
  );
};

const TabPaneComponent = childProps => {
  const { props } = useContext(myContext);
  const { sParamType } = childProps;
  const selectedData = handleGetSelectedData(props);
  const fieldsName = `b${sParamType.replace("s", "").trim()}ParamTable`;
  const bTable = selectedData[fieldsName];
  return (
    <div className="tabPaneComponent">
      {bTable ? (
        <ParamTableComponent {...childProps} />
      ) : (
        <RGLComponent {...childProps} />
      )}
    </div>
  );
};

const ParamTableComponent = childProps => {
  const { props, hooksProps } = useContext(myContext);
  const { tableName } = props;
  const { selectedData } = hooksProps;
  const { sParamType } = childProps;

  const [paramListTableProps, setParamListTableProps] = useState(null);
  const xlyTableRef = useRef(null);

  const tableData = props[`${tableName}Data`] || [];
  useEffect(
    () => {
      if (commonUtils.isNotEmptyObject(selectedData)) {
        const result = rglUtils.getTableParams(
          sParamType,
          selectedData,
          xlyTableRef
        );
        setParamListTableProps({
          ...commonBusiness.getTableTypes(sParamType, {
            ...props,
            ...result
          }),
          bSParamTable: true,
          // enabled: true,
          tableProps: {
            AutoTableHeight: handleGetTableHeight(props, xlyTableRef, true)
          },
          onDataChange: (...args) => {
            handleDataChange(props, args);
          }
        });
      }
    },
    [JSON.stringify(selectedData), tableData.length]
  );

  return (
    <div className="xly-workorder-list xlyTable" ref={xlyTableRef}>
      {paramListTableProps && <StaticEditTable {...paramListTableProps} />}
    </div>
  );
};

const RGLComponent = childProps => {
  const { props, hooksProps } = useContext(myContext);
  const { tableName } = props;
  const { selectedData } = hooksProps;
  const { sParamType } = childProps;
  const xlyRGLRef = useRef(null);
  // const [maxHeight, setMaxHeight] = useState("auto");
  const [rglConfig, setRglConfig] = useState({});
  const {
    layout = [],
    configs = [],
    paramData = {},
    record = {},
    recordDefault = {}
  } = rglConfig;
  const [layoutKey, setLayoutKey] = useState(0);
  useEffect(
    () => {
      if (commonUtils.isNotEmptyObject(selectedData)) {
        const result = rglUtils.getReactGridLayout(
          sParamType,
          selectedData,
          props.sModelsId,
          props.formRoute
        );
        setLayoutKey(selectedData.sId);
        setRglConfig(result);
      }
    },
    [JSON.stringify(selectedData)]
  );

  // const tableData = props[`${tableName}Data`] || [];
  // useEffect(
  //   () => {
  //     setMaxHeight(handleGetTableHeight(props, xlyRGLRef));
  //   },
  //   [tableData.length]
  // );

  return configs.length ? (
    <div
      style={{
        width: "100%",
        height: "100%",
        overflowY: "auto"
        // maxHeight
      }}
      key={layoutKey}
      ref={xlyRGLRef}
    >
      <ReactGridLayout
        margin={[0, 2]}
        verticalCompact={false}
        layout={layout}
        cols={24}
        rowHeight={28}
        isDraggable={false}
        isResizable={false}
        isDroppable={false}
      >
        {configs.map(child => {
          const showTypeProps = handleGetShowTypeProps({
            sParamType,
            child,
            props,
            layout,
            record,
            recordDefault
          });

          return (
            <div key={child.sName} id={child.sName} className="showType">
              {/* {showTypeProps.layoutW === 1 ? (
                <Tooltip placement="top" title={`${child.showName}:${showTypeProps.dataValue}`}>
                  <div>
                    <ShowType {...showTypeProps} />
                  </div>
                </Tooltip>
              ) : (  */}
              <Tooltip placement="top" title={showTypeProps.dataValue}>
                <div>
                  <ShowType {...showTypeProps} />
                </div>
              </Tooltip>
              {/* )} */}
            </div>
          );
        })}
      </ReactGridLayout>
    </div>
  ) : (
    <EmptyComponent />
  );
};

const EmptyComponent = () => {
  return <div className="emptyComponent">暂无数据</div>;
};

// 获取选中数据
const handleGetSelectedData = props => {
  const { tableName } = props;
  const iIndex = handleGetSelectedDataIndex(props);
  if (iIndex !== -1) {
    return props[`${tableName}Data`][iIndex];
  } else {
    return {};
  }
};

// 获取选中数据index
const handleGetSelectedDataIndex = props => {
  const { tableName } = props;
  const selectedRowKeys = props[`${tableName}SelectedRowKeys`] || [];

  let selectedDataIndex = -1;
  const tableData = props[`${tableName}Data`];
  if (commonUtils.isNotEmptyArr(tableData)) {
    if (commonUtils.isNotEmptyArr(selectedRowKeys)) {
      selectedDataIndex = tableData.findIndex(
        item => item.sId === selectedRowKeys[0]
      );
    } else {
      selectedDataIndex = 0;
    }
  }
  return selectedDataIndex;
};

// 获取表单参数
const handleGetShowTypeProps = params => {
  const { sParamType, child, props, layout, record, recordDefault } = params;
  const { app, form, tableName, comparedTableId, bSimpleMode } = props;

  // 计算标题和组件的宽度比
  let w = 6;
  let h = 1;
  const iIndex = layout.findIndex(item => item.i === child.sName);
  if (iIndex !== -1) {
    w = layout[iIndex].w;
    h = layout[iIndex].h;
  }
  const flexWidth = w > 2 ? (3 * 66) / w : 0;
  const formItemLayout = {
    labelCol: {
      flex: flexWidth + "%",
      style: {
        color: "rgba(0, 0, 0, 0.65)",
        backgroundColor: "#BFEFFF"
      }
    },
    wrapperCol: { flex: "auto" }
  };

  if (props.processTitleWidth) {
    formItemLayout.labelCol.flex = props.processTitleWidth;
  }

  let bDisabled = !props.enabled;
  const config = props[`${tableName}Config`];
  if (commonUtils.isNotEmptyObject(config)) {
    const sParamsConfig = config.gdsconfigformslave.find(
      item => item.sName === "sParams"
    );
    if (sParamsConfig && sParamsConfig.iTag === 1) {
      bDisabled = true;
    }
  }

  if (child.bReadOnly) {
    bDisabled = true;
  }

  const selectData = handleGetSelectedData(props);

  const bIFace = ["单双面", "印面"].includes(child.showName);
  const bAlumiteBomBillNo =
    child.showName === "电化铝BOM" || child.showName === "电化铝版本";

  let iFaceConfig = {};
  let alumiteBomBillNoConfig = {};

  let showConfig = { ...child };
  if (!bSimpleMode) {
    if (bIFace) {
      iFaceConfig = config.gdsconfigformslave.find(
        item => item.sName === "iFace"
      );
      showConfig = {
        ...iFaceConfig,
        sName: showConfig.sName,
        showName: showConfig.showName,
        bVisible: showConfig.bVisible
      };
    } else if (bAlumiteBomBillNo) {
      alumiteBomBillNoConfig = config.gdsconfigformslave.find(
        item => item.sName === "sAlumiteBomBillNo"
      );
      showConfig = {
        ...alumiteBomBillNoConfig,
        sName: showConfig.sName,
        showName: showConfig.showName,
        bVisible: showConfig.bVisible
      };
    }
  }

  const getDataValue = () => {
    if (props.bSimpleMode) {
      return record[child.sName];
    } else if (child.showName === "色序") {
      return selectData.sColorSerialMemo;
    } else if (bIFace) {
      if (commonUtils.isNotEmptyObject(iFaceConfig)) {
        const showDropDown = commonUtils.convertStrToObj(
          iFaceConfig.showDropDown
        );
        return showDropDown[selectData.iFace] || "";
      } else {
        return record[child.sName];
      }
    } else if (bAlumiteBomBillNo) {
      return selectData.sAlumiteBomBillNo;
    } else {
      return record[child.sName];
    }
  };

  const processTbName =
    location.pathname === "/indexPage/commonCostomTabBill"
      ? "slave0"
      : "process";

  return {
    ...props,
    className: h > 1 ? "multiLine" : "",
    key: `${child.sName}_${flexWidth}`,
    name: !bSimpleMode && bAlumiteBomBillNo ? tableName : sParamType,
    formItemLayout,
    onChange: (...args) => {
      handleDataChange(
        { ...props, bIFace, bAlumiteBomBillNo, showConfig, recordDefault },
        args
      );
    },
    onViewClick: props.handleViewClick,
    enabled: !bDisabled,
    bTable: true,
    bViewTable: true,
    dataValue: getDataValue(),
    costomClassName: "",
    layoutW: w,
    bSColorSerialMemo:
      !bSimpleMode && child.showName === "色序" && props.onViewChoose,
    onViewChoose: () => {
      props.onViewChoose("process", "sColorSerialMemo", selectData);
    },
    onFieldPopupModal: showConfig => {
      if (window[`${comparedTableId}FieldPopupModal`]) {
        if (bAlumiteBomBillNo) {
          window[`${comparedTableId}FieldPopupModal`](
            { ...showConfig, sName: "sAlumiteBomBillNo" },
            processTbName
          );
        } else {
          window[`${comparedTableId}FieldPopupModal`](showConfig, "process");
        }
      }
    },
    record: !bSimpleMode && bAlumiteBomBillNo ? selectData : record,

    // record: { 'sParam1': 111, 'sParam2': 222,'sParam3': 333,'sParam4': 444,'sParam5': 555 },
    // sId: viewRow.sId,
    app,
    form,
    getSqlDropDownData: props.getSqlDropDownData,
    getSqlCondition: props.getSqlCondition,
    handleSqlDropDownNewRecord: props.handleSqlDropDownNewRecord,
    getFloatNum: props.getFloatNum,
    showConfig: {
      ...showConfig,
      sName: showConfig.sNameParam ? showConfig.sNameParam : showConfig.sName
    },
    textArea: h > 2,
    formRoute: props.formRoute,
    onFieldDoubleClick: props.handleFieldDoubleClick
  };
};

// 判断是否在弹出框
const bInModal = el => {
  if (commonUtils.isEmpty(el) || commonUtils.isEmpty(el.classList)) {
    return false;
  } else if (el.classList.contains("ant-modal-root")) {
    return true;
  } else {
    return bInModal(el.parentNode);
  }
};

// 获取表格高度
const handleGetTableHeight = (props, ref, bTable) => {
  let tableHeight = "auto";
  if (bInModal(ref.current)) {
    tableHeight = "60vh";
  } else {
    const { comparedTableId } = props;
    if (comparedTableId) {
      const oTable = document.querySelector(`#${comparedTableId}`);
      if (oTable) {
        const oContainer = oTable.querySelector(".ant-table-container");
        if (oContainer) {
          tableHeight = oContainer.getBoundingClientRect().height;
          if (bTable) {
            tableHeight -= 30;
          }
          tableHeight = Math.max(tableHeight, 29 * 3); // 最少三行高度
        }
      }
    }
  }
  return tableHeight;
};

// 数据修改
const handleDataChange = (props, args) => {
  const {
    tableName,
    bIFace,
    bAlumiteBomBillNo,
    bSimpleMode,
    recordDefault
  } = props;
  const [sParamType, sName, returnValue, _sId, _dropDownDataNew, record] = args;

  if (
    returnValue[sName] &&
    typeof returnValue[sName] === "string" &&
    returnValue[sName].includes('"')
  ) {
    message.error("输入框不允许输入双引号");
    return;
  }
  const iIndex = handleGetSelectedDataIndex(props);
  if (iIndex !== -1) {
    const tableData = props[`${tableName}Data`];

    // 获取params数据
    const { sParams, [`${sParamType}Param`]: sParamStr } = tableData[iIndex];
    const recordDataAll = commonUtils.convertStrToObj(sParams, []);
    const recordItemIndex = recordDataAll.findIndex(
      item => item.sParamType === sParamType
    );

    let dataNew = {};
    if (props.showConfig && props.showConfig.sNameParam) {
      dataNew[props.showConfig.sName] = returnValue[sName];
    }
    dataNew =
      record && record.sParamKey
        ? { [record.sParamKey]: returnValue[sName] }
        : { ...dataNew, ...returnValue };

    if (recordItemIndex !== -1) {
      let tempData = {
        ...recordDefault,
        ...recordDataAll[recordItemIndex].data,
        ...dataNew
      };
      tempData = handleAssignField(
        props,
        recordDefault,
        tempData,
        sParamStr,
        sName
      );
      recordDataAll[recordItemIndex].data = tempData;
    } else {
      let tempData = {
        ...recordDefault,
        ...dataNew
      };
      tempData = handleAssignField(
        props,
        recordDefault,
        tempData,
        sParamStr,
        sName
      );
      recordDataAll.push({
        sParamType,
        data: tempData
      });
    }

    const { [`${sParamType}Param`]: paramConfigStr } = tableData[iIndex];
    const paramConfig = commonUtils.convertStrToObj(paramConfigStr);
    const sAssFieldName = sName.replace("sParam", "sParamAssFieldName");
    if (commonUtils.isNotEmptyStr(paramConfig[sAssFieldName])) {
      paramConfig[sAssFieldName].split(",").map(item => {
        tableData[iIndex][item] = dataNew[sName];
      });
    }

    tableData[iIndex].sParams = commonUtils.convertObjToStr(recordDataAll);
    tableData[iIndex].handleType = tableData[iIndex].handleType || "update";

    if (!bSimpleMode) {
      if (bIFace) {
        tableData[iIndex].iFace = isNaN(returnValue[sName])
          ? returnValue[sName]
          : Number(returnValue[sName]);
      }
      if (bAlumiteBomBillNo) {
        tableData[iIndex].sAlumiteBomBillNo = returnValue[sName];
      }
    }

    if (props.onCostomSaveData) {
      props.onCostomSaveData(tableData);
    } else {
      props.onSaveState({ [`${tableName}Data`]: tableData });
    }
  }
};

// 处理赋值字段
const handleAssignField = (
  props,
  recordDefault,
  tempData,
  sParamStr,
  sName
) => {
  const sParam = commonUtils.convertStrToObj(sParamStr);
  let sParamAssignFieldList = Object.keys(sParam).reduce((result, key) => {
    if (key.startsWith("sParamAssignField")) {
      const assignField = sParam[key];
      const iOrder = Number(key.replace("sParamAssignField", ""));
      if (!sParam[`sParamDropDownType${iOrder}`]) {
        const sParamName = `sParam${iOrder}`;
        const sParamFieldName = sParam[`sParamFieldName${iOrder}`];
        result.push({
          sParamName,
          sParamFieldName,
          assignField
        });
      }
    }
    return result;
  }, []);

  sParamAssignFieldList = sParamAssignFieldList.filter(item => {
    const { assignField } = item;
    const result = assignField.split(/[^a-zA-Z0-9]+/).filter(Boolean);
    return result.includes(sName);
  });

  if (sParamAssignFieldList.length) {
    sParamAssignFieldList.forEach(item => {
      const { sParamName, sParamFieldName, assignField } = item;
      let result;
      try {
        const str = Object.keys({ ...recordDefault, ...tempData }).reduce(
          (pre, cur) => {
            if (cur.startsWith("d") || cur.startsWith("i")) {
              return `${pre}let ${cur} = ${tempData[cur]}; `;
            } else {
              return `${pre}let ${cur} = "${tempData[cur]}"; `;
            }
          },
          ""
        );
        try {
          result = eval(str + assignField);
        } catch (error) {
          result = eval(str.replace(/let\ /g, "var ") + assignField);
        }
      } catch (error) {}
      if (result !== undefined) {
        tempData[sParamName] = result;
        if (sParamFieldName) {
          tempData[sParamFieldName] = result;
        }
      }
    });
  }

  return tempData;
};

export default CommonViewDragable;

/*
  props参数：
  {
    hideTabsNav: boolean, // 是否隐藏tab导航
    sParamData: Array, // tab展示的参数 格式[{ sParamType: 'sWorkOrder', sParamName: '工单参数' }, ...{} ]
    selectedData: {}, // 当前选中数据
    tableName: 'process', // 工序表名，用于修改数据
  }
**/
