import { db } from "@/db/client";
import { corruptFiles, users } from "@/db/schema";
import { desc, eq, sql } from "drizzle-orm";
import { approveAllPending, approveCorruptFile, dismissCorruptFile, retryFailedDeletion } from "./actions";

export const dynamic = "force-dynamic";

function formatBytes(value: bigint | null) {
  const bytes = Number(value ?? 0);
  if (!Number.isFinite(bytes) || bytes <= 0) return "unknown";
  const units = ["B", "KB", "MB", "GB", "TB"];
  let size = bytes;
  let unit = 0;
  while (size >= 1024 && unit < units.length - 1) {
    size /= 1024;
    unit += 1;
  }
  return size.toFixed(unit === 0 ? 0 : 1) + " " + units[unit];
}

function formatDate(value: Date | null) {
  return value ? value.toISOString().slice(0, 16).replace("T", " ") : "—";
}

const STATUS_STYLE: Record<string, string> = {
  pending: "border-admin-warn text-admin-warn",
  approved: "border-admin-accent text-admin-accent",
  deleted: "border-admin-line text-admin-muted",
  dismissed: "border-admin-line text-admin-muted",
  failed: "border-admin-warn text-admin-warn",
};

export default async function AdminCorruptPage() {
  const rows = await db
    .select({
      id: corruptFiles.id,
      fullPath: corruptFiles.fullPath,
      agent: corruptFiles.agent,
      tier: corruptFiles.tier,
      reason: corruptFiles.reason,
      sizeBytes: corruptFiles.sizeBytes,
      status: corruptFiles.status,
      firstDetectedAt: corruptFiles.firstDetectedAt,
      lastDetectedAt: corruptFiles.lastDetectedAt,
      reviewedAt: corruptFiles.reviewedAt,
      deletedAt: corruptFiles.deletedAt,
      deleteError: corruptFiles.deleteError,
      reviewerName: users.displayName,
    })
    .from(corruptFiles)
    .leftJoin(users, eq(users.id, corruptFiles.reviewedBy))
    .orderBy(desc(corruptFiles.lastDetectedAt))
    .limit(500);

  const [counts] = await db
    .select({
      pending: sql<number>`count(*) filter (where ${corruptFiles.status} = 'pending')::int`,
      approved: sql<number>`count(*) filter (where ${corruptFiles.status} = 'approved')::int`,
      deleted: sql<number>`count(*) filter (where ${corruptFiles.status} = 'deleted')::int`,
      failed: sql<number>`count(*) filter (where ${corruptFiles.status} = 'failed')::int`,
      reclaimable: sql<string>`coalesce(sum(${corruptFiles.sizeBytes}) filter (where ${corruptFiles.status} in ('pending','approved')), 0)::text`,
    })
    .from(corruptFiles);

  return (
    <div className="space-y-6">
      <div>
        <p className="text-xs font-semibold uppercase tracking-[0.32em] text-admin-accent">Integrity</p>
        <h1 className="mt-2 font-serif text-3xl font-semibold">Corrupt Files</h1>
        <p className="mt-2 max-w-3xl text-sm text-admin-muted">
          Files an agent could not read — either the container will not decode, or ffprobe cannot open it at all.
          Approving records your decision; the agent that reported the file performs the deletion, because Ampelos
          mounts these tiers read-only so no scan can damage the backup. Nothing is removed without an approval here.
        </p>
      </div>

      <div className="grid gap-3 sm:grid-cols-2 xl:grid-cols-5">
        {[
          { label: "Awaiting review", value: counts?.pending ?? 0 },
          { label: "Approved, not yet deleted", value: counts?.approved ?? 0 },
          { label: "Deleted", value: counts?.deleted ?? 0 },
          { label: "Delete failed", value: counts?.failed ?? 0 },
          { label: "Space reclaimable", value: formatBytes(BigInt(counts?.reclaimable ?? "0")) },
        ].map((tile) => (
          <div key={tile.label} className="admin-panel p-4">
            <p className="text-xs text-admin-muted">{tile.label}</p>
            <p className="mt-1 text-2xl font-semibold">{tile.value}</p>
          </div>
        ))}
      </div>

      {counts?.pending ? (
        <form action={approveAllPending} className="admin-panel flex flex-wrap items-center gap-3 p-4">
          <p className="text-sm text-admin-muted">
            Approve all {counts.pending} files currently awaiting review. Anything reported after this still needs its own approval.
          </p>
          <button type="submit" className="admin-nav-button px-4 py-2 text-sm font-medium">
            Approve all pending
          </button>
        </form>
      ) : null}

      <section className="admin-panel overflow-hidden">
        <div className="border-b border-admin-line px-5 py-4">
          <h2 className="font-serif text-xl font-semibold">Reported files</h2>
        </div>

        <div className="divide-y divide-admin-line">
          {rows.length ? rows.map((row) => (
            <div key={row.id} className="grid gap-3 px-5 py-4 xl:grid-cols-[1fr_auto]">
              <div className="min-w-0">
                <div className="flex flex-wrap items-center gap-2">
                  <span className={"rounded-md border px-2 py-0.5 text-xs font-semibold uppercase " + (STATUS_STYLE[row.status] ?? "border-admin-line text-admin-muted")}>
                    {row.status}
                  </span>
                  <span className="text-xs text-admin-muted">{row.agent}{row.tier ? ` · ${row.tier}` : ""}</span>
                  <span className="text-xs text-admin-muted">{formatBytes(row.sizeBytes)}</span>
                </div>
                <p className="mt-2 break-all text-sm">{row.fullPath}</p>
                <p className="mt-1 break-all text-xs text-admin-muted">{row.reason}</p>
                <p className="mt-1 text-xs text-admin-muted">
                  first seen {formatDate(row.firstDetectedAt)} · last seen {formatDate(row.lastDetectedAt)}
                  {row.reviewedAt ? ` · reviewed ${formatDate(row.reviewedAt)}${row.reviewerName ? " by " + row.reviewerName : ""}` : ""}
                  {row.deletedAt ? ` · deleted ${formatDate(row.deletedAt)}` : ""}
                </p>
                {row.deleteError ? (
                  <p className="mt-1 break-all text-xs text-admin-warn">delete failed: {row.deleteError}</p>
                ) : null}
              </div>

              <div className="flex shrink-0 flex-wrap items-start gap-2">
                {row.status === "pending" ? (
                  <>
                    <form action={approveCorruptFile}>
                      <input type="hidden" name="id" value={row.id} />
                      <button type="submit" className="admin-nav-button px-3 py-1.5 text-xs font-medium">Approve deletion</button>
                    </form>
                    <form action={dismissCorruptFile}>
                      <input type="hidden" name="id" value={row.id} />
                      <button type="submit" className="admin-nav-button px-3 py-1.5 text-xs font-medium">Keep</button>
                    </form>
                  </>
                ) : null}
                {row.status === "approved" ? (
                  <form action={dismissCorruptFile}>
                    <input type="hidden" name="id" value={row.id} />
                    <button type="submit" className="admin-nav-button px-3 py-1.5 text-xs font-medium">Cancel approval</button>
                  </form>
                ) : null}
                {row.status === "failed" ? (
                  <form action={retryFailedDeletion}>
                    <input type="hidden" name="id" value={row.id} />
                    <button type="submit" className="admin-nav-button px-3 py-1.5 text-xs font-medium">Retry deletion</button>
                  </form>
                ) : null}
              </div>
            </div>
          )) : (
            <p className="p-5 text-sm text-admin-muted">No agent has reported an unreadable file. Good.</p>
          )}
        </div>
      </section>
    </div>
  );
}
