"use client";

/**
 * MediaPicker — modal for selecting images from the existing Media Library.
 *
 * Props:
 *   open          — whether the modal is visible
 *   onClose       — called when modal is dismissed
 *   onSelect      — called with selected mediaId(s)
 *   multiSelect   — allow selecting multiple images (default false)
 *   filterCategory— pre-filter by category (e.g. "car")
 */

import { useCallback, useEffect, useState } from "react";
import Image from "next/image";
import {
  X, Search, Check, Loader2, ImageIcon, RefreshCw,
  Filter,
} from "lucide-react";
import { cn } from "@/lib/utils";
import { getAdminToken } from "@/lib/adminAuth";
import { resolveUploadUrl } from "@/lib/uploadUrl";

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

type Category = "all" | "car" | "banner" | "ad" | "brand" | "blog" | "news" | "general";

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

interface Variant  { url: string; size: number; filename: string }
interface MediaItem {
  id:           string;
  category:     string;
  originalName: string;
  width:        number;
  height:       number;
  thumbnail:    Variant;
  desktop:      Variant;
  uploadedAt:   string;
}

export interface PickedMedia {
  mediaId:      string;
  url:          string;   // desktop URL
  thumbnailUrl: string;
  tabletUrl:    string;
  mobileUrl:    string;
  originalName: string;
}

interface Props {
  open:             boolean;
  onClose:          () => void;
  onSelect:         (items: PickedMedia[]) => void;
  multiSelect?:     boolean;
  filterCategory?:  Category;
}

async function fetchMedia(category: Category, search: string): Promise<MediaItem[]> {
  const token = getAdminToken();
  const cat   = category === "all" ? "" : `&category=${category}`;
  const res   = await fetch(`${API}/api/upload/media?sort=newest&limit=200${cat}`, {
    headers: { ...(token ? { Authorization: `Bearer ${token}` } : {}) },
  });
  if (!res.ok) throw new Error("Failed to load media");
  const data: { items: MediaItem[] } = await res.json();
  if (!search) return data.items;
  const q = search.toLowerCase();
  return data.items.filter((i) => i.originalName.toLowerCase().includes(q));
}

export default function MediaPicker({
  open,
  onClose,
  onSelect,
  multiSelect    = false,
  filterCategory = "all",
}: Props) {
  const [items,    setItems]    = useState<MediaItem[]>([]);
  const [loading,  setLoading]  = useState(false);
  const [selected, setSelected] = useState<Set<string>>(new Set());
  const [cat,      setCat]      = useState<Category>(filterCategory);
  const [search,   setSearch]   = useState("");

  const load = useCallback(async () => {
    setLoading(true);
    try {
      setItems(await fetchMedia(cat, search));
    } catch { /* ignore */ }
    finally { setLoading(false); }
  }, [cat, search]);

  useEffect(() => {
    if (open) { setSelected(new Set()); load(); }
  }, [open, load]);

  function toggle(item: MediaItem) {
    setSelected((prev) => {
      const next = new Set(prev);
      if (next.has(item.id)) {
        next.delete(item.id);
      } else {
        if (!multiSelect) next.clear();
        next.add(item.id);
      }
      return next;
    });
  }

  function handleConfirm() {
    const picked = items
      .filter((i) => selected.has(i.id))
      .map((i) => ({
        mediaId:      i.id,
        url:          resolveUploadUrl((i as any).desktop?.url ?? ""),
        thumbnailUrl: resolveUploadUrl(i.thumbnail?.url ?? ""),
        tabletUrl:    resolveUploadUrl((i as any).tablet?.url ?? ""),
        mobileUrl:    resolveUploadUrl((i as any).mobile?.url ?? ""),
        originalName: i.originalName,
      }));
    onSelect(picked);
    onClose();
  }

  if (!open) return null;

  return (
    <div
      className="fixed inset-0 z-[200] flex items-center justify-center p-4 bg-black/60 backdrop-blur-sm"
      onClick={onClose}
    >
      <div
        className="bg-white rounded-3xl shadow-2xl w-full max-w-3xl max-h-[90vh] flex flex-col overflow-hidden"
        onClick={(e) => e.stopPropagation()}
      >
        {/* Header */}
        <div className="flex items-center justify-between px-5 py-4 border-b border-gray-100 shrink-0">
          <div>
            <h2 className="text-base font-black text-gray-900">Media Library</h2>
            <p className="text-xs text-gray-400">
              {multiSelect ? "Click images to select multiple" : "Click an image to select it"}
            </p>
          </div>
          <button onClick={onClose} className="p-2 rounded-xl hover:bg-gray-100 transition-colors">
            <X className="w-5 h-5 text-gray-400" />
          </button>
        </div>

        {/* Toolbar */}
        <div className="flex items-center gap-2 px-5 py-3 border-b border-gray-50 shrink-0 flex-wrap">
          {/* Category chips */}
          <div className="flex gap-1 flex-wrap">
            {CATS.map((c) => (
              <button
                key={c.value}
                onClick={() => setCat(c.value)}
                className={cn(
                  "text-[10px] font-bold px-2.5 py-1 rounded-lg transition-colors",
                  cat === c.value
                    ? "bg-gray-900 text-white"
                    : "bg-gray-100 text-gray-500 hover:bg-gray-200"
                )}
              >
                {c.label}
              </button>
            ))}
          </div>

          {/* Search */}
          <div className="relative w-full sm:w-auto sm:ml-auto min-w-0">
            <Search className="absolute left-2.5 top-1/2 -translate-y-1/2 w-3 h-3 text-gray-400" />
            <input
              type="text"
              value={search}
              onChange={(e) => setSearch(e.target.value)}
              placeholder="Search filename…"
              className="w-full sm:w-36 pl-7 pr-3 py-1.5 text-xs border border-gray-200 rounded-xl focus:outline-none focus:ring-2 focus:ring-violet-400 min-w-0"
            />
          </div>

          {/* Refresh */}
          <button
            onClick={load}
            disabled={loading}
            className="p-1.5 rounded-lg hover:bg-gray-100 transition-colors"
            title="Refresh"
          >
            <RefreshCw className={cn("w-3.5 h-3.5 text-gray-400", loading && "animate-spin")} />
          </button>
        </div>

        {/* Grid */}
        <div className="flex-1 overflow-y-auto p-4">
          {loading ? (
            <div className="flex items-center justify-center h-48">
              <Loader2 className="w-6 h-6 text-violet-500 animate-spin" />
            </div>
          ) : items.length === 0 ? (
            <div className="text-center py-20">
              <ImageIcon className="w-10 h-10 mx-auto mb-3 text-gray-200" />
              <p className="text-sm font-bold text-gray-400">No images found</p>
              <p className="text-xs text-gray-300 mt-1">Try a different category or search term</p>
            </div>
          ) : (
            <div className="grid grid-cols-3 sm:grid-cols-4 md:grid-cols-5 gap-2">
              {items.map((item) => {
                const isSelected = selected.has(item.id);
                return (
                  <button
                    key={item.id}
                    onClick={() => toggle(item)}
                    className={cn(
                      "relative aspect-square rounded-xl overflow-hidden border-2 transition-all group",
                      isSelected
                        ? "border-violet-500 ring-2 ring-violet-200"
                        : "border-gray-100 hover:border-gray-300"
                    )}
                  >
                    <Image
                      src={resolveUploadUrl(item.thumbnail?.url || (item as any).desktop?.url || "")}
                      alt={item.originalName}
                      fill
                      className="object-cover"
                      sizes="120px"
                      unoptimized
                    />
                    {/* Selected overlay */}
                    {isSelected && (
                      <div className="absolute inset-0 bg-violet-600/20 flex items-center justify-center">
                        <div className="w-6 h-6 bg-violet-600 rounded-full flex items-center justify-center shadow-lg">
                          <Check className="w-3.5 h-3.5 text-white" />
                        </div>
                      </div>
                    )}
                    {/* Hover label */}
                    <div className="absolute inset-x-0 bottom-0 bg-gradient-to-t from-black/70 to-transparent px-1.5 py-1 opacity-0 group-hover:opacity-100 transition-opacity">
                      <p className="text-[9px] text-white font-semibold truncate">{item.originalName}</p>
                    </div>
                  </button>
                );
              })}
            </div>
          )}
        </div>

        {/* Footer */}
        <div className="flex flex-col sm:flex-row sm:items-center justify-between gap-3 px-5 py-4 border-t border-gray-100 shrink-0">
          <p className="text-xs text-gray-400 text-center sm:text-left">
            {selected.size === 0
              ? `${items.length} images`
              : `${selected.size} selected`}
          </p>
          <div className="flex gap-2 justify-center sm:justify-end shrink-0">
            <button
              onClick={onClose}
              className="px-4 py-2 text-sm font-bold text-gray-600 bg-gray-100 hover:bg-gray-200 rounded-xl transition-colors"
            >
              Cancel
            </button>
            <button
              onClick={handleConfirm}
              disabled={selected.size === 0}
              className="px-4 py-2 text-sm font-black text-white bg-violet-600 hover:bg-violet-700 rounded-xl transition-colors disabled:opacity-40 disabled:cursor-not-allowed"
            >
              Use {selected.size > 0 ? `${selected.size} ` : ""}Selected
            </button>
          </div>
        </div>
      </div>
    </div>
  );
}
