const { range } = require('lodash');
const { isLeapYear } = require('../../models');
const { calcStartTime } = require('../../utils');

/**
 * Make statisical data look like a timeseries for plotting purposes
 *
 * @param series -- an object with the following keys: points, startTime, and endTime at a minimum. Each point should have a javascript month and day
 * @returns {*[]}
 */
export const coerceStatisticalSeries = function (series, period) {
    const startTime = calcStartTime(period, series.endTime);
    const startYear = startTime.getFullYear();
    const endYear = series.endTime.getFullYear();
    const yearRange = range(startYear, endYear + 1);
    let points = series.points;
    let plotablePoints = [];
    yearRange.forEach(year => {
        points.forEach(point => {
            let month = point.month;
            let day = point.day;
            let dataPoint = Object.assign({}, point);
            dataPoint.dateTime = dataPoint.dateTime ? dataPoint.dateTime : new Date(year, month, day);
            if (!isLeapYear(year)) {
                if(!(month === 1 && day === 29)) {
                    plotablePoints.push(dataPoint);
                }
            } else {
                plotablePoints.push(dataPoint);
            }
        });
    });
    let sortedPoints = plotablePoints.sort(function(a, b) {
        return a.dateTime - b.dateTime;
    });
    let filtered = sortedPoints.filter(x => startTime <= x.dateTime && x.dateTime <= series.endTime);
    let first = filtered[0];
    if (first.dateTime > startTime) {
        let previousIndex;
        if (sortedPoints.indexOf(first) === 0) {
            previousIndex = sortedPoints.length - 1;
        } else {
            previousIndex = sortedPoints.indexOf(first) - 1;
        }
        const previousVal = sortedPoints[previousIndex];
        let leftVal = Object.assign({}, previousVal);
        leftVal.dateTime = startTime;
        filtered.unshift(leftVal);
    }
    let last = filtered[filtered.length - 1];
    if (last.dateTime < series.endTime) {
        let rightVal = Object.assign({}, last);
        rightVal.dateTime = series.endTime;
        filtered.push(rightVal);
    }
    return filtered;
};