import { useMemo, useState } from "react";
import { BarChart3, Table2, X } from "lucide-react";
import {
    Bar,
    BarChart,
    CartesianGrid,
    ResponsiveContainer,
    Tooltip,
    XAxis,
    YAxis,
} from "recharts";
import type { ModuleSensorResponse } from "../../../types/meteo";
import type {
    AccumulatedBucket,
    AccumulatedRange,
} from "../hooks/useAccumulatedHistory";

type Props = {
    sensor: ModuleSensorResponse | null;
    title: string;
    theme: "dark" | "light";
    buckets: AccumulatedBucket[];
    loading: boolean;
    range: AccumulatedRange;
    onRangeChange: (range: AccumulatedRange) => void;
    onClose: () => void;
};

const RADIUS = "rounded-[5px]";

const RANGE_OPTIONS: Array<{ label: string; value: AccumulatedRange }> = [
    { label: "7D", value: "7d" },
    { label: "30D", value: "30d" },
    { label: "Mês", value: "month" },
    { label: "Ano", value: "year" },
];

export function AccumulatedHistoryModal({
    sensor,
    title,
    theme,
    buckets,
    loading,
    range,
    onRangeChange,
    onClose,
}: Props) {
    const isDark = theme === "dark";
    const palette = accumulatedPalette(isDark);
    const [mode, setMode] = useState<"chart" | "table">("chart");

    const stats = useMemo(() => {
        if (buckets.length === 0) {
            return { total: 0, average: 0, max: 0 };
        }

        const values = buckets.map((bucket) => bucket.total);

        return {
            total: values.reduce((sum, value) => sum + value, 0),
            average: values.reduce((sum, value) => sum + value, 0) / values.length,
            max: Math.max(...values),
        };
    }, [buckets]);

    if (!sensor) return null;

    const unit = buckets[0]?.unit ?? sensor.unit ?? "";

    return (
        <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/60 p-4 backdrop-blur-sm">
            <div
                className={
                    isDark
                        ? `${RADIUS} flex h-[82vh] w-full max-w-6xl flex-col overflow-hidden border border-white/10 bg-[#111827] text-slate-100 shadow-2xl`
                        : `${RADIUS} flex h-[82vh] w-full max-w-6xl flex-col overflow-hidden border border-slate-200 bg-white text-slate-950 shadow-[0_24px_70px_rgba(15,23,42,0.18)]`
                }
            >
                <header className="flex items-start justify-between gap-5 px-6 py-4">
                    <div>
                        <p
                            className={
                                isDark
                                    ? "mb-1 text-[11px] font-bold uppercase tracking-[0.22em] text-slate-500"
                                    : "mb-1 text-[11px] font-bold uppercase tracking-[0.22em] text-slate-400"
                            }
                        >
                            Acumulado
                        </p>

                        <h2 className="text-xl font-black tracking-[-0.03em]">
                            {title}
                        </h2>

                        <p className="mt-1 text-xs text-slate-500">
                            Chave: {sensor.key}
                        </p>
                    </div>

                    <button
                        type="button"
                        onClick={onClose}
                        className={
                            isDark
                                ? `${RADIUS} p-2 text-slate-400 transition hover:bg-white/5 hover:text-white`
                                : `${RADIUS} p-2 text-slate-400 transition hover:bg-slate-100 hover:text-slate-900`
                        }
                    >
                        <X className="h-5 w-5" />
                    </button>
                </header>

                <main className="flex min-h-0 flex-1 flex-col px-6 pb-5">
                    <section
                        className={
                            isDark
                                ? `${RADIUS} flex min-h-0 flex-1 flex-col border border-white/10 bg-[#0b1220] p-4`
                                : `${RADIUS} flex min-h-0 flex-1 flex-col border border-slate-200 bg-slate-50 p-4`
                        }
                    >
                        <div className="mb-4 flex flex-wrap items-center gap-2">
                            {RANGE_OPTIONS.map((option) => (
                                <button
                                    key={option.value}
                                    type="button"
                                    onClick={() => onRangeChange(option.value)}
                                    className={
                                        range === option.value
                                            ? activeButtonClass(isDark)
                                            : buttonClass(isDark)
                                    }
                                >
                                    {option.label}
                                </button>
                            ))}

                            <div className="ml-auto flex gap-2">
                                <button
                                    type="button"
                                    onClick={() => setMode("chart")}
                                    className={toggleButtonClass(isDark, mode === "chart")}
                                >
                                    <BarChart3 className="mr-2 inline h-4 w-4" />
                                    Gráfico
                                </button>

                                <button
                                    type="button"
                                    onClick={() => setMode("table")}
                                    className={toggleButtonClass(isDark, mode === "table")}
                                >
                                    <Table2 className="mr-2 inline h-4 w-4" />
                                    Tabela
                                </button>
                            </div>
                        </div>

                        <div className="mb-4 grid grid-cols-1 gap-3 sm:grid-cols-3">
                            <StatCard theme={theme} label="Total" value={formatValue(stats.total, unit)} />
                            <StatCard theme={theme} label="Média" value={formatValue(stats.average, unit)} />
                            <StatCard theme={theme} label="Máximo" value={formatValue(stats.max, unit)} />
                        </div>

                        <div className="min-h-0 flex-1">
                            {loading ? (
                                <EmptyState>A carregar acumulados...</EmptyState>
                            ) : buckets.length === 0 ? (
                                <EmptyState>Sem dados acumulados para este período.</EmptyState>
                            ) : mode === "chart" ? (
                                <ResponsiveContainer width="100%" height="100%">
                                    <BarChart
                                        data={buckets}
                                        margin={{ top: 16, right: 18, bottom: 8, left: 0 }}
                                    >
                                        <CartesianGrid
                                            stroke={palette.grid}
                                            strokeDasharray="4 6"
                                            vertical={false}
                                        />

                                        <XAxis
                                            dataKey="label"
                                            tick={{ fill: palette.axis, fontSize: 11 }}
                                            tickLine={false}
                                            axisLine={{ stroke: palette.axisLine }}
                                            minTickGap={20}
                                        />

                                        <YAxis
                                            tick={{ fill: palette.axis, fontSize: 11 }}
                                            tickLine={false}
                                            axisLine={{ stroke: palette.axisLine }}
                                            width={56}
                                        />

                                        <Tooltip
                                            cursor={{ fill: palette.cursor }}
                                            contentStyle={{
                                                background: palette.tooltipBg,
                                                border: `1px solid ${palette.tooltipBorder}`,
                                                borderRadius: "5px",
                                                color: palette.tooltipText,
                                                boxShadow: isDark
                                                    ? "0 18px 45px rgba(0,0,0,0.30)"
                                                    : "0 18px 45px rgba(15,23,42,0.14)",
                                            }}
                                            formatter={(value) => [
                                                formatValue(Number(value), unit),
                                                "Acumulado",
                                            ]}
                                        />

                                        <Bar
                                            dataKey="total"
                                            fill={palette.bar}
                                            radius={[3, 3, 0, 0]}
                                            isAnimationActive={false}
                                        />
                                    </BarChart>
                                </ResponsiveContainer>
                            ) : (
                                <div
                                    className={
                                        isDark
                                            ? `${RADIUS} h-full overflow-auto border border-white/10 bg-[#111827]`
                                            : `${RADIUS} h-full overflow-auto border border-slate-200 bg-white`
                                    }
                                >
                                    <table className="w-full text-left text-sm">
                                        <thead
                                            className={
                                                isDark
                                                    ? "sticky top-0 bg-[#111827] text-xs uppercase tracking-[0.14em] text-slate-500"
                                                    : "sticky top-0 bg-slate-50 text-xs uppercase tracking-[0.14em] text-slate-500"
                                            }
                                        >
                                            <tr>
                                                <th className="px-4 py-3">Período</th>
                                                <th className="px-4 py-3">Início</th>
                                                <th className="px-4 py-3">Fim</th>
                                                <th className="px-4 py-3 text-right">Total</th>
                                            </tr>
                                        </thead>

                                        <tbody>
                                            {buckets.map((bucket) => (
                                                <tr
                                                    key={`${bucket.from}-${bucket.to}`}
                                                    className={
                                                        isDark
                                                            ? "border-t border-white/10 text-slate-300"
                                                            : "border-t border-slate-200 text-slate-700"
                                                    }
                                                >
                                                    <td className="px-4 py-3 font-semibold">
                                                        {bucket.label}
                                                    </td>

                                                    <td className="px-4 py-3 text-slate-500">
                                                        {formatDate(bucket.from)}
                                                    </td>

                                                    <td className="px-4 py-3 text-slate-500">
                                                        {formatDate(bucket.to)}
                                                    </td>

                                                    <td
                                                        className={
                                                            isDark
                                                                ? "px-4 py-3 text-right font-black text-slate-100"
                                                                : "px-4 py-3 text-right font-black text-slate-950"
                                                        }
                                                    >
                                                        {formatValue(bucket.total, unit)}
                                                    </td>
                                                </tr>
                                            ))}
                                        </tbody>
                                    </table>
                                </div>
                            )}
                        </div>
                    </section>
                </main>
            </div>
        </div>
    );
}

function accumulatedPalette(isDark: boolean) {
    return isDark
        ? {
            bar: "#94a3b8",
            grid: "rgba(148,163,184,0.16)",
            axis: "#64748b",
            axisLine: "rgba(148,163,184,0.18)",
            cursor: "rgba(148,163,184,0.08)",
            tooltipBg: "#111827",
            tooltipBorder: "rgba(255,255,255,0.10)",
            tooltipText: "#e5e7eb",
        }
        : {
            bar: "#475569",
            grid: "#e2e8f0",
            axis: "#64748b",
            axisLine: "#cbd5e1",
            cursor: "rgba(148,163,184,0.12)",
            tooltipBg: "#ffffff",
            tooltipBorder: "#e2e8f0",
            tooltipText: "#0f172a",
        };
}

function EmptyState({ children }: { children: string }) {
    return (
        <div className="flex h-full items-center justify-center text-sm text-slate-400">
            {children}
        </div>
    );
}

function StatCard({
    theme,
    label,
    value,
}: {
    theme: "dark" | "light";
    label: string;
    value: string;
}) {
    const isDark = theme === "dark";

    return (
        <div
            className={
                isDark
                    ? `${RADIUS} border border-white/10 bg-[#111827] p-3`
                    : `${RADIUS} border border-slate-200 bg-white p-3`
            }
        >
            <p className="text-xs text-slate-500">{label}</p>

            <p
                className={
                    isDark
                        ? "mt-1 text-xl font-black text-slate-100"
                        : "mt-1 text-xl font-black text-slate-950"
                }
            >
                {value}
            </p>
        </div>
    );
}

function buttonClass(isDark: boolean) {
    return isDark
        ? `${RADIUS} border border-white/10 bg-white/[0.03] px-3 py-2 text-xs font-semibold text-slate-300 transition hover:bg-white/[0.06] hover:text-slate-100`
        : `${RADIUS} border border-slate-200 bg-white px-3 py-2 text-xs font-semibold text-slate-600 transition hover:bg-slate-100 hover:text-slate-950`;
}

function activeButtonClass(isDark: boolean) {
    return isDark
        ? `${RADIUS} border border-white/10 bg-slate-200 px-3 py-2 text-xs font-black text-slate-950`
        : `${RADIUS} border border-slate-300 bg-slate-900 px-3 py-2 text-xs font-black text-white`;
}

function toggleButtonClass(isDark: boolean, active: boolean) {
    if (active) return activeButtonClass(isDark);
    return buttonClass(isDark);
}

function formatValue(value: number, unit: string) {
    if (unit === "Wh/m²" && value >= 1000) {
        return `${(value / 1000).toFixed(2)} kWh/m²`;
    }

    return `${value.toFixed(1)}${unit ? ` ${unit}` : ""}`;
}

function formatDate(value: string) {
    return new Date(value).toLocaleString("pt-PT", {
        day: "2-digit",
        month: "2-digit",
        hour: "2-digit",
        minute: "2-digit",
    });
}