import { useEffect, useMemo, useState } from "react";

import {
    useClimateModuleStream,
    type ClimateModuleResponse,
} from "./useClimateModuleStream";

export type ClimateHistoryPoint = {
    timestamp: string;
    value: number;
};

export type ClimateHistoryByKey = Record<string, ClimateHistoryPoint[]>;

const MAX_POINTS_PER_SENSOR = 2000;

export function useClimateHistory() {
    const climate = useClimateModuleStream();

    const [historyByKey, setHistoryByKey] = useState<ClimateHistoryByKey>({});

    useEffect(() => {
        const module = climate.module;

        if (!module) return;

        setHistoryByKey((current) =>
            appendClimateSnapshot(current, module),
        );
    }, [climate.module]);

    const numericSensors = useMemo(
        () =>
            climate.sensors.filter(
                (sensor) =>
                    typeof sensor.value === "number" &&
                    Number.isFinite(sensor.value),
            ),
        [climate.sensors],
    );

    return {
        ...climate,
        sensors: numericSensors,
        historyByKey,
    };
}

function appendClimateSnapshot(
    current: ClimateHistoryByKey,
    snapshot: ClimateModuleResponse,
): ClimateHistoryByKey {
    const timestamp = snapshot.timestamp ?? new Date().toISOString();
    const next: ClimateHistoryByKey = { ...current };

    for (const sensor of snapshot.sensors) {
        if (typeof sensor.value !== "number" || !Number.isFinite(sensor.value)) {
            continue;
        }

        const key = sensor.key;
        const currentSeries = next[key] ?? [];

        const lastPoint = currentSeries[currentSeries.length - 1];

        if (lastPoint?.timestamp === timestamp) {
            continue;
        }

        next[key] = [
            ...currentSeries,
            {
                timestamp,
                value: sensor.value,
            },
        ].slice(-MAX_POINTS_PER_SENSOR);
    }

    return next;
}