import { Centers, ColorMap } from "./interfaces";

/**
  * 检查colorOrder是否可用, 即:colorOrder里是否已涵盖colorMap出现的所有颜色
  * @param colorMap 区块填色表
  * @param colorOrder 颜色排序列表
  */
export function validateOrder(colorMap: ColorMap, colorOrder: number[]): boolean {
  if (!colorMap || !colorOrder || colorOrder.length <= 0) {
    return false;
  }

  // colorMap里出现的颜色列表
  let allColors = Array.from(new Set(Object.values(colorMap).map(value => {
    return value.color;
  })));

  // 判断order是否包含全部colorMap中的颜色
  if (colorOrder.length < allColors.length) {
    return false;
  }
  for (let i = 0; i < allColors.length; i++) {
    if (!colorOrder.includes(allColors[i])) {
      return false;
    }
  }
  return true;
}


/**
 * 获得可用的colorOrder
 * 算法: 
 *    1. 如果有可用的手动顺序colorOrder, 则返回colorOrder
 *    2. 如果colorOrder不可用, 则判断自动顺序orderAuto是否可用, 可用即返回orderAuto
 *    3. 如果以上都不可用, 那么根据中心点centers和colorMap生成新的order并返回(注:该新order实际上是自动顺序orderAuto)
 *    4. 如果中心点没有, 只能返回null
 * 
 * @param colorMap 区块填色表
 * @param centers 中心点
 * @param colorOrder 手动顺序
 * @param orderAuto 自动顺序        
 */
export function getColorOrder(colorMap: ColorMap, centers: Centers, colorOrder: number[], orderAuto: number[]): number[] {
  if (validateOrder(colorMap, colorOrder)) {
    return colorOrder;
  }
  if (validateOrder(colorMap, orderAuto)) {
    return orderAuto;
  }
  return generateOrderAuto(colorMap, centers);
}


/**
 * 获得可用的colorOrder
 * 算法: 跟以上getColorOrder的区别是: 如果有colorOrder, 哪怕不完整, 也优先采用colorOrder排序, 剩余部分自动排序
 * 
 * @param colorMap 区块填色表
 * @param centers 中心点
 * @param colorOrder 手动顺序
 * @param orderAuto 自动顺序        
 */
export function getColorOrder2(colorMap: ColorMap, centers: Centers, colorOrder: number[], orderAuto: number[]): number[] {
  if (validateOrder(colorMap, colorOrder)) { // 手动排序完全可用, 直接返回
    return colorOrder;
  }
  if (!validateOrder(colorMap, orderAuto)) { // 检查下自动排序是否OK, 如果不OK则重新生成
    orderAuto = generateOrderAuto(colorMap, centers);
  }
  if (!colorOrder || colorOrder.length <= 0) { // colorOrder完全没有, 直接返回orderAuto
    return orderAuto;
  }

  // 接下来结合colorOrder和orderAuto 重新排序

  // 所有颜色
  let allColors = Array.from(new Set(Object.values(colorMap).map(value => {
    return value.color;
  })));

  // 首先根据colorOrder先做一轮排序
  allColors.sort((a, b) => {
    let aidx = colorOrder.indexOf(a);
    let bidx = colorOrder.indexOf(b);
    aidx = aidx < 0 ? 9999 : aidx;
    bidx = bidx < 0 ? 9999 : bidx;
    return aidx - bidx;
  });
  // 接着对剩下未排序的部分根据orderAuto进行排序
  allColors.sort((a, b) => {
    if (colorOrder.includes(a) || colorOrder.includes(b)) {
      return 0;  // 出现在colorOrder里的元素已经排过了,相对位置不变
    }
    let aidx = orderAuto.indexOf(a);
    let bidx = orderAuto.indexOf(b);
    aidx = aidx < 0 ? 9999 : aidx;
    bidx = bidx < 0 ? 9999 : bidx;
    return aidx - bidx;
  });

  return allColors;

}

/**
 * 生成自动顺序
 * @param colorMap 
 * @param centers 
 * @returns 
 */
export function generateOrderAuto(colorMap: ColorMap, centers: Centers): number[] {
  // 没有现成的order, 需要现场生成, 取决于有没有centers
  if (!centers || Object.keys(centers).length <= 0) {
    return null;
  }

  let colorHash = {};
  Object.keys(colorMap).forEach(areaIndex => {
    let { color } = colorMap[areaIndex];
    let point = centers[areaIndex];
    if (!point) { //标记!!! 发现colorMap里有的area在centers中心点中不存在, 导致出错. 需要认真评估这个问题的原因以及所带来的影响
      console.error("[generateOrderAuto] areaIndex: " + areaIndex + " in colorMap cannot be found in centers!");
      return;
    }
    if (!colorHash[color]) {
      colorHash[color] = {
        color: color,
        maxRadius: point.radius,
      }
    } else {
      if (point.radius > colorHash[color].maxRadius) {
        colorHash[color].maxRadius = point.radius;
      }
    }
  })
  let order = Object.values(colorHash)  // 生成默认order
    .sort((a: any, b: any) => {
      return b.maxRadius - a.maxRadius;
    })
    .map((item: any) => { return item.color });

  return order;
}