import { useEffect, useState, type ReactNode } from "react";
import {
    Activity,
    ChartNoAxesColumnIncreasing,
    CloudRain,
    Droplets,
    MoreHorizontal,
    Sun,
    Table2,
    Thermometer,
    TrendingUp,
    Wind,
} from "lucide-react";
import { useMeteoModuleStream } from "../hooks/useMeteoModuleStream";
import { MeteoHistoryModal } from "../components/MeteoHistoryModal";
import type { ModuleSensorResponse } from "../../../types/meteo";
import { useMeteoHistory } from "../hooks/useMeteoHistory";
import { AccumulatedHistoryModal } from "../components/AccumulatedHistoryModal";
import {
    useAccumulatedHistory,
    type AccumulatedRange,
} from "../hooks/useAccumulatedHistory";
import { useWeatherForecast } from "../hooks/useWeatherForecast";
import { WeatherForecastCard } from "../components/WeatherForecastCard";

type MeteoPageProps = {
    theme: "dark" | "light";
};

type HistoryMap = Record<string, number[]>;
type Accent = "amber" | "blue" | "cyan" | "emerald";

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

export function MeteoPage({ theme }: MeteoPageProps) {
    const { sensors } = useMeteoModuleStream();

    const [selectedSensor, setSelectedSensor] =
        useState<ModuleSensorResponse | null>(null);

    const [history, setHistory] = useState<HistoryMap>({});
    const [openMenu, setOpenMenu] = useState<string | null>(null);

    const [selectedAccumulated, setSelectedAccumulated] = useState<{
        title: string;
        sensor: ModuleSensorResponse | null;
    } | null>(null);

    const [accumulatedRange, setAccumulatedRange] =
        useState<AccumulatedRange>("7d");


    const temperature = findSensor(sensors, "temperatura.exterior");
    const humidity = findSensor(sensors, "humidade.exterior");
    const windDirection = findSensor(sensors, "direcao.vento");

    const windSpeed = maxSensor(
        sensors.filter((sensor) => sensor.key.startsWith("velocidade.vento.")),
    );

    const radiation = maxSensor(
        sensors.filter((sensor) => sensor.key.startsWith("radiacao.")),
    );

    const rainSensors = sensors.filter((sensor) => sensor.key.startsWith("chuva."));
    const rainSensor =
        findSensor(sensors, "chuva.atual") ??
        findSensor(sensors, "chuva.instantanea") ??
        findSensor(sensors, "chuva.intensidade") ??
        maxSensor(rainSensors);

    const rainValue = numericValue(rainSensor);
    const isRaining = rainValue !== null && rainValue > 0;

    const meteoHistory = useMeteoHistory(selectedSensor);

    const accumulatedHistory = useAccumulatedHistory(
        selectedAccumulated?.sensor ?? null,
        accumulatedRange,
    );

    const weatherForecast = useWeatherForecast();

    useEffect(() => {
        const samples: Array<[string, number | null]> = [
            ["temperatura.exterior", numericValue(temperature)],
            ["humidade.exterior", numericValue(humidity)],
            ["vento.velocidade", numericValue(windSpeed)],
            ["radiacao.solar", numericValue(radiation)],
            ["chuva.total", numericValue(rainSensor)],
        ];

        setHistory((current) => {
            const next = { ...current };

            for (const [key, value] of samples) {
                if (value === null || Number.isNaN(value)) continue;

                const previous = next[key] ?? [];
                const last = previous[previous.length - 1];

                if (last === value && previous.length > 1) continue;

                next[key] = [...previous, value].slice(-MAX_HISTORY_POINTS);
            }

            return next;
        });
    }, [
        temperature?.value,
        humidity?.value,
        windSpeed?.value,
        radiation?.value,
        rainSensor?.value,
    ]);

    return (
        <div className="space-y-5 pb-6">
            <WeatherForecastCard
                theme={theme}
                forecast={weatherForecast.forecast}
                loading={weatherForecast.loading}
                error={weatherForecast.error}
            />

            <div className="grid gap-5 2xl:grid-cols-[minmax(0,1fr)_420px_minmax(0,1fr)]">
                <div className="grid gap-5 md:grid-cols-2 2xl:grid-cols-1">
                    <MetricTile
                        theme={theme}
                        title="Temperatura"
                        subtitle="Temperatura exterior"
                        sensor={temperature}
                        icon={<Thermometer className="h-5 w-5" />}
                        accent="amber"
                        status={temperatureBadge(temperature)}
                        values={history["temperatura.exterior"]}
                        menuOpen={openMenu === "temperature"}
                        onMenuToggle={() =>
                            setOpenMenu(openMenu === "temperature" ? null : "temperature")
                        }
                        actions={[
                            {
                                label: "Ver gráfico",
                                icon: <ChartNoAxesColumnIncreasing className="h-4 w-4" />,
                                onClick: () => {
                                    setSelectedSensor(temperature ?? null);
                                    setOpenMenu(null);
                                },
                            },
                        ]}
                    />

                    <MetricTile
                        theme={theme}
                        title="Humidade"
                        subtitle="Humidade relativa"
                        sensor={humidity}
                        icon={<Droplets className="h-5 w-5" />}
                        accent="blue"
                        status={humidityBadge(humidity)}
                        values={history["humidade.exterior"]}
                        menuOpen={openMenu === "humidity"}
                        onMenuToggle={() =>
                            setOpenMenu(openMenu === "humidity" ? null : "humidity")
                        }
                        actions={[
                            {
                                label: "Ver gráfico",
                                icon: <ChartNoAxesColumnIncreasing className="h-4 w-4" />,
                                onClick: () => {
                                    setSelectedSensor(humidity ?? null);
                                    setOpenMenu(null);
                                },
                            },
                        ]}
                    />

                    <MetricTile
                        theme={theme}
                        title="Precipitação"
                        subtitle="Precipitação atual"
                        sensor={rainSensor}
                        icon={<CloudRain className="h-5 w-5" />}
                        accent="emerald"
                        status={isRaining ? "A chover" : "Sem chuva"}
                        values={history["chuva.total"]}
                        menuOpen={openMenu === "rain"}
                        onMenuToggle={() =>
                            setOpenMenu(openMenu === "rain" ? null : "rain")
                        }
                        actions={[
                            {
                                label: "Ver gráfico",
                                icon: <ChartNoAxesColumnIncreasing className="h-4 w-4" />,
                                onClick: () => {
                                    setSelectedSensor(rainSensor ?? null);
                                    setOpenMenu(null);
                                },
                            },
                            {
                                label: "Ver acumulado",
                                icon: <Table2 className="h-4 w-4" />,
                                onClick: () => {
                                    setSelectedAccumulated({
                                        title: "Precipitação acumulada",
                                        sensor: rainSensor ?? null,
                                    });
                                    setOpenMenu(null);
                                },
                            },
                        ]}
                    />
                </div>

                <CompassPanel theme={theme} direction={numericValue(windDirection)} />

                <div className="grid gap-4 md:grid-cols-2 2xl:grid-cols-1">
                    <MetricTile
                        theme={theme}
                        title="Vento"
                        subtitle="Velocidade do vento"
                        sensor={windSpeed}
                        icon={<Wind className="h-5 w-5" />}
                        accent="cyan"
                        status={windBadge(windSpeed)}
                        values={history["vento.velocidade"]}
                        menuOpen={openMenu === "wind"}
                        onMenuToggle={() =>
                            setOpenMenu(openMenu === "wind" ? null : "wind")
                        }
                        actions={[
                            {
                                label: "Ver gráfico",
                                icon: <ChartNoAxesColumnIncreasing className="h-4 w-4" />,
                                onClick: () => {
                                    setSelectedSensor(windSpeed ?? null);
                                    setOpenMenu(null);
                                },
                            },
                        ]}
                    />

                    <MetricTile
                        theme={theme}
                        title="Radiação solar"
                        subtitle="Radiação instantânea"
                        sensor={radiation}
                        icon={<Sun className="h-5 w-5" />}
                        accent="amber"
                        status={radiationBadge(radiation)}
                        values={history["radiacao.solar"]}
                        menuOpen={openMenu === "radiation"}
                        onMenuToggle={() =>
                            setOpenMenu(openMenu === "radiation" ? null : "radiation")
                        }
                        actions={[
                            {
                                label: "Ver gráfico",
                                icon: <ChartNoAxesColumnIncreasing className="h-4 w-4" />,
                                onClick: () => {
                                    setSelectedSensor(radiation ?? null);
                                    setOpenMenu(null);
                                },
                            },
                            {
                                label: "Ver acumulado",
                                icon: <Table2 className="h-4 w-4" />,
                                onClick: () => {
                                    setSelectedAccumulated({
                                        title: "Radiação solar acumulada",
                                        sensor: radiation ?? null,
                                    });
                                    setOpenMenu(null);
                                },
                            },
                        ]}
                    />
                </div>
            </div>

            <MeteoHistoryModal
                sensor={selectedSensor}
                theme={theme}
                points={meteoHistory.points}
                loading={meteoHistory.loading}
                hours={meteoHistory.hours}
                onHoursChange={meteoHistory.setHours}
                onClose={() => setSelectedSensor(null)}
            />

            <AccumulatedHistoryModal
                sensor={selectedAccumulated?.sensor ?? null}
                title={selectedAccumulated?.title ?? ""}
                theme={theme}
                buckets={accumulatedHistory.buckets}
                loading={accumulatedHistory.loading}
                range={accumulatedRange}
                onRangeChange={setAccumulatedRange}
                onClose={() => setSelectedAccumulated(null)}
            />
        </div>
    );
}

function MetricTile({
    theme,
    title,
    subtitle,
    sensor,
    customValue,
    customUnit,
    icon,
    accent,
    status,
    values,
    menuOpen,
    onMenuToggle,
    actions,
}: {
    theme: "dark" | "light";
    title: string;
    subtitle: string;
    sensor?: ModuleSensorResponse;
    customValue?: string;
    customUnit?: string;
    icon: ReactNode;
    accent: Accent;
    status: string;
    values?: number[];
    menuOpen: boolean;
    onMenuToggle: () => void;
    actions: Array<{
        label: string;
        icon: ReactNode;
        onClick: () => void;
    }>;
}) {
    const isDark = theme === "dark";
    const colors = accentColors(accent, isDark);
    const value = customValue ?? formatValue(sensor);
    const unit = customUnit ?? sensor?.unit;
    const trend = getTrend(values);

    return (
        <article
            className={
                isDark
                    ? `${RADIUS} group relative min-h-[190px] overflow-hidden border border-white/10 bg-[#111827] p-5 text-left shadow-[0_12px_30px_rgba(0,0,0,0.22)] transition duration-200 hover:border-white/15 hover:bg-[#141d2b]`
                    : `${RADIUS} group relative min-h-[190px] overflow-hidden border border-slate-200 bg-white p-5 text-left shadow-[0_10px_26px_rgba(15,23,42,0.06)] transition duration-200 hover:border-slate-300 hover:shadow-[0_14px_34px_rgba(15,23,42,0.08)]`
            }
        >
            <div className="relative z-20 flex items-start justify-between gap-4">
                <div className="flex items-start gap-4">
                    <div
                        className={`grid h-11 w-11 shrink-0 place-items-center ${RADIUS} border ${colors.iconBox} ${colors.icon}`}
                    >
                        {icon}
                    </div>

                    <div>
                        <h2
                            className={
                                isDark
                                    ? "text-[15px] font-bold tracking-[-0.01em] text-slate-100"
                                    : "text-[15px] font-bold tracking-[-0.01em] text-slate-950"
                            }
                        >
                            {title}
                        </h2>
                        <p
                            className={
                                isDark
                                    ? "mt-1 text-sm text-slate-400"
                                    : "mt-1 text-sm text-slate-500"
                            }
                        >
                            {subtitle}
                        </p>
                    </div>
                </div>

                <div className="relative shrink-0">
                    <button
                        type="button"
                        onClick={(event) => {
                            event.stopPropagation();
                            onMenuToggle();
                        }}
                        className={
                            isDark
                                ? `grid h-9 w-9 place-items-center ${RADIUS} text-slate-400 transition hover:bg-white/5 hover:text-slate-100`
                                : `grid h-9 w-9 place-items-center ${RADIUS} text-slate-400 transition hover:bg-slate-100 hover:text-slate-700`
                        }
                        aria-label={`Abrir ações de ${title}`}
                    >
                        <MoreHorizontal className="h-5 w-5" />
                    </button>

                    {menuOpen && (
                        <div
                            className={
                                isDark
                                    ? `absolute right-0 top-11 z-50 w-48 ${RADIUS} border border-white/10 bg-[#0f172a] p-1.5 shadow-xl`
                                    : `absolute right-0 top-11 z-50 w-48 ${RADIUS} border border-slate-200 bg-white p-1.5 shadow-xl`
                            }
                        >
                            {actions.map((action) => (
                                <button
                                    key={action.label}
                                    type="button"
                                    onClick={(event) => {
                                        event.stopPropagation();
                                        action.onClick();
                                    }}
                                    className={
                                        isDark
                                            ? `flex w-full items-center gap-3 ${RADIUS} px-3 py-2.5 text-sm font-semibold text-slate-300 transition hover:bg-white/5 hover:text-white`
                                            : `flex w-full items-center gap-3 ${RADIUS} px-3 py-2.5 text-sm font-semibold text-slate-700 transition hover:bg-slate-100 hover:text-slate-950`
                                    }
                                >
                                    {action.icon}
                                    {action.label}
                                </button>
                            ))}
                        </div>
                    )}
                </div>
            </div>

            <div className="relative z-10 mt-8">
                <div className="flex items-end justify-between gap-5">
                    <div>
                        <div
                            className={
                                isDark
                                    ? "flex items-end text-[50px] font-black leading-none tracking-[-0.07em] text-slate-100"
                                    : "flex items-end text-[50px] font-black leading-none tracking-[-0.07em] text-slate-950"
                            }
                        >
                            {value}
                            {unit && (
                                <span
                                    className={
                                        isDark
                                            ? "mb-1 ml-2 text-base font-bold tracking-[-0.02em] text-slate-400"
                                            : "mb-1 ml-2 text-base font-bold tracking-[-0.02em] text-slate-500"
                                    }
                                >
                                    {unit}
                                </span>
                            )}
                        </div>

                        <div className="mt-5 flex flex-wrap items-center gap-2">
                            <span
                                className={`inline-flex items-center justify-center ${RADIUS} border px-3 py-1.5 text-xs font-bold ${colors.badge}`}
                            >
                                {status}
                            </span>

                            <span
                                className={
                                    isDark
                                        ? `inline-flex items-center gap-1.5 ${RADIUS} border border-white/10 bg-white/[0.03] px-3 py-1.5 text-xs font-semibold text-slate-400`
                                        : `inline-flex items-center gap-1.5 ${RADIUS} border border-slate-200 bg-slate-50 px-3 py-1.5 text-xs font-semibold text-slate-500`
                                }
                            >
                                <TrendingUp className="h-3.5 w-3.5" />
                                {trend}
                            </span>
                        </div>
                    </div>
                </div>
            </div>

            <Sparkline
                values={values}
                className="absolute bottom-7 right-6 z-0 h-[62px] w-[220px]"
                strokeClassName={colors.stroke}
                glowClassName={colors.dot}
            />
        </article>
    );
}

function CompassPanel({
    theme,
    direction,
}: {
    theme: "dark" | "light";
    direction: number | null;
}) {
    const isDark = theme === "dark";
    const angle = direction ?? 0;
    const cardinal = directionName(direction);
    const degrees = direction !== null ? Math.round(direction) : null;

    return (
        <article
            className={
                isDark
                    ? `${RADIUS} relative flex min-h-[620px] flex-col overflow-hidden border border-white/10 bg-[#111827] p-6 shadow-[0_12px_30px_rgba(0,0,0,0.22)]`
                    : `${RADIUS} relative flex min-h-[620px] flex-col overflow-hidden border border-slate-200 bg-white p-6 shadow-[0_10px_26px_rgba(15,23,42,0.06)]`
            }
        >
            <div className="relative z-10 flex flex-col items-center">
                <span
                    className={
                        isDark
                            ? `inline-flex items-center gap-2 ${RADIUS} border border-white/10 bg-white/[0.03] px-3 py-1 text-[11px] font-bold uppercase tracking-[0.16em] text-slate-400`
                            : `inline-flex items-center gap-2 ${RADIUS} border border-slate-200 bg-slate-50 px-3 py-1 text-[11px] font-bold uppercase tracking-[0.16em] text-slate-500`
                    }
                >
                    <Activity className="h-3.5 w-3.5" />
                    Direção do vento
                </span>

                <h2
                    className={
                        isDark
                            ? "mt-4 text-[42px] font-black leading-none tracking-[-0.08em] text-slate-100"
                            : "mt-4 text-[42px] font-black leading-none tracking-[-0.08em] text-slate-950"
                    }
                >
                    {cardinal}
                </h2>

                <div className="mt-5 grid w-full grid-cols-2 gap-3">
                    <CompassStat
                        theme={theme}
                        label="Graus"
                        value={degrees !== null ? `${degrees}°` : "--"}
                    />
                    <CompassStat
                        theme={theme}
                        label="Quadrante"
                        value={directionQuadrant(direction)}
                        highlighted
                    />
                </div>
            </div>

            <div className="relative z-10 flex flex-1 items-center justify-center pt-6">
                <div className="relative h-[340px] w-[340px] max-w-full">
                    <div
                        className={
                            isDark
                                ? "absolute inset-0 rounded-full border border-white/10 bg-[#0b1220]"
                                : "absolute inset-0 rounded-full border border-slate-200 bg-slate-50"
                        }
                    />

                    <div
                        className={
                            isDark
                                ? "absolute inset-6 rounded-full border border-white/10"
                                : "absolute inset-6 rounded-full border border-slate-200"
                        }
                    />

                    <div
                        className={
                            isDark
                                ? "absolute inset-[78px] rounded-full border border-white/10 bg-white/[0.02]"
                                : "absolute inset-[78px] rounded-full border border-slate-200 bg-white"
                        }
                    />

                    {Array.from({ length: 72 }).map((_, index) => {
                        const major = index % 6 === 0;

                        return (
                            <span
                                key={index}
                                className={`absolute left-1/2 top-1/2 w-px origin-[50%_158px] ${major ? "h-4" : "h-2"
                                    } ${isDark ? "bg-slate-600/55" : "bg-slate-300"}`}
                                style={{
                                    transform: `translate(-50%, -158px) rotate(${index * 5}deg)`,
                                }}
                            />
                        );
                    })}

                    <CompassLabel label="N" isDark={isDark} className="left-1/2 top-[18px] -translate-x-1/2" />
                    <CompassLabel label="S" isDark={isDark} className="bottom-[18px] left-1/2 -translate-x-1/2" />
                    <CompassLabel label="W" isDark={isDark} className="left-[22px] top-1/2 -translate-y-1/2" />
                    <CompassLabel label="E" isDark={isDark} className="right-[22px] top-1/2 -translate-y-1/2" />

                    <div
                        className={
                            isDark
                                ? "absolute inset-[116px] rounded-full border border-white/10 bg-[#111827]"
                                : "absolute inset-[116px] rounded-full border border-slate-200 bg-white"
                        }
                    />

                    <div className="absolute inset-0 flex items-center justify-center">
                        <div className="relative h-28 w-28">
                            <div
                                className={
                                    isDark
                                        ? "absolute left-1/2 top-1/2 h-[126px] w-[10px] origin-bottom rounded-full bg-slate-300"
                                        : "absolute left-1/2 top-1/2 h-[126px] w-[10px] origin-bottom rounded-full bg-slate-700"
                                }
                                style={{
                                    clipPath: "polygon(50% 0%, 100% 100%, 50% 84%, 0% 100%)",
                                    transform: `translate(-50%, -100%) rotate(${angle}deg)`,
                                }}
                            />

                            <div
                                className={
                                    isDark
                                        ? "absolute left-1/2 top-1/2 h-[118px] w-[2px] origin-bottom rounded-full bg-white/60"
                                        : "absolute left-1/2 top-1/2 h-[118px] w-[2px] origin-bottom rounded-full bg-white/90"
                                }
                                style={{
                                    transform: `translate(-50%, -100%) rotate(${angle}deg)`,
                                }}
                            />

                            <div
                                className={
                                    isDark
                                        ? "absolute left-1/2 top-1/2 h-10 w-10 -translate-x-1/2 -translate-y-1/2 rounded-full border border-white/10 bg-[#0b1220]"
                                        : "absolute left-1/2 top-1/2 h-10 w-10 -translate-x-1/2 -translate-y-1/2 rounded-full border border-slate-200 bg-white"
                                }
                            />

                            <div
                                className={
                                    isDark
                                        ? "absolute left-1/2 top-1/2 h-3 w-3 -translate-x-1/2 -translate-y-1/2 rounded-full bg-slate-300"
                                        : "absolute left-1/2 top-1/2 h-3 w-3 -translate-x-1/2 -translate-y-1/2 rounded-full bg-slate-700"
                                }
                            />
                        </div>
                    </div>
                </div>
            </div>
        </article>
    );
}

function CompassStat({
    theme,
    label,
    value,
    highlighted,
}: {
    theme: "dark" | "light";
    label: string;
    value: string;
    highlighted?: boolean;
}) {
    const isDark = theme === "dark";

    return (
        <div
            className={
                isDark
                    ? `${RADIUS} border border-white/10 bg-white/[0.03] px-4 py-3`
                    : `${RADIUS} border border-slate-200 bg-slate-50 px-4 py-3`
            }
        >
            <p
                className={
                    isDark
                        ? "text-[10px] font-bold uppercase tracking-[0.16em] text-slate-500"
                        : "text-[10px] font-bold uppercase tracking-[0.16em] text-slate-400"
                }
            >
                {label}
            </p>

            <p
                className={
                    highlighted
                        ? isDark
                            ? "mt-1 text-xl font-black tracking-[-0.04em] text-slate-200"
                            : "mt-1 text-xl font-black tracking-[-0.04em] text-slate-800"
                        : isDark
                            ? "mt-1 text-xl font-black tracking-[-0.04em] text-slate-100"
                            : "mt-1 text-xl font-black tracking-[-0.04em] text-slate-950"
                }
            >
                {value}
            </p>
        </div>
    );
}

function CompassLabel({
    label,
    className,
    isDark,
}: {
    label: string;
    className: string;
    isDark: boolean;
}) {
    return (
        <span
            className={`absolute flex h-6 w-6 items-center justify-center rounded-full text-[13px] font-black leading-none tracking-[0.02em] ${isDark
                ? "bg-white/[0.03] text-slate-300"
                : "bg-white text-slate-500 shadow-sm"
                } ${className}`}
        >
            {label}
        </span>
    );
}

function Sparkline({
    values,
    className,
    strokeClassName,
    glowClassName,
}: {
    values?: number[];
    className?: string;
    strokeClassName: string;
    glowClassName: string;
}) {
    if (!values || values.length < 2) return null;

    const width = 220;
    const height = 62;
    const padding = 8;
    const min = Math.min(...values);
    const max = Math.max(...values);
    const range = max - min || 1;

    const points = values.map((value, index) => {
        const x = padding + (index / (values.length - 1)) * (width - padding * 2);
        const y = padding + (1 - (value - min) / range) * (height - padding * 2);
        return `${x},${y}`;
    });

    const last = points[points.length - 1].split(",").map(Number);

    return (
        <svg
            className={`pointer-events-none opacity-45 ${className}`}
            viewBox={`0 0 ${width} ${height}`}
            fill="none"
            aria-hidden="true"
        >
            <polyline
                points={points.join(" ")}
                className={strokeClassName}
                strokeWidth="2"
                strokeLinecap="round"
                strokeLinejoin="round"
                fill="none"
            />
            <circle cx={last[0]} cy={last[1]} r="3.5" className={glowClassName} />
        </svg>
    );
}

function findSensor(sensors: ModuleSensorResponse[], key: string) {
    return sensors.find((sensor) => sensor.key === key);
}

function numericValue(sensor?: ModuleSensorResponse) {
    return typeof sensor?.value === "number" ? sensor.value : null;
}

function maxSensor(sensors: ModuleSensorResponse[]) {
    return sensors
        .filter((sensor) => typeof sensor.value === "number")
        .sort((a, b) => Number(b.value) - Number(a.value))[0];
}

function formatValue(sensor?: ModuleSensorResponse) {
    if (!sensor) return "--";

    if (typeof sensor.value === "number") {
        return Number.isInteger(sensor.value)
            ? String(sensor.value)
            : sensor.value.toFixed(1);
    }

    if (typeof sensor.value === "boolean") {
        return sensor.value ? "On" : "Off";
    }

    if (sensor.value === null || sensor.value === undefined) {
        return "--";
    }

    return String(sensor.value);
}

function directionName(direction: number | null) {
    if (direction === null) return "--";

    const labels = ["N", "NE", "E", "SE", "S", "SW", "W", "NW"];
    const index = Math.round(direction / 45) % 8;

    return labels[index];
}

function directionQuadrant(direction: number | null) {
    if (direction === null) return "--";
    if (direction >= 315 || direction < 45) return "Norte";
    if (direction >= 45 && direction < 135) return "Este";
    if (direction >= 135 && direction < 225) return "Sul";
    return "Oeste";
}

function getTrend(values?: number[]) {
    if (!values || values.length < 2) return "Sem tendência";

    const first = values[0];
    const last = values[values.length - 1];
    const delta = last - first;

    if (Math.abs(delta) < 0.1) return "Estável";
    if (delta > 0) return "A subir";
    return "A descer";
}

function temperatureBadge(sensor?: ModuleSensorResponse) {
    const value = numericValue(sensor);
    if (value === null) return "Sem dados";
    if (value >= 30) return "Quente";
    if (value <= 10) return "Frio";
    return "Normal";
}

function humidityBadge(sensor?: ModuleSensorResponse) {
    const value = numericValue(sensor);
    if (value === null) return "Sem dados";
    if (value >= 80) return "Alta";
    if (value <= 35) return "Baixa";
    return "Normal";
}

function windBadge(sensor?: ModuleSensorResponse) {
    const value = numericValue(sensor);
    if (value === null) return "Sem dados";
    if (value >= 30) return "Forte";
    if (value >= 10) return "Moderado";
    return "Fraco";
}

function radiationBadge(sensor?: ModuleSensorResponse) {
    const value = numericValue(sensor);
    if (value === null) return "Sem dados";
    if (value >= 800) return "Alta";
    if (value >= 400) return "Média";
    return "Baixa";
}

function accentColors(accent: Accent, isDark: boolean) {
    switch (accent) {
        case "amber":
            return isDark
                ? {
                    icon: "text-amber-200",
                    stroke: "stroke-amber-200",
                    dot: "fill-amber-200",
                    iconBox: "border-white/10 bg-white/[0.03]",
                    badge: "border-white/10 bg-white/[0.03] text-slate-300",
                }
                : {
                    icon: "text-amber-700",
                    stroke: "stroke-amber-500",
                    dot: "fill-amber-500",
                    iconBox: "border-slate-200 bg-slate-50",
                    badge: "border-slate-200 bg-slate-50 text-slate-600",
                };

        case "blue":
            return isDark
                ? {
                    icon: "text-sky-200",
                    stroke: "stroke-sky-200",
                    dot: "fill-sky-200",
                    iconBox: "border-white/10 bg-white/[0.03]",
                    badge: "border-white/10 bg-white/[0.03] text-slate-300",
                }
                : {
                    icon: "text-sky-700",
                    stroke: "stroke-sky-500",
                    dot: "fill-sky-500",
                    iconBox: "border-slate-200 bg-slate-50",
                    badge: "border-slate-200 bg-slate-50 text-slate-600",
                };

        case "cyan":
            return isDark
                ? {
                    icon: "text-cyan-200",
                    stroke: "stroke-cyan-200",
                    dot: "fill-cyan-200",
                    iconBox: "border-white/10 bg-white/[0.03]",
                    badge: "border-white/10 bg-white/[0.03] text-slate-300",
                }
                : {
                    icon: "text-cyan-700",
                    stroke: "stroke-cyan-500",
                    dot: "fill-cyan-500",
                    iconBox: "border-slate-200 bg-slate-50",
                    badge: "border-slate-200 bg-slate-50 text-slate-600",
                };

        case "emerald":
            return isDark
                ? {
                    icon: "text-emerald-200",
                    stroke: "stroke-emerald-200",
                    dot: "fill-emerald-200",
                    iconBox: "border-white/10 bg-white/[0.03]",
                    badge: "border-white/10 bg-white/[0.03] text-slate-300",
                }
                : {
                    icon: "text-emerald-700",
                    stroke: "stroke-emerald-500",
                    dot: "fill-emerald-500",
                    iconBox: "border-slate-200 bg-slate-50",
                    badge: "border-slate-200 bg-slate-50 text-slate-600",
                };
    }
}