import {
  funArrDiv,
  funMA,
  funMS,
  funRound,
  TMixed,
  checkArrayOfNumbers,
  checkNumber,
} from "../common";

export function CR(
  HIGH: number[],
  LOW: number[],
  N: number = 26,
  M1: number = 10,
  M2: number = 20,
  M3: number = 40,
  M4: number = 62
): {
  CR: TMixed[];
  MA1: TMixed[];
  MA2: TMixed[];
  MA3: TMixed[];
  MA4: TMixed[];
} {
  // check input
  checkArrayOfNumbers(HIGH, "HIGH");
  checkArrayOfNumbers(LOW, "LOW");
  checkNumber(N, 1, HIGH, "N", "HIGH");
  checkNumber(M1, 1, HIGH, "M1", "HIGH");
  checkNumber(M2, 1, HIGH, "M2", "HIGH");
  checkNumber(M3, 1, HIGH, "M3", "HIGH");
  checkNumber(M4, 1, HIGH, "M4", "HIGH");

  // MID:=REF(HIGH+LOW,1)/2;
  const MID: TMixed[] = [
    null,
    ...HIGH.map((h, i) => (h + LOW[i]) / 2).slice(0, -1),
  ];
  console.log("MID:", MID.slice(0, 10));
  // CR:SUM(MAX(0,HIGH-MID),N)/SUM(MAX(0,MID-LOW),N)*100;
  const CR = funArrDiv(
    funMS(
      HIGH.map((h, i) => (MID[i] !== null ? Math.max(0, h - MID[i]) : null)),
      N
    ),
    funMS(
      LOW.map((l, i) => (MID[i] !== null ? Math.max(0, MID[i] - l) : null)),
      N
    )
  ).map((v) => (v !== null ? v * 100 : null));

  /**
   * ****************当REF的参数N为小数时，处理方式不同**********************
   * 前面补null个数为Math.ceil(N)
   * 后门的计算为 [].slice(Math.ceil(N  % 1),-Math.floor(N))
   * 这个特此说明一下，REF可以写成函数进行处理
   */
  // MA1:REF(MA(CR,M1),M1/2.5+1);
  const MA1: TMixed[] = [
    ...(Array.from({ length: Math.ceil(M1 / 2.5 + 1) }).fill(null) as TMixed[]),
    ...funMA(CR, M1)
      .slice(Math.ceil((M1 / 2.5) % 1), -Math.floor(M1 / 2.5 + 1))
      .map((v) => funRound(v, 3)),
  ];

  // MA2:REF(MA(CR,M2),M2/2.5+1);
  const MA2: TMixed[] = [
    ...(Array.from({ length: Math.ceil(M2 / 2.5 + 1) }).fill(null) as TMixed[]),
    ...funMA(CR, M2)
      .slice(Math.ceil((M2 / 2.5) % 1), -Math.floor(M2 / 2.5 + 1))
      .map((v) => funRound(v, 3)),
  ];

  // MA3:REF(MA(CR,M3),M3/2.5+1);
  const MA3: TMixed[] = [
    ...(Array.from({ length: Math.ceil(M3 / 2.5 + 1) }).fill(null) as TMixed[]),
    ...funMA(CR, M3)
      .slice(Math.ceil((M3 / 2.5) % 1), -Math.floor(M3 / 2.5 + 1))
      .map((v) => funRound(v, 3)),
  ];

  // MA4:REF(MA(CR,M4),M4/2.5+1);
  const MA4: TMixed[] = [
    ...(Array.from({ length: Math.ceil(M4 / 2.5 + 1) }).fill(null) as TMixed[]),
    ...funMA(CR, M4)
      .slice(Math.ceil((M4 / 2.5) % 1), -Math.floor(M4 / 2.5 + 1))
      .map((v) => funRound(v, 3)),
  ];

  return { CR: CR.map((v) => funRound(v, 3)), MA1, MA2, MA3, MA4 };
}
