'use client';

import { useEffect, useRef, useState } from 'react';
import { Upload, Trash2, Pencil, FileText, Film, X, Check, Filter } from 'lucide-react';
import toast from 'react-hot-toast';
import api from '@/lib/api';
import { Media } from '@/types';
import Button from '@/components/ui/Button';
import { ConfirmDeleteModal } from '@/components/ui/Modal';
import Pagination from '@/components/ui/Pagination';
import { PageSpinner } from '@/components/ui/Spinner';
import { Select } from '@/components/ui/Input';

const API_BASE = (process.env.NEXT_PUBLIC_API_URL || 'http://localhost:5000/api').replace('/api', '');

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

function MediaIcon({ mimetype }: { mimetype: string }) {
  if (mimetype.startsWith('video/')) return <Film size={32} className="text-purple-400" />;
  if (mimetype === 'application/pdf') return <FileText size={32} className="text-red-400" />;
  return <FileText size={32} className="text-gray-400" />;
}

interface EditMetaModalProps {
  media: Media;
  onClose: () => void;
  onSave: (data: { alt?: string; caption?: string; folder?: string }) => void;
}

function EditMetaModal({ media, onClose, onSave }: EditMetaModalProps) {
  const [alt, setAlt] = useState(media.alt ?? '');
  const [caption, setCaption] = useState(media.caption ?? '');
  const [folder, setFolder] = useState(media.folder ?? 'general');

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    onSave({ alt, caption, folder });
  };

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center p-4">
      <div className="absolute inset-0 bg-black/50" onClick={onClose} />
      <div className="relative bg-white rounded-xl shadow-xl w-full max-w-sm">
        <div className="flex items-center justify-between px-5 py-4 border-b">
          <h3 className="font-semibold text-gray-900">Edit metadata</h3>
          <button onClick={onClose} className="text-gray-400 hover:text-gray-600"><X size={18} /></button>
        </div>
        <form onSubmit={handleSubmit} className="p-5 space-y-4">
          <div className="space-y-1.5">
            <label className="block text-sm font-medium text-gray-700">Alt text</label>
            <input value={alt} onChange={(e) => setAlt(e.target.value)} className="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="Describe the image..." />
          </div>
          <div className="space-y-1.5">
            <label className="block text-sm font-medium text-gray-700">Caption</label>
            <input value={caption} onChange={(e) => setCaption(e.target.value)} className="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="Optional caption" />
          </div>
          <div className="space-y-1.5">
            <label className="block text-sm font-medium text-gray-700">Folder</label>
            <input value={folder} onChange={(e) => setFolder(e.target.value)} className="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="general" />
          </div>
          <div className="flex justify-end gap-3 pt-2">
            <button type="button" onClick={onClose} className="px-4 py-2 text-sm text-gray-600 border border-gray-300 rounded-lg hover:bg-gray-50">Cancel</button>
            <button type="submit" className="px-4 py-2 text-sm bg-blue-600 text-white rounded-lg hover:bg-blue-700">Save</button>
          </div>
        </form>
      </div>
    </div>
  );
}

export default function MediaPage() {
  const [items, setItems] = useState<Media[]>([]);
  const [totalPages, setTotalPages] = useState(1);
  const [page, setPage] = useState(1);
  const [typeFilter, setTypeFilter] = useState('');
  const [isLoading, setIsLoading] = useState(true);
  const [isUploading, setIsUploading] = useState(false);
  const [deleteTarget, setDeleteTarget] = useState<Media | null>(null);
  const [isDeleting, setIsDeleting] = useState(false);
  const [editTarget, setEditTarget] = useState<Media | null>(null);
  const [dragOver, setDragOver] = useState(false);
  const fileInputRef = useRef<HTMLInputElement>(null);

  const load = async (p = page) => {
    setIsLoading(true);
    try {
      const data = await api.getMedia({ type: typeFilter || undefined, page: p, limit: 24 });
      setItems(data.media ?? []);
      setTotalPages(data.pagination?.pages ?? 1);
    } catch {
      toast.error('Failed to load media');
    } finally {
      setIsLoading(false);
    }
  };

  useEffect(() => { load(); }, [page, typeFilter]); // eslint-disable-line react-hooks/exhaustive-deps

  const uploadFiles = async (files: File[]) => {
    if (!files.length) return;
    setIsUploading(true);
    let successCount = 0;
    for (const file of files) {
      try {
        const formData = new FormData();
        formData.append('file', file);
        await api.uploadMedia(formData);
        successCount++;
      } catch {
        toast.error(`Failed to upload ${file.name}`);
      }
    }
    if (successCount > 0) {
      toast.success(`${successCount} file${successCount > 1 ? 's' : ''} uploaded`);
      load(1);
      setPage(1);
    }
    setIsUploading(false);
  };

  const handleFileInput = (e: React.ChangeEvent<HTMLInputElement>) => {
    if (e.target.files) {
      uploadFiles(Array.from(e.target.files));
      e.target.value = '';
    }
  };

  const handleDrop = (e: React.DragEvent) => {
    e.preventDefault();
    setDragOver(false);
    if (e.dataTransfer.files) uploadFiles(Array.from(e.dataTransfer.files));
  };

  const handleDelete = async () => {
    if (!deleteTarget) return;
    setIsDeleting(true);
    try {
      await api.deleteMedia(deleteTarget._id);
      toast.success('File deleted');
      setDeleteTarget(null);
      load();
    } catch {
      toast.error('Failed to delete file');
    } finally {
      setIsDeleting(false);
    }
  };

  const handleEditSave = async (data: { alt?: string; caption?: string; folder?: string }) => {
    if (!editTarget) return;
    try {
      await api.updateMedia(editTarget._id, data);
      toast.success('Metadata updated');
      setEditTarget(null);
      load();
    } catch {
      toast.error('Failed to update metadata');
    }
  };

  const copyUrl = (url: string) => {
    navigator.clipboard.writeText(`${API_BASE}${url}`);
    toast.success('URL copied');
  };

  return (
    <div className="space-y-5">
      <div className="flex items-center justify-between">
        <h1 className="text-2xl font-bold text-gray-900">Media Library</h1>
        <Button onClick={() => fileInputRef.current?.click()} isLoading={isUploading}>
          <Upload size={16} />
          Upload
        </Button>
        <input ref={fileInputRef} type="file" multiple className="hidden" onChange={handleFileInput} accept="image/*,video/mp4,video/webm,application/pdf" />
      </div>

      {/* Upload dropzone */}
      <div
        onDrop={handleDrop}
        onDragOver={(e) => { e.preventDefault(); setDragOver(true); }}
        onDragLeave={() => setDragOver(false)}
        onClick={() => fileInputRef.current?.click()}
        className={`border-2 border-dashed rounded-xl p-8 text-center cursor-pointer transition-colors ${
          dragOver ? 'border-blue-400 bg-blue-50' : 'border-gray-200 hover:border-gray-300 hover:bg-gray-50'
        }`}
      >
        <Upload size={24} className="mx-auto text-gray-400 mb-2" />
        <p className="text-sm text-gray-500">
          Drop files here or <span className="text-blue-600">click to upload</span>
        </p>
        <p className="text-xs text-gray-400 mt-1">Images, videos, PDFs — max 10MB each</p>
      </div>

      {/* Filters */}
      <div className="flex items-center gap-3">
        <Filter size={14} className="text-gray-400" />
        <div className="w-40">
          <Select
            value={typeFilter}
            onChange={(e) => { setTypeFilter(e.target.value); setPage(1); }}
            options={[
              { value: '', label: 'All types' },
              { value: 'image', label: 'Images' },
              { value: 'video', label: 'Videos' },
              { value: 'document', label: 'Documents' },
            ]}
          />
        </div>
      </div>

      {/* Grid */}
      {isLoading ? (
        <PageSpinner />
      ) : items.length === 0 ? (
        <div className="py-16 text-center text-gray-400 text-sm">
          No files found. Upload something!
        </div>
      ) : (
        <div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-6 gap-3">
          {items.map((item) => (
            <div key={item._id} className="group relative bg-white rounded-lg border border-gray-200 overflow-hidden hover:shadow-md transition-shadow">
              {/* Thumbnail */}
              <div className="aspect-square bg-gray-100 flex items-center justify-center">
                {item.mimetype.startsWith('image/') ? (
                  // eslint-disable-next-line @next/next/no-img-element
                  <img
                    src={`${API_BASE}${item.url}`}
                    alt={item.alt || item.originalName}
                    className="w-full h-full object-cover"
                  />
                ) : (
                  <MediaIcon mimetype={item.mimetype} />
                )}
              </div>

              {/* Info */}
              <div className="p-2">
                <p className="text-xs text-gray-700 truncate font-medium" title={item.originalName}>
                  {item.originalName}
                </p>
                <p className="text-xs text-gray-400">{formatBytes(item.size)}</p>
              </div>

              {/* Actions overlay */}
              <div className="absolute inset-0 bg-black/60 opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center gap-2">
                <button
                  onClick={() => copyUrl(item.url)}
                  title="Copy URL"
                  className="p-1.5 bg-white rounded text-gray-700 hover:text-blue-600 hover:bg-blue-50"
                >
                  <Check size={14} />
                </button>
                <button
                  onClick={() => setEditTarget(item)}
                  title="Edit metadata"
                  className="p-1.5 bg-white rounded text-gray-700 hover:text-blue-600 hover:bg-blue-50"
                >
                  <Pencil size={14} />
                </button>
                <button
                  onClick={() => setDeleteTarget(item)}
                  title="Delete"
                  className="p-1.5 bg-white rounded text-gray-700 hover:text-red-600 hover:bg-red-50"
                >
                  <Trash2 size={14} />
                </button>
              </div>
            </div>
          ))}
        </div>
      )}

      {totalPages > 1 && (
        <div className="flex justify-center">
          <Pagination page={page} totalPages={totalPages} onPageChange={setPage} />
        </div>
      )}

      <ConfirmDeleteModal
        isOpen={!!deleteTarget}
        onClose={() => setDeleteTarget(null)}
        onConfirm={handleDelete}
        itemName={deleteTarget?.originalName ?? ''}
        isLoading={isDeleting}
      />

      {editTarget && (
        <EditMetaModal
          media={editTarget}
          onClose={() => setEditTarget(null)}
          onSave={handleEditSave}
        />
      )}
    </div>
  );
}
