import { Layout } from "./interface";
import { computed, reactive, toRefs } from "vue";
// import { useRoute } from "vue-router";
// import { useAuthStore } from "@/stores/modules/auth";
import { useLayoutStore } from "@/stores/modules/layout";
import { ColumnProps } from "@/components/LjVxeTable/interface";
import { isFunction, isObject } from "@/utils/is";
import { cloneDeep, pick, has, get, set, defaultsDeep } from "lodash-es";
import { streamlineFunc } from "@/utils";
import { defineColumnStyle } from "@/config/columnStyle";
import tableJson from "@/languages/modules/zh-cn/table.json";
import { TABLE_TYPE_FILTER } from "@/config/index";

/**
 * @description 表格布局信息
 * @param {string} type 布局类型
 * @param {Object} t i18n
 * @param {Array} columns 初始化布局数据
 * @param {Array} layoutAttr 布局读取/保存时，赋值的属性名称
 * @param {Object} layoutAttrDefine 布局默认设置，保存时移除，默认的属性
 * @param {boolean} autoLoadLayout 自动获取布局
 * @param {String} dwname 布局名称
 * @param {Function} loadLayoutCallBack 加载布局时，返回的数据进行处理的方法
 * @param {Function} flatColumnsCallBack 扁平化布局时，返回的数据进行处理的方法
 * */
export const useDwLayout = (
  dwtype: "table" | "detail",
  t: any,
  columns: ColumnProps<any>[],
  layoutAttr: string[] = [],
  layoutAttrDefine: any = {},
  autoLoadLayout: boolean = false,
  dwname?: string,
  loadLayoutCallBack?: (data: any) => any,
  flatColumnsCallBack?: (data: any) => any,
  editable?: boolean
) => {
  // 布局暂存数据
  const layoutStore = useLayoutStore();
  /**
   * @description 额外由后台决定的columns属性
   */
  const onlyReadAttr = ["datatype", "enum", "pbformat", "tabsequence"];
  /**
   * @description 别名字段集合(field)，由后台定义title值
   */
  const aliasAttr = ["status", "woodcode", "pcode", "mtrlsectype", "zxmtrlmode", "usermtrlmode", "otheramt", "excolumn"];

  const state = reactive<Layout.LayoutStateProps>({
    tableColumns: cloneDeep(columns),
    dwLayout: [],
    flatColumns: []
  });

  const dwFieldMap = new Map();

  const loadLayoutFunc = async () => {
    if (dwname) {
      console.log("BF 数行化BF，还原个性设置 state.tableColumns.value :>> ", state.tableColumns);
      // console.log("await layoutStore.getDwLayout(dwname) :>> ", await layoutStore.getDwLayout(dwname, autoLoadLayout));
      let layout = await layoutStore.getDwLayout(dwname, autoLoadLayout);
      console.log("BF loadLayoutFunc layout :>> ", layout);
      if (layout?.hasOwnProperty("itemvalue") && layout.itemvalue) {
        // 表格结构： {tableprop: string, columns: string}
        typeof layout.itemvalue == "string" && (layout.itemvalue = JSON.parse(layout.itemvalue.replace(/'/g, '"')));
        // 兼容部分结构直接记录行数据
        if (layout.itemvalue.hasOwnProperty("columns") && layout.itemvalue.columns) {
          state.dwLayout = layout.itemvalue.columns;
        } else {
          state.dwLayout = layout.itemvalue;
        }

        loadLayoutCallBack && loadLayoutCallBack(layout.itemvalue);
      }
      console.log("onMounted state.dwLayout :>> ", state.dwLayout);
      loadDwLayoutFunc(state.dwLayout);
      console.log("数行化BF，还原个性设置 state.tableColumns.value :>> ", state.tableColumns);
      // 扁平化，并读取个性设置
      // state.flatColumns = flatColumnsFunc(state.tableColumns, dwFieldMap);
      // console.log("读取个性设置 state.flatColumns :>> ", state.flatColumns);
      // 数行化，还原个性设置
      // tableColumns.value = restoreColumnsFunc(state.flatColumns);
      // console.log("数行化，还原个性设置 tableColumns.value :>> ", tableColumns.value);
    }
    state.flatColumns = flatColumnsFunc(state.tableColumns, dwFieldMap);
    console.log("state.flatColumns :>> ", state.flatColumns);
  };

  /**
   * @description 读取个性布局,用Map()储存
   * @param loadLayout 读取的布局数据
   */
  const loadDwLayoutFunc = (loadLayout: ColumnProps[] = [], sort: boolean = true) => {
    console.log("loadLayout.value :>> ", loadLayout);
    if (!loadLayout || !loadLayout.length) return false;

    if (sort) {
      // 个性布局加顺序号
      for (const i in loadLayout) {
        loadLayout[i].colorder = Number(i);
      }
    }

    // 个性布局构建键值Map()
    dwFieldMap.clear();
    for (const item of loadLayout) {
      dwFieldMap.set(item.field, item);
    }
    console.log("dwFieldMap :>> ", dwFieldMap);
  };

  // /**
  //  * @description 默认值赋值,
  //  * @param {Object} item 数据项
  //  * @param {Object/Array} defineValue 默认数据
  //  */
  // const setDefineVal = (item: any, defineValue: any) => {
  //   for (const key in defineValue) {
  //     if (key == "visible") {
  //       item[key] = item[key] === false ? false : defineValue[key];
  //     } else {
  //       if (isObject(item[key])) {
  //         setDefineVal(item[key], defineValue[key]);
  //       } else if (isArray(item[key])) {
  //         item[key].forEach((itm: any) => {
  //           setDefineVal(itm, defineValue[key][0]);
  //         });
  //       } else {
  //         item[key] = item[key] ?? defineValue[key];
  //       }
  //       item[key] = item[key] ?? defineValue[key];
  //     }
  //   }
  // };

  let _checkAttr = [...layoutAttr, ...onlyReadAttr];
  /**
   * 读取个性化布局
   * @param {object} item 原始column数据
   * @param {object} userStyle 个性化布局
   * @returns {object} 返回完成恢复默认值的个性布局数据
   */
  const loadUserStyle = (item: any, userStyle: any) => {
    // let _item = cloneDeep(item);
    // 只有部分列的title值，取自后台数据
    let attr = cloneDeep(_checkAttr);
    if (item.field && item.title && (!aliasAttr.includes(item.field) || (item.field == "status" && item.enum))) {
      attr = attr.filter((item: string) => item != "title");
    }

    // if (item.field == "status") {
    //   console.log("bf loadUserStyle attr :>> ", attr);
    //   console.log("bf userStyle attr :>> ", userStyle);
    // }
    // 只读授权的字段
    let _load = pick(userStyle, attr);
    // 先赋值datatype，处理并获取，默认赋值
    _load.datatype && (item.datatype = _load.datatype);
    _load.enum && (item.enum = _load.enum);
    let _define = getDefineAttr(item, layoutAttrDefine);

    // 强→弱
    defaultsDeep(_load, _define, item);
    // console.log("_load :>> ", item.field, _load);
    // console.log("item :>> ", item);
    // console.log("_define :>> ", _define);
    _load.colorder = userStyle.colorder;
    userStyle.table && (_load.table = userStyle.table);
    if (!userStyle?.basicinfo?.group && item?.basicinfo?.group) {
      delete _load.basicinfo.group;
    }
    // if (!userStyle?.basicinfo?.ishidden && item?.basicinfo?.ishidden) {
    //   delete _load.basicinfo.ishidden;
    // }
    // console.log("loadUserStyle _load :>> ", _load);

    // if (item.field == "status") {
    //   console.log("loadUserStyle _load :>> ", _load);
    // }
    return _load;
  };

  /**
   * 默认值：补充具有指定特征的属性
   * @param item column, 列
   * @param layoutAttrDefine 默认值对象
   * @returns 组合默认特征后的默认值对象
   */
  const getDefineAttr = (item: any, defineColumn: any) => {
    let _define: any = {};
    if (item.hasOwnProperty("datatype")) {
      _define = cloneDeep(defineColumnStyle[item.datatype]);
    } else {
      let matched = false;
      for (const key in defineColumnStyle) {
        if (key.indexOf("$") > -1 || key.indexOf("^") > -1) {
          // 正则表达式
          let reg = new RegExp(key);
          if (reg.test(item.field)) {
            _define = cloneDeep(defineColumnStyle[key]);
            matched = true;
            // if (key.indexOf("date") > -1) {
            //   console.log("getDefineAttr item :>> ", item);
            //   if (item.title.indexOf("日期") > -1) {
            //     _define.format = "yyyy-MM-dd";
            //   } else if (item.title.indexOf("时间") > -1) {
            //     _define.format = "yyyy-MM-dd HH:mm";
            //     _define.width = 160;
            //   }
            // }
            break;
          }
        }
      }
      if (!matched && !item.datatype && !item.enum) {
        _define.align = "left";
      }
    }

    // 弱→强 : 组件默认 + 特征默认 + 原始自定义
    // return { ...defineColumn, ..._define, ...item };
    return defaultsDeep(item, _define, defineColumn);
  };

  const _tableJson = tableJson as any;
  /**
   * @description 扁平化 初始化 columns
   * @param argColumns
   * @param dwMap
   * @param flatArr
   * @returns
   */
  const flatColumnsFunc = (argColumns: ColumnProps[], dwMap: Map<KeyType, any> = new Map(), flatArr: ColumnProps[] = []) => {
    argColumns.forEach(async (col: any) => {
      if (col._children?.length) flatArr.push(...flatColumnsFunc(col._children, dwMap));

      if (dwMap.size) {
        // 读取个性设置属性
        if (!dwMap.has(col.field)) {
          dwMap.set(col.field, {});
        }
        let userStyle = dwMap.get(col.field) ?? undefined;
        if (userStyle && !userStyle?.limited) {
          col = loadUserStyle(col, userStyle);
          // console.log("col _define :>> ", col, userStyle);

          flatColumnsCallBack && (col = flatColumnsCallBack(col));

          let _define = getDefineAttr(col, layoutAttrDefine);
          flatArr.push(_define);
        }

        /**补充：后台数据，没有输出的数据列 */
        if (!userStyle) {
          if (TABLE_TYPE_FILTER.includes(col.type) || col.field == "pid") {
            flatArr.push(col);
          }
        }
      } else {
        /**当个性布局为空时，读取默认 */
        let _define = getDefineAttr(col, layoutAttrDefine);
        let _limited = isFunction(_define?.limited) ? _define.limited() : _define?.limited ?? false;
        // console.log(
        //   "当个性布局为空时，读取默认 isFunction(userStyle?.limited) :>>",
        //   col.field,
        //   _define,
        //   isFunction(_define?.limited),
        //   _limited
        // );

        if (!_limited) {
          // 给每一项 column 添加默认属性
          // setDefineVal(col, _define);
          defaultsDeep(col, _define);

          flatColumnsCallBack && (col = flatColumnsCallBack(col));
          flatArr.push(col);
        }
      }

      if (TABLE_TYPE_FILTER.includes(col.type)) {
      } else if (col.field == "pid") {
        col.title = t(`table.${col.field}`);
      } else if (col.field == "operation") {
        col.title = t(`table.${col.field}`);
      } else {
        if (!["status", "woodcode", "pcode"].includes(col.field)) {
          if (col.table) {
            Object.keys(_tableJson).includes(col.table) &&
              Object.keys(_tableJson[col.table]).includes(col.field) &&
              (col.title = t(`table.${col.table}.${col.field}`));
          } else {
            Object.keys(tableJson).includes(col.field) && (col.title = t(`table.${col.field}`));
          }
        }
      }
      // col.title.indexOf("table") > -1 && (col.title = undefined);
    });

    console.log("dwMap :>> ", dwMap, flatArr);

    /**补充前端没有，但后台有返回的数据列 */
    dwMap.forEach((item, key) => {
      // console.log("补充前端没有，但后台有返回的数据列 item :>> ", item);
      if (item.limited) return;
      let index = flatArr.findIndex(item => item.field === key);
      if (index == -1) {
        let _define = getDefineAttr(item, layoutAttrDefine);
        let data = loadUserStyle({}, _define);
        flatColumnsCallBack && (data = flatColumnsCallBack(data));
        flatArr.push(data);
      }
    });

    // 读取个性设置后，排序，
    if (dwMap.size) {
      flatArr.sort((a, b) => {
        return a.colorder! - b.colorder!;
      });
    }
    console.log("flatArr", flatArr);
    return flatArr.filter(item => !item._children?.length);
  };

  /**
   * 补充数据列中，具有枚举的数据列，自动补充render
   * @param columns 数据列
   * @returns
   */
  const loadRenderAttr = (argColumns: any) => {
    argColumns.forEach((item: any) => {
      if (!item.render) {
        /** 复选框 */
        if (item?.datatype == "checkbox") {
          item.render = (scope: any) => {
            let _keys = Object.keys(scope);
            let _data = _keys.includes("row") ? scope.row : _keys.includes("searchParam") ? scope.searchParam : scope;
            let _field = scope?.column.field ?? "";
            // switch (Number(_data[_field])) {
            //   case 1:
            //     return <el-checkbox class={"el-checkbox__disabled-checked"} checked={true} disabled={true} label="111" />;
            //   default: // 0
            //     let bool = false;
            //     return <el-checkbox v-model={bool} disabled={true} label="44" />;
            // }
            return (
              <>
                <el-checkbox
                  v-model={_data[_field]}
                  class={{ "el-checkbox__disabled-checked": Number(_data[_field]) }}
                  true-value={1}
                  false-value={0}
                  disabled={!editable}
                />
              </>
            );
          };
        } else if (item.enum && item.enum.length) {
          /**普通：enum,数值转文本 */
          item.render = (scope: any) => {
            let _keys = Object.keys(scope);
            let _data: any = _keys.includes("row") ? scope.row : _keys.includes("searchParam") ? scope.searchParam : scope;
            let _field = scope?.column.field ?? "";
            let _item: any = {};
            scope.enum && (_item = scope.enum.find((item: any) => item.value == Number(_data[_field])));
            if (dwtype == "detail") {
              return <el-input value={_item?.label} disabled={true} {...item.basicinfo.props} />;
            } else {
              return _item?.label ?? "";
            }
          };
        } else if (item?.datatype == "html") {
          item.render = (scope: any) => {
            let _keys = Object.keys(scope);
            let _data = _keys.includes("row") ? scope.row : _keys.includes("searchParam") ? scope.searchParam : scope;
            let _field = scope?.column.field ?? "";
            let html_data = _data[_field];
            if (html_data) {
              // 空格替换为&nbsp;
              html_data = html_data.replace(/ /g, "&nbsp;");
            }
            return <div v-html={html_data} />;
          };
        }
      }
      if (!item.editRender && !item.editColRender && item.tabsequence) {
        console.log("item.enum :>> ", item.field, item.enum);
        if (item.enum) {
          item.editRender = { name: "$select", options: item.enum };
        } else if (item.datatype == "checkbox") {
          item.editRender = {};
          item.editColRender = (scope: any) => {
            const { column, row, status } = scope;
            let _keys = Object.keys(scope);
            let _data: any = _keys.includes("row") ? scope.row : scope;
            let _field = scope?.column.field ?? "";
            // if (Number(_data[_field]) == 0) {
            //   row[_field] = 0;
            // }

            return (
              <>
                <el-checkbox v-model={_data[_field]} true-value={1} false-value={0} class="vxe-edit-col-middle"></el-checkbox>
              </>
            );
          };
        } else if (item.datatype == "date") {
          item.editRender = { name: "$input", props: { type: "date" } };
        } else if (item.datatype == "datetime") {
          item.editRender = { name: "$input", props: { type: "datetime" } };
        } else if (item.datatype == "number" || item.datatype == "integer") {
          item.editRender = { name: "$input", props: { type: "number" } };
        } else if (item.datatype == "input") {
          item.editRender = { name: "$input", props: {} };
        }
      }
      if (item.hasOwnProperty("editRender")) {
        item.editRender.autoFocus = true;
        item.editRender.autoSelect = true;
      }
    });
    return argColumns;
  };

  /**
   * 获取对象属性，或属性路径
   * @param {Object} define 对象
   * @param {string} pre 前缀
   * @returns {Array} 默认值字段集合
   */
  const getKeys = (define: any, pre = "") => {
    let keys: string[] = [];
    for (const key in define) {
      if (Object.prototype.toString.call(define[key]) === `[object Object]`) {
        let _pre = pre ? pre + "." : "";
        keys = keys.concat(getKeys(define[key], _pre + key));
      } else {
        let _keys: string[] = [key];
        pre && _keys.unshift(pre);
        let strKeys = _keys.join(".");
        keys.push(strKeys);
      }
    }
    return keys;
  };

  /**
   * @description 去除默认值，保存个性化数据
   * @param column 需要保存的数据列原型
   * @param params 主表其他参数 {basicinfo: ..., tableprop: {scrollY: ..., search: ..., ... }}
   * @returns {Object} 主表保存数据模型 {tableprop:..., columns: ...}
   */
  const columnStreamlineFunc = (column: any, params?: any, oColumns?: any) => {
    // 入参的columns被污染？？？
    let _oriColumns = oColumns ?? cloneDeep(columns);
    // let _oriColumns = cloneDeep(columns);
    console.log("column :>> ", column);
    console.log("oriColumns :>> ", JSON.stringify(_oriColumns));

    // 默认值字段集合
    let defineAttr = getKeys(layoutAttrDefine);
    defineAttr.unshift("field");

    // 取默认值 + 自定义业务columns = 动态默认值属性
    let oriDedine = _oriColumns
      .filter((item: any) => item.field)
      .map((item: any) => {
        item.basicinfo && delete item.basicinfo.visible;
        item.basicinfo && delete item.basicinfo.ishidden;
        let _define = getDefineAttr(item, layoutAttrDefine);
        return pick(defaultsDeep(item, _define), defineAttr);
      });
    console.log("streamlineFunc column :>> ", column);
    console.log("streamlineFunc props.layoutAttr :>> ", layoutAttr);
    console.log("streamlineFunc oriDedine :>> ", oriDedine);
    let _columns = column.filter((item: any) => item.field);

    // let saveCol: any = {
    //   columns: streamlineFunc(_columns, layoutAttr, oriDedine)
    // };
    let saveCol: any = {};

    isObject(params) && (saveCol.tableprop = params);

    saveCol.columns = streamlineFunc(_columns, layoutAttr, oriDedine);

    console.log("columnStreamlineFunc settingConfirm saveCol :>> ", saveCol);
    return saveCol;
  };

  /**
   * @description 获取最新的表格布局
   * @param {boolean} keepBasicinfo 是否保留线上basicinfo部分
   * @param {boolean} online 是否获取线上版本
   * @param {number} empid 员工id
   * @param {Map} enumMap 各属性enum集合，还原记录
   * @returns {Array} Columns
   */
  const getOriColumns = async (
    keepBasicinfo: boolean,
    online: boolean = false,
    empid?: number,
    enumMap?: any,
    oColumns?: any
  ) => {
    if (!dwname) return [];
    // 入参的columns被污染？？？
    let _curCol = oColumns ?? columns;
    // console.log("layout _curCol :>> ", JSON.stringify(_curCol));
    // console.log("layout oColumns :>> ", JSON.stringify(oColumns));
    // console.log("layout columns :>> ", JSON.stringify(columns));

    console.log("keepBasicinfo, online, empid :>> ", keepBasicinfo, online, empid);
    let layout: any;
    if (online) {
      layout = await layoutStore.getDwLayout_online(empid!, dwname, 0);
    } else {
      // 获取缓存中最新的表格布局
      layout = await layoutStore.getDwLayout(dwname);
    }

    let oriColumns = [];
    console.log("getOriColumns layout :>> ", JSON.stringify(layout));
    if (layout?.hasOwnProperty("itemvalue") && layout.itemvalue) {
      typeof layout.itemvalue == "string" && (layout.itemvalue = JSON.parse(layout.itemvalue.replace(/'/g, '"')));
      // 兼容部分结构直接记录行数据
      if (layout.itemvalue.hasOwnProperty("columns") && layout.itemvalue.columns) {
        oriColumns = layout.itemvalue.columns;
      } else {
        oriColumns = layout.itemvalue;
      }
    } else {
      return {
        columns: []
      };
    }

    console.log("layout oriColumns :>> ", JSON.stringify(oriColumns));

    let prototype: any = [];
    if (keepBasicinfo) {
      // 读取默认属性
      loadDwLayoutFunc(_curCol, false);
      console.log("keepBasicinfo dwFieldMap :>> ", keepBasicinfo, dwFieldMap);
      // 仅仅读取详情页的basicinfo部分，其他读取原有
      let loadMaps = new Map();
      for (const sitm of oriColumns) {
        let oriMap = dwFieldMap.get(sitm.field);
        console.log("sitm :>> ", oriMap, sitm);
        if (oriMap) {
          oriMap.basicinfo = defaultsDeep(sitm.basicinfo, oriMap.basicinfo);
        } else {
          oriMap = sitm;
        }

        if (enumMap.has(sitm.field)) {
          oriMap.enum = enumMap.get(sitm.field);
        }

        loadMaps.set(sitm.field, oriMap);
      }
      console.log("loadMaps :>> ", loadMaps);

      prototype = flatColumnsFunc(oriColumns, loadMaps);
    } else {
      // 读取默认属性
      loadDwLayoutFunc(_curCol, false);
      prototype = flatColumnsFunc(oriColumns, dwFieldMap);
    }

    /**备用（重置）：原始数据列 */
    let _ori = prototype.filter((item: any) => !TABLE_TYPE_FILTER.includes(item.type!) && item.field !== "operation");
    console.log("getOriColumns oriColumns _ori:>> ", _ori);
    // return _ori;
    return {
      ...layout.itemvalue,
      columns: _ori
    };
  };

  return {
    ...toRefs(state),
    dwFieldMap,
    loadLayoutFunc,
    loadDwLayoutFunc,
    flatColumnsFunc,
    getDefineAttr,
    loadRenderAttr,
    columnStreamlineFunc,
    getOriColumns
  };
};
