
'use client';

import * as React from 'react';
import { Search, Send, Download, X, List, LayoutGrid, CheckSquare, XSquare } from 'lucide-react';
import { Input } from '@/components/ui/input';
import { Logo } from '@/components/logo';
import { FolderTree } from '@/components/folder-tree';
import { FileList } from '@/components/file-list';
import { findNodeByPath, getAllFiles, getNodesByIds } from '@/lib/utils';
import type { File as FileType, Folder, FileSystemNode } from '@/app/api/files/route';
import { Card, CardContent } from './ui/card';
import { MobileSheet } from './mobile-sheet';
import { Button } from './ui/button';
import Link from 'next/link';
import { ThemeToggle } from './theme-toggle';
import { AnimatePresence, motion } from 'framer-motion';
import { useToast } from '@/hooks/use-toast';
import JSZip from 'jszip';
import { GridView } from './grid-view';
import { ToggleGroup, ToggleGroupItem } from './ui/toggle-group';
import { useLocalStorage } from '@/hooks/use-local-storage';
import { cn } from '@/lib/utils';


interface FileBrowserProps {
  initialData: Folder;
  isPublicShare?: boolean;
}

export function FileBrowser({ initialData, isPublicShare = false }: FileBrowserProps) {
  const [fileSystemData] = React.useState(initialData);
  const [currentPath, setCurrentPath] = React.useState('/');
  const [searchTerm, setSearchTerm] = React.useState('');
  const [selectedIds, setSelectedIds] = React.useState<string[]>([]);
  const [view, setView] = useLocalStorage<'list' | 'grid'>('file-browser-view', 'grid');
  const [isSelectionMode, setIsSelectionMode] = React.useState(false);
  
  const { toast, dismiss } = useToast();

  React.useEffect(() => {
    if (!isSelectionMode) {
      setSelectedIds([]);
    }
  }, [isSelectionMode]);

  const handleSearchChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    setSearchTerm(event.target.value);
    setSelectedIds([]); // Clear selection on new search
  };

  const currentFolder = React.useMemo(() => {
      if (isPublicShare) return fileSystemData;
      return findNodeByPath(fileSystemData, currentPath);
  }, [fileSystemData, currentPath, isPublicShare]);


  const { filesToShow, foldersToShow, allVisibleItems } = React.useMemo(() => {
    if (searchTerm) {
      const allFiles = getAllFiles(fileSystemData);
      const filteredFiles = allFiles.filter((file) =>
        file.name.toLowerCase().includes(searchTerm.toLowerCase())
      );
      return { 
        filesToShow: filteredFiles, 
        foldersToShow: [],
        allVisibleItems: filteredFiles,
      };
    }

    if (currentFolder && currentFolder.type === 'folder') {
      const files = currentFolder.children.filter(
        (child): child is FileType => child.type === 'file'
      );
      const folders = currentFolder.children.filter(
        (child): child is Folder => child.type === 'folder'
      );
      return { 
        filesToShow: files, 
        foldersToShow: folders,
        allVisibleItems: [...folders, ...files]
      };
    }
    return { filesToShow: [], foldersToShow: [], allVisibleItems: [] };
  }, [fileSystemData, currentPath, searchTerm, currentFolder]);
  
  const breadcrumbs = currentPath.split('/').filter(Boolean);

  const handleSelectAll = (isChecked: boolean) => {
    if (isChecked) {
      setSelectedIds(allVisibleItems.map(item => item.id));
    } else {
      setSelectedIds([]);
    }
  };
  
  const handleSelectItem = (id: string, isChecked: boolean) => {
    setSelectedIds(prev => 
      isChecked ? [...prev, id] : prev.filter(selectedId => selectedId !== id)
    );
  };
  
  const handleBatchDownload = async () => {
    const { saveAs } = await import('file-saver');

    const { id: toastId } = toast({
      title: 'Preparing Download',
      description: 'Zipping your files... Please wait.',
    });

    try {
        const selectedNodes = getNodesByIds(fileSystemData, selectedIds);
        
        const filesToZip: FileType[] = [];
        selectedNodes.forEach(node => {
            if (node.type === 'file') {
                filesToZip.push(node);
            } else if (node.type === 'folder') {
                filesToZip.push(...getAllFiles(node));
            }
        });

        if (filesToZip.length === 0) {
            toast({
                variant: 'destructive',
                title: 'No Files Selected',
                description: 'Please select files to download.',
            });
            dismiss(toastId);
            return;
        }

        const zip = new JSZip();

        await Promise.all(
            filesToZip.map(async (file) => {
                const response = await fetch(file.path);
                const blob = await response.blob();
                // Use the relative path within the zip file
                const zipPath = file.path.startsWith('/') ? file.path.substring(1) : file.path;
                zip.file(zipPath, blob);
            })
        );
        
        const zipBlob = await zip.generateAsync({ type: 'blob' });
        saveAs(zipBlob, 'medico-docs.zip');

        toast({
            title: 'Download Ready',
            description: 'Your ZIP file has been downloaded.',
        });

    } catch (error) {
        console.error('Batch download failed:', error);
        toast({
            variant: 'destructive',
            title: 'Download Failed',
            description: 'There was an error creating the ZIP file.',
        });
    } finally {
        dismiss(toastId);
        setSelectedIds([]);
        setIsSelectionMode(false);
    }
  };


  const numSelected = selectedIds.length;

  return (
    <div className="grid md:grid-cols-[280px_1fr] h-screen w-full bg-background font-body text-foreground">
      <aside className={cn("hidden md:flex flex-col border-r bg-card", isPublicShare && "hidden")}>
        <div className="p-4 border-b">
          <Logo />
        </div>
        <div className="flex-1 overflow-auto py-2">
          <FolderTree
            rootFolder={fileSystemData}
            currentPath={currentPath}
            onSelectFolder={setCurrentPath}
          />
        </div>
      </aside>

      <div className="flex flex-col">
        <header className="flex h-16 items-center gap-4 border-b bg-card px-6 shrink-0">
          <div className="md:hidden">
            {isPublicShare ? <Logo /> : <MobileSheet rootFolder={fileSystemData} currentPath={currentPath} onSelectFolder={setCurrentPath} />}
          </div>
          {!isPublicShare && <div className="hidden md:block w-[215px]"/>}
          <div className="relative flex-1">
            <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-5 w-5 text-muted-foreground" />
            <Input
              placeholder="Search documents by name..."
              className="pl-10 h-10 bg-card"
              value={searchTerm}
              onChange={handleSearchChange}
            />
          </div>
          <ThemeToggle />
           {isSelectionMode ? (
              <Button variant="outline" onClick={() => setIsSelectionMode(false)}>
                <XSquare className="mr-2 h-4 w-4" />
                Cancel
              </Button>
            ) : (
              <Button variant="outline" onClick={() => setIsSelectionMode(true)}>
                <CheckSquare className="mr-2 h-4 w-4" />
                Select
              </Button>
            )}
           {!isPublicShare && (
             <Link href="https://t.me/ztx" target="_blank">
                <Button>
                    <Send className="mr-2 h-4 w-4" />
                    Contact Me
                </Button>
             </Link>
           )}
        </header>

        <main className="flex-1 overflow-auto p-6 space-y-4">
          <div className="flex items-center justify-between gap-4">
               <div className="flex items-center gap-2 text-sm text-muted-foreground">
                  {isPublicShare || breadcrumbs.length === 0 ? (
                    <span>{currentFolder?.name || 'Files'}</span>
                  ) : (
                    <React.Fragment>
                      <span className="cursor-pointer hover:underline" onClick={() => setCurrentPath('/')}>Files</span>
                      {breadcrumbs.map((crumb, index) => {
                        const path = '/' + breadcrumbs.slice(0, index + 1).join('/');
                        return (
                          <React.Fragment key={index}>
                            <span>/</span>
                            <span className="cursor-pointer hover:underline" onClick={() => setCurrentPath(path)}>{crumb}</span>
                          </React.Fragment>
                        )
                      })}
                    </React.Fragment>
                  )}
              </div>
              <ToggleGroup type="single" value={view} onValueChange={(value) => { if (value) setView(value as 'list' | 'grid')}} size="sm">
                  <ToggleGroupItem value="list" aria-label="List view">
                     <List className="h-4 w-4" />
                  </ToggleGroupItem>
                  <ToggleGroupItem value="grid" aria-label="Grid view">
                     <LayoutGrid className="h-4 w-4" />
                  </ToggleGroupItem>
              </ToggleGroup>
          </div>
          <h1 className="text-2xl font-bold">
            {searchTerm ? `Search Results` : currentFolder?.name}
          </h1>
          <Card className="shadow-sm">
            <CardContent className="p-0">
               {view === 'list' ? (
                  <FileList 
                      files={filesToShow} 
                      folders={foldersToShow} 
                      searchTerm={searchTerm} 
                      onSelectFolder={setCurrentPath}
                      selectedIds={selectedIds}
                      onSelectAll={handleSelectAll}
                      onSelectItem={handleSelectItem}
                      allItemCount={allVisibleItems.length}
                      isSelectionActive={isSelectionMode}
                      isPublicShare={isPublicShare}
                    />
                ) : (
                  <GridView
                      files={filesToShow}
                      folders={foldersToShow}
                      searchTerm={searchTerm}
                      onSelectFolder={setCurrentPath}
                      selectedIds={selectedIds}
                      onSelectItem={handleSelectItem}
                      isSelectionActive={isSelectionMode}
                      isPublicShare={isPublicShare}
                  />
                )}
            </CardContent>
          </Card>
        </main>
        <AnimatePresence>
        {numSelected > 0 && (
            <motion.div
              initial={{ y: 100, opacity: 0 }}
              animate={{ y: 0, opacity: 1 }}
              exit={{ y: 100, opacity: 0 }}
              transition={{ type: 'spring', stiffness: 300, damping: 30 }}
              className="fixed bottom-6 left-1/2 -translate-x-1/2 w-auto bg-primary/90 text-primary-foreground backdrop-blur-md rounded-lg shadow-2xl z-50 overflow-hidden"
            >
                <div className="flex items-center gap-4 px-4 py-2">
                    <div className="flex items-center gap-2">
                      <Button variant="ghost" size="icon" className="hover:bg-primary-foreground/10" onClick={() => setSelectedIds([])}>
                         <X className="h-5 w-5" />
                      </Button>
                      <span className="font-medium text-sm whitespace-nowrap">{numSelected} item{numSelected > 1 ? 's' : ''} selected</span>
                    </div>
                    <div className="h-6 w-px bg-primary-foreground/20" />
                    <div className="flex items-center gap-2">
                        <Button variant="ghost" className="hover:bg-primary-foreground/10" onClick={handleBatchDownload}>
                            <Download className="mr-2 h-4 w-4"/>
                            Download
                        </Button>
                    </div>
                </div>
            </motion.div>
        )}
        </AnimatePresence>
      </div>
    </div>
  );
}
