import { useState, useEffect, useCallback } from 'react';
import {
  Settings, Server, Cpu, Activity, MessageSquare,
  Send, RefreshCw, Check, X, Zap, Database,
  ChevronDown, ChevronUp, Loader2, AlertTriangle
} from 'lucide-react';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Badge } from '@/components/ui/badge';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { ScrollArea } from '@/components/ui/scroll-area';
import { cn } from '@/lib/utils';
import { useToast } from '@/hooks/use-toast';
import {
  SmartComponentRenderer,
  parseMessageForComponents,
  isUIComponentMessage,
  UIComponentMessage,
} from '@/components/smart-ui';

interface LocalAIModel {
  id: string;
  object: string;
  owned_by?: string;
}

interface ChatMessage {
  role: 'user' | 'assistant';
  content: string;
  uiComponents?: UIComponentMessage[];
}

interface LocalAIStatus {
  connected: boolean;
  status?: string;
  error?: string;
}

export default function LocalAIWidget() {
  const { toast } = useToast();
  const [endpoint, setEndpoint] = useState(() => 
    localStorage.getItem('localai-endpoint') || 'http://localhost:8080'
  );
  const [tempEndpoint, setTempEndpoint] = useState(endpoint);
  const [showSettings, setShowSettings] = useState(false);
  const [status, setStatus] = useState<LocalAIStatus>({ connected: false });
  const [models, setModels] = useState<LocalAIModel[]>([]);
  const [selectedModel, setSelectedModel] = useState<string>('');
  const [isLoading, setIsLoading] = useState(false);
  const [activeTab, setActiveTab] = useState('status');
  
  // Chat state
  const [messages, setMessages] = useState<ChatMessage[]>([]);
  const [inputMessage, setInputMessage] = useState('');
  const [isSending, setIsSending] = useState(false);

  // Check LocalAI status
  const checkStatus = useCallback(async () => {
    setIsLoading(true);
    try {
      // Try health endpoint first
      const healthResponse = await fetch(`${endpoint}/readyz`, {
        method: 'GET',
        signal: AbortSignal.timeout(5000),
      });
      
      if (healthResponse.ok) {
        setStatus({ connected: true, status: 'healthy' });
      } else {
        // Try alternative health check
        const altResponse = await fetch(`${endpoint}/v1/models`, {
          method: 'GET',
          signal: AbortSignal.timeout(5000),
        });
        
        if (altResponse.ok) {
          setStatus({ connected: true, status: 'healthy' });
        } else {
          setStatus({ connected: false, error: 'Server unhealthy' });
        }
      }
    } catch (error) {
      setStatus({ 
        connected: false, 
        error: error instanceof Error ? error.message : 'Connection failed' 
      });
    } finally {
      setIsLoading(false);
    }
  }, [endpoint]);

  // Fetch available models
  const fetchModels = useCallback(async () => {
    try {
      const response = await fetch(`${endpoint}/v1/models`, {
        method: 'GET',
        signal: AbortSignal.timeout(10000),
      });
      
      if (response.ok) {
        const data = await response.json();
        const modelList = data.data || [];
        setModels(modelList);
        if (modelList.length > 0 && !selectedModel) {
          setSelectedModel(modelList[0].id);
        }
      }
    } catch (error) {
      console.error('Failed to fetch models:', error);
    }
  }, [endpoint, selectedModel]);

  // Send chat message
  const sendMessage = async () => {
    if (!inputMessage.trim() || !selectedModel || isSending) return;

    const userMessage: ChatMessage = { role: 'user', content: inputMessage };
    setMessages(prev => [...prev, userMessage]);
    setInputMessage('');
    setIsSending(true);

    try {
      const response = await fetch(`${endpoint}/v1/chat/completions`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          model: selectedModel,
          messages: [...messages, userMessage].map(m => ({
            role: m.role,
            content: m.content
          })),
          max_tokens: 500,
        }),
        signal: AbortSignal.timeout(30000),
      });

      if (response.ok) {
        const data = await response.json();
        const assistantContent = data.choices?.[0]?.message?.content || 'No response';
        setMessages(prev => [...prev, { role: 'assistant', content: assistantContent }]);
      } else {
        throw new Error('Failed to get response');
      }
    } catch (error) {
      toast({
        title: "Error",
        description: error instanceof Error ? error.message : 'Failed to send message',
        variant: "destructive",
      });
      // Remove the user message if it failed
      setMessages(prev => prev.slice(0, -1));
    } finally {
      setIsSending(false);
    }
  };

  // Save endpoint
  const saveEndpoint = () => {
    setEndpoint(tempEndpoint);
    localStorage.setItem('localai-endpoint', tempEndpoint);
    setShowSettings(false);
    setStatus({ connected: false });
    setModels([]);
    toast({
      title: "Endpoint opdateret",
      description: `Forbinder til ${tempEndpoint}`,
    });
  };

  // Initial check
  useEffect(() => {
    checkStatus();
    fetchModels();
  }, [checkStatus, fetchModels]);

  return (
    <div className="h-full flex flex-col">
      {/* Header */}
      <div className="flex items-center justify-between mb-3">
        <div className="flex items-center gap-2">
          <div className={cn(
            "w-2 h-2 rounded-full",
            status.connected ? "bg-green-500 animate-pulse" : "bg-red-500"
          )} />
          <span className="text-xs font-mono text-muted-foreground">
            {status.connected ? 'CONNECTED' : 'DISCONNECTED'}
          </span>
        </div>
        <Button 
          variant="ghost" 
          size="sm" 
          onClick={() => setShowSettings(!showSettings)}
          className="h-6 w-6 p-0"
        >
          <Settings className={cn("w-3 h-3 transition-transform", showSettings && "rotate-90")} />
        </Button>
      </div>

      {/* Settings Panel */}
      {showSettings && (
        <div className="mb-3 p-2 bg-secondary/30 rounded border border-border/30 space-y-2">
          <label className="text-[10px] text-muted-foreground">LocalAI Endpoint</label>
          <div className="flex gap-2">
            <Input
              value={tempEndpoint}
              onChange={(e) => setTempEndpoint(e.target.value)}
              placeholder="http://localhost:8080"
              className="h-7 text-xs font-mono bg-background/50"
            />
            <Button size="sm" onClick={saveEndpoint} className="h-7 px-2">
              <Check className="w-3 h-3" />
            </Button>
          </div>
        </div>
      )}

      {/* Main Content */}
      <Tabs value={activeTab} onValueChange={setActiveTab} className="flex-1 flex flex-col">
        <TabsList className="grid grid-cols-3 h-7 bg-secondary/30">
          <TabsTrigger value="status" className="text-[10px] data-[state=active]:bg-primary/20">
            <Server className="w-3 h-3 mr-1" />
            Status
          </TabsTrigger>
          <TabsTrigger value="models" className="text-[10px] data-[state=active]:bg-primary/20">
            <Database className="w-3 h-3 mr-1" />
            Models
          </TabsTrigger>
          <TabsTrigger value="chat" className="text-[10px] data-[state=active]:bg-primary/20">
            <MessageSquare className="w-3 h-3 mr-1" />
            Chat
          </TabsTrigger>
        </TabsList>

        {/* Status Tab */}
        <TabsContent value="status" className="flex-1 mt-2">
          <div className="space-y-2">
            <div className="flex items-center justify-between p-2 bg-background/50 rounded">
              <span className="text-xs text-muted-foreground">Server</span>
              <Badge variant={status.connected ? "default" : "destructive"} className="text-[9px]">
                {status.connected ? 'Online' : 'Offline'}
              </Badge>
            </div>
            <div className="flex items-center justify-between p-2 bg-background/50 rounded">
              <span className="text-xs text-muted-foreground">Endpoint</span>
              <span className="text-[10px] font-mono text-primary truncate max-w-[120px]">{endpoint}</span>
            </div>
            <div className="flex items-center justify-between p-2 bg-background/50 rounded">
              <span className="text-xs text-muted-foreground">Models</span>
              <span className="text-xs font-mono text-primary">{models.length}</span>
            </div>
            {status.error && (
              <div className="p-2 bg-destructive/10 border border-destructive/30 rounded">
                <div className="flex items-center gap-1 text-destructive text-[10px]">
                  <AlertTriangle className="w-3 h-3" />
                  {status.error}
                </div>
              </div>
            )}
            <Button 
              variant="outline" 
              size="sm" 
              onClick={() => { checkStatus(); fetchModels(); }}
              disabled={isLoading}
              className="w-full h-7 text-xs"
            >
              {isLoading ? <Loader2 className="w-3 h-3 animate-spin mr-1" /> : <RefreshCw className="w-3 h-3 mr-1" />}
              Refresh
            </Button>
          </div>
        </TabsContent>

        {/* Models Tab */}
        <TabsContent value="models" className="flex-1 mt-2">
          {models.length === 0 ? (
            <div className="text-center py-4 text-xs text-muted-foreground">
              {status.connected ? 'Ingen modeller fundet' : 'Forbind til LocalAI først'}
            </div>
          ) : (
            <ScrollArea className="h-32">
              <div className="space-y-1">
                {models.map((model) => (
                  <div 
                    key={model.id}
                    onClick={() => setSelectedModel(model.id)}
                    className={cn(
                      "p-2 rounded cursor-pointer transition-colors text-xs font-mono",
                      selectedModel === model.id 
                        ? "bg-primary/20 border border-primary/30" 
                        : "bg-background/50 hover:bg-background/80"
                    )}
                  >
                    <div className="flex items-center justify-between">
                      <span className="truncate">{model.id}</span>
                      {selectedModel === model.id && <Check className="w-3 h-3 text-primary" />}
                    </div>
                  </div>
                ))}
              </div>
            </ScrollArea>
          )}
        </TabsContent>

        {/* Chat Tab */}
        <TabsContent value="chat" className="flex-1 mt-2 flex flex-col">
          {!status.connected ? (
            <div className="text-center py-4 text-xs text-muted-foreground">
              Forbind til LocalAI først
            </div>
          ) : !selectedModel ? (
            <div className="text-center py-4 text-xs text-muted-foreground">
              Vælg en model først
            </div>
          ) : (
            <>
              <ScrollArea className="flex-1 h-24 mb-2">
                <div className="space-y-2 pr-2">
                  {messages.length === 0 ? (
                    <div className="text-center py-2 text-[10px] text-muted-foreground">
                      Start en samtale med {selectedModel}
                    </div>
                  ) : (
                    messages.map((msg, i) => {
                      // Parse message for UI components
                      const parts = parseMessageForComponents(msg.content);
                      const hasComponents = parts.some(p => isUIComponentMessage(p));

                      return (
                        <div
                          key={i}
                          className={cn(
                            "p-2 rounded text-[10px]",
                            msg.role === 'user'
                              ? "bg-primary/20 ml-4"
                              : "bg-secondary/50 mr-4"
                          )}
                        >
                          <div className="text-[8px] text-muted-foreground mb-1 uppercase">
                            {msg.role}
                            {hasComponents && (
                              <Badge variant="outline" className="ml-2 text-[7px] py-0">
                                UI
                              </Badge>
                            )}
                          </div>
                          <div className="space-y-2">
                            {parts.map((part, j) => {
                              if (isUIComponentMessage(part)) {
                                return (
                                  <SmartComponentRenderer
                                    key={`${i}-${j}`}
                                    message={part}
                                    className="my-2"
                                  />
                                );
                              }
                              // Render text parts
                              return part ? (
                                <div key={`${i}-${j}`} className="whitespace-pre-wrap">
                                  {part}
                                </div>
                              ) : null;
                            })}
                          </div>
                        </div>
                      );
                    })
                  )}
                  {isSending && (
                    <div className="flex items-center gap-1 text-[10px] text-muted-foreground">
                      <Loader2 className="w-3 h-3 animate-spin" />
                      Tænker...
                    </div>
                  )}
                </div>
              </ScrollArea>
              <div className="flex gap-1">
                <Input
                  value={inputMessage}
                  onChange={(e) => setInputMessage(e.target.value)}
                  onKeyDown={(e) => e.key === 'Enter' && sendMessage()}
                  placeholder="Skriv besked..."
                  className="h-7 text-xs bg-background/50"
                  disabled={isSending}
                />
                <Button 
                  size="sm" 
                  onClick={sendMessage}
                  disabled={isSending || !inputMessage.trim()}
                  className="h-7 w-7 p-0"
                >
                  <Send className="w-3 h-3" />
                </Button>
              </div>
            </>
          )}
        </TabsContent>
      </Tabs>
    </div>
  );
}
