'use client';
import { LineChart, Line, YAxis, XAxis, CartesianGrid, Tooltip, Area, Label } from 'recharts';
import spacetime from 'spacetime';
import regression from 'regression';

interface DataPoint {
    id: string; // measurement.id
    datetime: Date;
    value: number;
    unit: string;
};

function polynomialTrendline(data: DataPoint[], degree: number) {
    // Map your data to the form required by regression-js: [x, y]
    // Here we convert datetime to a numeric value (e.g., milliseconds since epoch)
    const regressionData = data.map((dp, i) => [i, dp.value]) as [number, number][];

    const result = regression.polynomial(regressionData, { order: degree });
    // result.equation contains the polynomial coefficients,
    // and result.predict(x) returns the predicted y for a given x value.
    return result;
}

function formatXAxis(tickItem: [number, number]) {
    const month = spacetime(tickItem).format('{month-short}');
    if (spacetime(tickItem).day() === 1) {
        return spacetime(tickItem).format('{month-short} {date}');
    } else {
        return spacetime(tickItem).format('{date}');
    }
}

function yAxisTicks(data: DataPoint[]) {
    const bounds = data.map(dp => Math.round(dp.value)).sort().filter((_v, i, a) => i === 0 || i === a.length - 1);
    const lowerBound = bounds[0] - (bounds[0] % 2);
    const upperBound = bounds[1] + (2 - bounds[1] % 2);
    // Create an array of ticks from lowerBound to upperBound in increments of 2
    return Array.from({ length: (upperBound - lowerBound) / 2 + 1 }, (_, i) => lowerBound + 2 * i);
}

export default function TimeseriesChart({ data, timeseriesName }: { data: DataPoint[], timeseriesName: string }) {
    const unit = data[0] ? data[0].unit : '';

    const polyResult = polynomialTrendline(data, 1)// 2 for quadratic
    const dataWithFit = (data.map((dp, i) => {
        return {
            datetime: dp.datetime,
            value: dp.value,
            smoothed: polyResult.predict(i)[1],
        };
    }));

    return (
        <div className='flex flex-col items-center'>
            <h2>
                Trend: {(7 * polyResult.equation[0]).toFixed(1)} {unit}/week
            </h2>
            <LineChart width={800} height={400} data={dataWithFit}>
                <CartesianGrid stroke="#999" />
                <Tooltip
                    labelFormatter={(d) => `${spacetime(d).format("{month-short} {date}, {hour}{ampm}")}`}
                    labelStyle={{ color: 'white' }}
                    formatter={(value, name, props) => [value, name === 'smoothed' ? 'Trend' : timeseriesName]}
                    contentStyle={{ backgroundColor: 'hsl(var(--border))', color: 'black' }}
                />
                <XAxis dataKey="datetime" tickFormatter={formatXAxis} tickMargin={10} tickSize={10} />
                <YAxis unit={` ${unit}`} width={120} domain={yAxisTicks(data).filter((v, i) => i === 0 || i === yAxisTicks(data).length - 1)}
                    allowDecimals={false}
                    ticks={yAxisTicks(data)} />
                <Line type="natural" dataKey="value" stroke="white" activeDot={{ stroke: 'pink', strokeWidth: 2, r: 5 }} dot={{ fill: 'red', stroke: 'red', strokeWidth: 1 }} />

                <Line type="natural" dataKey="smoothed" stroke={polyResult.equation[0] > 0 ? "red" : "green"} dot={false} />
            </LineChart>
        </div>
    );
} 