"use client";
import * as React from "react";
import {
  Server,
  HardDrive,
  Database,
  Layers,
  Trash2,
  Loader2,
  RefreshCw,
} from "lucide-react";
import { Shell } from "@/components/layout/shell";
import { Card, CardHeader, CardTitle, CardContent, CardDescription } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Kpi } from "@/components/ui/kpi";
import { Badge } from "@/components/ui/badge";
import { bytesHuman } from "@/lib/format";

interface SystemInfo {
  docker: Array<{ type: string; total: number; active: number; size: string; reclaimable: string }>;
  registry: { repos: string[]; count: number };
  disk: { total: number; free: number; used: number; usedPct: number } | null;
}

const TYPE_LABEL_VI: Record<string, string> = {
  Images: "Image",
  Containers: "Container",
  "Local Volumes": "Volume",
  "Build Cache": "Build cache",
};

export default function AdminPage() {
  const [info, setInfo] = React.useState<SystemInfo | null>(null);
  const [loading, setLoading] = React.useState(true);
  const [running, setRunning] = React.useState<string | null>(null);
  const [result, setResult] = React.useState<{ ok: boolean; text: string } | null>(null);

  const refresh = React.useCallback(async () => {
    setLoading(true);
    try {
      const r = await fetch("/api/admin/system", { cache: "no-store" });
      if (r.ok) setInfo(await r.json());
    } finally {
      setLoading(false);
    }
  }, []);

  React.useEffect(() => {
    refresh();
  }, [refresh]);

  const cleanup = async (target: "build-cache" | "images" | "all") => {
    const labels: Record<typeof target, string> = {
      "build-cache": "build cache",
      images: "image không dùng",
      all: "build cache + image",
    };
    if (!confirm(`Dọn ${labels[target]}?`)) return;
    setRunning(target);
    setResult(null);
    try {
      const r = await fetch("/api/admin/cleanup", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ target }),
      });
      const body = await r.json();
      const reclaimed = body.reclaimedBytes
        ? ` · giải phóng ${bytesHuman(body.reclaimedBytes)}`
        : "";
      const errLine = !body.ok && body.output
        ? ` (${String(body.output).split("\n")[0].slice(0, 120)})`
        : "";
      setResult({
        ok: !!body.ok,
        text: `${labels[target]}: ${body.ok ? "thành công" : "thất bại"}${reclaimed}${errLine}`,
      });
      await refresh();
    } catch (e) {
      setResult({ ok: false, text: `${labels[target]}: lỗi ${(e as Error).message}` });
    } finally {
      setRunning(null);
    }
  };

  return (
    <Shell
      actions={
        <Button variant="outline" size="sm" onClick={refresh} disabled={loading}>
          <RefreshCw className={loading ? "h-3.5 w-3.5 animate-spin" : "h-3.5 w-3.5"} />
          Làm mới
        </Button>
      }
    >
      <div className="space-y-6">
        <div>
          <h1 className="text-2xl font-semibold tracking-tight">Quản trị</h1>
          <p className="mt-1 text-sm text-muted-foreground">
            Tình trạng hệ thống, registry Docker, và các lệnh dọn dẹp.
          </p>
        </div>

        <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
          <Kpi
            label="Đĩa đã dùng"
            value={info?.disk ? `${info.disk.usedPct}%` : "—"}
            hint={
              info?.disk
                ? `Còn ${bytesHuman(info.disk.free)} / ${bytesHuman(info.disk.total)}`
                : "đang tải"
            }
            icon={<HardDrive className="h-4 w-4" />}
            tone={
              info?.disk && info.disk.usedPct > 85
                ? "danger"
                : info?.disk && info.disk.usedPct > 70
                  ? "warning"
                  : "success"
            }
          />
          <Kpi
            label="Image trong registry"
            value={info?.registry.count ?? "—"}
            hint={
              info?.registry.repos.length
                ? info.registry.repos.slice(0, 3).join(", ") +
                  (info.registry.repos.length > 3 ? "…" : "")
                : "Chưa có image"
            }
            icon={<Database className="h-4 w-4" />}
            tone="info"
          />
          <Kpi
            label="Docker objects"
            value={info?.docker.reduce((sum, d) => sum + d.total, 0) ?? "—"}
            hint={
              info?.docker.length
                ? info.docker
                    .filter((d) => d.total > 0)
                    .map((d) => `${(TYPE_LABEL_VI[d.type] ?? d.type).toLowerCase()}:${d.total}`)
                    .join(" · ")
                : "đang tải"
            }
            icon={<Layers className="h-4 w-4" />}
          />
        </div>

        <Card>
          <CardHeader>
            <CardTitle>Lưu trữ Docker</CardTitle>
            <CardDescription>
              Dữ liệu từ <code className="text-mono">docker system df</code>
            </CardDescription>
          </CardHeader>
          <CardContent className="p-0">
            {info?.docker.length ? (
              <ul className="divide-y divide-border/60">
                {info.docker.map((d) => (
                  <li key={d.type} className="flex items-center gap-3 px-5 py-3 text-sm">
                    <Server className="h-4 w-4 shrink-0 text-muted-foreground" />
                    <span className="w-24 font-medium text-foreground">
                      {TYPE_LABEL_VI[d.type] ?? d.type}
                    </span>
                    <span className="text-mono text-xs text-muted-foreground">
                      tổng {d.total} · dùng {d.active}
                    </span>
                    <span className="ml-auto flex items-center gap-2">
                      <span className="text-mono text-foreground/90">{d.size}</span>
                      {d.reclaimable !== "0B" && (
                        <Badge tone="warning">có thể thu hồi {d.reclaimable}</Badge>
                      )}
                    </span>
                  </li>
                ))}
              </ul>
            ) : (
              <div className="px-5 py-8 text-center text-sm text-muted-foreground">
                {loading ? "Đang tải…" : "Không có thông tin Docker"}
              </div>
            )}
          </CardContent>
        </Card>

        <Card>
          <CardHeader>
            <CardTitle>Registry catalog</CardTitle>
            <CardDescription>Danh sách image trong registry nội bộ</CardDescription>
          </CardHeader>
          <CardContent>
            {info?.registry.repos.length ? (
              <div className="flex flex-wrap gap-2">
                {info.registry.repos.map((r) => (
                  <code
                    key={r}
                    className="rounded-md border border-border bg-surface px-2 py-1 text-xs text-mono text-foreground/90"
                  >
                    {r}
                  </code>
                ))}
              </div>
            ) : (
              <p className="text-sm text-muted-foreground">Chưa có image.</p>
            )}
          </CardContent>
        </Card>

        <Card>
          <CardHeader>
            <CardTitle>Dọn dẹp</CardTitle>
            <CardDescription>
              Giải phóng đĩa bằng cách prune build cache và image không dùng.
            </CardDescription>
          </CardHeader>
          <CardContent className="space-y-3">
            <div className="grid gap-3 sm:grid-cols-3">
              <CleanupAction
                label="Build cache"
                description="docker builder prune"
                disabled={!!running}
                running={running === "build-cache"}
                onClick={() => cleanup("build-cache")}
              />
              <CleanupAction
                label="Image không dùng"
                description="docker image prune -a"
                disabled={!!running}
                running={running === "images"}
                onClick={() => cleanup("images")}
              />
              <CleanupAction
                label="Cả hai"
                description="cache + image"
                disabled={!!running}
                running={running === "all"}
                onClick={() => cleanup("all")}
                tone="danger"
              />
            </div>
            {result && (
              <p
                className={
                  "rounded-md border px-3 py-2 text-xs text-mono " +
                  (result.ok
                    ? "border-success/30 bg-success/10 text-success"
                    : "border-destructive/30 bg-destructive/10 text-destructive")
                }
              >
                {result.text}
              </p>
            )}
          </CardContent>
        </Card>
      </div>
    </Shell>
  );
}

function CleanupAction({
  label,
  description,
  running,
  disabled,
  onClick,
  tone = "default",
}: {
  label: string;
  description: string;
  running: boolean;
  disabled: boolean;
  onClick: () => void;
  tone?: "default" | "danger";
}) {
  return (
    <button
      type="button"
      onClick={onClick}
      disabled={disabled}
      className={[
        "flex flex-col items-start gap-1 rounded-md border bg-surface p-3 text-left transition-colors",
        "disabled:cursor-not-allowed disabled:opacity-60",
        tone === "danger"
          ? "border-destructive/30 hover:border-destructive/50 hover:bg-destructive/5"
          : "border-border hover:border-primary/40 hover:bg-primary/5",
      ].join(" ")}
    >
      <div className="flex w-full items-center gap-2">
        {running ? (
          <Loader2 className="h-4 w-4 animate-spin text-muted-foreground" />
        ) : (
          <Trash2
            className={
              tone === "danger" ? "h-4 w-4 text-destructive" : "h-4 w-4 text-muted-foreground"
            }
          />
        )}
        <span className="text-sm font-medium text-foreground">{label}</span>
      </div>
      <span className="text-mono text-2xs text-muted-foreground">{description}</span>
    </button>
  );
}
