
"use client";

import { useState, useEffect, Suspense } from "react";
import { useSearchParams, useRouter } from "next/navigation";
import PhotoViewer from "@/components/photo-viewer";
import VideoViewer from "@/components/video-viewer";
import TextViewer from "@/components/text-viewer";
import VirtualizedFolderGrid from "@/components/virtualized-media-grid";
import { createPortal } from "react-dom";
import { X, Copy, Download } from "lucide-react";
import { Button } from "@/components/ui/button";

interface FileSystemItem {
  name: string;
  path: string;
  isDirectory: boolean;
  size: number;
  thumbnail?: string;
  type?: string;
  id?: number;
  avg_rating?: number;
  star_count?: number;
}

interface BreadcrumbItem {
  name: string;
  path: string;
}

const FolderViewerPage = () => {
  const searchParams = useSearchParams();
  const router = useRouter();
  const path = searchParams.get("path");
  const [selectedVideo, setSelectedVideo] = useState<FileSystemItem | null>(null);
  const [isPlayerOpen, setIsPlayerOpen] = useState(false);
  const [isVideoLoading, setIsVideoLoading] = useState(false);
  const [selectedPhoto, setSelectedPhoto] = useState<FileSystemItem | null>(null);
  const [isPhotoViewerOpen, setIsPhotoViewerOpen] = useState(false);
  const [currentPhotoIndex, setCurrentPhotoIndex] = useState(0);
  const [selectedText, setSelectedText] = useState<FileSystemItem | null>(null);
  const [isTextViewerOpen, setIsTextViewerOpen] = useState(false);
  const [libraries, setLibraries] = useState<{id: number, path: string}[]>([]);

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

  const fetchLibraries = async () => {
    try {
      const res = await fetch('/api/libraries');
      const data = await res.json();
      setLibraries(data);
    } catch (error) {
      console.error('Error fetching libraries:', error);
    }
  };

  const formatFileSize = (bytes: number) => {
    if (bytes === 0) return '0 Bytes';
    const k = 1024;
    const sizes = ['Bytes', 'KB', 'MB', 'GB'];
    const i = Math.floor(Math.log(bytes) / Math.log(k));
    return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
  };

  const getLibraryRoot = (currentPath: string): string | null => {
    if (!currentPath || libraries.length === 0) return null;
    
    for (const library of libraries) {
      if (currentPath.startsWith(library.path)) {
        return library.path;
      }
    }
    return null;
  };

  const getBreadcrumbs = (currentPath: string): BreadcrumbItem[] => {
    if (!currentPath) return [];
    
    const libraryRoot = getLibraryRoot(currentPath);
    if (!libraryRoot) return [{ name: 'Unknown', path: currentPath }];
    
    const relativePath = currentPath.substring(libraryRoot.length);
    const pathParts = relativePath.split('/').filter(part => part.length > 0);
    
    const breadcrumbs: BreadcrumbItem[] = [];
    
    const libraryName = libraryRoot.split('/').pop() || libraryRoot;
    breadcrumbs.push({ name: libraryName, path: libraryRoot });
    
    let accumulatedPath = libraryRoot;
    pathParts.forEach((part, index) => {
      accumulatedPath += '/' + part;
      breadcrumbs.push({
        name: part,
        path: accumulatedPath
      });
    });
    
    return breadcrumbs;
  };

  const getParentPath = (currentPath: string): string => {
    if (!currentPath) return '';
    
    const libraryRoot = getLibraryRoot(currentPath);
    if (!libraryRoot) return '';
    
    if (currentPath === libraryRoot) return '';
    
    const pathParts = currentPath.split('/');
    const libraryParts = libraryRoot.split('/').filter(part => part.length > 0);
    
    const filteredPathParts = pathParts.filter(part => part.length > 0);
    
    if (filteredPathParts.length <= libraryParts.length) return '';
    
    const parentParts = filteredPathParts.slice(0, -1);
    return '/' + parentParts.join('/');
  };

  const handleBackClick = () => {
    const parentPath = getParentPath(path || '');
    if (parentPath) {
      router.push(`/folder-viewer?path=${parentPath}`);
    } else {
      router.push('/folder-viewer');
    }
  };

  const handleBreadcrumbClick = (breadcrumbPath: string) => {
    if (breadcrumbPath === '') {
      router.push('/folder-viewer');
    } else {
      router.push(`/folder-viewer?path=${breadcrumbPath}`);
    }
  };

  const handleVideoClick = (item: FileSystemItem) => {
    if (item.type === 'video' && item.id) {
      setIsVideoLoading(true);
      setSelectedVideo(item);
      setIsPlayerOpen(true);
      setTimeout(() => setIsVideoLoading(false), 500);
    }
  };

  const handleClosePlayer = () => {
    setIsPlayerOpen(false);
    setSelectedVideo(null);
  };

  const handlePhotoClick = (item: FileSystemItem, index: number) => {
    if (item.type === 'photo' && item.id) {
      setSelectedPhoto(item);
      setIsPhotoViewerOpen(true);
    }
  };

  const handleClosePhotoViewer = () => {
    setIsPhotoViewerOpen(false);
    setSelectedPhoto(null);
  };

  const handleTextClick = (item: FileSystemItem) => {
    if (item.type === 'text') {
      setSelectedText(item);
      setIsTextViewerOpen(true);
    }
  };

  const handleCloseTextViewer = () => {
    setIsTextViewerOpen(false);
    setSelectedText(null);
  };

  const [currentItems, setCurrentItems] = useState<FileSystemItem[]>([]);

  // Custom Text Viewer Component for files without IDs
  const FolderTextViewer = ({ 
    text, 
    isOpen, 
    onClose 
  }: { 
    text: FileSystemItem; 
    isOpen: boolean; 
    onClose: () => void; 
  }) => {
    const [content, setContent] = useState<string>('');
    const [loading, setLoading] = useState(false);
    const [error, setError] = useState<string>('');
    const [selectedEncoding, setSelectedEncoding] = useState<string>('utf8');
    const [availableEncodings] = useState<string[]>(['utf8', 'gbk', 'gb2312', 'big5', 'latin1']);

    useEffect(() => {
      if (isOpen && text) {
        loadTextContent();
      }
    }, [isOpen, text, selectedEncoding]);

    const loadTextContent = async () => {
      setLoading(true);
      setError('');
      setContent('');

      try {
        const response = await fetch(`/api/files/content?path=${encodeURIComponent(text.path)}&encoding=${selectedEncoding}`);
        if (!response.ok) {
          throw new Error('Failed to load text file');
        }
        const data = await response.json();
        
        // Handle base64 encoded content
        if (data.encoding === 'base64') {
          try {
            const decodedContent = atob(data.content);
            setContent(decodedContent);
          } catch (err) {
            setError('Failed to decode file content');
          }
        } else {
          setContent(data.content || '');
        }
      } catch (err) {
        setError(err instanceof Error ? err.message : 'Failed to load text file');
      } finally {
        setLoading(false);
      }
    };

    if (!isOpen) return null;

    return createPortal(
      <div className="fixed inset-0 bg-black/90 z-50 flex items-center justify-center p-4">
        <div className="relative w-full max-w-6xl h-[90vh] bg-zinc-900 rounded-xl border border-zinc-800 flex flex-col">
          {/* Header */}
          <div className="flex items-center justify-between p-4 border-b border-zinc-800 flex-shrink-0">
            <div className="flex-1 min-w-0">
              <h2 className="text-lg font-semibold text-white truncate">{text.name}</h2>
              <p className="text-sm text-zinc-400 truncate">{text.path}</p>
            </div>
            <button
              onClick={onClose}
              className="p-2 text-zinc-400 hover:text-white hover:bg-zinc-800 rounded-lg transition-colors ml-4 flex-shrink-0"
            >
              <X className="h-5 w-5" />
            </button>
          </div>

          {/* Encoding Selection */}
          <div className="flex items-center gap-3 p-3 border-b border-zinc-800 bg-zinc-800/50 flex-shrink-0">
            <span className="text-sm text-zinc-300 font-medium">Encoding:</span>
            <select
              value={selectedEncoding}
              onChange={(e) => setSelectedEncoding(e.target.value)}
              className="bg-zinc-700 border border-zinc-600 text-white text-sm rounded-lg px-3 py-1.5 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
            >
              {availableEncodings.map((encoding) => (
                <option key={encoding} value={encoding} className="bg-zinc-700">
                  {encoding.toUpperCase()}
                </option>
              ))}
            </select>
            <span className="text-xs text-zinc-400 ml-2">
              {selectedEncoding === 'utf8' ? '(Default)' : 
               selectedEncoding === 'gbk' || selectedEncoding === 'gb2312' ? '(Chinese)' : 
               selectedEncoding === 'big5' ? '(Traditional Chinese)' : '(Other)'}
            </span>
          </div>

          {/* Content */}
          <div className="flex-1 overflow-hidden p-4 min-h-0">
            {loading ? (
              <div className="flex items-center justify-center h-full">
                <div className="text-zinc-400">Loading...</div>
              </div>
            ) : error ? (
              <div className="flex items-center justify-center h-full">
                <div className="text-red-400">{error}</div>
              </div>
            ) : (
              <div className="h-full overflow-auto bg-zinc-950 rounded-lg border border-zinc-700 custom-scrollbar">
                <pre className="text-sm text-zinc-300 font-mono whitespace-pre-wrap break-words leading-relaxed p-4">
                  {content}
                </pre>
              </div>
            )}
          </div>

          {/* Footer */}
          <div className="flex items-center justify-between p-4 border-t border-zinc-800 bg-zinc-800/50 flex-shrink-0">
            <div className="text-sm text-zinc-400">
              Size: {formatFileSize(text.size)}
            </div>
            <div className="flex gap-2">
              <Button
                onClick={() => navigator.clipboard.writeText(content)}
                variant="outline"
                size="sm"
                className="border-zinc-600 text-zinc-300 hover:bg-zinc-700 hover:text-white"
              >
                <Copy className="h-4 w-4 mr-2" />
                Copy
              </Button>
              <Button
                onClick={() => {
                  const blob = new Blob([content], { type: 'text/plain; charset=utf-8' });
                  const url = URL.createObjectURL(blob);
                  const a = document.createElement('a');
                  a.href = url;
                  a.download = text.name;
                  a.click();
                  URL.revokeObjectURL(url);
                }}
                size="sm"
                className="bg-blue-600 hover:bg-blue-700 text-white"
              >
                <Download className="h-4 w-4 mr-2" />
                Download
              </Button>
            </div>
          </div>
        </div>
      </div>,
      document.body
    );
  };

  const handleNextPhoto = () => {
    // Navigate to next photo, skipping videos
    const photos = currentItems.filter(item => item.type === 'photo' && item.id);
    if (photos.length === 0) return;
    
    const currentPhotoId = selectedPhoto?.id;
    if (!currentPhotoId) return;
    
    const currentIndexInPhotos = photos.findIndex(p => p.id === currentPhotoId);
    if (currentIndexInPhotos === -1) return;
    
    const nextIndex = (currentIndexInPhotos + 1) % photos.length;
    const nextPhoto = photos[nextIndex];
    
    setSelectedPhoto(nextPhoto);
  };

  const handlePrevPhoto = () => {
    // Navigate to previous photo, skipping videos
    const photos = currentItems.filter(item => item.type === 'photo' && item.id);
    if (photos.length === 0) return;
    
    const currentPhotoId = selectedPhoto?.id;
    if (!currentPhotoId) return;
    
    const currentIndexInPhotos = photos.findIndex(p => p.id === currentPhotoId);
    if (currentIndexInPhotos === -1) return;
    
    const prevIndex = (currentIndexInPhotos - 1 + photos.length) % photos.length;
    const prevPhoto = photos[prevIndex];
    
    setSelectedPhoto(prevPhoto);
  };

  if (!path) {
    return (
      <div className="min-h-screen bg-zinc-950">
        <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
          <div className="flex flex-col items-center justify-center min-h-[60vh]">
            <div className="text-center max-w-md">
              <div className="w-20 h-20 bg-zinc-900 rounded-2xl flex items-center justify-center mx-auto mb-6 shadow-lg">
                <div className="h-10 w-10 text-blue-500">📁</div>
              </div>
              <h2 className="text-2xl font-bold text-white mb-2">Select a Library</h2>
              <p className="text-zinc-400">
                Choose a media library from the sidebar to browse your files
              </p>
            </div>
          </div>
        </div>
      </div>
    );
  }

  return (
    <>
      <VirtualizedFolderGrid
        currentPath={path}
        onVideoClick={handleVideoClick}
        onPhotoClick={handlePhotoClick}
        onTextClick={handleTextClick}
        onBackClick={handleBackClick}
        onBreadcrumbClick={handleBreadcrumbClick}
        breadcrumbs={getBreadcrumbs(path)}
        libraries={libraries}
        onItemsLoaded={setCurrentItems}
      />

      {/* Photo Viewer */}
      <PhotoViewer
        photo={selectedPhoto!}
        isOpen={isPhotoViewerOpen}
        onClose={handleClosePhotoViewer}
        onNext={handleNextPhoto}
        onPrev={handlePrevPhoto}
        showNavigation={true}
        showBookmarks={false}
        showRatings={false}
        formatFileSize={formatFileSize}
      />

      {/* Video Viewer */}
      <VideoViewer
        video={selectedVideo!}
        isOpen={isPlayerOpen}
        onClose={handleClosePlayer}
        showBookmarks={false}
        showRatings={false}
        formatFileSize={formatFileSize}
      />

      {/* Text Viewer */}
      <TextViewer
        text={selectedText!}
        isOpen={isTextViewerOpen}
        onClose={handleCloseTextViewer}
        formatFileSize={formatFileSize}
      />

      {/* Custom Text Viewer for files without IDs */}
      {selectedText && <FolderTextViewer text={selectedText} isOpen={isTextViewerOpen} onClose={handleCloseTextViewer} />}
    </>
  );
};

const FolderViewerPageWrapper = () => (
  <Suspense fallback={<div>Loading...</div>}>
    <FolderViewerPage />
  </Suspense>
);

export default FolderViewerPageWrapper;
