"use client";

import { useRef, useState, useTransition } from "react";
import { useRouter } from "next/navigation";
import { Badge, Button } from "@/components/ui";
import { Field, inputClass } from "@/components/ui/form";
import { deleteMediaAction, updateMediaAction } from "@/lib/actions/media";
import { formatBytes } from "@/lib/utils";

export interface MediaRow {
  id: string; filename: string; mimeType: string; sizeBytes: number; altText: string | null; caption: string | null; attribution: string | null;
  folder: string | null; isPrivate: boolean; width: number | null; height: number | null; usages: number; updatedAt: string;
}

export function MediaCard({ row, canEdit, canDelete, view = "grid", selected = false, onToggle }: { row: MediaRow; canEdit: boolean; canDelete: boolean; view?: "grid" | "list"; selected?: boolean; onToggle?: () => void }) {
  const router = useRouter();
  const dialog = useRef<HTMLDialogElement>(null);
  const [pending, start] = useTransition();
  const [message, setMessage] = useState<{ ok: boolean; text: string } | null>(null);
  const [confirm, setConfirm] = useState(false);
  const isImage = row.mimeType.startsWith("image/");

  function save(form: FormData) {
    start(async () => {
      const res = await updateMediaAction(row.id, {
        altText: String(form.get("altText") ?? ""), caption: String(form.get("caption") ?? ""), attribution: String(form.get("attribution") ?? ""),
        folder: String(form.get("folder") ?? ""), isPrivate: form.get("isPrivate") === "on",
      });
      if (res.ok) { dialog.current?.close(); router.refresh(); } else setMessage({ ok: false, text: res.error });
    });
  }
  function remove() {
    start(async () => {
      const res = await deleteMediaAction(row.id);
      if (res.ok) { dialog.current?.close(); router.refresh(); } else { setMessage({ ok: false, text: res.error }); setConfirm(false); }
    });
  }

  const open = () => { setMessage(null); setConfirm(false); dialog.current?.showModal(); };
  const thumb = isImage ? (
    // eslint-disable-next-line @next/next/no-img-element -- own media route
    <img src={`/api/media/${row.id}`} alt={row.altText ?? ""} loading="lazy" className={view === "list" ? "size-10 shrink-0 rounded bg-muted object-cover" : "aspect-[4/3] w-full bg-muted object-contain p-2"} />
  ) : (
    <div className={view === "list" ? "grid size-10 shrink-0 place-items-center rounded bg-muted text-[10px] font-medium" : "grid aspect-[4/3] place-items-center bg-muted text-sm font-medium"}>PDF</div>
  );
  const check = onToggle ? <input type="checkbox" checked={selected} onChange={onToggle} aria-label={`Select ${row.filename}`} className={view === "list" ? "size-4" : "absolute right-2 top-2 size-4"} /> : null;
  return (
    <li className={view === "list" ? `flex items-center gap-3 rounded-lg border bg-card px-3 py-2 ${selected ? "border-primary" : "border-border"}` : `relative overflow-hidden rounded-xl border bg-card ${selected ? "border-primary ring-2 ring-primary/30" : "border-border"}`}>
      {check}
      <button type="button" onClick={open} className={view === "list" ? "flex min-w-0 flex-1 items-center gap-3 text-left" : "block w-full text-left"} aria-label={`Details for ${row.filename}`}>
        {thumb}
        {view === "list" ? (
          <>
            <span className="min-w-0 flex-1 truncate text-sm font-medium">{row.filename}</span>
            <span className="hidden w-20 text-xs text-muted-foreground sm:block">{row.mimeType.split("/")[1]?.toUpperCase()}</span>
            <span className="w-20 text-xs text-muted-foreground">{formatBytes(row.sizeBytes)}</span>
            <span className="hidden w-28 text-xs text-muted-foreground md:block">{new Date(row.updatedAt).toLocaleDateString("en-GB", { timeZone: "UTC", day: "numeric", month: "short", year: "numeric" })}</span>
            {row.isPrivate ? <Badge tone="warning">private</Badge> : null}
          </>
        ) : (
          <div className="space-y-1 p-3 text-center">
            <p className="truncate text-sm font-medium">{row.filename}</p>
            <p className="text-xs text-muted-foreground">{formatBytes(row.sizeBytes)}{row.width ? ` · ${row.width}×${row.height}` : ""}</p>
            <div className="flex flex-wrap justify-center gap-1">
              {row.isPrivate ? <Badge tone="warning">private</Badge> : null}
              {isImage && !row.altText ? <Badge tone="warning">no alt text</Badge> : null}
              {row.usages > 0 ? <Badge tone="info">used {row.usages}×</Badge> : null}
            </div>
          </div>
        )}
      </button>
      <dialog ref={dialog} aria-label={`Edit ${row.filename}`} className="m-auto w-[min(32rem,92vw)] rounded-lg border border-border bg-card p-4 text-foreground backdrop:bg-black/40">
        <form action={save} className="space-y-3">
          <h2 className="text-sm font-semibold">{row.filename}</h2>
          {message ? <p role="alert" className="text-sm text-danger">{message.text}</p> : null}
          <Field id={`alt-${row.id}`} label="Alt text"><input id={`alt-${row.id}`} name="altText" defaultValue={row.altText ?? ""} maxLength={250} disabled={!canEdit} className={inputClass} /></Field>
          <Field id={`cap-${row.id}`} label="Caption"><input id={`cap-${row.id}`} name="caption" defaultValue={row.caption ?? ""} maxLength={500} disabled={!canEdit} className={inputClass} /></Field>
          <Field id={`attr-${row.id}`} label="Credit / attribution"><input id={`attr-${row.id}`} name="attribution" defaultValue={row.attribution ?? ""} maxLength={255} disabled={!canEdit} className={inputClass} /></Field>
          <Field id={`fold-${row.id}`} label="Folder" help="A path such as branding/logos. Leave empty for the top level."><input id={`fold-${row.id}`} name="folder" defaultValue={row.folder ?? ""} maxLength={190} disabled={!canEdit} className={inputClass} /></Field>
          <label className="flex items-center gap-2 text-sm"><input type="checkbox" name="isPrivate" defaultChecked={row.isPrivate} disabled={!canEdit || (row.usages > 0 && !row.isPrivate)} /> Private{row.usages > 0 && !row.isPrivate ? " (in use, so it must stay public)" : ""}</label>
          <p className="text-xs text-muted-foreground">Used in {row.usages} place{row.usages === 1 ? "" : "s"}.</p>
          <div className="flex flex-wrap items-center gap-2">
            {canEdit ? <Button type="submit" disabled={pending}>Save</Button> : null}
            <Button variant="ghost" onClick={() => dialog.current?.close()}>Close</Button>
            {canDelete ? (
              confirm ? (
                <><Button variant="danger" disabled={pending} onClick={remove}>Confirm delete</Button><Button variant="ghost" onClick={() => setConfirm(false)}>Cancel</Button></>
              ) : (
                <Button variant="ghost" className="ml-auto" onClick={() => setConfirm(true)}>Delete</Button>
              )
            ) : null}
          </div>
        </form>
      </dialog>
    </li>
  );
}
