import Vue from "vue";
import CellSlot from "@base/components/table/CellSlot.vue";

let instance = null;

let TempSoltConstructor = Vue.extend(CellSlot);

function initTempSoltConstructorInstance() {
  if (!instance) {
    instance = new TempSoltConstructor();
  }
  return instance;
}

function destroyTempSoltConstructorInstance() {
  if (instance) {
    instance.$destroy();
    instance = null;
  }
}

export function getFilterValue(obj){
  return getCellValue(obj);
}

export function getCellValue(obj) {
  let {column, $table} = obj;
  let params = createParams(obj);
  let h = $table.$createElement;
  let that = $table.$xegrid.params.originOption.vue;

  let cellValue;
  if (column.slots && column.slots.filterVal) {
    cellValue = column.slots.filterVal(params);
  } else if(column.renderCell){
    let result = column.renderCell(h, params);
    cellValue = vNodeRender(result);
  }else{
    if(column.slots?.default){
      let result = column.slots.default(obj, h);
      cellValue = vNodeRender(result);
    }else{
      cellValue = obj.row[column.field];
    }
  }
  return cellValue;
}

export function createParams(obj) {
  let $xetable = obj.$table;
  let {column, row} = obj;
  let fixedType = $xetable.$refs.tableBody.fixedType,
    afterFullData = $xetable.afterFullData,
    tableData = $xetable.tableData;
  var columnIndex = $xetable.getColumnIndex(column);
  let items = tableData;

  var _columnIndex = $xetable.getVTColumnIndex(column);

  let overflowX = $xetable.overflowX;
  var fixedHiddenColumn = fixedType
    ? column.fixed !== fixedType
    : column.fixed && overflowX;

  let tableColumn = $xetable.tableColumn,
    scrollXLoad = $xetable.scrollXLoad,
    scrollYLoad = $xetable.scrollYLoad,
    allColumnOverflow = $xetable.showOverflow,
    isAllOverflow = $xetable.isAllOverflow,
    mergeList = $xetable.mergeList,
    spanMethod = $xetable.spanMethod,
    keyboardConfig = $xetable.keyboardConfig,
    keyboardOpts = $xetable.keyboardOpts,
    fixedColumn = $xetable.$refs.tableBody.fixedColumn,
    visibleColumn = $xetable.visibleColumn;

  if (obj.tableColumn == null) {
    if (fixedType) {
      if (
        scrollXLoad
        || scrollYLoad
        || (allColumnOverflow ? isAllOverflow : allColumnOverflow)
      ) {
        if (
          !mergeList.length
          && !spanMethod
          && !(keyboardConfig && keyboardOpts.isMerge)
        ) {
          tableColumn = fixedColumn;
        } else {
          tableColumn = visibleColumn; // 检查固定列是否被合并，合并范围是否超出固定列
          // if (mergeList.length && !isMergeLeftFixedExceeded && fixedType === 'left') {
          //   tableColumn = fixedColumn
          // } else if (mergeList.length && !isMergeRightFixedExceeded && fixedType === 'right') {
          //   tableColumn = fixedColumn
          // } else {
          //   tableColumn = visibleColumn
          // }
        }
      } else {
        tableColumn = visibleColumn;
      }
    }
  } else {
    tableColumn = obj.tableColumn;
  }

  var rowid = $xetable.getRowid(row);
  let fullAllDataRowIdData = $xetable.fullAllDataRowIdData;
  var rest = fullAllDataRowIdData[rowid];
  var rowLevel = rest ? rest.level : 0;
  var seq = rest ? rest.seq : -1;
  var renderType = "body";

  let $rowIndex = obj.$rowIndex;
  if ($rowIndex == null) {
    tableData.some(function (item, index) {
      let flag = rowid == $xetable.getRowid(item);
      if (flag) {
        $rowIndex = index;
      }
      return flag;
    });
  }

  let $columnIndex = obj.$columnIndex;
  if ($columnIndex == null) {
    tableColumn.some(function (item, index) {
      let flag = column.id == item.id;
      if (flag) {
        $columnIndex = index;
      }
      return flag;
    });
  }

  var _rowIndex = $xetable.getVTRowIndex(row); // 确保任何情况下 rowIndex 都精准指向真实 data 索引
  var rowIndex = $xetable.getRowIndex(row); // 事件绑定
  var params = {
    $table: $xetable,
    seq: seq,
    rowid: rowid,
    row: row,
    rowIndex: rowIndex,
    $rowIndex: $rowIndex,
    _rowIndex: _rowIndex,
    column: column,
    columnIndex: columnIndex,
    $columnIndex: $columnIndex,
    _columnIndex: _columnIndex,
    fixed: fixedType,
    type: renderType,
    isHidden: fixedHiddenColumn,
    level: rowLevel,
    visibleData: afterFullData,
    data: tableData,
    items: items,
  };
  return params;
}

function vNodeRender(vNodes) {
  if (vNodes === null || vNodes === undefined) {
    return null;
  }
  let type = typeof vNodes;
  if (type == "string" || type == "number") {
    return vNodes;
  }

  let cellValue = "";
  let contents = [];
  // let instance = null;
  let loop = function (item) {
    if (item && item.children && item.children.length > 0) {
      let arr = [];
      item.children.forEach(function (child) {
        if (child.componentOptions) {
          initTempSoltConstructorInstance();
          instance.$slots.default = child;
          instance.$mount();
          cellValue = "";
          if (child.componentInstance && child.componentInstance.$el) {
            cellValue = domRender(child.componentInstance.$el);
          }
          arr.push(cellValue);
          instance.$slots.default = null;
        } else {
          let text = loop(child);
          if (text != null) {
            arr.push(text);
          }
        }
      });
      return arr.join("");
    } else {
      if (item.text != null) {
        return item.text;
      }
    }
  };

  vNodes.forEach(function (vNode) {
    if (vNode !== undefined && vNode !== null) {
      if (vNode.componentOptions) {
        initTempSoltConstructorInstance();
        instance.$slots.default = vNode;
        instance.$mount();
        cellValue = "";
        if (vNode.componentInstance && vNode.componentInstance.$el) {
          cellValue = domRender(vNode.componentInstance.$el);
        }
        contents.push(cellValue);
        // instance.$destroy();
        instance.$slots.default = null;
        // instance = null;
      } else {
        if (vNode && vNode.children && vNode.children.length > 0) {
          let text = loop(vNode);
          if (text != null) {
            contents.push(text);
          }
        } else {
          let type1 = typeof vNode;
          if (type1 == "string" || type1 == "number") {
            contents.push(vNode);
          } else if (vNode.text != null) {
            contents.push(vNode.text);
          }
        }
      }
    }
  });
  destroyTempSoltConstructorInstance();
  // instance = null;
  return contents.join("").trim();
}

function groupDomRender(dom) {
  let contents = [];
  let loop = function (item) {
    if (item && item.children && item.children.length > 0) {
      let arr = [];
      Array.from(item.children).forEach((child) => {
        let text = loop(child);
        if (text != null) {
          arr.push(text);
        }
      });
      return arr.join("");
    } else {
      var style = window.getComputedStyle(item); //el即DOM元素
      let classList = Array.from(item.classList);
      if (style.display === "none") {
      } else if (item.nodeName == "INPUT") {
        if (item.type == "radio") {
          if (item.checked && classList.includes("el-radio__original")) {
            let value = item.parentNode.parentNode.innerText || "";
            if (value) {
              contents.push(value);
            }
          }
        } else if (item.type == "checkbox") {
          if (item.checked && classList.includes("el-checkbox__original")) {
            let value = item.parentNode.parentNode.innerText || "";
            if (value) {
              contents.push(value);
            }
          }
        }
      }
    }
  };
  loop(dom);
  return contents.join(",");
}

function selectGroupRender(dom) {
  let ul = dom.querySelector(".el-select-dropdown__list");
  if (ul) {
    let lis = ul.children;
    if (lis) {
      return Array.from(lis)
        .filter((li) => {
          let classList = Array.from(li.classList);
          return classList.includes("selected");
        })
        .map((li) => {
          return li.innerText;
        })
        .join(",");
    } else {
      return "";
    }
  } else {
    return "";
  }
}

function domRender(dom) {
  let loop = function (item) {
    if(item?.nodeName=="#comment")return "";
    var style = window.getComputedStyle(item); //el即DOM元素
    let role = item.getAttribute("role");
    let classList = Array.from(item.classList);

    if (style.display === "none") {
      return "";
    } else if (role == "group") {
      return groupDomRender(item);
    } else if (role == "radiogroup") {
      return groupDomRender(item);
    } else if (
      classList.includes("el-select")
      && item["@@clickoutsideContext"]
    ) {
      return selectGroupRender(item);
    } else if (item && item.children && item.children.length > 0) {
      let arr = [];
      Array.from(item.children).forEach((child) => {
        let text = loop(child);
        if (text != null) {
          arr.push(text);
        }
      });
      return arr.join("");
    } else {
      if (item.nodeName == "INPUT" || item.nodeName == "TEXTAREA") {
        return item.value;
      } else if (item.innerText != null && item.innerText != "") {
        return item.innerText;
      } else {
        return "";
      }
    }
  };
  let res = loop(dom).trim();
  return res;
}
