"use client";

import { clsx } from "clsx";
import { ServerWithKeys } from "@/lib/api";
import { Card, CardHeader, CardTitle } from "@/components/ui";
import { formatBytes, formatDate } from "../format";
import type { TabId } from "../ServerTabs";

/*
 * Overview answers one question: is anything wrong with this machine, and where
 * do I go about it. The detail lives on the other tabs — everything here either
 * states a fact about the host or points at the tab that can act on it.
 */

export interface Attention {
    tone: "danger" | "warning";
    title: string;
    detail: string;
    /** The tab that can do something about it. */
    goTo: TabId;
    action: string;
}

function StoragePanel({ server }: { server: ServerWithKeys }) {
    const partitions = server.inventory?.partitions ?? [];

    return (
        <Card padding={false}>
            <div className="flex items-center justify-between border-b border-border px-6 py-4">
                <h2 className="text-lg font-semibold text-text-primary">Storage</h2>
                <span className="font-mono text-[0.68rem] uppercase tracking-[0.13em] text-text-secondary">
                    {partitions.length} partition{partitions.length !== 1 ? "s" : ""}
                </span>
            </div>
            {partitions.length === 0 ? (
                <p className="px-6 py-10 text-center text-sm text-text-secondary">No partitions reported. The agent sends a full inventory every 15 minutes.</p>
            ) : (
                <div className="space-y-4 px-6 py-5">
                    {partitions.map((p) => {
                        const pct = p.total_bytes > 0 ? (p.used_bytes / p.total_bytes) * 100 : 0;
                        return (
                            <div key={p.mountpoint}>
                                <div className="mb-1.5 flex flex-wrap items-baseline justify-between gap-x-4 gap-y-1">
                                    <span className="font-mono text-sm text-text-primary">{p.mountpoint}</span>
                                    <span className="font-mono text-xs text-text-secondary">
                                        {formatBytes(p.used_bytes)} / {formatBytes(p.total_bytes)}
                                        {p.fstype ? ` · ${p.fstype}` : ""}
                                    </span>
                                </div>
                                <div className="h-[3px] w-full overflow-hidden rounded-full bg-well">
                                    <div className={clsx("h-full rounded-full", pct >= 90 ? "bg-danger" : pct >= 75 ? "bg-warning" : "bg-accent")} style={{ width: `${Math.min(100, pct)}%` }} />
                                </div>
                            </div>
                        );
                    })}
                </div>
            )}
        </Card>
    );
}

function Fact({ term, children, mono = true }: { term: string; children: React.ReactNode; mono?: boolean }) {
    return (
        <div className="flex items-baseline justify-between gap-4 border-b border-border-soft py-2.5 last:border-b-0">
            <dt className="shrink-0 text-xs text-text-secondary">{term}</dt>
            <dd className={clsx("min-w-0 break-all text-right text-sm text-text-primary", mono && "font-mono text-xs")}>{children}</dd>
        </div>
    );
}

function MachinePanel({ server }: { server: ServerWithKeys }) {
    return (
        <Card padding={false}>
            <div className="border-b border-border px-6 py-4">
                <h2 className="text-lg font-semibold text-text-primary">Machine</h2>
            </div>
            <dl className="px-6 py-2">
                <Fact term="OS" mono={false}>
                    {server.os_info || "unknown"}
                </Fact>
                {server.inventory?.kernel && <Fact term="Kernel">{server.inventory.kernel}</Fact>}
                {server.inventory?.cpu.model && <Fact term="CPU">{server.inventory.cpu.model}</Fact>}
                <Fact term="Agent version">{server.agent_version ? `v${server.agent_version}` : "unknown"}</Fact>
                <Fact term="Last seen" mono={false}>
                    {server.last_seen ? formatDate(server.last_seen) : "Never"}
                </Fact>
                <Fact term="Registered" mono={false}>
                    {formatDate(server.created_at)}
                </Fact>
                <Fact term="Server ID">{server.server_id}</Fact>
            </dl>
        </Card>
    );
}

function AttentionPanel({ items, onGoTo }: { items: Attention[]; onGoTo: (tab: TabId) => void }) {
    return (
        <Card padding={false}>
            <div className="border-b border-border px-6 py-4">
                <CardHeader className="mb-0">
                    <CardTitle className="text-lg font-semibold">Needs attention</CardTitle>
                </CardHeader>
            </div>
            {items.length === 0 ? (
                <p className="px-6 py-10 text-center text-sm text-success">Nothing outstanding on this server.</p>
            ) : (
                <ul className="divide-y divide-border-soft">
                    {items.map((item) => (
                        <li key={item.title} className="flex flex-wrap items-center justify-between gap-3 px-6 py-3.5">
                            <div className="flex min-w-0 items-start gap-3">
                                {/* The dot is recognition, never the message — the title says
                                    what is wrong on its own. */}
                                <span className={clsx("mt-1.5 h-1.5 w-1.5 shrink-0 rounded-full", item.tone === "danger" ? "bg-danger" : "bg-warning")} />
                                <div className="min-w-0">
                                    <p className="text-sm font-medium text-text-primary">{item.title}</p>
                                    <p className="font-mono text-xs text-text-secondary">{item.detail}</p>
                                </div>
                            </div>
                            <button type="button" onClick={() => onGoTo(item.goTo)} className="text-sm font-semibold text-accent transition-colors hover:text-accent-hover">
                                {item.action} →
                            </button>
                        </li>
                    ))}
                </ul>
            )}
        </Card>
    );
}

export function OverviewTab({ server, attention, onGoTo }: { server: ServerWithKeys; attention: Attention[]; onGoTo: (tab: TabId) => void }) {
    return (
        <div className="space-y-6">
            <AttentionPanel items={attention} onGoTo={onGoTo} />
            {/* Collapses at xl, not lg: the 240px sidebar leaves a 1280px laptop
                about 1010px, which is not enough for a two-thirds split. */}
            <div className="grid grid-cols-1 gap-6 xl:grid-cols-3">
                <div className="xl:col-span-2">
                    <StoragePanel server={server} />
                </div>
                <MachinePanel server={server} />
            </div>
        </div>
    );
}
