import type { MetricsTimeline } from "~/server/api/metrics/[project_id]/timeline/generic";

import { type Slice } from '../shared/services/DateService';

export const hoursOffset = -(new Date().getTimezoneOffset() / 60);

function matchDateWithSlice(a: Date, b: Date, slice: Slice): boolean {
    if (a.getFullYear() != b.getFullYear()) return false;
    if (a.getMonth() != b.getMonth()) return false;
    if (slice === 'month') return true;
    if (a.getDate() != b.getDate()) return false;
    if (slice === 'day') return true;
    if (a.getHours() != b.getHours()) return false;
    if (slice === 'hour') return true;
    return true;
}

type FixMetricsOptions = {
    advanced?: boolean,
    advancedGroupKey?: string,
    timeLabels?: boolean
}
export function fixMetrics(result: { data: MetricsTimeline[], from: string, to: string }, slice: Slice, _options?: FixMetricsOptions) {

    const options = {
        advanced: false,
        advancedGroupKey: 'default',
        timeLabels: false,
        ..._options
    }

    const allDates: Date[] = [];

    let currentDate = new Date(result.from);
    while (currentDate <= new Date(result.to)) {
        allDates.push(new Date(currentDate));
        if (slice == 'hour') {
            currentDate.setHours(currentDate.getHours() + 1);
        } else if (slice == 'day') {
            currentDate.setDate(currentDate.getDate() + 1);
        } else if (slice == 'month') {
            currentDate.setMonth(currentDate.getMonth() + 1);
        } else if (slice == 'year') {
            currentDate.setFullYear(currentDate.getFullYear() + 1);
        }
    }

    const allKeys = !options.advanced ? [] : Array.from(new Set(result.data.map((e: any) => e[options.advancedGroupKey])).values());

    console.log({ allKeys, allDates })

    const fixed: any[] = allDates.map(matchDate => {

        if (!options.advanced) {
            const target = result.data.find(e => matchDateWithSlice(new Date(e._id), matchDate, slice));
            return { _id: target ? new Date(target._id) : matchDate, count: target?.count || 0 }
        }

        const targets = result.data.filter(e => matchDateWithSlice(new Date(e._id), matchDate, slice));

        const returnObject: any = {
            _id: targets.length == 0 ? matchDate : new Date(targets[0]._id),
            count: allKeys.map(e => {
                return {
                    key: e,
                    value: targets.find((k: any) => k[options.advancedGroupKey] == e)?.count || 0
                }
            })
        }

        return returnObject;
    });


    if (slice === 'day' || slice == 'hour') fixed.pop();

    const data = fixed.map(e => e.count);
    const avgTrend = data.slice(0, -1).reduce((a, e) => a + e, 0) / (data.length - 1);
    const t = data.at(-1) || 0;
    const trend = (100 / avgTrend * t) - 100;

    return {
        labels: options.timeLabels ?
            fixed.map(e => {
                return e._id;
            }) : fixed.map(e => {
                if (slice == 'hour') {
                    return `${e._id.getHours().toString().padStart(2, '0')}:00`
                } else if (slice == 'day') {
                    return `${e._id.getDate().toString().padStart(2, '0')}/${(e._id.getMonth() + 1).toString().padStart(2, '0')}`
                } else if (slice == 'month') {
                    return `${(e._id.getMonth() + 1).toString().padStart(2, '0')}/${e._id.getFullYear().toString()}`
                } else if (slice == 'year') {
                    return `${e._id.getFullYear().toString()}`
                } else {
                    return '???'
                }
            }),
        data,
        trend,
        allKeys
    }


}
