import {
    Area,
    AreaChart,
    CartesianGrid,
    ResponsiveContainer,
    Tooltip,
    XAxis,
    YAxis,
} from "recharts";
import type { HistorianDashboardResponse } from "../../../types/historian";

type ChartSeries = {
    key: string;
    label: string;
    color: string;
};

type DashboardTrendChartProps = {
    title: string;
    subtitle: string;
    data: HistorianDashboardResponse | null;
    series: ChartSeries[];
    theme: "dark" | "light";
};

export function DashboardTrendChart({
    title,
    subtitle,
    data,
    series,
    theme,
}: DashboardTrendChartProps) {
    const isDark = theme === "dark";
    const chartData = buildChartData(data, series);

    return (
        <div
            className={
                isDark
                    ? "rounded-2xl border border-white/10 bg-[#142230] p-5 shadow-[0_16px_40px_rgba(0,0,0,0.22)]"
                    : "rounded-2xl border border-slate-200 bg-white p-5 shadow-sm"
            }
        >
            <div className="mb-5 flex items-start justify-between gap-4">
                <div>
                    <h2 className={isDark ? "text-base font-semibold text-white" : "text-base font-semibold text-slate-950"}>
                        {title}
                    </h2>
                    <p className={isDark ? "text-sm text-slate-400" : "text-sm text-slate-500"}>
                        {subtitle}
                    </p>
                </div>

                <div className="flex flex-wrap justify-end gap-2">
                    {series.map((item) => (
                        <div key={item.key} className="flex items-center gap-1.5 text-xs">
                            <span
                                className="h-2 w-2 rounded-full"
                                style={{ backgroundColor: item.color }}
                            />
                            <span className={isDark ? "text-slate-300" : "text-slate-600"}>
                                {item.label}
                            </span>
                        </div>
                    ))}
                </div>
            </div>

            <div className="h-72">
                <ResponsiveContainer width="100%" height="100%">
                    <AreaChart data={chartData} margin={{ top: 8, right: 8, left: -16, bottom: 0 }}>
                        <defs>
                            {series.map((item) => (
                                <linearGradient key={item.key} id={gradientId(item.label)} x1="0" y1="0" x2="0" y2="1">
                                    <stop offset="5%" stopColor={item.color} stopOpacity={0.35} />
                                    <stop offset="95%" stopColor={item.color} stopOpacity={0.02} />
                                </linearGradient>
                            ))}
                        </defs>

                        <CartesianGrid
                            strokeDasharray="4 4"
                            vertical={false}
                            stroke={isDark ? "rgba(148,163,184,0.16)" : "rgba(100,116,139,0.18)"}
                        />

                        <XAxis
                            dataKey="time"
                            tickLine={false}
                            axisLine={false}
                            stroke={isDark ? "#94a3b8" : "#64748b"}
                            fontSize={12}
                        />

                        <YAxis
                            tickLine={false}
                            axisLine={false}
                            stroke={isDark ? "#94a3b8" : "#64748b"}
                            fontSize={12}
                        />

                        <Tooltip
                            cursor={{
                                stroke: isDark ? "#64748b" : "#94a3b8",
                                strokeWidth: 1,
                            }}
                            contentStyle={{
                                background: isDark ? "#0B1220" : "#ffffff",
                                border: isDark ? "1px solid rgba(255,255,255,0.12)" : "1px solid #e2e8f0",
                                borderRadius: "14px",
                                color: isDark ? "#f8fafc" : "#0f172a",
                                boxShadow: "0 18px 45px rgba(0,0,0,0.25)",
                            }}
                            labelStyle={{
                                color: isDark ? "#cbd5e1" : "#475569",
                                fontWeight: 600,
                            }}
                        />

                        {series.map((item) => (
                            <Area
                                key={item.key}
                                type="monotone"
                                dataKey={item.label}
                                stroke={item.color}
                                fill={`url(#${gradientId(item.label)})`}
                                strokeWidth={2.5}
                                dot={false}
                                activeDot={{ r: 4 }}
                                isAnimationActive={false}
                            />
                        ))}
                    </AreaChart>
                </ResponsiveContainer>
            </div>
        </div>
    );
}

function buildChartData(
    data: HistorianDashboardResponse | null,
    series: ChartSeries[],
) {
    if (!data) return [];

    const pointsByTimestamp = new Map<string, Record<string, string | number>>();

    for (const item of series) {
        const points = data.series[item.key] ?? [];

        for (const point of points) {
            const timestamp = point.timestamp;
            const existing = pointsByTimestamp.get(timestamp) ?? {
                timestamp,
                time: formatTime(timestamp),
            };

            existing[item.label] = point.numericValue ?? 0;
            pointsByTimestamp.set(timestamp, existing);
        }
    }

    return Array.from(pointsByTimestamp.values()).sort((a, b) =>
        String(a.timestamp).localeCompare(String(b.timestamp)),
    );
}

function formatTime(timestamp: string) {
    return new Date(timestamp).toLocaleTimeString("pt-PT", {
        hour: "2-digit",
        minute: "2-digit",
    });
}

function gradientId(label: string) {
    return `gradient-${label
        .toLowerCase()
        .replace(/\s+/g, "-")
        .replace(/\./g, "")}`;
}