import { HOUR, DAY, SECOND, MINUTE } from '../../utils/tower.js';
import dayjs from 'dayjs';
import _ from 'lodash';

var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
  for (var prop in b || (b = {}))
    if (__hasOwnProp.call(b, prop))
      __defNormalProp(a, prop, b[prop]);
  if (__getOwnPropSymbols)
    for (var prop of __getOwnPropSymbols(b)) {
      if (__propIsEnum.call(b, prop))
        __defNormalProp(a, prop, b[prop]);
    }
  return a;
};
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
var __objRest = (source, exclude) => {
  var target = {};
  for (var prop in source)
    if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
      target[prop] = source[prop];
  if (source != null && __getOwnPropSymbols)
    for (var prop of __getOwnPropSymbols(source)) {
      if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
        target[prop] = source[prop];
    }
  return target;
};
function filterPointsByDateRange(points, dateRange) {
  const [startDate, endDate] = dateRange;
  return points == null ? void 0 : points.filter((point) => {
    const pointDate = dayjs(point.t);
    if (startDate && pointDate.isBefore(startDate)) {
      return false;
    }
    if (endDate && pointDate.isAfter(endDate)) {
      return false;
    }
    return true;
  });
}
const parseRange = (range) => {
  const span = parseInt(range.slice(0, range.length - 1));
  const unit = range.slice(range.length - 1);
  return { span, unit };
};
function getRangeTimestamp(dateRange) {
  const [startDate, endDate] = dateRange;
  return endDate.valueOf() - startDate.valueOf();
}
const xaxisCal = (lastTime, dateRange) => {
  const tangeTime = getRangeTimestamp(dateRange);
  const tick = tangeTime / 4;
  const msPerMinute = MINUTE * 1e3;
  const lastTimeMinute = dayjs(lastTime).minute();
  const baseline = lastTimeMinute < 30 ? lastTime - lastTimeMinute * msPerMinute : lastTime - lastTimeMinute * msPerMinute + msPerMinute * 30;
  return [baseline - tick * 3, baseline - tick * 2, baseline - tick, baseline];
};
const tickFormatter = (tick, dateRange) => {
  const rangeTime = getRangeTimestamp(dateRange);
  if (rangeTime <= 2 * HOUR * 1e3) {
    return dayjs(tick).format("HH:mm:ss");
  }
  if (rangeTime <= 4 * DAY * 1e3) {
    return dayjs(tick).format("MM/DD HH:mm:ss");
  }
  return dayjs(tick).format("MM/DD");
};
function getXAxisDomain(dateRange, xaxisLastTime) {
  const [startDate, endDate] = dateRange;
  return [startDate.valueOf(), xaxisLastTime != null ? xaxisLastTime : endDate.valueOf()];
}
const getMs = (dateRange) => {
  const [startDate, endDate] = dateRange;
  return endDate.valueOf() - startDate.valueOf();
};
const getStep = (dateRange) => {
  const [startDate, endDate] = dateRange;
  const range = endDate.valueOf() - startDate.valueOf();
  if (range <= 2 * 60 * 60 * 1e3) {
    return SECOND * 30 * 1e3;
  }
  if (range <= 24 * 60 * 60 * 1e3) {
    return MINUTE * 5 * 1e3;
  }
  if (range <= 7 * 24 * 60 * 60 * 1e3) {
    return MINUTE * 30 * 1e3;
  }
  if (range <= 30 * 24 * 60 * 60 * 1e3) {
    return DAY * 1e3;
  }
  return DAY * 1e3;
};
const filterDataOverlapping = (data, startTimestamp, length, step, tolerance) => {
  const points = [...new Array(Math.round(length))].map((_2, index) => {
    return startTimestamp + index * step;
  }).map((timestamp) => {
    const closestPoint = _.minBy(
      data.filter((value) => {
        return Math.abs(value.t - timestamp) < tolerance;
      }),
      (value) => {
        return Math.abs(value.t - timestamp);
      }
    );
    if (closestPoint == null) {
      return {
        t: timestamp,
        v: -Infinity
      };
    }
    return closestPoint;
  });
  return points;
};
const convertDataStruct = (streams) => {
  const points = streams.flatMap((points2, index) => {
    return points2.map((point) => {
      return __spreadProps(__spreadValues({}, point), { [`v${index}`]: point.v });
    });
  });
  const groupedPoints = _.groupBy(points, (point) => {
    return point.t;
  });
  const combinedPoints = Object.entries(groupedPoints).map(([key, values]) => {
    return values.reduce((p, c) => {
      const _a = __spreadValues(__spreadValues({}, p), c), values2 = __objRest(_a, ["v"]);
      return values2;
    }, {});
  });
  return combinedPoints;
};
const filterOverlappingMetric = (metric, dateRange) => {
  const range = getMs(dateRange);
  return __spreadProps(__spreadValues({}, metric), {
    sample_streams: metric.sample_streams.map((stream) => __spreadProps(__spreadValues({}, stream), {
      points: filterDataOverlapping(
        stream.points,
        dateRange[0].valueOf(),
        range / stream.step,
        stream.step,
        stream.tolerance
      )
    }))
  });
};

export { convertDataStruct, filterDataOverlapping, filterOverlappingMetric, filterPointsByDateRange, getMs, getStep, getXAxisDomain, parseRange, tickFormatter, xaxisCal };
