import type { Metadata } from "next";
import Image from "next/image";
import { desc, ilike, or, sql } from "drizzle-orm";
import { Images, Trash2, Copy, Search, RefreshCw } from "lucide-react";
import { requireAdmin } from "@/lib/auth/admin-guard";
import { db } from "@/lib/db/client";
import { mediaAssets } from "@/lib/db/schema";
import {
  AdminHeading,
  FormSection,
  KpiCard,
  Toolbar,
  SearchInput,
  EmptyState,
  formatAdminDateTime,
} from "@/components/admin";
import { Button } from "@/components/Button";
import {
  scanMediaLibrary,
  deleteMediaAsset,
  updateMediaMeta,
} from "./actions";

export const metadata: Metadata = { title: "Media library" };
export const dynamic = "force-dynamic";

function formatBytes(n: number | null | undefined): string {
  if (!n) return "—";
  const kb = n / 1024;
  if (kb < 1024) return `${kb.toFixed(1)} KB`;
  return `${(kb / 1024).toFixed(2)} MB`;
}

export default async function AdminMediaLibraryPage({
  searchParams,
}: {
  searchParams: Promise<{ q?: string; page?: string }>;
}) {
  await requireAdmin();
  const params = await searchParams;
  const query = (params.q ?? "").trim();
  const page = Math.max(1, Number(params.page ?? "1") || 1);
  const perPage = 24;

  const where = query
    ? or(
        ilike(mediaAssets.path, `%${query}%`),
        ilike(mediaAssets.originalName, `%${query}%`),
        ilike(mediaAssets.altText, `%${query}%`),
      )
    : undefined;

  const [{ total }] = await db
    .select({ total: sql<number>`count(*)`.mapWith(Number) })
    .from(mediaAssets)
    .where(where ?? sql`true`);

  const rows = await db
    .select()
    .from(mediaAssets)
    .where(where ?? sql`true`)
    .orderBy(desc(mediaAssets.createdAt))
    .limit(perPage)
    .offset((page - 1) * perPage);

  const [stats] = await db
    .select({
      total: sql<number>`count(*)`.mapWith(Number),
      bytes: sql<number>`coalesce(sum(file_size), 0)`.mapWith(Number),
    })
    .from(mediaAssets);

  const totalPages = Math.max(1, Math.ceil(total / perPage));

  return (
    <>
      <AdminHeading
        eyebrow="Content"
        title="Media library"
        lede="All images uploaded through the admin. Assign alt text for accessibility and remove unused files."
        actions={
          <form action={scanMediaLibrary}>
            <Button
              type="submit"
              variant="secondary"
              className="!px-3 !py-1.5 !text-[13px]"
            >
              <RefreshCw className="h-3.5 w-3.5" aria-hidden />
              Rescan uploads folder
            </Button>
          </form>
        }
      />

      <div className="mb-6 grid grid-cols-2 gap-4 lg:grid-cols-3">
        <KpiCard label="Assets" value={stats.total} tone="ink" Icon={Images} />
        <KpiCard label="Total size" value={formatBytes(stats.bytes)} tone="blue" />
        <KpiCard label="Search results" value={total} tone="slate" Icon={Search} />
      </div>

      <div className="mb-4">
        <Toolbar
          actions={
            <form method="GET" action="/admin/media">
              <SearchInput
                defaultValue={query}
                placeholder="Search by filename or alt text…"
              />
            </form>
          }
        >
          <span className="text-[12px] text-[var(--color-slate)]">
            {total.toLocaleString()} asset{total === 1 ? "" : "s"}
          </span>
        </Toolbar>
      </div>

      {rows.length === 0 ? (
        <EmptyState
          Icon={Images}
          title={query ? "No matching assets" : "No media yet"}
          description={
            query
              ? "Try a different search term."
              : "Upload an image anywhere in the admin — it will appear here automatically."
          }
        />
      ) : (
        <div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3">
          {rows.map((m) => (
            <FormSection
              key={m.id}
              title={m.originalName || m.path.split("/").pop() || ""}
              description={m.path}
              padded={false}
            >
              <div className="relative aspect-[4/3] w-full overflow-hidden bg-[var(--color-mist)]">
                <Image
                  src={m.thumbnailPath ?? m.path}
                  alt={m.altText || ""}
                  fill
                  unoptimized={m.path.endsWith(".svg")}
                  className="object-contain"
                  sizes="(max-width: 1024px) 50vw, 33vw"
                />
              </div>
              <div className="px-5 py-4 text-[12px] text-[var(--color-slate)]">
                <div className="flex items-center justify-between">
                  <span>{formatBytes(m.fileSize)}</span>
                  <span>{formatAdminDateTime(m.createdAt)}</span>
                </div>
                <form action={updateMediaMeta} className="mt-3 flex flex-col gap-2">
                  <input type="hidden" name="id" value={m.id} />
                  <label className="block">
                    <span className="text-[10px] font-bold uppercase tracking-wider text-[var(--color-slate)]">
                      Alt text
                    </span>
                    <input
                      name="altText"
                      defaultValue={m.altText}
                      maxLength={500}
                      placeholder="Describe the image"
                      className="mt-1 w-full rounded-md border border-[var(--color-line)] bg-white px-2 py-1.5 text-[13px]"
                    />
                  </label>
                  <label className="block">
                    <span className="text-[10px] font-bold uppercase tracking-wider text-[var(--color-slate)]">
                      Caption (optional)
                    </span>
                    <input
                      name="caption"
                      defaultValue={m.caption}
                      maxLength={1000}
                      className="mt-1 w-full rounded-md border border-[var(--color-line)] bg-white px-2 py-1.5 text-[13px]"
                    />
                  </label>
                  <div className="mt-1 flex items-center justify-between gap-2">
                    <button
                      type="submit"
                      className="inline-flex items-center gap-1 rounded-md bg-[var(--color-blue)] px-3 py-1 text-[12px] font-semibold text-white hover:opacity-90"
                    >
                      Save
                    </button>
                    <div className="flex items-center gap-1">
                      <CopyPathButton path={m.path} />
                      <DeleteAssetForm id={m.id} label={m.originalName || m.path} />
                    </div>
                  </div>
                </form>
              </div>
            </FormSection>
          ))}
        </div>
      )}

      {totalPages > 1 && (
        <div className="mt-6 flex items-center justify-between text-[13px] text-[var(--color-slate)]">
          <span>
            Page {page} of {totalPages}
          </span>
          <div className="flex gap-2">
            {page > 1 && (
              <a
                href={`/admin/media?${new URLSearchParams({
                  q: query,
                  page: String(page - 1),
                }).toString()}`}
                className="rounded-md border border-[var(--color-line)] px-3 py-1 font-semibold text-[var(--color-ink)] hover:bg-[var(--color-mist)]"
              >
                Previous
              </a>
            )}
            {page < totalPages && (
              <a
                href={`/admin/media?${new URLSearchParams({
                  q: query,
                  page: String(page + 1),
                }).toString()}`}
                className="rounded-md border border-[var(--color-line)] px-3 py-1 font-semibold text-[var(--color-ink)] hover:bg-[var(--color-mist)]"
              >
                Next
              </a>
            )}
          </div>
        </div>
      )}
    </>
  );
}

function DeleteAssetForm({ id, label }: { id: string; label: string }) {
  return (
    <form action={deleteMediaAsset}>
      <input type="hidden" name="id" value={id} />
      <button
        type="submit"
        title="Delete asset"
        aria-label={`Delete ${label}`}
        className="inline-flex items-center rounded-md p-1 text-[var(--color-slate)] hover:bg-red-50 hover:text-red-600"
      >
        <Trash2 className="h-4 w-4" aria-hidden />
      </button>
    </form>
  );
}

function CopyPathButton({ path }: { path: string }) {
  return (
    <a
      href={path}
      target="_blank"
      rel="noreferrer"
      title={`Open ${path}`}
      aria-label={`Open ${path} in a new tab`}
      className="inline-flex items-center rounded-md p-1 text-[var(--color-slate)] hover:bg-[var(--color-mist)] hover:text-[var(--color-blue)]"
    >
      <Copy className="h-4 w-4" aria-hidden />
    </a>
  );
}
