import React, { useState, useRef, useMemo, useEffect } from 'react';
import { format } from 'date-fns';
import {
    Upload,
    FileText,
    Download,
    Trash2,
    File,
    Image as ImageIcon,
    Loader2,
    FolderOpen,
    LayoutGrid,
    List as ListIcon,
    Search,
    CloudUpload,
    X,
    FileSpreadsheet,
    FileCode
} from 'lucide-react';
import { Button } from '@/components/ui/button';
import { Card } from '@/components/ui/card';
import { Badge } from '@/components/ui/badge';
import { Input } from '@/components/ui/input';
import {
    Dialog,
    DialogContent,
    DialogHeader,
    DialogTitle,
    DialogFooter,
    DialogDescription,
} from '@/components/ui/dialog';
import {
    Select,
    SelectContent,
    SelectItem,
    SelectTrigger,
    SelectValue,
} from '@/components/ui/select';
import {
    Tabs,
    TabsContent,
    TabsList,
    TabsTrigger,
} from '@/components/ui/tabs';
import { Label } from '@/components/ui/label';
import { ScrollArea } from '@/components/ui/scroll-area';
import { cn } from '@/lib/utils';
import { toast } from 'sonner';
import { useAttachments, ATTACHMENT_CATEGORIES, type AttachmentCategory } from '@/hooks/useAttachments';

interface ContactAttachmentsTabProps {
    contactId: string;
}

// --- Utils ---

const formatFileSize = (bytes: number): string => {
    if (bytes < 1024) return `${bytes} B`;
    if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
    return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
};

const getFileIcon = (mimeType: string): React.ElementType => {
    if (mimeType.includes('pdf')) return FileText;
    if (mimeType.startsWith('image/')) return ImageIcon;
    if (mimeType.includes('sheet') || mimeType.includes('csv') || mimeType.includes('excel')) return FileSpreadsheet;
    if (mimeType.includes('json') || mimeType.includes('xml')) return FileCode;
    return File;
};

const CATEGORY_COLORS: Record<string, string> = {
    general: 'bg-slate-100 text-slate-700 border-slate-200',
    contract: 'bg-emerald-100 text-emerald-700 border-emerald-200',
    invoice: 'bg-amber-100 text-amber-700 border-amber-200',
    proposal: 'bg-violet-100 text-violet-700 border-violet-200',
    report: 'bg-blue-100 text-blue-700 border-blue-200',
    image: 'bg-pink-100 text-pink-700 border-pink-200',
    other: 'bg-gray-100 text-gray-700 border-gray-200',
};

// --- Sub-Components ---

/**
 * Async component to load and display image thumbnails securely
 */
const AttachmentThumbnail = ({
    path,
    alt,
    getDownloadUrl,
    fallbackIcon: Icon
}: {
    path: string;
    alt: string;
    getDownloadUrl: (path: string) => Promise<string>;
    fallbackIcon: React.ElementType;
}) => {
    const [src, setSrc] = useState<string | null>(null);
    const [loading, setLoading] = useState(true);
    const [error, setError] = useState(false);

    useEffect(() => {
        let isMounted = true;

        const fetchUrl = async () => {
            try {
                const url = await getDownloadUrl(path);
                if (isMounted) {
                    setSrc(url);
                    setLoading(false);
                }
            } catch (err) {
                if (isMounted) {
                    setError(true);
                    setLoading(false);
                }
            }
        };

        fetchUrl();
        return () => { isMounted = false; };
    }, [path, getDownloadUrl]);

    if (loading) {
        return (
            <div className="absolute inset-0 flex items-center justify-center bg-muted/30">
                <Loader2 className="h-5 w-5 animate-spin text-muted-foreground/50" />
            </div>
        );
    }

    if (error || !src) {
        return (
            <div className="absolute inset-0 flex items-center justify-center bg-muted/30">
                <Icon className="h-10 w-10 text-muted-foreground/30" />
            </div>
        );
    }

    return (
        <div className="absolute inset-0 bg-checkerboard">
            <img
                src={src}
                alt={alt}
                className="w-full h-full object-cover transition-transform duration-500 hover:scale-110"
                loading="lazy"
            />
        </div>
    );
};

// --- Main Component ---

export function ContactAttachmentsTab({ contactId }: ContactAttachmentsTabProps) {
    const {
        attachments,
        isLoading,
        upload,
        deleteAttachment,
        getDownloadUrl,
        isUploading,
        isDeleting,
    } = useAttachments(contactId);

    const fileInputRef = useRef<HTMLInputElement>(null);
    const [selectedFile, setSelectedFile] = useState<File | null>(null);
    const [selectedCategory, setSelectedCategory] = useState<AttachmentCategory>('general');
    const [showUploadDialog, setShowUploadDialog] = useState(false);

    // View State
    const [viewMode, setViewMode] = useState<'list' | 'grid'>('grid'); // Default to grid for images
    const [searchQuery, setSearchQuery] = useState('');
    const [activeTab, setActiveTab] = useState<string>('all');
    const [isDragging, setIsDragging] = useState(false);

    // Filtering Logic
    const filteredAttachments = useMemo(() => {
        return attachments.filter(file => {
            const matchesSearch = file.file_name.toLowerCase().includes(searchQuery.toLowerCase());
            const matchesCategory = activeTab === 'all' || file.category === activeTab;
            return matchesSearch && matchesCategory;
        });
    }, [attachments, searchQuery, activeTab]);

    // Handlers
    const handleFileSelect = (e: React.ChangeEvent<HTMLInputElement>) => {
        const file = e.target.files?.[0];
        if (file) {
            setSelectedFile(file);
            setShowUploadDialog(true);
        }
    };

    const handleDrop = (e: React.DragEvent) => {
        e.preventDefault();
        setIsDragging(false);
        const file = e.dataTransfer.files?.[0];
        if (file) {
            setSelectedFile(file);
            setShowUploadDialog(true);
        }
    };

    const handleUpload = async () => {
        if (!selectedFile) return;

        try {
            await upload({ file: selectedFile, category: selectedCategory });
            toast.success('File uploaded successfully');
            setSelectedFile(null);
            setSelectedCategory('general');
            setShowUploadDialog(false);
            if (fileInputRef.current) fileInputRef.current.value = '';
        } catch (error) {
            // Error handled in hook
        }
    };

    const handleDownload = async (filePath: string, fileName: string) => {
        try {
            const url = await getDownloadUrl(filePath);
            const link = document.createElement('a');
            link.href = url;
            link.download = fileName;
            link.target = '_blank';
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);
        } catch (error) {
            toast.error('Failed to download file');
        }
    };

    const handleDelete = async (attachmentId: string) => {
        try {
            await deleteAttachment(attachmentId);
            toast.success('File deleted');
        } catch (error) {
            // Error handled in hook
        }
    };

    if (isLoading) {
        return (
            <div className="flex flex-col items-center justify-center h-64 space-y-3">
                <Loader2 className="h-8 w-8 animate-spin text-primary/50" />
                <p className="text-sm text-muted-foreground">Loading documents...</p>
            </div>
        );
    }

    return (
        <div className="flex flex-col h-full space-y-4">
            {/* Header Toolbar */}
            <div className="flex flex-col sm:flex-row items-start sm:items-center justify-between gap-4">
                <div className="flex items-center gap-2">
                    <h3 className="text-lg font-semibold text-foreground flex items-center gap-2">
                        Attachments
                        <Badge variant="secondary" className="font-normal text-xs">{attachments.length}</Badge>
                    </h3>
                </div>

                <div className="flex items-center gap-2 w-full sm:w-auto">
                    <div className="relative flex-1 sm:w-48">
                        <Search className="absolute left-2 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-muted-foreground" />
                        <Input
                            placeholder="Search files..."
                            value={searchQuery}
                            onChange={(e) => setSearchQuery(e.target.value)}
                            className="h-8 pl-8 text-xs bg-muted/30 border-transparent focus:bg-background focus:border-border transition-all"
                        />
                    </div>

                    <div className="flex items-center bg-muted/50 rounded-lg p-0.5 border">
                        <Button
                            variant={viewMode === 'list' ? 'secondary' : 'ghost'}
                            size="icon"
                            className="h-7 w-7"
                            onClick={() => setViewMode('list')}
                            title="List View"
                        >
                            <ListIcon className="h-3.5 w-3.5" />
                        </Button>
                        <Button
                            variant={viewMode === 'grid' ? 'secondary' : 'ghost'}
                            size="icon"
                            className="h-7 w-7"
                            onClick={() => setViewMode('grid')}
                            title="Grid View"
                        >
                            <LayoutGrid className="h-3.5 w-3.5" />
                        </Button>
                    </div>

                    <Button
                        size="sm"
                        className="gap-2 h-8"
                        onClick={() => fileInputRef.current?.click()}
                        disabled={isUploading}
                    >
                        {isUploading ? <Loader2 className="h-3.5 w-3.5 animate-spin" /> : <Upload className="h-3.5 w-3.5" />}
                        <span className="hidden sm:inline">Upload</span>
                    </Button>
                    <input
                        ref={fileInputRef}
                        type="file"
                        className="hidden"
                        onChange={handleFileSelect}
                    />
                </div>
            </div>

            {/* Main Content: Tabs & Drop Zone */}
            <div
                className={cn(
                    "flex-1 flex flex-col min-h-0 relative transition-all rounded-xl border-2 border-transparent",
                    isDragging && "border-primary border-dashed bg-primary/5"
                )}
                onDragOver={(e) => { e.preventDefault(); setIsDragging(true); }}
                onDragLeave={() => setIsDragging(false)}
                onDrop={handleDrop}
            >
                {isDragging && (
                    <div className="absolute inset-0 z-50 flex items-center justify-center backdrop-blur-[1px]">
                        <div className="bg-background/90 p-6 rounded-lg shadow-lg border-2 border-primary border-dashed text-center animate-in zoom-in-95 duration-200">
                            <CloudUpload className="h-10 w-10 text-primary mx-auto mb-2" />
                            <p className="font-semibold text-lg">Drop file to upload</p>
                        </div>
                    </div>
                )}

                <Tabs value={activeTab} onValueChange={setActiveTab} className="flex-1 flex flex-col">
                    <div className="px-1 mb-4">
                        <ScrollArea orientation="horizontal" className="pb-2 -mb-2">
                            <TabsList className="h-8 bg-transparent p-0 gap-1">
                                <TabsTrigger value="all" className="h-7 px-3 text-xs data-[state=active]:bg-primary/10 data-[state=active]:text-primary border border-transparent data-[state=active]:border-primary/20 rounded-md">
                                    All Files
                                </TabsTrigger>
                                {ATTACHMENT_CATEGORIES.map(cat => (
                                    <TabsTrigger key={cat} value={cat} className="capitalize h-7 px-3 text-xs data-[state=active]:bg-primary/10 data-[state=active]:text-primary border border-transparent data-[state=active]:border-primary/20 rounded-md">
                                        {cat}
                                    </TabsTrigger>
                                ))}
                            </TabsList>
                        </ScrollArea>
                    </div>

                    <div className="flex-1 min-h-0 bg-muted/10 rounded-lg border border-dashed">
                        <ScrollArea className="h-full">
                            <div className="p-4">
                                {filteredAttachments.length === 0 ? (
                                    <div className="flex flex-col items-center justify-center py-12 text-center">
                                        <div className="h-12 w-12 rounded-full bg-muted flex items-center justify-center mb-3">
                                            <FolderOpen className="h-6 w-6 text-muted-foreground/50" />
                                        </div>
                                        <h3 className="font-medium text-sm">
                                            {searchQuery ? 'No matching files found' : 'No documents yet'}
                                        </h3>
                                        <p className="text-xs text-muted-foreground mt-1 max-w-[250px] mb-4">
                                            {searchQuery
                                                ? 'Try adjusting your search terms'
                                                : 'Drag and drop files here or click Upload to get started.'}
                                        </p>
                                        {!searchQuery && (
                                            <Button variant="outline" size="sm" onClick={() => fileInputRef.current?.click()}>
                                                Select File
                                            </Button>
                                        )}
                                    </div>
                                ) : (
                                    <div className={cn(
                                        "grid gap-3",
                                        viewMode === 'grid' ? "grid-cols-2 sm:grid-cols-3 md:grid-cols-4" : "grid-cols-1"
                                    )}>
                                        {filteredAttachments.map((file) => {
                                            const FileIcon = getFileIcon(file.mime_type);
                                            const catStyle = CATEGORY_COLORS[file.category] || CATEGORY_COLORS.other;
                                            const isImage = file.mime_type.startsWith('image/');

                                            if (viewMode === 'grid') {
                                                return (
                                                    <Card
                                                        key={file.id}
                                                        className="group relative overflow-hidden transition-all hover:shadow-md border-muted hover:border-border"
                                                    >
                                                        {/* Thumbnail / Icon Area */}
                                                        <div className="aspect-[4/3] bg-muted/30 border-b relative overflow-hidden">
                                                            {isImage ? (
                                                                <AttachmentThumbnail
                                                                    path={file.file_path}
                                                                    alt={file.file_name}
                                                                    getDownloadUrl={getDownloadUrl}
                                                                    fallbackIcon={ImageIcon}
                                                                />
                                                            ) : (
                                                                <div className="absolute inset-0 flex items-center justify-center bg-slate-50 dark:bg-slate-900/50">
                                                                    <FileIcon className="h-12 w-12 text-slate-300 dark:text-slate-600" />
                                                                </div>
                                                            )}

                                                            {/* Hover Actions Overlay */}
                                                            <div className="absolute inset-0 bg-black/50 opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center gap-2 backdrop-blur-[1px]">
                                                                <Button
                                                                    size="icon"
                                                                    variant="secondary"
                                                                    className="h-8 w-8 rounded-full shadow-lg"
                                                                    onClick={() => handleDownload(file.file_path, file.file_name)}
                                                                    title="Download"
                                                                >
                                                                    <Download className="h-4 w-4" />
                                                                </Button>
                                                                <Button
                                                                    size="icon"
                                                                    variant="destructive"
                                                                    className="h-8 w-8 rounded-full shadow-lg"
                                                                    onClick={() => handleDelete(file.id)}
                                                                    title="Delete"
                                                                >
                                                                    <Trash2 className="h-4 w-4" />
                                                                </Button>
                                                            </div>
                                                        </div>

                                                        {/* Info Footer */}
                                                        <div className="p-2.5">
                                                            <p className="font-medium text-xs truncate mb-1.5" title={file.file_name}>
                                                                {file.file_name}
                                                            </p>
                                                            <div className="flex items-center justify-between">
                                                                <Badge variant="outline" className={cn("px-1.5 py-0 text-[10px] h-4 font-normal border-0 uppercase tracking-wide", catStyle)}>
                                                                    {file.category}
                                                                </Badge>
                                                                <span className="text-[10px] text-muted-foreground">
                                                                    {formatFileSize(file.file_size)}
                                                                </span>
                                                            </div>
                                                        </div>
                                                    </Card>
                                                );
                                            }

                                            // List View
                                            return (
                                                <Card
                                                    key={file.id}
                                                    className="group bg-card hover:bg-muted/30 transition-all border-transparent hover:border-border shadow-sm hover:shadow-none"
                                                >
                                                    <div className="p-3 flex items-center gap-3">
                                                        <div className="h-10 w-10 rounded-lg bg-muted flex items-center justify-center shrink-0 overflow-hidden relative">
                                                            {isImage ? (
                                                                <AttachmentThumbnail
                                                                    path={file.file_path}
                                                                    alt={file.file_name}
                                                                    getDownloadUrl={getDownloadUrl}
                                                                    fallbackIcon={ImageIcon}
                                                                />
                                                            ) : (
                                                                <FileIcon className="h-5 w-5 text-muted-foreground" />
                                                            )}
                                                        </div>

                                                        <div className="flex-1 min-w-0 grid gap-0.5">
                                                            <div className="flex items-center gap-2">
                                                                <p className="font-medium text-sm truncate max-w-[200px] sm:max-w-md">{file.file_name}</p>
                                                                <Badge variant="outline" className={cn("px-1.5 py-0 text-[10px] h-4 font-normal border-0 capitalize", catStyle)}>
                                                                    {file.category}
                                                                </Badge>
                                                            </div>
                                                            <div className="flex items-center gap-2 text-xs text-muted-foreground">
                                                                <span>{formatFileSize(file.file_size)}</span>
                                                                <span>•</span>
                                                                <span>{format(new Date(file.created_at), 'MMM d, yyyy')}</span>
                                                            </div>
                                                        </div>

                                                        <div className="flex items-center gap-1 opacity-0 group-hover:opacity-100 transition-opacity">
                                                            <Button
                                                                variant="ghost"
                                                                size="icon"
                                                                className="h-8 w-8 text-muted-foreground hover:text-foreground"
                                                                onClick={() => handleDownload(file.file_path, file.file_name)}
                                                            >
                                                                <Download className="h-4 w-4" />
                                                            </Button>
                                                            <Button
                                                                variant="ghost"
                                                                size="icon"
                                                                className="h-8 w-8 text-muted-foreground hover:text-destructive"
                                                                onClick={() => handleDelete(file.id)}
                                                                disabled={isDeleting}
                                                            >
                                                                <Trash2 className="h-4 w-4" />
                                                            </Button>
                                                        </div>
                                                    </div>
                                                </Card>
                                            );
                                        })}
                                    </div>
                                )}
                            </div>
                        </ScrollArea>
                    </div>
                </Tabs>
            </div>

            {/* Upload Dialog */}
            <Dialog open={showUploadDialog} onOpenChange={setShowUploadDialog}>
                <DialogContent className="sm:max-w-md">
                    <DialogHeader>
                        <DialogTitle>Finalize Upload</DialogTitle>
                        <DialogDescription>Categorize your file to keep things organized.</DialogDescription>
                    </DialogHeader>

                    <div className="space-y-4 py-2">
                        <div className="flex items-center gap-3 p-3 rounded-lg border bg-muted/40">
                            <div className="h-10 w-10 rounded-lg bg-background border flex items-center justify-center shadow-sm">
                                <File className="h-5 w-5 text-primary" />
                            </div>
                            <div className="flex-1 min-w-0">
                                <p className="font-medium text-sm truncate">{selectedFile?.name}</p>
                                <p className="text-xs text-muted-foreground">
                                    {selectedFile && formatFileSize(selectedFile.size)}
                                </p>
                            </div>
                            <Button variant="ghost" size="icon" className="h-6 w-6" onClick={() => setShowUploadDialog(false)}>
                                <X className="h-4 w-4" />
                            </Button>
                        </div>

                        <div className="space-y-2">
                            <Label>Category</Label>
                            <Select
                                value={selectedCategory}
                                onValueChange={(v) => setSelectedCategory(v as AttachmentCategory)}
                            >
                                <SelectTrigger>
                                    <SelectValue />
                                </SelectTrigger>
                                <SelectContent>
                                    {ATTACHMENT_CATEGORIES.map((category) => (
                                        <SelectItem key={category} value={category} className="capitalize">
                                            {category}
                                        </SelectItem>
                                    ))}
                                </SelectContent>
                            </Select>
                        </div>
                    </div>

                    <DialogFooter className="gap-2 sm:gap-0">
                        <Button variant="ghost" onClick={() => setShowUploadDialog(false)}>
                            Cancel
                        </Button>
                        <Button onClick={handleUpload} disabled={isUploading}>
                            {isUploading ? (
                                <>
                                    <Loader2 className="h-4 w-4 mr-2 animate-spin" />
                                    Uploading...
                                </>
                            ) : (
                                <>
                                    <CloudUpload className="h-4 w-4 mr-2" />
                                    Upload File
                                </>
                            )}
                        </Button>
                    </DialogFooter>
                </DialogContent>
            </Dialog>
        </div>
    );
}