"use client";

import { useEffect, useState, useCallback } from "react";
import Image from "next/image";
import {
  Images, Search, Trash2, Copy, Check, Loader2, Upload,
  HardDrive, X, ImageIcon, RotateCcw, AlertTriangle,
  ArrowDownAZ, Clock, FileArchive, Filter,
} from "lucide-react";
import { cn } from "@/lib/utils";
import ImageUpload from "@/components/admin/ImageUpload";
import { getAdminToken } from "@/lib/adminAuth";
import { resolveUploadUrl } from "@/lib/uploadUrl";

const API = process.env.NEXT_PUBLIC_API_URL || "http://localhost:8000";

type Category  = "all" | "banner" | "ad" | "brand" | "blog" | "news" | "general";
type SortKey   = "newest" | "oldest" | "largest" | "smallest";
type ViewMode  = "active" | "trash";

const CATEGORIES: { value: Category; label: string }[] = [
  { value: "all",     label: "All"     },
  { value: "banner",  label: "Banners" },
  { value: "ad",      label: "Ads"     },
  { value: "brand",   label: "Brands"  },
  { value: "blog",    label: "Blogs"   },
  { value: "news",    label: "News"    },
  { value: "general", label: "General" },
];

const SORTS: { value: SortKey; label: string }[] = [
  { value: "newest",   label: "Newest first"  },
  { value: "oldest",   label: "Oldest first"  },
  { value: "largest",  label: "Largest first" },
  { value: "smallest", label: "Smallest first"},
];

interface Variant { url: string; size: number; filename: string; }
interface MediaItem {
  id:           string;
  category:     string;
  originalName: string;
  width:        number;
  height:       number;
  originalSize: number;
  status:       "active" | "trash";
  deletedAt?:   string;
  desktop:      Variant;
  tablet:       Variant;
  mobile:       Variant;
  thumbnail:    Variant;
  uploadedAt:   string;
}
interface Stats {
  totalImages: number;
  trashCount:  number;
  storedMB:    number;
  byCategory:  Record<string, { count: number }>;
}
interface UsageItem { collection: string; id: string; title: string; }

function fmtBytes(n: number) {
  if (n < 1024)        return `${n} B`;
  if (n < 1024*1024)   return `${(n/1024).toFixed(1)} KB`;
  return `${(n/(1024*1024)).toFixed(2)} MB`;
}
function fmtDate(iso: string) {
  return new Date(iso).toLocaleDateString("en-IN", { day:"2-digit", month:"short", year:"numeric" });
}
async function apiFetch(path: string, opts: RequestInit = {}) {
  const token = getAdminToken();
  const res = await fetch(`${API}${path}`, {
    headers: {
      "Content-Type": "application/json",
      ...(token ? { Authorization: `Bearer ${token}` } : {}),
    },
    ...opts,
  });
  if (!res.ok) throw new Error(await res.text());
  if (res.status === 204) return null;
  return res.json();
}

// ── Usage popover ──────────────────────────────────────────────────────────────

function UsagePopover({ mediaId, onClose }: { mediaId: string; onClose: () => void }) {
  const [loading, setLoading] = useState(true);
  const [usages,  setUsages]  = useState<UsageItem[]>([]);

  useEffect(() => {
    apiFetch(`/api/upload/media/${mediaId}/usage`)
      .then((d) => { setUsages(d.usages || []); setLoading(false); })
      .catch(() => setLoading(false));
  }, [mediaId]);

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center p-4 pb-[calc(1rem+env(safe-area-inset-bottom,0px))] pt-[calc(1rem+env(safe-area-inset-top,0px))] bg-black/50 backdrop-blur-sm"
         onClick={onClose}>
      <div className="bg-white rounded-2xl shadow-2xl w-full max-w-sm overflow-hidden max-h-[90dvh] overflow-y-auto"
           onClick={(e) => e.stopPropagation()}>
        <div className="flex items-center justify-between px-5 py-3.5 border-b border-gray-100">
          <h3 className="text-sm font-black text-gray-900">Image Usage</h3>
          <button onClick={onClose} className="p-2 rounded-lg hover:bg-gray-100 shrink-0" aria-label="Close">
            <X className="w-4 h-4 text-gray-400" />
          </button>
        </div>
        <div className="p-4">
          {loading ? (
            <div className="flex justify-center py-4"><Loader2 className="w-5 h-5 text-gray-400 animate-spin" /></div>
          ) : usages.length === 0 ? (
            <div className="text-center py-4">
              <p className="text-sm font-semibold text-gray-500">Not used anywhere</p>
              <p className="text-xs text-gray-400 mt-1">This image can be safely deleted.</p>
            </div>
          ) : (
            <div className="space-y-2">
              <p className="text-xs text-gray-500 mb-2">Used in {usages.length} place{usages.length !== 1 ? "s" : ""}:</p>
              {usages.map((u, i) => (
                <div key={i} className="flex items-start gap-2 bg-amber-50 border border-amber-100 rounded-xl px-3 py-2 min-w-0">
                  <AlertTriangle className="w-3.5 h-3.5 text-amber-500 mt-0.5 shrink-0" />
                  <div className="min-w-0">
                    <p className="text-xs font-bold text-gray-800 break-words">{u.title}</p>
                    <p className="text-[10px] text-gray-400">{u.collection}</p>
                  </div>
                </div>
              ))}
              <p className="text-[10px] text-gray-400 mt-2">
                Remove all references before deleting this image.
              </p>
            </div>
          )}
        </div>
      </div>
    </div>
  );
}

// ── Media card ─────────────────────────────────────────────────────────────────

function MediaCard({
  item, viewMode, onDelete, onRestore, onPermanent,
}: {
  item:        MediaItem;
  viewMode:    ViewMode;
  onDelete:    (id: string) => void;
  onRestore:   (id: string) => void;
  onPermanent: (id: string) => void;
}) {
  const [copied,    setCopied]    = useState<string | null>(null);
  const [showUsage, setShowUsage] = useState(false);

  function copyUrl(type: "desktop" | "tablet" | "mobile" | "thumbnail") {
    const url = item[type]?.url ?? "";
    navigator.clipboard.writeText(url).then(() => {
      setCopied(type);
      setTimeout(() => setCopied(null), 2000);
    });
  }

  const catColor: Record<string, string> = {
    banner:  "bg-blue-100 text-blue-700",
    ad:      "bg-orange-100 text-orange-700",
    brand:   "bg-purple-100 text-purple-700",
    blog:    "bg-green-100 text-green-700",
    news:    "bg-cyan-100 text-cyan-700",
    general: "bg-gray-100 text-gray-500",
  };

  return (
    <>
      {showUsage && <UsagePopover mediaId={item.id} onClose={() => setShowUsage(false)} />}

      <div className={cn(
        "bg-white rounded-2xl border shadow-sm overflow-hidden group hover:shadow-md transition-all min-w-0",
        viewMode === "trash" ? "border-red-100 opacity-80" : "border-gray-100"
      )}>
        {/* Thumbnail */}
        <div className="relative aspect-video bg-gray-50 overflow-hidden">
          <Image
            src={resolveUploadUrl(item.thumbnail?.url || item.desktop?.url || "")}
            alt={item.originalName}
            fill
            className="object-cover group-hover:scale-105 transition-transform duration-300"
            sizes="(max-width:640px) 50vw, (max-width:1024px) 33vw, 25vw"
            unoptimized
          />
          <div className={cn("absolute top-2 left-2 text-[10px] font-black px-2 py-0.5 rounded-full",
            catColor[item.category] || "bg-gray-100 text-gray-500")}>
            {item.category}
          </div>
          {viewMode === "trash" && (
            <div className="absolute top-2 right-2 bg-red-500/90 text-white text-[10px] font-black px-2 py-0.5 rounded-full">
              TRASH
            </div>
          )}
          {viewMode === "active" && (
            <button onClick={() => onDelete(item.id)}
              className="absolute top-2 right-2 p-2 bg-red-500 text-white rounded-lg opacity-100 sm:opacity-0 sm:group-hover:opacity-100 transition-opacity hover:bg-red-600 shadow"
              title="Move to trash" aria-label="Move to trash">
              <Trash2 className="w-3 h-3" />
            </button>
          )}
        </div>

        {/* Info */}
        <div className="p-3">
          <p className="text-xs font-bold text-gray-800 truncate" title={item.originalName}>
            {item.originalName}
          </p>
          <p className="text-[10px] text-gray-400 mt-0.5">
            {item.width}×{item.height} · {fmtDate(item.uploadedAt)}
          </p>

          {/* Copy buttons */}
          {viewMode === "active" && (
            <div className="flex gap-1 mt-2">
              {(["desktop", "tablet", "mobile", "thumbnail"] as const).map((t) => (
                <button key={t} onClick={() => copyUrl(t)}
                  className={cn(
                    "flex-1 flex items-center justify-center gap-0.5 text-[9px] font-bold py-1 rounded-lg transition-colors",
                    copied === t ? "bg-green-100 text-green-700" : "bg-gray-50 text-gray-500 hover:bg-blue-50 hover:text-blue-600"
                  )} title={`Copy ${t} URL`}>
                  {copied === t ? <Check className="w-2.5 h-2.5" /> : <Copy className="w-2.5 h-2.5" />}
                  {t === "desktop" ? "D" : t === "tablet" ? "T" : t === "mobile" ? "M" : "Th"}
                </button>
              ))}
            </div>
          )}

          {/* Sizes row */}
          <div className="flex gap-1 mt-1.5 flex-wrap">
            {(["desktop","tablet","mobile","thumbnail"] as const).map((t) => item[t]?.size ? (
              <span key={t} className="text-[9px] font-mono text-gray-300">
                {t[0].toUpperCase()}:{fmtBytes(item[t].size)}
              </span>
            ) : null)}
          </div>

          {/* Actions row */}
          <div className="flex gap-1.5 mt-2.5">
            {viewMode === "active" && (
              <button onClick={() => setShowUsage(true)}
                className="flex-1 text-[10px] font-bold py-1.5 rounded-lg bg-gray-50 hover:bg-blue-50 text-gray-500 hover:text-blue-600 transition-colors">
                Usage
              </button>
            )}
            {viewMode === "trash" && (
              <>
                <button onClick={() => onRestore(item.id)}
                  className="flex-1 flex items-center justify-center gap-1 text-[10px] font-bold py-1.5 rounded-lg bg-green-50 text-green-700 hover:bg-green-100 transition-colors">
                  <RotateCcw className="w-3 h-3" /> Restore
                </button>
                <button onClick={() => onPermanent(item.id)}
                  className="flex-1 text-[10px] font-bold py-1.5 rounded-lg bg-red-50 text-red-600 hover:bg-red-100 transition-colors">
                  Delete Forever
                </button>
              </>
            )}
          </div>
        </div>
      </div>
    </>
  );
}

// ── Page ───────────────────────────────────────────────────────────────────────

export default function AdminMediaPage() {
  const [items,      setItems]      = useState<MediaItem[]>([]);
  const [stats,      setStats]      = useState<Stats | null>(null);
  const [loading,    setLoading]    = useState(true);
  const [viewMode,   setViewMode]   = useState<ViewMode>("active");
  const [cat,        setCat]        = useState<Category>("all");
  const [sort,       setSort]       = useState<SortKey>("newest");
  const [search,     setSearch]     = useState("");
  const [toast,      setToast]      = useState("");
  const [showUpload, setShowUpload] = useState(false);
  const [uploadCat,  setUploadCat]  = useState<Category>("general");
  const [newUrl,     setNewUrl]     = useState("");

  const showToast = (msg: string) => { setToast(msg); setTimeout(() => setToast(""), 3200); };

  const load = useCallback(async () => {
    setLoading(true);
    try {
      const endpoint = viewMode === "trash"
        ? `/api/upload/media/trash?skip=0&limit=200`
        : `/api/upload/media?sort=${sort}&limit=200${cat !== "all" ? `&category=${cat}` : ""}`;
      const [mediaData, statsData] = await Promise.all([
        apiFetch(endpoint),
        apiFetch("/api/upload/media/stats"),
      ]);
      setItems(mediaData.items || []);
      setStats(statsData);
    } catch { showToast("Failed to load media library"); }
    finally { setLoading(false); }
  }, [viewMode, cat, sort]);

  useEffect(() => { load(); }, [load]);

  async function softDelete(id: string) {
    if (!confirm("Move this image to the trash?")) return;
    try {
      await apiFetch(`/api/upload/media/${id}`, { method: "DELETE" });
      showToast("Moved to trash");
      await load();
    } catch (e: unknown) {
      showToast(e instanceof Error ? e.message : "Cannot delete — image may be in use");
    }
  }

  async function restore(id: string) {
    try {
      await apiFetch(`/api/upload/media/${id}/restore`, { method: "POST" });
      showToast("Image restored"); await load();
    } catch { showToast("Restore failed"); }
  }

  async function permanent(id: string) {
    if (!confirm("Permanently delete this image? This cannot be undone.")) return;
    try {
      await apiFetch(`/api/upload/media/${id}/permanent`, { method: "DELETE" });
      showToast("Permanently deleted"); await load();
    } catch { showToast("Delete failed"); }
  }

  const filtered = search
    ? items.filter((i) => i.originalName.toLowerCase().includes(search.toLowerCase()))
    : items;

  return (
    <div className="p-4 sm:p-6 max-w-6xl mx-auto min-w-0">
      {toast && (
        <div className="fixed top-[calc(1.5rem+env(safe-area-inset-top,0px))] left-4 right-4 sm:left-auto sm:right-6 sm:max-w-sm z-50 bg-gray-900 text-white text-sm font-semibold px-5 py-3 rounded-2xl shadow-xl animate-fade-in break-words">
          {toast}
        </div>
      )}

      {/* Header */}
      <div className="flex flex-col sm:flex-row sm:items-center justify-between gap-4 mb-6">
        <div className="flex items-center gap-3 min-w-0">
          <div className="w-10 h-10 rounded-2xl bg-gradient-to-br from-violet-600 to-purple-500 flex items-center justify-center shrink-0">
            <Images className="w-5 h-5 text-white" />
          </div>
          <div className="min-w-0">
            <h1 className="text-xl font-black text-gray-900">Media Library</h1>
            <p className="text-sm text-gray-500">Upload, search, manage all images</p>
          </div>
        </div>
        <button onClick={() => setShowUpload(!showUpload)}
          className="flex items-center justify-center gap-2 px-4 py-2.5 bg-gradient-to-r from-violet-600 to-purple-500 text-white text-sm font-black rounded-2xl hover:opacity-90 transition-all shadow-md w-full sm:w-auto shrink-0">
          <Upload className="w-4 h-4" /> Upload
        </button>
      </div>

      {/* Stats */}
      {stats && (
        <div className="grid grid-cols-2 sm:grid-cols-4 gap-3 mb-6">
          <div className="bg-white rounded-2xl border border-gray-100 shadow-sm p-4">
            <Images className="w-5 h-5 mb-2 text-violet-600" />
            <p className="text-xl font-black text-gray-900">{stats.totalImages}</p>
            <p className="text-xs text-gray-500">Active Images</p>
          </div>
          <div className="bg-white rounded-2xl border border-gray-100 shadow-sm p-4">
            <HardDrive className="w-5 h-5 mb-2 text-blue-600" />
            <p className="text-xl font-black text-gray-900">{stats.storedMB} MB</p>
            <p className="text-xs text-gray-500">Storage Used</p>
          </div>
          <div className="bg-white rounded-2xl border border-gray-100 shadow-sm p-4">
            <FileArchive className="w-5 h-5 mb-2 text-red-500" />
            <p className="text-xl font-black text-gray-900">{stats.trashCount}</p>
            <p className="text-xs text-gray-500">In Trash</p>
          </div>
          <div className="bg-white rounded-2xl border border-gray-100 shadow-sm p-4">
            <Filter className="w-5 h-5 mb-2 text-gray-400" />
            <p className="text-xl font-black text-gray-900">{Object.keys(stats.byCategory).length}</p>
            <p className="text-xs text-gray-500">Categories</p>
          </div>
        </div>
      )}

      {/* Upload panel */}
      {showUpload && (
        <div className="bg-white rounded-2xl border border-gray-100 shadow-sm p-5 mb-6">
          <div className="flex items-center justify-between mb-4">
            <h3 className="font-black text-gray-900 text-sm">Upload New Image</h3>
            <button onClick={() => { setShowUpload(false); setNewUrl(""); }}
              className="p-1 rounded hover:bg-gray-100">
              <X className="w-4 h-4 text-gray-400" />
            </button>
          </div>
          <div className="flex flex-wrap items-center gap-3 mb-4">
            <label className="text-xs font-bold text-gray-600 shrink-0">Category:</label>
            <select value={uploadCat} onChange={(e) => setUploadCat(e.target.value as Category)}
              className="text-sm border border-gray-200 rounded-xl px-3 py-1.5 focus:outline-none focus:ring-2 focus:ring-violet-400 min-w-0 flex-1 sm:flex-none">
              {CATEGORIES.filter((c) => c.value !== "all").map((c) => (
                <option key={c.value} value={c.value}>{c.label}</option>
              ))}
            </select>
          </div>
          <ImageUpload
            multi
            label=""
            value={newUrl}
            category={uploadCat === "all" ? "general" : uploadCat}
            onChange={(r) => {
              setNewUrl(r.desktopUrl);
              showToast("Uploaded!");
              setTimeout(() => { setShowUpload(false); setNewUrl(""); load(); }, 1200);
            }}
            onClear={() => setNewUrl("")}
            aspectRatio="21/5"
          />
        </div>
      )}

      {/* Toolbar */}
      <div className="flex flex-wrap items-center gap-2 mb-5">
        {/* Active / Trash toggle */}
        <div className="flex bg-gray-100 p-1 rounded-xl">
          <button onClick={() => setViewMode("active")}
            className={cn("px-3 py-1.5 text-xs font-bold rounded-lg transition-colors",
              viewMode === "active" ? "bg-white shadow-sm text-gray-900" : "text-gray-500 hover:text-gray-700")}>
            Active
          </button>
          <button onClick={() => setViewMode("trash")}
            className={cn("px-3 py-1.5 text-xs font-bold rounded-lg transition-colors flex items-center gap-1",
              viewMode === "trash" ? "bg-white shadow-sm text-red-600" : "text-gray-500 hover:text-gray-700")}>
            <Trash2 className="w-3 h-3" /> Trash {stats?.trashCount ? `(${stats.trashCount})` : ""}
          </button>
        </div>

        {/* Category filter (active only) */}
        {viewMode === "active" && (
          <div className="flex gap-1 flex-wrap">
            {CATEGORIES.map((c) => (
              <button key={c.value} onClick={() => setCat(c.value)}
                className={cn("text-xs font-bold px-2.5 py-1.5 rounded-xl transition-colors",
                  cat === c.value ? "bg-gray-900 text-white" : "bg-gray-100 text-gray-600 hover:bg-gray-200")}>
                {c.label}
                {stats?.byCategory?.[c.value] && <span className="ml-1 opacity-60">({stats.byCategory[c.value].count})</span>}
              </button>
            ))}
          </div>
        )}

        {/* Sort */}
        {viewMode === "active" && (
          <select value={sort} onChange={(e) => setSort(e.target.value as SortKey)}
            className="text-xs border border-gray-200 rounded-xl px-2.5 py-1.5 focus:outline-none focus:ring-2 focus:ring-violet-400 bg-white text-gray-600 font-semibold">
            {SORTS.map((s) => <option key={s.value} value={s.value}>{s.label}</option>)}
          </select>
        )}

        {/* Search */}
        <div className="relative w-full sm:w-48 sm:ml-auto">
          <Search className="absolute left-3 top-1/2 -translate-y-1/2 w-3.5 h-3.5 text-gray-400" />
          <input type="text" value={search} onChange={(e) => setSearch(e.target.value)}
            placeholder="Search by filename…"
            className="w-full pl-8 pr-8 py-2 text-sm border border-gray-200 rounded-xl focus:outline-none focus:ring-2 focus:ring-violet-400"
          />
          {search && <button onClick={() => setSearch("")} className="absolute right-2 top-1/2 -translate-y-1/2 p-1.5 rounded-lg hover:bg-gray-100" aria-label="Clear search"><X className="w-3 h-3 text-gray-400" /></button>}
        </div>
      </div>

      {/* Grid */}
      {loading ? (
        <div className="flex items-center justify-center h-48">
          <Loader2 className="w-6 h-6 text-violet-500 animate-spin" />
        </div>
      ) : filtered.length === 0 ? (
        <div className="text-center py-20 bg-white rounded-3xl border border-gray-100">
          <ImageIcon className="w-10 h-10 mx-auto mb-3 text-gray-200" />
          <p className="font-bold text-gray-500">
            {viewMode === "trash" ? "Trash is empty" : search ? "No images match your search" : "No images uploaded yet"}
          </p>
        </div>
      ) : (
        <>
          <p className="text-xs text-gray-400 mb-3">{filtered.length} image{filtered.length !== 1 ? "s" : ""}</p>
          <div className="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-3">
            {filtered.map((item) => (
              <MediaCard
                key={item.id}
                item={item}
                viewMode={viewMode}
                onDelete={softDelete}
                onRestore={restore}
                onPermanent={permanent}
              />
            ))}
          </div>
        </>
      )}
    </div>
  );
}
