"use client";

import { useEffect, useState, useRef } from "react";
import { api } from "@/lib/api";
import { cn } from "@/lib/utils";
import { Upload, Trash2, Copy, Film, Image as ImageIcon, Check, Pencil, X } from "lucide-react";

interface MediaItem {
  id: string;
  slug: string;
  type: "image" | "video";
  mimeType: string;
  size: number;
  originalFilename: string;
  uploadedBy: string;
  createdAt: string;
  url: string;
  title?: string;
  description?: string;
  altText?: string;
}

interface EditForm {
  title: string;
  description: string;
  altText: string;
}

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

export default function GalleryPage() {
  const [media, setMedia] = useState<MediaItem[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState("");
  const [uploading, setUploading] = useState(false);
  const [copiedId, setCopiedId] = useState<string | null>(null);
  const [editingItem, setEditingItem] = useState<MediaItem | null>(null);
  const [editForm, setEditForm] = useState<EditForm>({ title: "", description: "", altText: "" });
  const [saving, setSaving] = useState(false);
  const fileInputRef = useRef<HTMLInputElement>(null);

  const loadMedia = async () => {
    try {
      const data = await api.getMediaList();
      setMedia(data);
    } catch (err: any) {
      setError(err.message);
    } finally {
      setLoading(false);
    }
  };

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

  const handleUpload = async (e: React.ChangeEvent<HTMLInputElement>) => {
    const files = e.target.files;
    if (!files || files.length === 0) return;

    setUploading(true);
    setError("");

    try {
      for (const file of Array.from(files)) {
        await api.uploadMedia(file);
      }
      await loadMedia();
    } catch (err: any) {
      setError(err.message);
    } finally {
      setUploading(false);
      if (fileInputRef.current) fileInputRef.current.value = "";
    }
  };

  const handleDelete = async (id: string) => {
    if (!confirm("Delete this media item? This cannot be undone.")) return;
    try {
      await api.deleteMedia(id);
      await loadMedia();
    } catch (err: any) {
      setError(err.message);
    }
  };

  const handleCopyUrl = async (item: MediaItem) => {
    const url = `${window.location.origin}/media/${item.id}`;
    await navigator.clipboard.writeText(url);
    setCopiedId(item.id);
    setTimeout(() => setCopiedId(null), 2000);
  };

  const openEdit = (item: MediaItem) => {
    setEditingItem(item);
    setEditForm({
      title: item.title || "",
      description: item.description || "",
      altText: item.altText || "",
    });
  };

  const handleSaveEdit = async () => {
    if (!editingItem) return;
    setSaving(true);
    setError("");
    try {
      await api.updateMedia(editingItem.id, {
        title: editForm.title,
        description: editForm.description,
        altText: editForm.altText,
      });
      setEditingItem(null);
      await loadMedia();
    } catch (err: any) {
      setError(err.message);
    } finally {
      setSaving(false);
    }
  };

  if (loading) {
    return (
      <div className="flex items-center justify-center min-h-[60vh]">
        <div className="text-on-surface/50">Loading gallery...</div>
      </div>
    );
  }

  return (
    <div className="space-y-6">
      <div className="flex items-center justify-between">
        <h1 className="text-2xl font-bold text-on-surface">Media Gallery</h1>
        <div>
          <input
            ref={fileInputRef}
            type="file"
            accept="image/*,video/*"
            multiple
            onChange={handleUpload}
            className="hidden"
          />
          <button
            onClick={() => fileInputRef.current?.click()}
            disabled={uploading}
            className="flex items-center gap-2 px-4 py-2 rounded-lg bg-gradient-to-r from-primary to-primary-container text-on-primary font-semibold text-sm hover:opacity-90 transition-opacity disabled:opacity-50"
          >
            <Upload size={16} />
            {uploading ? "Uploading..." : "Upload Media"}
          </button>
        </div>
      </div>

      {error && <p className="text-error text-sm">{error}</p>}

      {media.length === 0 ? (
        <div className="text-center py-20">
          <ImageIcon size={48} className="mx-auto text-on-surface/20 mb-4" />
          <p className="text-on-surface/50 text-sm">No media uploaded yet.</p>
          <p className="text-on-surface/30 text-xs mt-1">
            Upload images or videos to get started.
          </p>
        </div>
      ) : (
        <div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-4">
          {media.map((item) => (
            <div
              key={item.id}
              className="group bg-surface-container-low rounded-xl overflow-hidden"
            >
              <div className="relative aspect-square bg-surface-container-highest">
                {item.type === "image" ? (
                  <img
                    src={`/media/${item.id}?w=300`}
                    alt={item.altText || item.title || item.originalFilename}
                    className="w-full h-full object-cover"
                    loading="lazy"
                  />
                ) : (
                  <div className="w-full h-full flex items-center justify-center">
                    <Film size={40} className="text-on-surface/30" />
                  </div>
                )}

                <span
                  className={cn(
                    "absolute top-2 left-2 rounded-full px-2 py-0.5 text-[10px] font-bold uppercase",
                    item.type === "image"
                      ? "bg-blue-900/60 text-blue-300"
                      : "bg-purple-900/60 text-purple-300"
                  )}
                >
                  {item.type}
                </span>

                <div className="absolute inset-0 bg-black/0 group-hover:bg-black/40 transition-colors flex items-center justify-center gap-2 opacity-0 group-hover:opacity-100">
                  <button
                    onClick={() => handleCopyUrl(item)}
                    className="p-2 rounded-lg bg-white/20 hover:bg-white/30 text-white transition-colors"
                    title="Copy Full URL"
                  >
                    {copiedId === item.id ? <Check size={16} /> : <Copy size={16} />}
                  </button>
                  <button
                    onClick={() => openEdit(item)}
                    className="p-2 rounded-lg bg-white/20 hover:bg-white/30 text-white transition-colors"
                    title="Edit Media"
                  >
                    <Pencil size={16} />
                  </button>
                  <button
                    onClick={() => handleDelete(item.id)}
                    className="p-2 rounded-lg bg-red-500/30 hover:bg-red-500/50 text-white transition-colors"
                    title="Delete"
                  >
                    <Trash2 size={16} />
                  </button>
                </div>
              </div>

              <div className="p-3">
                <p className="text-on-surface text-xs font-medium truncate" title={item.title || item.originalFilename}>
                  {item.title || item.originalFilename}
                </p>
                <p className="text-on-surface/40 text-[10px] mt-0.5">
                  {formatFileSize(item.size)}
                </p>
              </div>
            </div>
          ))}
        </div>
      )}

      {editingItem && (
        <div className="fixed inset-0 z-50 flex items-center justify-center p-4">
          <div className="absolute inset-0 bg-black/60" onClick={() => setEditingItem(null)} />
          <div className="relative bg-surface-container-low rounded-2xl w-full max-w-lg overflow-hidden">
            <div className="flex items-center justify-between p-5 border-b border-surface-container-highest">
              <h2 className="text-lg font-semibold text-on-surface">Edit Media</h2>
              <button
                onClick={() => setEditingItem(null)}
                className="text-on-surface/50 hover:text-on-surface transition-colors"
              >
                <X size={20} />
              </button>
            </div>

            <div className="p-5 space-y-4">
              <div className="flex items-center gap-4 p-3 bg-surface-container-highest rounded-lg">
                {editingItem.type === "image" ? (
                  <img
                    src={`/media/${editingItem.id}?w=100`}
                    alt=""
                    className="w-14 h-14 rounded-lg object-cover shrink-0"
                  />
                ) : (
                  <div className="w-14 h-14 rounded-lg bg-surface-container flex items-center justify-center shrink-0">
                    <Film size={20} className="text-on-surface/30" />
                  </div>
                )}
                <div className="min-w-0">
                  <p className="text-on-surface text-sm font-medium truncate">{editingItem.originalFilename}</p>
                  <p className="text-on-surface/40 text-xs">
                    {editingItem.type} &middot; {formatFileSize(editingItem.size)} &middot; {editingItem.mimeType}
                  </p>
                </div>
              </div>

              <div>
                <label className="text-on-surface/60 text-xs mb-1.5 block">Title</label>
                <input
                  value={editForm.title}
                  onChange={(e) => setEditForm({ ...editForm, title: e.target.value })}
                  placeholder="SEO title for this media"
                  className="bg-surface-container-highest text-on-surface rounded-lg px-4 py-3 w-full focus:outline-none focus:ring-1 focus:ring-primary/40 text-sm"
                />
              </div>

              <div>
                <label className="text-on-surface/60 text-xs mb-1.5 block">Description</label>
                <textarea
                  value={editForm.description}
                  onChange={(e) => setEditForm({ ...editForm, description: e.target.value })}
                  placeholder="SEO description for this media"
                  rows={3}
                  className="bg-surface-container-highest text-on-surface rounded-lg px-4 py-3 w-full focus:outline-none focus:ring-1 focus:ring-primary/40 text-sm resize-none"
                />
              </div>

              <div>
                <label className="text-on-surface/60 text-xs mb-1.5 block">Alt Text</label>
                <input
                  value={editForm.altText}
                  onChange={(e) => setEditForm({ ...editForm, altText: e.target.value })}
                  placeholder="Accessible alt text for images"
                  className="bg-surface-container-highest text-on-surface rounded-lg px-4 py-3 w-full focus:outline-none focus:ring-1 focus:ring-primary/40 text-sm"
                />
              </div>
            </div>

            <div className="flex justify-end gap-3 p-5 border-t border-surface-container-highest">
              <button
                onClick={() => setEditingItem(null)}
                className="px-5 py-2 rounded-lg bg-surface-container-highest text-on-surface font-semibold text-sm hover:bg-surface-container-high transition-colors"
              >
                Cancel
              </button>
              <button
                onClick={handleSaveEdit}
                disabled={saving}
                className="px-5 py-2 rounded-lg bg-gradient-to-r from-primary to-primary-container text-on-primary font-semibold text-sm hover:opacity-90 transition-opacity disabled:opacity-50"
              >
                {saving ? "Saving..." : "Save"}
              </button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}
