"use client";

/**
 * Page Studio — Image Library modal. Three tabs:
 *   Uploaded  — browse/search brand assets (PNG/JPG), upload new
 *   From Website — scrape images from the brand's website
 *   Free Images — search Unsplash/Pexels for stock photos
 */

import { useCallback, useEffect, useRef, useState } from "react";
import { X, Upload, Search, ImageIcon, Trash2, Loader2, AlertCircle, Check, Globe, Camera } from "lucide-react";
import WebsiteImagesTab from "./website-images-tab";
import FreeImagesTab from "./free-images-tab";

export interface BrandAssetDto {
  id: string; filename: string; url: string; type: string; mimeType: string;
  fileSize: number; width: number | null; height: number | null;
  altText: string | null; tags: string[]; uploadedAt: string;
}
interface Props { brandId: string; open: boolean; onClose: () => void; onSelect: (asset: BrandAssetDto) => void }

const ACCEPT = "image/png,image/jpeg";
const MAX_BYTES = 10 * 1024 * 1024;
const TYPES = ["logo", "photo", "icon", "background"] as const;
type Tab = "uploaded" | "website" | "free";
const TAB_META: { id: Tab; label: string; icon: React.ReactNode }[] = [
  { id: "uploaded", label: "Uploaded", icon: <Upload className="w-3 h-3" /> },
  { id: "website", label: "From Website", icon: <Globe className="w-3 h-3" /> },
  { id: "free", label: "Free Images", icon: <Camera className="w-3 h-3" /> },
];

export default function ImageLibrary({ brandId, open, onClose, onSelect }: Props) {
  const [tab, setTab] = useState<Tab>("uploaded");
  const [assets, setAssets] = useState<BrandAssetDto[]>([]);
  const [loading, setLoading] = useState(false);
  const [query, setQuery] = useState("");
  const [typeFilter, setTypeFilter] = useState<string>("all");
  const [uploading, setUploading] = useState(false);
  const [uploadPct, setUploadPct] = useState(0);
  const [uploadError, setUploadError] = useState<string | null>(null);
  const [dragActive, setDragActive] = useState(false);
  const [showUpload, setShowUpload] = useState(false);
  const fileInput = useRef<HTMLInputElement>(null);

  const load = useCallback(async () => {
    setLoading(true);
    try {
      const res = await fetch(`/api/brands/${brandId}/assets`);
      if (res.ok) { const data = await res.json(); setAssets(data.assets || []); }
    } finally { setLoading(false); }
  }, [brandId]);
  useEffect(() => { if (open && tab === "uploaded") load(); }, [open, load, tab]);

  const handleFile = useCallback(async (file: File) => {
    setUploadError(null);
    if (!["image/png", "image/jpeg"].includes(file.type)) return setUploadError("Only PNG and JPG files are allowed.");
    if (file.size > MAX_BYTES) return setUploadError("File exceeds 10MB limit.");
    setUploading(true); setUploadPct(5);
    try {
      const fd = new FormData();
      fd.append("file", file); fd.append("type", "photo");
      const tick = setInterval(() => setUploadPct((p) => Math.min(90, p + 7)), 120);
      const res = await fetch(`/api/brands/${brandId}/assets`, { method: "POST", body: fd });
      clearInterval(tick); setUploadPct(100);
      if (!res.ok) { const err = await res.json().catch(() => ({})); throw new Error(err.error || "Upload failed"); }
      const { asset } = await res.json();
      setAssets((prev) => [asset, ...prev]);
      setShowUpload(false); onSelect(asset); onClose();
    } catch (err) {
      setUploadError(err instanceof Error ? err.message : "Upload failed");
    } finally { setUploading(false); setTimeout(() => setUploadPct(0), 600); }
  }, [brandId, onSelect, onClose]);

  const onDrop = useCallback((e: React.DragEvent) => {
    e.preventDefault(); setDragActive(false);
    const f = e.dataTransfer.files?.[0]; if (f) handleFile(f);
  }, [handleFile]);

  const deleteAsset = async (id: string) => {
    if (!confirm("Delete this image?")) return;
    const res = await fetch(`/api/brands/${brandId}/assets/${id}`, { method: "DELETE" });
    if (res.ok) setAssets((prev) => prev.filter((a) => a.id !== id));
  };

  // For website/free tabs — create a synthetic BrandAssetDto from URL
  const handleExternalSelect = useCallback((url: string, alt: string) => {
    const synth: BrandAssetDto = {
      id: `ext_${Date.now()}`, filename: alt || "image", url, type: "photo",
      mimeType: "image/jpeg", fileSize: 0, width: null, height: null,
      altText: alt, tags: [], uploadedAt: new Date().toISOString(),
    };
    onSelect(synth); onClose();
  }, [onSelect, onClose]);

  if (!open) return null;

  const q = query.toLowerCase();
  const filtered = assets.filter((a) => {
    if (typeFilter !== "all" && a.type !== typeFilter) return false;
    if (!q) return true;
    return a.filename.toLowerCase().includes(q) || a.tags.some((t) => t.toLowerCase().includes(q));
  });

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-slate-900/60 p-4" onClick={onClose}>
      <div className="bg-white rounded-2xl shadow-2xl w-full max-w-4xl max-h-[85vh] flex flex-col overflow-hidden" onClick={(e) => e.stopPropagation()}>

        {/* Header + tabs */}
        <div className="flex items-center justify-between border-b border-slate-200 px-5 py-4">
          <div className="flex items-center gap-4">
            <h2 className="font-bold text-slate-900">Image Library</h2>
            <div className="flex bg-slate-100 rounded-lg p-0.5">
              {TAB_META.map((t) => (
                <button key={t.id} onClick={() => setTab(t.id)}
                  className={`flex items-center gap-1.5 px-3 py-1.5 rounded-md text-xs font-semibold transition-colors ${
                    tab === t.id ? "bg-white text-slate-900 shadow-sm" : "text-slate-500 hover:text-slate-700"
                  }`}>{t.icon} {t.label}</button>
              ))}
            </div>
          </div>
          <button onClick={onClose} className="p-1.5 rounded-lg hover:bg-slate-100 text-slate-500"><X className="w-4 h-4" /></button>
        </div>

        <div className="flex-1 overflow-auto p-5">
          {/* ── Uploaded tab ── */}
          {tab === "uploaded" && !showUpload && (
            <>
              <div className="flex items-center gap-2 mb-4">
                <div className="relative flex-1">
                  <Search className="w-3.5 h-3.5 text-slate-400 absolute left-3 top-1/2 -translate-y-1/2" />
                  <input value={query} onChange={(e) => setQuery(e.target.value)} placeholder="Search by filename or tag…" className="w-full pl-9 pr-3 py-2 text-sm border border-slate-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500/40 focus:border-blue-500" />
                </div>
                <select value={typeFilter} onChange={(e) => setTypeFilter(e.target.value)} className="text-sm border border-slate-200 rounded-lg px-3 py-2 bg-white">
                  <option value="all">All types</option>
                  {TYPES.map((t) => <option key={t} value={t} className="capitalize">{t}</option>)}
                </select>
                <button onClick={() => setShowUpload(true)} className="flex items-center gap-1.5 px-3 py-2 bg-slate-900 text-white text-xs font-semibold rounded-lg hover:bg-slate-800">
                  <Upload className="w-3 h-3" /> Upload
                </button>
              </div>

              {loading ? (
                <div className="flex items-center justify-center py-16 text-slate-400"><Loader2 className="w-5 h-5 animate-spin" /></div>
              ) : filtered.length === 0 ? (
                <div className="text-center py-16 text-slate-400">
                  <ImageIcon className="w-10 h-10 mx-auto mb-3 text-slate-200" />
                  <p className="text-sm font-semibold text-slate-600 mb-1">No images yet</p>
                  <p className="text-xs">Upload a PNG or JPG to get started.</p>
                </div>
              ) : (
                <div className="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 gap-3">
                  {filtered.map((a) => (
                    <div key={a.id} className="group relative rounded-xl border border-slate-200 overflow-hidden bg-white hover:border-slate-300 hover:shadow-md transition-all">
                      <button onClick={() => { onSelect(a); onClose(); }} className="block w-full aspect-square bg-slate-50 flex items-center justify-center">
                        {/* eslint-disable-next-line @next/next/no-img-element */}
                        <img src={a.url} alt={a.altText || a.filename} className="max-w-full max-h-full object-contain" />
                      </button>
                      <div className="px-2.5 py-2 border-t border-slate-100 text-left">
                        <p className="text-[11px] font-semibold text-slate-700 truncate">{a.filename}</p>
                        <p className="text-[10px] text-slate-400">{a.width && a.height ? `${a.width}×${a.height}` : a.type}</p>
                      </div>
                      <button onClick={(e) => { e.stopPropagation(); deleteAsset(a.id); }} className="absolute top-1.5 right-1.5 opacity-0 group-hover:opacity-100 transition-opacity w-6 h-6 rounded-md bg-white/90 border border-slate-200 flex items-center justify-center text-slate-500 hover:text-red-600 hover:border-red-200">
                        <Trash2 className="w-3 h-3" />
                      </button>
                      {a.type === "logo" && (
                        <span className="absolute top-1.5 left-1.5 flex items-center gap-0.5 px-1.5 py-0.5 rounded-md bg-brand-600 text-white text-[9px] font-bold uppercase tracking-wider">
                          <Check className="w-2.5 h-2.5" /> Logo
                        </span>
                      )}
                    </div>
                  ))}
                </div>
              )}
            </>
          )}

          {/* Upload sub-view */}
          {tab === "uploaded" && showUpload && (
            <>
              <button onClick={() => setShowUpload(false)} className="text-xs text-slate-500 hover:text-slate-700 mb-3">&larr; Back to library</button>
              <div onDragOver={(e) => { e.preventDefault(); setDragActive(true); }} onDragLeave={() => setDragActive(false)} onDrop={onDrop} onClick={() => fileInput.current?.click()}
                className={`border-2 border-dashed rounded-2xl px-6 py-16 text-center cursor-pointer transition-colors ${dragActive ? "border-blue-500 bg-blue-50" : "border-slate-300 hover:border-slate-400"}`}>
                <Upload className="w-10 h-10 text-slate-300 mx-auto mb-3" />
                <p className="text-sm font-bold text-slate-700">Drop PNG or JPG files here</p>
                <p className="text-xs text-slate-500 mt-1">Only PNG and JPG files. Max 10MB.</p>
                <button type="button" className="mt-4 px-4 py-2 bg-slate-900 text-white text-xs font-semibold rounded-lg hover:bg-slate-800">Choose File</button>
                <input ref={fileInput} type="file" accept={ACCEPT} className="hidden" onChange={(e) => { const f = e.target.files?.[0]; if (f) handleFile(f); }} />
              </div>
              {uploading && (
                <div className="mt-4">
                  <div className="flex items-center gap-2 text-xs text-slate-600 mb-1.5"><Loader2 className="w-3.5 h-3.5 animate-spin" /> Uploading… {uploadPct}%</div>
                  <div className="h-1.5 bg-slate-100 rounded-full overflow-hidden"><div className="h-full bg-blue-500 transition-all" style={{ width: `${uploadPct}%` }} /></div>
                </div>
              )}
              {uploadError && (
                <div className="mt-4 flex items-start gap-2 rounded-lg border border-red-200 bg-red-50 px-3 py-2 text-xs text-red-700">
                  <AlertCircle className="w-3.5 h-3.5 mt-0.5 shrink-0" /><span>{uploadError}</span>
                </div>
              )}
            </>
          )}

          {/* ── From Website tab ── */}
          {tab === "website" && <WebsiteImagesTab brandId={brandId} onSelect={handleExternalSelect} />}

          {/* ── Free Images tab ── */}
          {tab === "free" && <FreeImagesTab brandId={brandId} onSelect={handleExternalSelect} />}
        </div>
      </div>
    </div>
  );
}
