/**
 * DataSourceSelector - Full-featured dynamic data source picker
 * Fetches ALL available sources from backend with search/filter
 */

import { useState, useEffect, useMemo } from 'react';
import {
  Check, Database, RefreshCw, Plus, Search, X,
  Wifi, Globe, Cpu, Activity, Zap, Server, Brain, HardDrive
} from 'lucide-react';
import { Button } from '@/components/ui/button';
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Badge } from '@/components/ui/badge';
import { ScrollArea } from '@/components/ui/scroll-area';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { cn } from '@/lib/utils';
import { API_URL } from '@/config/api';

export interface DataSourceConfig {
  id: string;
  name: string;
  description: string;
  endpoint: string;
  type: 'rest' | 'websocket' | 'mcp' | 'graphql';
  category: 'system' | 'data' | 'ai' | 'external' | 'realtime' | 'custom';
  refreshInterval?: number;
  tags: string[];
  active: boolean;
}

interface DataSourcesResponse {
  total: number;
  categories: string[];
  types: string[];
  sources: DataSourceConfig[];
}

// Category icons
const categoryIcons: Record<string, typeof Database> = {
  system: Server,
  data: HardDrive,
  ai: Brain,
  external: Globe,
  realtime: Zap,
  custom: Cpu
};

// Type colors
const typeColors: Record<string, string> = {
  rest: 'bg-green-500/20 text-green-400 border-green-500/30',
  websocket: 'bg-blue-500/20 text-blue-400 border-blue-500/30',
  mcp: 'bg-purple-500/20 text-purple-400 border-purple-500/30',
  graphql: 'bg-pink-500/20 text-pink-400 border-pink-500/30'
};

interface DataSourceSelectorProps {
  /** Currently selected data source */
  selectedSource?: DataSourceConfig;
  /** Called when a new source is selected */
  onSourceChange: (source: DataSourceConfig) => void;
  /** Show as dialog (default) or inline */
  inline?: boolean;
  /** Dialog open state (controlled) */
  open?: boolean;
  /** Dialog close callback */
  onOpenChange?: (open: boolean) => void;
  className?: string;
}

export function DataSourceSelector({
  selectedSource,
  onSourceChange,
  inline = false,
  open,
  onOpenChange,
  className
}: DataSourceSelectorProps) {
  const [sources, setSources] = useState<DataSourceConfig[]>([]);
  const [categories, setCategories] = useState<string[]>([]);
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [searchQuery, setSearchQuery] = useState('');
  const [selectedCategory, setSelectedCategory] = useState<string>('all');
  const [testingSource, setTestingSource] = useState<string | null>(null);

  // Fetch sources from backend
  const fetchSources = async () => {
    setIsLoading(true);
    setError(null);
    try {
      const response = await fetch(`${API_URL}/api/datasources`);
      if (!response.ok) throw new Error('Failed to fetch data sources');
      const data: DataSourcesResponse = await response.json();
      setSources(data.sources);
      setCategories(['all', ...data.categories]);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Unknown error');
      // Fallback to empty
      setSources([]);
    } finally {
      setIsLoading(false);
    }
  };

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

  // Filter sources based on search and category
  const filteredSources = useMemo(() => {
    return sources.filter(source => {
      // Category filter
      if (selectedCategory !== 'all' && source.category !== selectedCategory) {
        return false;
      }
      // Search filter
      if (searchQuery) {
        const query = searchQuery.toLowerCase();
        return (
          source.name.toLowerCase().includes(query) ||
          source.description.toLowerCase().includes(query) ||
          source.endpoint.toLowerCase().includes(query) ||
          source.tags.some(t => t.toLowerCase().includes(query))
        );
      }
      return true;
    });
  }, [sources, searchQuery, selectedCategory]);

  // Group by category for display
  const groupedSources = useMemo(() => {
    const groups: Record<string, DataSourceConfig[]> = {};
    filteredSources.forEach(source => {
      if (!groups[source.category]) {
        groups[source.category] = [];
      }
      groups[source.category].push(source);
    });
    return groups;
  }, [filteredSources]);

  // Test connection
  const testConnection = async (sourceId: string) => {
    setTestingSource(sourceId);
    try {
      await fetch(`${API_URL}/api/datasources/${sourceId}/test`, { method: 'POST' });
    } catch {
      // Silent fail
    } finally {
      setTestingSource(null);
    }
  };

  const handleSelect = (source: DataSourceConfig) => {
    onSourceChange(source);
    onOpenChange?.(false);
  };

  const content = (
    <div className={cn("space-y-4", className)}>
      {/* Search Bar */}
      <div className="relative">
        <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
        <Input
          placeholder="Søg i datakilder..."
          value={searchQuery}
          onChange={(e) => setSearchQuery(e.target.value)}
          className="pl-10 pr-10"
        />
        {searchQuery && (
          <button
            onClick={() => setSearchQuery('')}
            className="absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground"
          >
            <X className="h-4 w-4" />
          </button>
        )}
      </div>

      {/* Category Tabs */}
      <Tabs value={selectedCategory} onValueChange={setSelectedCategory}>
        <TabsList className="w-full flex-wrap h-auto gap-1 p-1">
          {categories.map(cat => (
            <TabsTrigger
              key={cat}
              value={cat}
              className="text-xs capitalize"
            >
              {cat === 'all' ? 'Alle' : cat}
              <Badge variant="secondary" className="ml-1 h-4 px-1 text-[10px]">
                {cat === 'all'
                  ? sources.length
                  : sources.filter(s => s.category === cat).length}
              </Badge>
            </TabsTrigger>
          ))}
        </TabsList>
      </Tabs>

      {/* Loading State */}
      {isLoading && (
        <div className="flex items-center justify-center py-8">
          <RefreshCw className="h-6 w-6 animate-spin text-primary" />
          <span className="ml-2 text-muted-foreground">Henter datakilder...</span>
        </div>
      )}

      {/* Error State */}
      {error && (
        <div className="p-4 bg-destructive/10 border border-destructive/30 rounded-lg">
          <p className="text-sm text-destructive">{error}</p>
          <Button variant="outline" size="sm" onClick={fetchSources} className="mt-2">
            Prøv igen
          </Button>
        </div>
      )}

      {/* Sources List */}
      {!isLoading && !error && (
        <ScrollArea className="h-[400px] pr-4">
          <div className="space-y-6">
            {Object.entries(groupedSources).map(([category, categorySources]) => {
              const Icon = categoryIcons[category] || Database;
              return (
                <div key={category}>
                  {/* Category Header */}
                  <div className="flex items-center gap-2 mb-2 sticky top-0 bg-background py-1">
                    <Icon className="h-4 w-4 text-primary" />
                    <span className="text-xs font-mono uppercase tracking-wider text-muted-foreground">
                      {category}
                    </span>
                    <span className="text-xs text-muted-foreground">
                      ({categorySources.length})
                    </span>
                  </div>

                  {/* Sources Grid */}
                  <div className="grid gap-2">
                    {categorySources.map(source => {
                      const isSelected = selectedSource?.id === source.id;
                      const isTesting = testingSource === source.id;

                      return (
                        <div
                          key={source.id}
                          onClick={() => handleSelect(source)}
                          className={cn(
                            "p-3 rounded-lg border cursor-pointer transition-all",
                            "hover:border-primary/50 hover:bg-primary/5",
                            isSelected
                              ? "bg-primary/10 border-primary/50 ring-1 ring-primary/30"
                              : "bg-secondary/30 border-border/30"
                          )}
                        >
                          <div className="flex items-start justify-between gap-2">
                            <div className="flex-1 min-w-0">
                              <div className="flex items-center gap-2 flex-wrap">
                                <span className="font-medium text-sm truncate">
                                  {source.name}
                                </span>
                                <Badge
                                  variant="outline"
                                  className={cn("text-[10px] px-1.5 h-5", typeColors[source.type])}
                                >
                                  {source.type.toUpperCase()}
                                </Badge>
                                {isSelected && (
                                  <Check className="h-4 w-4 text-primary shrink-0" />
                                )}
                              </div>
                              <p className="text-xs text-muted-foreground mt-1 line-clamp-2">
                                {source.description}
                              </p>
                              <div className="flex items-center gap-2 mt-2">
                                <code className="text-[10px] text-muted-foreground bg-secondary/50 px-1.5 py-0.5 rounded">
                                  {source.endpoint}
                                </code>
                                {source.refreshInterval && (
                                  <span className="text-[10px] text-muted-foreground">
                                    {Math.round(source.refreshInterval / 1000)}s
                                  </span>
                                )}
                              </div>
                              {/* Tags */}
                              {source.tags.length > 0 && (
                                <div className="flex flex-wrap gap-1 mt-2">
                                  {source.tags.slice(0, 4).map(tag => (
                                    <span
                                      key={tag}
                                      className="text-[9px] px-1.5 py-0.5 bg-secondary rounded text-muted-foreground"
                                    >
                                      {tag}
                                    </span>
                                  ))}
                                  {source.tags.length > 4 && (
                                    <span className="text-[9px] text-muted-foreground">
                                      +{source.tags.length - 4}
                                    </span>
                                  )}
                                </div>
                              )}
                            </div>
                            <Button
                              variant="ghost"
                              size="icon"
                              className="h-7 w-7 shrink-0"
                              onClick={(e) => {
                                e.stopPropagation();
                                testConnection(source.id);
                              }}
                              disabled={isTesting}
                            >
                              <RefreshCw className={cn("h-3 w-3", isTesting && "animate-spin")} />
                            </Button>
                          </div>
                        </div>
                      );
                    })}
                  </div>
                </div>
              );
            })}

            {/* Empty State */}
            {filteredSources.length === 0 && (
              <div className="text-center py-8">
                <Database className="h-12 w-12 mx-auto text-muted-foreground/50 mb-2" />
                <p className="text-sm text-muted-foreground">
                  {searchQuery
                    ? `Ingen datakilder matcher "${searchQuery}"`
                    : 'Ingen datakilder fundet'}
                </p>
              </div>
            )}
          </div>
        </ScrollArea>
      )}

      {/* Footer Stats */}
      <div className="flex items-center justify-between text-xs text-muted-foreground border-t border-border/30 pt-3">
        <span>
          {filteredSources.length} af {sources.length} datakilder
        </span>
        <Button variant="ghost" size="sm" onClick={fetchSources} disabled={isLoading}>
          <RefreshCw className={cn("h-3 w-3 mr-1", isLoading && "animate-spin")} />
          Opdater
        </Button>
      </div>
    </div>
  );

  // Inline mode
  if (inline) {
    return content;
  }

  // Dialog mode
  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="max-w-2xl max-h-[90vh]">
        <DialogHeader>
          <DialogTitle className="flex items-center gap-2">
            <Database className="h-5 w-5 text-primary" />
            Vælg Datakilde
          </DialogTitle>
          <DialogDescription>
            Vælg en datakilde fra listen nedenfor. Datakilder opdateres automatisk.
          </DialogDescription>
        </DialogHeader>
        {content}
      </DialogContent>
    </Dialog>
  );
}

// Compact trigger button for CyberCard
export function DataSourceTrigger({
  selectedSource,
  onClick,
  className
}: {
  selectedSource?: DataSourceConfig;
  onClick: () => void;
  className?: string;
}) {
  return (
    <button
      onClick={onClick}
      className={cn(
        "flex items-center gap-1 text-xs text-muted-foreground hover:text-primary transition-colors",
        className
      )}
    >
      <Database className="h-3 w-3" />
      <span className="truncate max-w-[100px]">
        {selectedSource?.name || 'Vælg kilde'}
      </span>
    </button>
  );
}

export default DataSourceSelector;
