import { CalculateUnit } from "@/type/BaseEnum";
import { isArray, isArrayLength, isUUIDv4 } from "./is";
import { useMessage } from "@/hooks/useMessage";
import { useErrorConfirm } from "./useErrorConfirm";

const { ElMessageBox } = useMessage();
const { report } = useErrorConfirm();
/**
 * 处理动态表格表头数据（客户费用、成本费用）
 * @returns
 */
export function useDealHeaderData() {
  /**
   * 处理为费用明细目标数组
   * @param dealArr 要处理的数组
   * @param excludedArr 排除合并的字段
   * @param excludeKeys 最终排除对应字段
   */
  const dealHeaderDetailsListDataTrget = (
    dealArr: Recordable[],
    excludeKeys: string[]
  ) => {
    if (!(isArrayLength(dealArr) && isArrayLength(excludeKeys))) return [];
    // 保留现有的分区键值
    for (let obj of dealArr) {
      for (let key of Object.keys(obj)) {
        // 如果不存在现有的分区删除之前的分区键值
        if (isUUIDv4(key) && !excludeKeys.includes(key)) {
          delete obj[key];
        }
      }
    }
    // const excludedArr = [
    //   "originalBeginWeight",
    //   "originalEndWeight",
    //   "originalCalculateUnit",
    //   "countBeginWeight",
    //   "countEndWeight",
    //   "countCalculateUnit",
    //   "feeItemSpecialFlag",
    //   "feeItemId",
    //   "countModel",
    //   "id",
    //   "packageType",
    //   "feeItemName",
    //   "shareType",
    //   "_X_ROW_KEY",
    //   "orderNumber",
    //   "currencyCode",
    //   "partitionName",
    // ];
    // 使用 filter 方法过滤出在 分区id 的剩余参数字段
    const notPartitionArray = Object.keys(dealArr[0]).filter(item => !excludeKeys.includes(item));
    // 将两个数组合并，并使用 Set 来保留唯一值，注（客户与成本通用的数据、"id", "_X_ROW_KEY"是用于判断显示数据的）
    const mergeArr = [...notPartitionArray, "id", "_X_ROW_KEY", "countCalculateUnit", "shareType"]
    const excludedArr = [...new Set(mergeArr)]
    // 将分区键转为对应字段存储
    const oneArray = dealArr.reduce((ac, cr) => {
      // 分别处理每个属性
      Object.keys(cr).forEach((key) => {
        // 如果该属性不是 name 或 age，将其添加到新对象中
        if (!excludedArr.includes(key)) {
          ac.push({
            originalBeginWeight: cr.originalBeginWeight,
            originalEndWeight: cr.originalEndWeight,
            originalCalculateUnit: cr.originalCalculateUnit,
            feeItemSpecialFlag: cr.feeItemSpecialFlag,
            countCalculateUnit: CalculateUnit.COUNT_CALCULATE_UNIT,
            feeItemId: cr.feeItemId,
            countModel: cr.countModel,
            packageType: cr.packageType,
            feeItemName: cr.feeItemName,
            shareType: cr.shareType,
            [key]: cr[key],
            // ...cr,
          });
        }
      });
      return ac;
    }, []);
    // 将对应数组转为目标数组
    const trgetArray = oneArray.map((obj) => {
      const partitionId = Object.keys(obj).find(
        (key) => !excludedArr.includes(key)
      ) as string;
      if (!partitionId) return;
      const offerPrice = obj[partitionId];
      // 合并对象
      return Object.assign({ partitionId, offerPrice }, { ...obj });
    });
    // 根据分区编号的键排除对应对象的键值
    const filteredArr = trgetArray.reduce((acc, curr) => {
      const filtered = Object.keys(curr)
        .filter((key) => !excludeKeys.includes(key))
        .reduce((obj, key) => {
          obj[key] = curr[key];
          return obj;
        }, {});
      acc.push(filtered);
      return acc;
    }, []);

    return filteredArr || [];
  };

  /**
   * 还原表格数据
   */
  const dealOriginalDetailsListDataTrget = (
    oldData: Recordable[],
    num: number
  ) => {
    if (!isArray(oldData)) return [];
    // 存储二维数组
    const twoDimensionalArr: Recordable[] = [];
    let index = 0;
    // 截取数组转为二维数组
    while (index < oldData.length) {
      const subArr = oldData.slice(index, index + num);
      twoDimensionalArr.push(subArr);
      index += num;
    }
    // console.log(twoDimensionalArr, ":twoDimensionalArr");
    const targetResult = twoDimensionalArr.map((subArr) => {
      return subArr.reduce((acc, item) => {
        // 将数组中的每个对象扩展成该对象和 partitionId 对应 offerPrice 的键值对
        const { partitionId, offerPrice, ...rest } = item;
        acc[partitionId] = offerPrice;
        return { ...acc, ...rest };
      }, {});
    });
    // console.log(targetResult, ":targetResult");
    return targetResult;
  };

  /**
   * 还原分区特殊参数数据
   */
  const dealOriginalSpecialParameters = (
    oldData: Recordable[],
    num: number
  ) => {
    if (!isArray(oldData) || num === 0) return [];
    // 存储二维数组
    const twoDimensionalArr: Recordable[] = [];
    let index = 0;
    // 截取数组转为二维数组
    while (index < oldData.length) {
      const subArr = oldData.slice(index, index + num);
      twoDimensionalArr.push(subArr);
      index += num;
    }
    const targetResult = twoDimensionalArr.map((subArr) => {
      return subArr.reduce((acc, item) => {
        // 将数组中的每个对象扩展成该对象和 partitionId 对应 setValue 的键值对
        const { partitionId, setValue, ...rest } = item;
        acc[partitionId] = setValue;
        return { ...acc, ...rest };
      }, {});
    });
    return targetResult;
  };

  /**
   * 处理为特殊参数目标数组
   * @param dealArr 要处理的数组
   * @param excludeKeys 最终排除对应字段
   */
  const dealHeaderSpecialParameterTrget = (
    dealArr: Recordable[],
    excludeKeys: string[]
  ) => {
    if (!isArray(dealArr) && !isArray(excludeKeys)) return;
    const excludedArr = ["specialParametersId", "id", "feeItemId", "_X_ROW_KEY"];
    // 需要过滤字段
    // const excludedProps = ["name", "age"];
    // 将分区键转为对应字段存储
    const oneArray = dealArr.reduce((ac, cr) => {
      // 分别处理每个属性
      Object.keys(cr).forEach((key) => {
        // 如果该属性不是 name 或 age，将其添加到新对象中
        if (!excludedArr.includes(key)) {
          ac.push({
            specialParametersId: cr.specialParametersId,
            feeItemId: cr.feeItemId,
            [key]: cr[key],
          });
        }
      });
      return ac;
    }, []);
    // 将对应数组转为目标数组
    const trgetArray = oneArray.map((obj) => {
      const partitionId = Object.keys(obj).find(
        (key) => !excludedArr.includes(key)
      ) as string;
      if (!partitionId) return;
      const setValue = obj[partitionId];
      // 合并对象
      return Object.assign({ partitionId, setValue }, { ...obj });
    });
    // 根据分区编号的键排除对应对象的键值
    const filteredArr = trgetArray.reduce((acc, curr) => {
      const filtered = Object.keys(curr)
        .filter((key) => !excludeKeys.includes(key))
        .reduce((obj, key) => {
          obj[key] = curr[key];
          return obj;
        }, {});
      acc.push(filtered);
      return acc;
    }, []);

    return filteredArr || [];
  };

  // 将相邻相同 feeItemId 的对象分组
  const dealPartitionListResult = (data: Recordable[], headNum: number) => {
    if (!isArrayLength(data)) return []
    const result: Recordable[] = [];
    let currentGroup: Recordable[] = [];
    // 遍历数组，将相邻相同 feeItemId 的对象分组
    for (let i = 0; i < data.length; i++) {
      if (currentGroup.length === 0 || (data[i].feeItemId === currentGroup[0].feeItemId && currentGroup.length < headNum)) {
        currentGroup.push(data[i]);
      } else {
        result.push(currentGroup);
        currentGroup = [data[i]];
      }
    }
    // 将最后一组加入结果
    if (currentGroup.length > 0) {
      result.push(currentGroup);
    }
    return result
  }

  return {
    dealHeaderDetailsListDataTrget,
    dealHeaderSpecialParameterTrget,
    dealOriginalDetailsListDataTrget,
    dealOriginalSpecialParameters,
    dealPartitionListResult
  };
}

/**
 *
 * @param oldTwoDimensionalArr 原始数据
 * @param headFieldArr 表头字段数据
 * @param num 表头数
 */
async function getDealHeaderDatainfo(
  oldTwoDimensionalArr: Recordable[],
  headFieldArr: Recordable[],
  num: number
) {
  if (!isArrayLength(oldTwoDimensionalArr) && !isArrayLength(headFieldArr))
    return;
  // console.time('运行时间');
  // 统计默认顺序显示数量
  try {
    const countFeeLength = new Map();
    let currentIndex = 0;
    // 默认添加第一个进去
    const item = oldTwoDimensionalArr[0];
    const keys = `${item.originalBeginWeight}_${item.originalEndWeight}_${item.countModel.countType}`;
    countFeeLength.set(keys, 1);
    const feeLength = oldTwoDimensionalArr.length;
    for (let index = 0; index < feeLength; index++) {
      const item = oldTwoDimensionalArr[index];
      const keys = `${item.originalBeginWeight}_${item.originalEndWeight}_${item.countModel.countType}`;
      if (index === currentIndex + 1) {
        countFeeLength.has(keys)
          ? countFeeLength.set(keys, countFeeLength.get(keys) + 1)
          : countFeeLength.set(keys, 1);
      }
      currentIndex = index;
    }

    // 转数组
    const countFeeArray = Array.from(countFeeLength.values());
    // console.log(countFeeArray, '需要截取的数量');
    // 存储二维数组
    const twoDimensionalArr: Array<Recordable[]> = [];
    let headNum = 0;
    const countFeeArrayLength = countFeeArray.length;
    for (let index = 0; index < countFeeArrayLength; index++) {
      const subArr = oldTwoDimensionalArr.slice(
        headNum,
        headNum + countFeeArray[index]
      );
      twoDimensionalArr.push(subArr);
      headNum += num;
    }
    // 错误的数据
    const oldErrorDataArr: Array<Recordable[]> = [];
    const twoDimensionalArrLength = twoDimensionalArr.length;
    for (let index = 0; index < twoDimensionalArrLength; index++) {
      const itemArr = twoDimensionalArr[index];
      if (itemArr.length < num) {
        oldErrorDataArr.push(itemArr);
      }
    }
    const totalErrorDataArr: Recordable[] = [];
    oldErrorDataArr.map((itemArr) => {
      const bigLength = itemArr.length > 0;
      if (bigLength) {
        const errorArr = headFieldArr.filter(
          (fieldArr) => !itemArr.some((it) => it.partitionId === fieldArr.prop)
        );
        totalErrorDataArr.push({ oldArr: bigLength && itemArr[0], errorArr });
      }
    });
    let htmlStr = "<div>温馨提示（数据错缺失会导致数据显示错误）：</div>";
    totalErrorDataArr.forEach((item) => {
      if (item && item.oldArr && isArrayLength(item.errorArr)) {
        htmlStr += `<div>
                        起始重量(${item.oldArr.originalBeginWeight})-结束重量(${
          item.oldArr.originalEndWeight
        })数据出错：
                        ${item.errorArr
                          .map((field) => field.label)
                          .join("，")}。
                    </div>`;
      }
    });
    if (htmlStr) {
      ElMessageBox.alert(htmlStr, { dangerouslyUseHTMLString: true });
    }
    return twoDimensionalArr;
  } catch (error) {
    report(error);
  }
  // console.timeEnd('运行时间');
}
