'use client';

import { useState, useMemo, useEffect } from 'react';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Badge } from '@/components/ui/badge';
import { type ModelInfo, apiClient } from '@/lib/api';
import {
  Search,
  RefreshCw,
  Download,
  Trash2,
  CheckCircle2,
  XCircle,
  Loader2,
  HardDrive,
  FileText,
  Zap,
  Copy,
  MoreHorizontal,
  Eye,
  EyeOff,
  Filter,
  Grid3X3,
  List,
  ChevronLeft,
  ChevronRight,
  Image,
  Star,
  Calendar,
  Folder,
  Info,
  TrendingUp
} from 'lucide-react';
import { cn } from '@/lib/utils';

interface ModelListProps {
  models: ModelInfo[];
  loading: boolean;
  onRefresh: () => void;
  onLoadModel: (modelId: string) => void;
  onUnloadModel: (modelId: string) => void;
  onConvertModel?: (modelName: string, quantizationType: string) => void;
  actionLoading: string | null;
  statistics?: any;
  searchTerm?: string;
  onSearchChange?: (term: string) => void;
  onLoadPage?: (page: number) => void;
  pagination?: any;
}

type ViewMode = 'grid' | 'list';

export function ModelList({
  models,
  loading,
  onRefresh,
  onLoadModel,
  onUnloadModel,
  onConvertModel,
  actionLoading,
  statistics,
  searchTerm: externalSearchTerm = '',
  onSearchChange,
  onLoadPage
}: ModelListProps) {
  const [internalSearchTerm, setInternalSearchTerm] = useState('');
  const [selectedType, setSelectedType] = useState<string>('all');
  const [showFullPaths, setShowFullPaths] = useState(false);
  const [viewMode, setViewMode] = useState<ViewMode>('grid');
  const [availableTypes, setAvailableTypes] = useState<Array<{ type: string; description: string }>>([]);
  const [convertingModel, setConvertingModel] = useState<string | null>(null);
  const [selectedQuantization, setSelectedQuantization] = useState<string>('q4_0');

  // Use external search term if provided, otherwise use internal state
  const currentSearchTerm = externalSearchTerm || internalSearchTerm;
  const setSearchTerm = onSearchChange || setInternalSearchTerm;

  // Fetch available model types from API
  useEffect(() => {
    const fetchModelTypes = async () => {
      try {
        const types = await apiClient.getModelTypes();
        setAvailableTypes(types);
      } catch (error) {
        console.error('Failed to fetch model types:', error);
      }
    };
    fetchModelTypes();
  }, []);

  // Calculate model type statistics
  const modelStats = useMemo(() => {
    const stats = models.reduce((acc, model) => {
      const type = model.type || 'unknown';
      acc[type] = (acc[type] || 0) + 1;
      return acc;
    }, {} as Record<string, number>);

    // Combine available types from API with actual model counts
    const typesWithCounts = availableTypes.map(typeInfo => ({
      type: typeInfo.type,
      count: stats[typeInfo.type] || 0,
      description: typeInfo.description
    }));

    // Add any types that exist in models but not in the API response
    Object.keys(stats).forEach(type => {
      if (!availableTypes.find(t => t.type === type)) {
        typesWithCounts.push({
          type,
          count: stats[type],
          description: ''
        });
      }
    });

    return {
      total: models.length,
      loaded: models.filter(m => m.loaded).length,
      types: typesWithCounts.sort((a, b) => a.type.localeCompare(b.type))
    };
  }, [models, availableTypes]);


  // Filter models
  const filteredModels = useMemo(() => {
    return models.filter(model => {
      const matchesSearch = model.name.toLowerCase().includes(currentSearchTerm.toLowerCase()) ||
                           (model.sha256_short && model.sha256_short.toLowerCase().includes(currentSearchTerm.toLowerCase()));
      const matchesType = selectedType === 'all' || model.type === selectedType;
      return matchesSearch && matchesType;
    });
  }, [models, currentSearchTerm, selectedType]);

  // Get display name (compact vs full path)
  const getDisplayName = (model: ModelInfo) => {
    if (showFullPaths && model.path) {
      return model.path;
    }
    return model.name;
  };

  // Check if model type can be loaded
  const canLoadModel = (modelType: string): boolean => {
    const loadableTypes = ['checkpoint', 'upscaler'];
    return loadableTypes.includes(modelType.toLowerCase());
  };

  // Get model type icon
  const getTypeIcon = (type: string) => {
    switch (type.toLowerCase()) {
      case 'stable-diffusion':
      case 'sd':
        return <Image className="h-4 w-4" />;
      case 'vae':
        return <Zap className="h-4 w-4" />;
      case 'textual-inversion':
      case 'embedding':
        return <FileText className="h-4 w-4" />;
      default:
        return <HardDrive className="h-4 w-4" />;
    }
  };

  // Format file size
  const formatFileSize = (size?: number) => {
    if (!size) return 'Unknown';
    if (size < 1024 * 1024) return `${(size / 1024).toFixed(1)} KB`;
    return `${(size / (1024 * 1024)).toFixed(1)} MB`;
  };

  // Format date
  const formatDate = (dateString?: string) => {
    if (!dateString) return 'Unknown';
    try {
      return new Date(dateString).toLocaleDateString();
    } catch {
      return 'Unknown';
    }
  };

  // Get model type badge with appropriate color
  const getModelTypeBadge = (type: string) => {
    const typeLower = type.toLowerCase();
    if (typeLower.includes('checkpoint') || typeLower.includes('stable-diffusion')) {
      return (
        <Badge variant="secondary" className="text-xs bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200">
          <Image className="h-3 w-3 mr-1" />
          Checkpoint
        </Badge>
      );
    }
    if (typeLower.includes('vae')) {
      return (
        <Badge variant="secondary" className="text-xs bg-purple-100 text-purple-800 dark:bg-purple-900 dark:text-purple-200">
          <Zap className="h-3 w-3 mr-1" />
          VAE
        </Badge>
      );
    }
    if (typeLower.includes('lora')) {
      return (
        <Badge variant="secondary" className="text-xs bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200">
          <Star className="h-3 w-3 mr-1" />
          LoRA
        </Badge>
      );
    }
    if (typeLower.includes('embedding') || typeLower.includes('textual')) {
      return (
        <Badge variant="secondary" className="text-xs bg-orange-100 text-orange-800 dark:bg-orange-900 dark:text-orange-200">
          <FileText className="h-3 w-3 mr-1" />
          Embedding
        </Badge>
      );
    }
    if (typeLower.includes('esrgan') || typeLower.includes('upscaler')) {
      return (
        <Badge variant="secondary" className="text-xs bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200">
          <TrendingUp className="h-3 w-3 mr-1" />
          Upscaler
        </Badge>
      );
    }
    return (
      <Badge variant="secondary" className="text-xs">
        <HardDrive className="h-3 w-3 mr-1" />
        {type}
      </Badge>
    );
  };

  return (
    <div className="space-y-6">
      {/* Controls */}
      <Card>
        <CardHeader>
          <div className="flex items-center justify-between">
            <div>
              <CardTitle>Model Management</CardTitle>
              <CardDescription>
                {modelStats.total} models total • {modelStats.loaded} loaded
              </CardDescription>
            </div>
            <div className="flex gap-2">
              <Button
                variant={viewMode === 'grid' ? 'default' : 'outline'}
                size="sm"
                onClick={() => setViewMode('grid')}
              >
                <Grid3X3 className="h-4 w-4" />
              </Button>
              <Button
                variant={viewMode === 'list' ? 'default' : 'outline'}
                size="sm"
                onClick={() => setViewMode('list')}
              >
                <List className="h-4 w-4" />
              </Button>
              <Button onClick={onRefresh} disabled={loading}>
                <RefreshCw className={`h-4 w-4 mr-2 ${loading ? 'animate-spin' : ''}`} />
                Refresh
              </Button>
            </div>
          </div>
        </CardHeader>
        <CardContent className="space-y-4">
          <div className="flex gap-4">
            <div className="flex-1">
              <Label htmlFor="search">Search Models</Label>
              <div className="relative">
                <Search className="absolute left-3 top-3 h-4 w-4 text-muted-foreground" />
                <Input
                  id="search"
                  placeholder="Search by name or hash..."
                  value={currentSearchTerm}
                  onChange={(e) => setSearchTerm(e.target.value)}
                  className="pl-10"
                />
              </div>
            </div>
            <div className="flex items-end gap-2">
              <Button
                variant="outline"
                size="sm"
                onClick={() => setShowFullPaths(!showFullPaths)}
              >
                {showFullPaths ? <EyeOff className="h-4 w-4 mr-2" /> : <Eye className="h-4 w-4 mr-2" />}
                {showFullPaths ? 'Hide Paths' : 'Show Paths'}
              </Button>
            </div>
          </div>

          {/* Model Type Counters */}
          <div className="space-y-2">
            <div className="flex items-center gap-2">
              <Filter className="h-4 w-4" />
              <span className="text-sm font-medium">Filter by type:</span>
            </div>
            <div className="flex gap-2 flex-wrap">
              <Button
                variant={selectedType === 'all' ? 'default' : 'outline'}
                size="sm"
                onClick={() => setSelectedType('all')}
              >
                All ({modelStats.total})
              </Button>
              {modelStats.types.map((typeInfo) => (
                <Button
                  key={typeInfo.type}
                  variant={selectedType === typeInfo.type ? 'default' : 'outline'}
                  size="sm"
                  onClick={() => setSelectedType(typeInfo.type)}
                  className="flex items-center gap-2"
                  title={typeInfo.description}
                >
                  {getTypeIcon(typeInfo.type)}
                  {typeInfo.type} ({typeInfo.count})
                </Button>
              ))}
            </div>
          </div>
        </CardContent>
      </Card>

      {/* Models Grid/List */}
      {viewMode === 'grid' ? (
        <div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
          {filteredModels.map(model => (
            <Card key={model.id || model.name} className={cn(
              'transition-all hover:shadow-md relative',
              model.loaded ? 'border-green-500 bg-green-50/50 dark:bg-green-950/20' : ''
            )}>
              <CardContent className="p-4">
                <div className="space-y-3">
                  <div className="flex items-start justify-between">
                    <div className="flex items-center gap-2">
                      {model.loaded ? (
                        <CheckCircle2 className="h-4 w-4 text-green-500" />
                      ) : (
                        <XCircle className="h-4 w-4 text-muted-foreground" />
                      )}
                      <div className="flex items-center gap-1">
                        {getTypeIcon(model.type)}
                        <span className="text-xs text-muted-foreground">{model.type}</span>
                      </div>
                    </div>
                  </div>

                  <div className="space-y-2">
                    <div className="flex items-start justify-between gap-2">
                      <h3 className="font-semibold text-sm truncate" title={getDisplayName(model)}>
                        {getDisplayName(model)}
                      </h3>
                      {getModelTypeBadge(model.type)}
                    </div>
                    
                    {/* Enhanced model information */}
                    <div className="space-y-1 text-xs text-muted-foreground">
                      <div className="flex items-center gap-2">
                        <HardDrive className="h-3 w-3" />
                        <span>{formatFileSize(model.size || model.file_size)}</span>
                      </div>
                      
                      {model.path && (
                        <div className="flex items-center gap-2">
                          <Folder className="h-3 w-3" />
                          <span className="truncate" title={model.path}>
                            {showFullPaths ? model.path : model.path.split('/').pop()}
                          </span>
                        </div>
                      )}
                      
                      {model.sha256_short && (
                        <div className="flex items-center gap-1">
                          <span className="font-mono">{model.sha256_short}</span>
                          <Button
                            variant="ghost"
                            size="sm"
                            className="h-4 w-4 p-0"
                            onClick={() => navigator.clipboard.writeText(model.sha256_short!)}
                          >
                            <Copy className="h-3 w-3" />
                          </Button>
                        </div>
                      )}
                      
                    </div>
                  </div>

                  <div className="flex gap-2 pt-2">
                    {model.loaded ? (
                      <Button
                        variant="outline"
                        size="sm"
                        className="flex-1"
                        onClick={() => onUnloadModel(model.id || model.name)}
                        disabled={actionLoading === model.id}
                      >
                        {actionLoading === model.id ? (
                          <Loader2 className="h-3 w-3 animate-spin" />
                        ) : (
                          <Trash2 className="h-3 w-3" />
                        )}
                        Unload
                      </Button>
                    ) : (
                      <>
                        {canLoadModel(model.type) ? (
                          <Button
                            variant="default"
                            size="sm"
                            className="flex-1"
                            onClick={() => onLoadModel(model.id || model.name)}
                            disabled={actionLoading === model.id}
                          >
                            {actionLoading === model.id ? (
                              <Loader2 className="h-3 w-3 animate-spin" />
                            ) : (
                              <Download className="h-3 w-3" />
                            )}
                            Load
                          </Button>
                        ) : (
                          <Button
                            variant="outline"
                            size="sm"
                            className="flex-1"
                            disabled={true}
                            title={`Cannot load ${model.type} models`}
                          >
                            <Download className="h-3 w-3" />
                            Load
                          </Button>
                        )}
                      </>
                    )}
                    {onConvertModel && (
                      convertingModel === model.name ? (
                        <div className="flex gap-2 items-center flex-1">
                          <select
                            value={selectedQuantization}
                            onChange={(e) => setSelectedQuantization(e.target.value)}
                            className="flex-1 h-8 rounded-md border border-input bg-background px-2 text-sm"
                          >
                            <option value="f32">F32 (Full precision)</option>
                            <option value="f16">F16 (Half precision)</option>
                            <option value="q8_0">Q8_0 (8-bit)</option>
                            <option value="q5_1">Q5_1 (5-bit)</option>
                            <option value="q5_0">Q5_0 (5-bit)</option>
                            <option value="q4_1">Q4_1 (4-bit)</option>
                            <option value="q4_0">Q4_0 (4-bit)</option>
                            <option value="q4_K">Q4_K (4-bit K-quant)</option>
                            <option value="q3_K">Q3_K (3-bit K-quant)</option>
                            <option value="q2_K">Q2_K (2-bit K-quant)</option>
                          </select>
                          <Button
                            variant="default"
                            size="sm"
                            onClick={() => {
                              onConvertModel(model.name, selectedQuantization);
                              setConvertingModel(null);
                            }}
                            disabled={actionLoading === model.id}
                          >
                            <CheckCircle2 className="h-3 w-3" />
                          </Button>
                          <Button
                            variant="outline"
                            size="sm"
                            onClick={() => setConvertingModel(null)}
                          >
                            <XCircle className="h-3 w-3" />
                          </Button>
                        </div>
                      ) : (
                        <Button
                          variant="outline"
                          size="sm"
                          onClick={() => setConvertingModel(model.name)}
                          disabled={actionLoading === model.id}
                        >
                          <Zap className="h-3 w-3" />
                          Convert
                        </Button>
                      )
                    )}
                  </div>
                </div>
              </CardContent>
            </Card>
          ))}
        </div>
      ) : (
        <div className="space-y-2">
          {filteredModels.map(model => (
            <Card key={model.id || model.name} className={cn(
              'transition-all hover:shadow-md relative',
              model.loaded ? 'border-green-500 bg-green-50/50 dark:bg-green-950/20' : ''
            )}>
              <CardContent className="p-4">
                <div className="flex items-center justify-between">
                  <div className="flex items-center gap-4">
                    <div className="flex items-center gap-2">
                      {model.loaded ? (
                        <CheckCircle2 className="h-5 w-5 text-green-500" />
                      ) : (
                        <XCircle className="h-5 w-5 text-muted-foreground" />
                      )}
                      <div className="flex items-center gap-2">
                        {getTypeIcon(model.type)}
                        <div className="flex-1">
                          <div className="flex items-center gap-2 mb-2">
                            <h3 className="font-semibold">{getDisplayName(model)}</h3>
                            {getModelTypeBadge(model.type)}
                          </div>
                          <div className="space-y-1 text-sm text-muted-foreground">
                            <div className="flex items-center gap-4">
                              <span className="flex items-center gap-1">
                                <HardDrive className="h-3 w-3" />
                                {formatFileSize(model.size || model.file_size)}
                              </span>
                              {model.path && (
                                <span className="flex items-center gap-1">
                                  <Folder className="h-3 w-3" />
                                  {showFullPaths ? model.path : model.path.split('/').pop()}
                                </span>
                              )}
                            </div>
                            {model.sha256_short && (
                              <div className="flex items-center gap-2">
                                <span className="font-mono">{model.sha256_short}</span>
                                <Button
                                  variant="ghost"
                                  size="sm"
                                  className="h-4 w-4 p-0"
                                  onClick={() => navigator.clipboard.writeText(model.sha256_short!)}
                                >
                                  <Copy className="h-4 w-4" />
                                </Button>
                              </div>
                            )}
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                  <div className="flex gap-2">
                    {model.sha256_short && (
                      <Button
                        variant="ghost"
                        size="sm"
                        onClick={() => navigator.clipboard.writeText(model.sha256_short!)}
                      >
                        <Copy className="h-4 w-4" />
                      </Button>
                    )}
                    {model.loaded ? (
                      <Button
                        variant="outline"
                        size="sm"
                        onClick={() => onUnloadModel(model.id || model.name)}
                        disabled={actionLoading === model.id}
                      >
                        {actionLoading === model.id ? (
                          <Loader2 className="h-4 w-4 animate-spin" />
                        ) : (
                          <Trash2 className="h-4 w-4" />
                        )}
                        Unload
                      </Button>
                    ) : (
                      <>
                        {canLoadModel(model.type) ? (
                          <Button
                            variant="default"
                            size="sm"
                            onClick={() => onLoadModel(model.id || model.name)}
                            disabled={actionLoading === model.id}
                          >
                            {actionLoading === model.id ? (
                              <Loader2 className="h-4 w-4 animate-spin" />
                            ) : (
                              <Download className="h-4 w-4" />
                            )}
                            Load
                          </Button>
                        ) : (
                          <Button
                            variant="outline"
                            size="sm"
                            disabled={true}
                            title={`Cannot load ${model.type} models`}
                          >
                            <Download className="h-4 w-4" />
                            Load
                          </Button>
                        )}
                      </>
                    )}
                    {onConvertModel && (
                      <Button
                        variant="outline"
                        size="sm"
                        onClick={() => onConvertModel(model.name, 'q4_0')}
                        disabled={actionLoading === model.id}
                      >
                        <Zap className="h-4 w-4" />
                        Convert
                      </Button>
                    )}
                  </div>
                </div>
              </CardContent>
            </Card>
          ))}
        </div>
      )}

      {filteredModels.length === 0 && (
        <Card>
          <CardContent className="text-center py-12">
            <p className="text-muted-foreground">No models found matching your criteria.</p>
          </CardContent>
        </Card>
      )}
    </div>
  );
}
