"use client";

import { useState, useTransition } from "react";
import { useRouter } from "next/navigation";
import {
  uploadMediaAction,
  updateMediaAltAction,
  deleteMediaAction,
} from "./_actions";

export type Media = {
  id: string;
  filename: string;
  url: string;
  mime: string;
  size: number;
  alt: string | null;
  width: number | null;
  height: number | null;
  createdAt: Date;
};

function fmtSize(n: number): string {
  if (n < 1024) return `${n} B`;
  if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} KB`;
  return `${(n / 1024 / 1024).toFixed(1)} MB`;
}

export function UploadForm() {
  const router = useRouter();
  const [pending, startTransition] = useTransition();
  const [error, setError] = useState<string | null>(null);
  const [success, setSuccess] = useState<string | null>(null);

  function submit(e: React.FormEvent<HTMLFormElement>) {
    e.preventDefault();
    setError(null);
    setSuccess(null);
    const fd = new FormData(e.currentTarget);
    startTransition(async () => {
      const res = await uploadMediaAction(fd);
      if (!res.ok) setError(res.error);
      else {
        setSuccess(`Đã upload: ${res.url}`);
        (e.target as HTMLFormElement).reset();
        router.refresh();
      }
    });
  }

  return (
    <form
      onSubmit={submit}
      className="rounded-xl border border-stroke-subtle bg-bg-elevated/40 p-5 mb-6"
    >
      <h2 className="font-display font-semibold text-lg mb-3">Upload ảnh</h2>
      {error && (
        <div className="rounded-lg border border-rose-500/40 bg-rose-500/10 px-3 py-2 text-sm text-rose-300 mb-3">
          {error}
        </div>
      )}
      {success && (
        <div className="rounded-lg border border-emerald-500/40 bg-emerald-500/10 px-3 py-2 text-sm text-emerald-300 mb-3">
          {success}
        </div>
      )}
      <div className="grid sm:grid-cols-[1fr_auto] gap-3 items-end">
        <div className="space-y-2">
          <label className="text-xs font-medium text-ink-muted block">
            File <span className="text-ink-muted/60">(JPEG/PNG/WebP/AVIF/GIF/SVG · max 10MB)</span>
          </label>
          <input
            type="file"
            name="file"
            required
            accept="image/jpeg,image/png,image/webp,image/avif,image/gif,image/svg+xml"
            className="w-full text-sm file:mr-3 file:px-3 file:py-1.5 file:rounded-lg file:border-0 file:bg-bg-elevated file:border-stroke-subtle file:text-sm file:cursor-pointer file:hover:bg-bg-overlay"
          />
          <input
            type="text"
            name="alt"
            placeholder="Alt text (mô tả ảnh, dùng cho SEO + accessibility)"
            className="w-full px-3 py-2 rounded-lg bg-bg-elevated border border-stroke-subtle text-sm"
          />
        </div>
        <button
          type="submit"
          disabled={pending}
          className="px-5 py-2 rounded-lg bg-accent-primary text-white text-sm font-medium hover:bg-accent-primary/90 disabled:opacity-50 transition"
        >
          {pending ? "Uploading…" : "Upload"}
        </button>
      </div>
    </form>
  );
}

export function BulkAltButton({ missingCount }: { missingCount: number }) {
  const router = useRouter();
  const [pending, setPending] = useState(false);
  const [result, setResult] = useState<string | null>(null);
  const [error, setError] = useState<string | null>(null);

  async function run() {
    if (
      !confirm(
        `Sinh alt text bằng AI cho ${Math.min(20, missingCount)} ảnh đầu tiên thiếu alt? (chia mẻ 20 mỗi lần)`,
      )
    )
      return;
    setPending(true);
    setResult(null);
    setError(null);
    try {
      const res = await fetch("/api/admin/media/bulk-generate-alt", {
        method: "POST",
        headers: { "content-type": "application/json" },
        body: JSON.stringify({ limit: 20, onlyMissing: true }),
      });
      const data = (await res.json()) as
        | {
            ok: true;
            updated: number;
            processed: number;
            results: Array<{ filename: string; alt: string; source: string }>;
          }
        | { ok: false; error: string };
      if (!data.ok) {
        setError(data.error);
      } else {
        const aiCount = data.results.filter((r) => r.source === "ai").length;
        setResult(
          `✓ Đã sinh alt cho ${data.updated}/${data.processed} ảnh (AI: ${aiCount}, heuristic: ${data.updated - aiCount}).`,
        );
        router.refresh();
      }
    } catch (e) {
      setError(e instanceof Error ? e.message : "Lỗi mạng");
    }
    setPending(false);
  }

  return (
    <div className="flex flex-col items-end gap-1">
      <button
        type="button"
        onClick={run}
        disabled={pending}
        className="px-3 py-1.5 rounded-lg bg-violet-500/15 text-violet-300 text-sm font-medium hover:bg-violet-500/25 disabled:opacity-50 transition border border-violet-500/30"
      >
        {pending ? "Đang sinh…" : `✨ AI sinh alt cho ${Math.min(20, missingCount)} ảnh`}
      </button>
      {result && <div className="text-xs text-emerald-300">{result}</div>}
      {error && <div className="text-xs text-rose-300">{error}</div>}
    </div>
  );
}

export function MediaCard({ m }: { m: Media }) {
  const router = useRouter();
  const [editing, setEditing] = useState(false);
  const [pending, startTransition] = useTransition();
  const [error, setError] = useState<string | null>(null);
  const [copied, setCopied] = useState(false);
  const [genPending, setGenPending] = useState(false);
  const [genSrc, setGenSrc] = useState<string | null>(null);

  function copy() {
    navigator.clipboard.writeText(m.url).then(() => {
      setCopied(true);
      setTimeout(() => setCopied(false), 1500);
    });
  }

  function saveAlt(e: React.FormEvent<HTMLFormElement>) {
    e.preventDefault();
    const fd = new FormData(e.currentTarget);
    const alt = String(fd.get("alt") ?? "");
    startTransition(async () => {
      await updateMediaAltAction(m.id, alt);
      setEditing(false);
      router.refresh();
    });
  }

  async function generateAlt() {
    setGenPending(true);
    setError(null);
    setGenSrc(null);
    try {
      const res = await fetch(`/api/admin/media/${m.id}/generate-alt`, {
        method: "POST",
        headers: { "content-type": "application/json" },
        body: JSON.stringify({ apply: true }),
      });
      const data = (await res.json()) as
        | {
            ok: true;
            suggestion: { alt: string; source: string; usedBy: Array<{ slug: string }> };
          }
        | { ok: false; error: string };
      if (!data.ok) {
        setError(data.error);
      } else {
        setGenSrc(data.suggestion.source);
        router.refresh();
      }
    } catch (e) {
      setError(e instanceof Error ? e.message : "Lỗi mạng");
    }
    setGenPending(false);
  }

  function remove() {
    if (!confirm(`Xóa ảnh "${m.filename}"?`)) return;
    startTransition(async () => {
      const res = await deleteMediaAction(m.id);
      if (!res.ok) setError(res.error);
      else router.refresh();
    });
  }

  return (
    <div className="rounded-xl border border-stroke-subtle bg-bg-elevated/40 overflow-hidden flex flex-col">
      <div className="aspect-video bg-bg-overlay relative">
        {m.mime.startsWith("image/") ? (
          // eslint-disable-next-line @next/next/no-img-element
          <img
            src={m.url}
            alt={m.alt ?? m.filename}
            className="w-full h-full object-cover"
            loading="lazy"
          />
        ) : (
          <div className="flex items-center justify-center h-full text-ink-muted text-xs">
            {m.mime}
          </div>
        )}
      </div>
      <div className="p-3 flex-1 flex flex-col gap-2">
        <div className="text-xs font-mono truncate text-ink-secondary" title={m.filename}>
          {m.filename}
        </div>
        <div className="flex items-center justify-between text-[10px] text-ink-muted">
          <span>{fmtSize(m.size)}</span>
          <span>{m.mime.replace("image/", "")}</span>
        </div>

        {editing ? (
          <form onSubmit={saveAlt} className="flex gap-1.5">
            <input
              name="alt"
              defaultValue={m.alt ?? ""}
              autoFocus
              className="flex-1 px-2 py-1 rounded bg-bg-elevated border border-stroke-subtle text-xs"
              placeholder="Alt text"
            />
            <button
              type="submit"
              disabled={pending}
              className="text-xs px-2 py-1 rounded bg-accent-primary text-white disabled:opacity-50"
            >
              ✓
            </button>
            <button
              type="button"
              onClick={() => setEditing(false)}
              className="text-xs px-2 py-1 rounded text-ink-muted hover:bg-bg-overlay"
            >
              ✕
            </button>
          </form>
        ) : (
          <div className="flex items-start gap-1.5">
            <button
              type="button"
              onClick={() => setEditing(true)}
              className="flex-1 text-left text-xs text-ink-muted hover:text-ink-primary truncate min-h-[1.5em]"
              title="Click để sửa alt text"
            >
              {m.alt || <span className="italic text-ink-muted/60">— chưa có alt text</span>}
            </button>
            <button
              type="button"
              onClick={generateAlt}
              disabled={genPending}
              className="text-[10px] px-1.5 py-0.5 rounded bg-violet-500/15 text-violet-300 hover:bg-violet-500/25 disabled:opacity-50 shrink-0"
              title="Tự sinh alt text bằng AI"
            >
              {genPending ? "…" : "✨ AI"}
            </button>
          </div>
        )}

        {genSrc && (
          <div className="text-[10px] text-emerald-300/80">
            ✓ Đã tạo từ {genSrc === "ai" ? "AI" : genSrc === "context" ? "ngữ cảnh bài" : "tên file"}
          </div>
        )}

        {error && <div className="text-xs text-rose-300">{error}</div>}

        <div className="flex items-center gap-1.5 mt-auto pt-2 border-t border-stroke-subtle">
          <button
            type="button"
            onClick={copy}
            className="flex-1 text-xs px-2 py-1.5 rounded border border-stroke-subtle hover:border-accent-primary transition"
          >
            {copied ? "Đã copy ✓" : "Copy URL"}
          </button>
          <button
            type="button"
            onClick={remove}
            disabled={pending}
            className="text-xs px-2 py-1.5 rounded text-rose-300 hover:bg-rose-500/10 disabled:opacity-50 transition"
          >
            Xóa
          </button>
        </div>
      </div>
    </div>
  );
}
