'use client';

import { useState, useEffect } from 'react';
import api, { assetsApi } from '@/lib/api';
import { clsx } from 'clsx';
import { toast } from 'react-hot-toast';
import {
  X,
  Search,
  Image as ImageIcon,
  Video,
  Mic,
  FileText,
  Check,
  Loader2,
  FolderOpen,
  Upload,
} from 'lucide-react';
import FileUpload from './FileUpload';

interface Asset {
  id: string;
  filename: string;
  file_type: string;
  mime_type: string;
  width?: number;
  height?: number;
  thumbnail_url: string | null;
  file_url: string;
  created_at: string;
  source_module?: string;
}

interface AssetLibraryProps {
  isOpen: boolean;
  onClose: () => void;
  onSelect: (asset: Asset) => void;
  fileTypes?: string[];  // ['image', 'video', 'audio']
  title?: string;
  multiple?: boolean;
}

const FILE_TYPE_ICONS = {
  image: ImageIcon,
  video: Video,
  audio: Mic,
  document: FileText,
};

export default function AssetLibrary({
  isOpen,
  onClose,
  onSelect,
  fileTypes = ['image', 'video', 'audio'],
  title = 'Select from My Files',
  multiple = false,
}: AssetLibraryProps) {
  const [assets, setAssets] = useState<Asset[]>([]);
  const [loading, setLoading] = useState(false);
  const [search, setSearch] = useState('');
  const [selectedType, setSelectedType] = useState<string | null>(null);
  const [page, setPage] = useState(1);
  const [totalPages, setTotalPages] = useState(1);
  const [selectedAssets, setSelectedAssets] = useState<Set<string>>(new Set());
  const [showUpload, setShowUpload] = useState(false);
  const [uploading, setUploading] = useState(false);

  useEffect(() => {
    if (isOpen) {
      loadAssets();
    }
  }, [isOpen, search, selectedType, page]);

  const loadAssets = async () => {
    setLoading(true);
    try {
      const types = selectedType ? selectedType : fileTypes.join(',');
      const response = await api.get('/assets/library', {
        params: {
          file_types: types,
          search: search || undefined,
          page,
          limit: 20,
        },
      });
      setAssets(response.data.items);
      setTotalPages(response.data.pages);
    } catch (error) {
      console.error('Failed to load assets:', error);
    } finally {
      setLoading(false);
    }
  };

  const handleSelect = (asset: Asset) => {
    if (multiple) {
      const newSelected = new Set(selectedAssets);
      if (newSelected.has(asset.id)) {
        newSelected.delete(asset.id);
      } else {
        newSelected.add(asset.id);
      }
      setSelectedAssets(newSelected);
    } else {
      onSelect(asset);
      onClose();
    }
  };

  const handleConfirmMultiple = () => {
    const selected = assets.filter(a => selectedAssets.has(a.id));
    selected.forEach(asset => onSelect(asset));
    onClose();
  };

  const handleUpload = async (file: File) => {
    setUploading(true);
    try {
      const response = await assetsApi.upload(file);
      toast.success('File uploaded!');
      loadAssets();  // Reload to show new file
      // Auto-select the new file
      if (!multiple) {
        onSelect(response.data);
        setShowUpload(false);
        onClose();
      }
    } catch (error) {
      toast.error('Failed to upload file');
    } finally {
      setUploading(false);
    }
  };

  if (!isOpen) return null;

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/70 backdrop-blur-sm">
      <div className="bg-forge-dark border border-gray-800 rounded-xl w-full max-w-4xl max-h-[80vh] flex flex-col">
        {/* Header */}
        <div className="p-4 border-b border-gray-800 flex items-center justify-between">
          <div className="flex items-center gap-3">
            <FolderOpen className="w-5 h-5 text-forge-yellow" />
            <h2 className="text-lg font-semibold text-white">{title}</h2>
          </div>
          <div className="flex items-center gap-2">
            <button
              onClick={() => setShowUpload(!showUpload)}
              className="px-3 py-2 bg-forge-yellow/10 text-forge-yellow rounded-lg hover:bg-forge-yellow/20 transition-colors flex items-center gap-2 text-sm"
            >
              <Upload className="w-4 h-4" />
              Upload New
            </button>
            <button
              onClick={onClose}
              className="p-2 text-gray-400 hover:text-white transition-colors"
            >
              <X className="w-5 h-5" />
            </button>
          </div>
        </div>

        {/* Filters */}
        <div className="p-4 border-b border-gray-800 flex items-center gap-4">
          {/* Search */}
          <div className="relative flex-1">
            <Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-500" />
            <input
              type="text"
              placeholder="Search files..."
              value={search}
              onChange={(e) => {
                setSearch(e.target.value);
                setPage(1);
              }}
              className="w-full pl-10 pr-4 py-2 bg-forge-gray border border-gray-700 rounded-lg text-white placeholder-gray-500 focus:border-forge-yellow focus:outline-none"
            />
          </div>

          {/* Type filters */}
          <div className="flex items-center gap-2">
            <button
              onClick={() => {
                setSelectedType(null);
                setPage(1);
              }}
              className={clsx(
                'px-3 py-2 rounded-lg text-sm font-medium transition-colors',
                !selectedType
                  ? 'bg-forge-yellow text-black'
                  : 'bg-forge-gray text-gray-400 hover:text-white'
              )}
            >
              All
            </button>
            {fileTypes.map((type) => {
              const Icon = FILE_TYPE_ICONS[type as keyof typeof FILE_TYPE_ICONS] || FileText;
              return (
                <button
                  key={type}
                  onClick={() => {
                    setSelectedType(type);
                    setPage(1);
                  }}
                  className={clsx(
                    'px-3 py-2 rounded-lg text-sm font-medium transition-colors flex items-center gap-2',
                    selectedType === type
                      ? 'bg-forge-yellow text-black'
                      : 'bg-forge-gray text-gray-400 hover:text-white'
                  )}
                >
                  <Icon className="w-4 h-4" />
                  {type.charAt(0).toUpperCase() + type.slice(1)}
                </button>
              );
            })}
          </div>
        </div>

        {/* Upload Section */}
        {showUpload && (
          <div className="p-4 border-b border-gray-800">
            <FileUpload
              onUpload={handleUpload}
              accept={
                fileTypes.includes('image')
                  ? { 'image/*': ['.png', '.jpg', '.jpeg', '.webp', '.gif'] }
                  : fileTypes.includes('video')
                    ? { 'video/*': ['.mp4', '.webm', '.mov'] }
                    : { 'audio/*': ['.mp3', '.wav', '.ogg'] }
              }
              label="Drop file here or click to upload"
            />
            {uploading && (
              <div className="mt-2 flex items-center gap-2 text-forge-yellow text-sm">
                <Loader2 className="w-4 h-4 animate-spin" />
                Uploading...
              </div>
            )}
          </div>
        )}

        {/* Asset Grid */}
        <div className="flex-1 overflow-y-auto p-4">
          {loading ? (
            <div className="flex items-center justify-center h-48">
              <Loader2 className="w-8 h-8 text-forge-yellow animate-spin" />
            </div>
          ) : assets.length === 0 ? (
            <div className="flex flex-col items-center justify-center h-48 text-gray-500">
              <FolderOpen className="w-12 h-12 mb-3" />
              <p>No files found</p>
              <p className="text-sm">Upload some files or generate content to see them here</p>
            </div>
          ) : (
            <div className="grid grid-cols-4 md:grid-cols-5 lg:grid-cols-6 gap-3">
              {assets.map((asset) => {
                const isSelected = selectedAssets.has(asset.id);
                const Icon = FILE_TYPE_ICONS[asset.file_type as keyof typeof FILE_TYPE_ICONS] || FileText;

                // Determine preview URL
                let previewUrl = null;
                if (asset.thumbnail_url) {
                  previewUrl = `${process.env.NEXT_PUBLIC_API_URL}${asset.thumbnail_url}`;
                } else if (asset.mime_type?.startsWith('image/')) {
                  // Fallback to direct download for images without thumbnails
                  previewUrl = `/api/v1/assets/${asset.id}/download`;
                }

                return (
                  <button
                    key={asset.id}
                    onClick={() => handleSelect(asset)}
                    className={clsx(
                      'relative aspect-square rounded-lg overflow-hidden border-2 transition-all hover:scale-105',
                      isSelected
                        ? 'border-forge-yellow'
                        : 'border-transparent hover:border-gray-600'
                    )}
                  >
                    {/* Thumbnail or Icon */}
                    {previewUrl ? (
                      <img
                        src={previewUrl}
                        alt={asset.filename}
                        className="w-full h-full object-cover"
                        loading="lazy"
                      />
                    ) : (
                      <div className="w-full h-full bg-forge-gray flex items-center justify-center">
                        <Icon className="w-8 h-8 text-gray-500" />
                      </div>
                    )}

                    {/* Selection indicator */}
                    {multiple && isSelected && (
                      <div className="absolute top-2 right-2 w-6 h-6 bg-forge-yellow rounded-full flex items-center justify-center">
                        <Check className="w-4 h-4 text-black" />
                      </div>
                    )}

                    {/* File type badge */}
                    <div className="absolute bottom-0 left-0 right-0 bg-black/70 px-2 py-1">
                      <p className="text-xs text-gray-300 truncate">{asset.filename}</p>
                    </div>
                  </button>
                );
              })}
            </div>
          )}
        </div>

        {/* Pagination */}
        {totalPages > 1 && (
          <div className="p-4 border-t border-gray-800 flex items-center justify-center gap-2">
            <button
              onClick={() => setPage(p => Math.max(1, p - 1))}
              disabled={page === 1}
              className="px-3 py-1 bg-forge-gray rounded text-sm text-gray-400 hover:text-white disabled:opacity-50"
            >
              Previous
            </button>
            <span className="text-sm text-gray-400">
              Page {page} of {totalPages}
            </span>
            <button
              onClick={() => setPage(p => Math.min(totalPages, p + 1))}
              disabled={page === totalPages}
              className="px-3 py-1 bg-forge-gray rounded text-sm text-gray-400 hover:text-white disabled:opacity-50"
            >
              Next
            </button>
          </div>
        )}

        {/* Footer for multiple selection */}
        {multiple && selectedAssets.size > 0 && (
          <div className="p-4 border-t border-gray-800 flex items-center justify-between">
            <span className="text-sm text-gray-400">
              {selectedAssets.size} file(s) selected
            </span>
            <button
              onClick={handleConfirmMultiple}
              className="px-4 py-2 bg-forge-yellow text-black font-medium rounded-lg hover:bg-forge-yellow/90"
            >
              Use Selected
            </button>
          </div>
        )}
      </div>
    </div>
  );
}
