
'use client';

import * as React from 'react';
import ReactDOM from 'react-dom';
import { FileText, Download, X, Eye, Loader2, File as FileIcon, Presentation, Share2 } from 'lucide-react';
import { TableRow, TableCell } from '@/components/ui/table';
import { Button } from '@/components/ui/button';
import {
  Tooltip,
  TooltipContent,
  TooltipProvider,
  TooltipTrigger,
} from '@/components/ui/tooltip';
import type { File as FileType } from '@/app/api/files/route';
import { useToast } from "@/hooks/use-toast"
import { Progress } from './ui/progress';
import { cn } from '@/lib/utils';
import dynamic from 'next/dynamic';
import { Badge } from './ui/badge';
import { Checkbox } from './ui/checkbox';
import { ShareDialog } from './share-dialog';

const PdfThumbnail = dynamic(() => import('./pdf-thumbnail').then(mod => mod.PdfThumbnail), {
  ssr: false,
  loading: () => <div className="h-[280px] w-[200px] flex items-center justify-center bg-muted"><Loader2 className="h-8 w-8 animate-spin text-primary" /></div>
});


function PdfLoader() {
  const [isMounted, setIsMounted] = React.useState(false);

  React.useEffect(() => {
    setIsMounted(true);
    return () => setIsMounted(false);
  }, []);

  if (!isMounted) {
    return null;
  }
  
  return ReactDOM.createPortal(
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-background/80">
      <Loader2 className="h-8 w-8 animate-spin text-primary" />
    </div>,
    document.body
  );
}

const PdfViewer = dynamic(() => import('./pdf-viewer').then(mod => mod.PdfViewer), {
  ssr: false,
  loading: () => <PdfLoader />,
});

interface FileItemProps extends React.HTMLAttributes<HTMLTableRowElement> {
  file: FileType;
  isSelected: boolean;
  onSelectItem: (id: string, isSelected: boolean) => void;
  isSelectionActive: boolean;
  isPublicShare?: boolean;
}

const fileTypeConfig = {
    pdf: {
        icon: FileText,
        color: 'destructive' as const,
        label: 'PDF',
    },
    docx: {
        icon: FileText,
        color: 'default' as const,
        label: 'DOCX',
    },
    pptx: {
        icon: Presentation,
        color: 'secondary' as const,
        label: 'PPTX',
    },
    other: {
        icon: FileIcon,
        color: 'outline' as const,
        label: 'File'
    }
}


export function FileItem({ file, className, isSelected, onSelectItem, isSelectionActive, isPublicShare, ...props }: FileItemProps) {
  const [downloadProgress, setDownloadProgress] = React.useState<number | null>(null);
  const [isDownloading, setIsDownloading] = React.useState(false);
  const downloadAbortController = React.useRef<AbortController | null>(null);
  const [isPreviewOpen, setIsPreviewOpen] = React.useState(false);
  const [isShareOpen, setIsShareOpen] = React.useState(false);


  const { toast } = useToast();

  const handleRowClick = (e: React.MouseEvent<HTMLTableRowElement>) => {
    if ((e.target as HTMLElement).closest('[role="checkbox"]') || (e.target as HTMLElement).closest('button')) {
      return;
    }

    if (isSelectionActive) {
      onSelectItem(file.id, !isSelected);
    } else if (file.fileType === 'pdf') {
       setIsPreviewOpen(true);
    }
  }

  const handleDownload = async () => {
    if (isDownloading) {
       if (downloadAbortController.current) {
        downloadAbortController.current.abort();
      }
      return;
    }
    
    setIsDownloading(true);
    setDownloadProgress(0);

    const controller = new AbortController();
    downloadAbortController.current = controller;

    try {
      const response = await fetch(file.path, {
        signal: controller.signal,
      });

      if (!response.ok) {
        throw new Error('Network response was not ok');
      }

      if (!response.body) {
        throw new Error('Response body is null');
      }

      const contentLength = response.headers.get('content-length');
      const totalSize = contentLength ? parseInt(contentLength, 10) : 0;
      let loaded = 0;

      const reader = response.body.getReader();
      const chunks: Uint8Array[] = [];
      
      while (true) {
        const { done, value } = await reader.read();
        if (done) {
          break;
        }
        chunks.push(value);
        loaded += value.length;
        if (totalSize > 0) {
          const progress = Math.round((loaded / totalSize) * 100);
          setDownloadProgress(progress);
        }
      }

      const blob = new Blob(chunks);
      const url = window.URL.createObjectURL(blob);
      const link = document.createElement('a');
      link.href = url;
      link.download = file.name;
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
      window.URL.revokeObjectURL(url);
      setDownloadProgress(100);

    } catch (error: any) {
        if (error.name === 'AbortError') {
            console.log('Download was aborted.');
        } else {
            toast({
                variant: "destructive",
                title: "Download Error",
                description: "There was a problem downloading the file.",
            });
            console.error('Download error:', error);
        }
    } finally {
      setIsDownloading(false);
      setDownloadProgress(null);
      downloadAbortController.current = null;
    }
  };
  
  const config = fileTypeConfig[file.fileType] ?? fileTypeConfig.other;
  const Icon = config.icon;

  const FileNameDisplay = (
    <span className="cursor-pointer hover:underline" onClick={(e) => {e.stopPropagation(); if (file.fileType === 'pdf' && !isSelectionActive) setIsPreviewOpen(true);}}>{file.name}</span>
  )

  const handleShareClick = (e: React.MouseEvent) => {
    e.stopPropagation();
    setIsShareOpen(true);
  }

  return (
    <>
      <TableRow 
         className={cn("group cursor-pointer", className, isSelected && "bg-accent/50")} 
         data-selected={isSelected}
         onClick={handleRowClick}
         {...props}
      >
        <TableCell className={cn("w-[40px]", !isSelectionActive && "hidden")} onClick={(e) => e.stopPropagation()}>
           <Checkbox 
              checked={isSelected}
              onCheckedChange={(checked) => onSelectItem(file.id, Boolean(checked))}
              aria-label={`Select file ${file.name}`}
            />
        </TableCell>
        <TableCell className="font-medium">
          <div className="flex items-center gap-3">
            <Icon className="h-5 w-5 text-muted-foreground" />
            <div className="flex-1 flex flex-col gap-1">
               <div className="flex items-center gap-2">
                 {file.fileType === 'pdf' ? (
                    <TooltipProvider delayDuration={200}>
                        <Tooltip>
                            <TooltipTrigger asChild>
                                {FileNameDisplay}
                            </TooltipTrigger>
                            <TooltipContent className="p-0 border-2 border-primary/20 shadow-2xl bg-muted" side="bottom" align="start">
                                <PdfThumbnail fileUrl={file.path} />
                            </TooltipContent>
                        </Tooltip>
                    </TooltipProvider>
                 ) : FileNameDisplay }

                 <Badge variant={config.color}>{config.label}</Badge>
               </div>
               {isDownloading && downloadProgress !== null && (
                  <div className="flex items-center gap-2 mt-1">
                      <Progress value={downloadProgress} className="w-full h-1.5" />
                      <span className="text-xs text-muted-foreground w-10 text-right">{downloadProgress}%</span>
                  </div>
               )}
            </div>
          </div>
        </TableCell>
        <TableCell className="text-muted-foreground max-w-sm truncate">
          <p>{file.contentSnippet}</p>
        </TableCell>
        <TableCell className="text-right">
          <div className="flex items-center justify-end gap-2">
              <TooltipProvider>
                 {!isPublicShare && (
                     <Tooltip>
                        <TooltipTrigger asChild>
                           <Button variant="ghost" size="icon" onClick={handleShareClick}>
                               <Share2 className="h-4 w-4" />
                               <span className="sr-only">Share</span>
                           </Button>
                        </TooltipTrigger>
                        <TooltipContent><p>Share</p></TooltipContent>
                     </Tooltip>
                 )}
                <Tooltip>
                  <TooltipTrigger asChild>
                    <Button variant="ghost" size="icon" onClick={(e) => {e.stopPropagation(); if (file.fileType === 'pdf') setIsPreviewOpen(true);}} disabled={file.fileType !== 'pdf'}>
                        <Eye className="h-4 w-4" />
                        <span className="sr-only">Preview</span>
                    </Button>
                  </TooltipTrigger>
                  <TooltipContent>
                    <p>Preview (PDFs only)</p>
                  </TooltipContent>
                </Tooltip>
                <Tooltip>
                  <TooltipTrigger asChild>
                    <Button variant="ghost" size="icon" onClick={(e) => {e.stopPropagation(); handleDownload();}}>
                        {isDownloading ? <X className="h-4 w-4" /> : <Download className="h-4 w-4" />}
                        <span className="sr-only">{isDownloading ? 'Cancel' : 'Download'}</span>
                    </Button>
                  </TooltipTrigger>
                  <TooltipContent>
                    <p>{isDownloading ? 'Cancel' : 'Download'}</p>
                  </TooltipContent>
                </Tooltip>
              </TooltipProvider>
          </div>
        </TableCell>
      </TableRow>
      {isPreviewOpen && file.fileType === 'pdf' && (
        <PdfViewer 
          isOpen={isPreviewOpen} 
          onOpenChange={setIsPreviewOpen} 
          fileUrl={file.path}
          fileName={file.name}
        />
      )}
      {!isPublicShare && (
        <ShareDialog
            isOpen={isShareOpen}
            onOpenChange={setIsShareOpen}
            itemName={file.name}
            itemPath={file.path}
            itemType="file"
        />
      )}
    </>
  );
}
