import { ConnectionStatus } from "@/components/ConnectionStatus";
import { Header } from "@/components/Header";
import { DonutChart } from "@/components/DonutChart";
import { LineChartCard } from "@/components/LineChartCard";
import { MetricCard } from "@/components/MetricCard";
import { SysinfoCard } from "@/components/SysinfoCard";
import { useChartData } from "@/hooks/useChartData";
import {
    formatBits,
    formatPercentage,
    calcPercentage,
    formatBytes,
} from "@/services/utils";
import { useParams } from "react-router-dom";
import { useWebsocket } from "@/hooks/useWebsocket";
import { getHistoricalData, TimePeriod } from "@/services/store";
import { useEffect, useState } from "react";
import { StatusMessage } from "@/services/types";
import { TimePeriodSelector } from "@/components/TimePeriodSelector";

export function AgentPage() {
    const { agent } = useParams();
    const { status, message } = useWebsocket(`ws://localhost:3000/ws/${agent}`);

    const [period, setPeriod] = useState<TimePeriod | "realtime">("all");
    const [history, setHistory] = useState<StatusMessage[] | null>(null);

    useEffect(() => {
        const fetchData = async () => {
            const data = await getHistoricalData(
                `http://localhost:3000/history/${agent}/${period}`,
            );
            setHistory(data);
        };

        fetchData();
    }, [agent, period]);

    const { metrics } = message ?? {};
    const { cpuData, memoryData, networkData } = useChartData(
        period === "realtime" ? message! : history,
    );

    const getMetricStatus = (percentage: number | undefined) => {
        if (!percentage) return "nil";

        if (percentage < 50) return "good";
        if (percentage < 80) return "warning";
        return "critical";
    };

    const cpuUsage = metrics?.cpu.usage ?? 0;

    const memoryUsed = metrics?.memory.used ?? 0;
    const memoryTotal = metrics?.memory.total ?? 0;
    const memoryUsage = calcPercentage(memoryUsed, memoryTotal);

    const diskFree = (metrics?.disk.total ?? 0) - (metrics?.disk.free ?? 0);
    const diskTotal = metrics?.disk.total ?? 0;
    const diskUsage = calcPercentage(diskFree, diskTotal);

    const networkUp = metrics?.network.up ?? 0;
    const networkDown = metrics?.network.down ?? 0;
    const networkUsage = networkUp + networkDown;

    return (
        <div>
            <Header
                props={{
                    title: "Status Monitor",
                    subtitle: agent!,
                    hasBackButton: true,
                    rightComponent: (
                        <ConnectionStatus
                            status={status ?? "disconnected"}
                            timestamp={message?.timestamp}
                        />
                    ),
                }}
            />
            <main className="max-w-7xl mx-auto py-8">
                <div className="mx-2">
                    <h2 className="text-xl font-semibold mb-4">Overview</h2>

                    <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 mb-8">
                        <MetricCard
                            props={{
                                title: "CPU USAGE",
                                value: formatPercentage(cpuUsage),
                                status: getMetricStatus(cpuUsage),
                                subtitle: `${metrics?.cpu.threads ?? 0} threads`,
                            }}
                        >
                            <DonutChart
                                data={{
                                    labels: ["Usage", "Total"],
                                    values: [cpuUsage, 100 - cpuUsage],
                                    colors: ["#3b82f6", "#262626"],
                                }}
                                centerText={formatPercentage(cpuUsage)}
                                size="sm"
                            />
                        </MetricCard>

                        <MetricCard
                            props={{
                                title: "MEMORY USAGE",
                                value: formatPercentage(memoryUsage),
                                status: getMetricStatus(memoryUsage),
                                subtitle: `${formatBytes(memoryUsed)} / ${formatBytes(memoryTotal)}`,
                            }}
                        >
                            <DonutChart
                                data={{
                                    labels: ["Used", "Free"],
                                    values: [memoryUsage, 100 - memoryUsage],
                                    colors: ["#3b82f6", "#262626"],
                                }}
                                centerText={formatPercentage(memoryUsage)}
                                size="sm"
                            />
                        </MetricCard>

                        <MetricCard
                            props={{
                                title: "NETWORK ACTIVITY",
                                value: formatBits(networkUsage),
                                status: "nil",
                                subtitle: `↑ ${formatBits(networkUp)}/s ↓ ${formatBits(networkDown)}/s`,
                            }}
                        >
                            <DonutChart
                                data={{
                                    labels: ["Upload", "Download"],
                                    values: [
                                        message ? networkUp : 1,
                                        message ? networkDown : 1,
                                    ],
                                    colors: ["#ef4444", "#3b82f6"],
                                }}
                                size="sm"
                            />
                        </MetricCard>
                    </div>

                    <MetricCard
                        props={{
                            title: "DISK USAGE",
                            value: formatPercentage(diskUsage),
                            status: getMetricStatus(diskUsage),
                            subtitle: `${formatBytes(diskFree)} free of ${formatBytes(diskTotal)}`,
                        }}
                    >
                        <div className="w-full bg-[#141414] rounded-full h-4">
                            <div
                                className={`h-4 rounded-full transition-all duration-500 ${
                                    getMetricStatus(diskUsage) == "good"
                                        ? "bg-green-500"
                                        : getMetricStatus(diskUsage) ==
                                            "warning"
                                          ? "bg-yellow-500"
                                          : "bg-red-500"
                                }`}
                                style={{ width: `${diskUsage}%` }}
                            />
                        </div>
                    </MetricCard>

                    <div className="flex flex-col my-10">
                        <h2 className="text-xl font-semibold mb-4">Details</h2>
                        <div className="mt-3">
                            <TimePeriodSelector
                                currentPeriod={period}
                                onChange={setPeriod}
                            />
                        </div>

                        <div className="grid grid-cols-1 lg:grid-cols-2 gap-6 my-8">
                            <LineChartCard title="CPU Usage" data={cpuData} />
                            <LineChartCard
                                title="Memory Usage"
                                data={memoryData}
                            />
                            <LineChartCard
                                title="Network Activity"
                                data={networkData}
                            />

                            <SysinfoCard sysinfo={metrics?.system_info} />
                        </div>
                    </div>
                </div>
            </main>
        </div>
    );
}
