import getMoment from 'moment';

/**
 * 將後端的 chart data 加入最大、最小值，折線圖
 * @param   {array} baseData 後端給的 10 個時間點
 * @param   {number} xMax 2022-05-23T18:00:00
 * @param   {number} xMin 2022-05-23T08:00:00
 * @param   {number} isPercent 是否以百分比顯示
 * @param   {number} yMax case
 * @param   {number} yMin case
 * @returns {array} 可直接套入 chart.js 的 data
 */
export function setLineChartData(baseData, xMax, xMin, isPercent, yMax, yMin) {
  let data = baseData.map(i=>({x:i.x,y:i.y}))
  // y 軸斜率計算請參考 ./public/timeFrameSlope 的圖
  // x 值為 0 ~ 11,
  // 將三的座標(ax, ay), (bx, by), (cx, cy)命名為 (a, b), (c, d), (e, f)
  // 最小值: (f - b)(c - a) = (e - a)(d - b)，求 b = (ed - ad - fa - fc) / (e - c - a)
  // 最大值: (f - b)(e - c) = (f - d)(e - a)，求 f = (be - bc -de + da) / (a - c)

  // y 軸最小值
  let a = 0;
  let b;
  let c = 1;
  let d = baseData[0].y;
  let e = 2;
  let f = baseData[1].y;
  b = (e*d - a*d - f*a - f*c) / (e - c - a)
  if(isPercent) b = b >= 1 ? 1 : b <= 0 ? 0 : b;
  else b = b >= yMax ? yMax : b <= yMin ? yMin : b;

  // y 軸最大值
  let ma = 9;
  let mb = baseData[8].y;
  let mc = 10;
  let md = baseData[9].y;
  let me = 11;
  let mf;
  mf = (mb*me - mb*mc -md*me + md*ma) / (ma - mc);
  if(isPercent) mf = mf >= 1 ? 1 : mf <= 0 ? 0 : mf;
  else mf = mf >= yMax ? yMax : mf <= yMin ? yMin : mf;

  // 添加最小值
  data.unshift({
    x: xMin,
    y: b,
  })
  // 添加最大值
  data.push({
    x: xMax,
    y: mf,
  })

  return data;
};
/**
 * 將後端的 chart data 加入最大、最小值，長條圖
 * @param   {array} baseData 後端給的 10 個時間點
 * @param   {number} xMax 2022-05-23T18:00:00
 * @param   {number} xMin 2022-05-23T08:00:00
 * @returns {array} 可直接套入 chart.js 的 data
 */
export function setBarChartData(baseData) {
  let data = baseData.map(i =>{
    return {
      x: getMoment(i.x).format('YYYY/M/D hh:mm:ss'),
      y: i.y
    }
  })
  return data
};
/**
 * 將一段時間均分成多段的時間點
 * @param   {string} startTime 開始時間(ex: 434) 總秒數
 * @param   {string} endTime   結束時間(ex: 259065) 總秒數
 * @param   {number} amount    切分成多少段
 * @returns {array}            均分成多段的時間 array
 */
export function timeRange(minTime, maxTime, amount) {
  // x 軸(時間軸)的範圍是最大-最小，從最小值按照 index 累加間距到最大值
  const startTime = minTime;
  const endTime = maxTime;
  let timeRange = []; // return數據初始化
  const timeGap = (endTime - startTime) / (amount - 1); // 切分成多少段

  for (let i = 0; i < amount; i++) {
    timeRange.push(startTime + timeGap * i);
  }
  timeRange = timeRange.map(value => Math.round(value));
  return timeRange;
};
/**
 * 將 y 軸的值分割成跟 x 時間軸一樣的等份，使用統計學 R 語言算出貝茲曲線攻勢
 * @param   {array}  data       切分成多少段
 * @param   {number} yAmount    切分成多少段
 * @param   {number} yMax       y 最大值
 * @returns {array}             均分成多段的時間 array
 */
export function yTimeRange(data, yAmount, yMax) {
  const yRange = [];
  const yGap = (1/ (yAmount-1));

  // 貝茲曲線公式
  const threebsr = function (t, a1, a2, a3, a4) {
    return (
      (1 - t) * (1 - t) * (1 - t) * a1 +
        3 * t * (1 - t)* (1 - t) * a2 +
        3 * t * t *  (1 - t) * a3 +
        t * t * t * a4
    )
  };

   for (let j = 0; j < data.length - 1; j++) {
     for (let i = 0; i <= 1; i += yGap*11) {
    yRange.push(threebsr(i, data[j].y, data[j].y, data[j + 1].y, data[j + 1].y));
    }
  }

  if(yRange.length < yAmount) {
    let len = yAmount - yRange.length;
    for (let i = 0; i < len; i++) {
      yRange.push(yRange[yRange.length - 1]);
    }
  }
  else if(yRange.length > yAmount) {
    let len = yRange.length - yAmount;
    for(let i = 0; i < len; i++) {
      yRange.splice(1, 1);
    }
  }

  return yRange;
};
/**
 * 找出選擇的時間點的 index
 * @param {array} data xVal
 * @param {number} xValue x 值
 * @returns {numver} x index
 */
export function getXIndex(data, xValue) {
  let closestElement = data[0]; // 假定第一个元素是最接近的
  let closestIndex = xValue; // 假定第一个元素的索引是 0
  let smallestDifference = Math.abs(xValue - data[0]); // 初始差值设为第一个元素与目标数的差值

  for (let i = 0; i < data.length; i++) {
    let difference = Math.abs(xValue - data[i]);

    if (difference <= smallestDifference) {
      closestElement = data[i];
      closestIndex = i;
      smallestDifference = difference;
    }
  }

  return closestIndex;
};
/**
 *
 * @param {number} seconds
 * @returns {string}
 */
export function formatTime(seconds) {
  if(!isNaN(seconds)) {
    const remainingSeconds = seconds % 60;
    const minutes = (Math.floor(seconds - remainingSeconds) / 60) % 60;
    const hours = (Math.floor(seconds / 3600)) % 24;
    const days = Math.floor(seconds / (3600 * 24));

    let result = '';
    if (days > 0) {
      result += `${days}d`;
    }
    if (hours > 0) {
      result += `${hours}h`;
    }
    if (minutes > 0) {
      result += `${minutes}m`;
    }
    result += `${remainingSeconds}s`;

    return result.trim(); // 去除最后一个空格
  } else return null;
}
