import { Plus, Trash2, Eye, EyeOff, X, Search, Loader2 } from "lucide-react"
import { useState, useRef, useEffect } from "react"
import { Button } from "@/components/ui/button"
import { Card, CardContent, CardDescription, CardHeader, CardTitle, CardFooter } from "@/components/ui/card"
import { Badge } from "@/components/ui/badge"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { useLlmProviders, useUpdateLlmProviders } from "@/hooks/useConfig"
import { LlmProvider, LlmModel } from "@/types/config"
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog"
import { useToast } from "@/hooks/use-toast"
import axios from "axios"

export function AIProviderTab() {
  const { data: providers, isLoading } = useLlmProviders();
  const updateProviders = useUpdateLlmProviders();
  const { toast } = useToast();
  
  const [isAddOpen, setIsAddOpen] = useState(false);
  const [formData, setFormData] = useState({ name: '', url: '', key: '' });

  const handleSave = () => {
      if (!formData.name || !formData.url || !formData.key) {
          toast({ title: "Validation Error", description: "All fields are required", type: "error" });
          return;
      }
      
      const id = formData.name.toLowerCase().replace(/\s+/g, '_');
      if (providers && providers[id]) {
          toast({ title: "Validation Error", description: "Provider with this name already exists", type: "error" });
          return;
      }

      const newProvider: LlmProvider = {
          name: formData.name,
          api_base_url: formData.url,
          api_key: formData.key,
          models: []
      };
      
      const newProviders = { ...providers, [id]: newProvider };
      
      updateProviders.mutate(newProviders, {
          onSuccess: () => {
              toast({ title: "Success", description: "Provider added successfully" });
              setIsAddOpen(false);
              setFormData({ name: '', url: '', key: '' });
          },
          onError: (err) => {
             toast({ title: "Error", description: "Failed to add provider: " + err, type: "error" });
          }
      });
  }

  const handleDelete = (id: string) => {
      if (!providers) return;
      const { [id]: removed, ...rest } = providers;
      updateProviders.mutate(rest, {
          onSuccess: () => toast({ title: "Success", description: "Provider removed" }),
          onError: () => toast({ title: "Error", description: "Failed to remove provider", type: "error" })
      });
  }

  const handleUpdateProvider = (id: string, updatedProvider: LlmProvider, showToast: boolean = true) => {
      if (!providers) return;
      const newProviders = { ...providers, [id]: updatedProvider };
      updateProviders.mutate(newProviders, {
          onSuccess: () => {
              if (showToast) {
                  toast({ title: "Success", description: "Provider updated" });
              }
          },
          onError: () => toast({ title: "Error", description: "Failed to update provider", type: "error" })
      });
  }

  if (isLoading) {
    return <div>Loading providers...</div>;
  }
  
  // Handle empty state explicitly if data is loaded but empty
  if (providers && Object.keys(providers).length === 0) {
     // Fallthrough to render normally, showing empty list
  }

  return (
    <div className="space-y-6">
      <div className="flex justify-between items-center">
        <div>
           <h3 className="text-lg font-medium">已配置的服务商</h3>
           <p className="text-sm text-muted-foreground">管理连接到系统的 LLM API。</p>
        </div>
        <Dialog open={isAddOpen} onOpenChange={setIsAddOpen}>
          <DialogTrigger asChild>
            <Button><Plus className="mr-2 h-4 w-4" /> 添加 Provider</Button>
          </DialogTrigger>
          <DialogContent className="sm:max-w-[425px]">
            <DialogHeader>
              <DialogTitle>添加 AI Provider</DialogTitle>
              <DialogDescription>
                配置新的 LLM 服务商连接信息。
              </DialogDescription>
            </DialogHeader>
            <div className="grid gap-4 py-4">
              <div className="grid grid-cols-4 items-center gap-4">
                <Label htmlFor="name" className="text-right">名称</Label>
                <Input 
                    id="name" 
                    placeholder="e.g. OpenAI" 
                    className="col-span-3" 
                    value={formData.name}
                    onChange={(e) => setFormData({...formData, name: e.target.value})}
                />
              </div>
              <div className="grid grid-cols-4 items-center gap-4">
                <Label htmlFor="url" className="text-right">Base URL</Label>
                <Input 
                    id="url" 
                    placeholder="https://api.openai.com/v1" 
                    className="col-span-3" 
                    value={formData.url}
                    onChange={(e) => setFormData({...formData, url: e.target.value})}
                />
              </div>
              <div className="grid grid-cols-4 items-center gap-4">
                <Label htmlFor="key" className="text-right">API Key</Label>
                <Input 
                    id="key" 
                    type="password" 
                    className="col-span-3" 
                    value={formData.key}
                    onChange={(e) => setFormData({...formData, key: e.target.value})}
                />
              </div>
            </div>
            <DialogFooter>
              <Button type="submit" onClick={handleSave} disabled={updateProviders.isPending}>
                  {updateProviders.isPending ? "保存中..." : "保存"}
              </Button>
            </DialogFooter>
          </DialogContent>
        </Dialog>
      </div>

      <div className="grid gap-6 md:grid-cols-1 lg:grid-cols-2">
        {providers && Object.entries(providers).map(([id, provider]) => (
          <ProviderCard 
            key={id} 
            id={id} 
            provider={provider} 
            onDelete={() => handleDelete(id)} 
            onUpdate={(p, showToast) => handleUpdateProvider(id, p, showToast)}
          />
        ))}
      </div>
    </div>
  )
}

function ProviderCard({ id, provider, onDelete, onUpdate }: { id: string, provider: LlmProvider, onDelete: () => void, onUpdate: (p: LlmProvider, showToast?: boolean) => void }) {
  const [showKey, setShowKey] = useState(false);
  // const discoverModels = useDiscoverModels(); // Removed as we now fetch manually
  const { toast } = useToast();
  
  // Discovered models cache for search (not saved to config)
  const [discoveredModels, setDiscoveredModels] = useState<LlmModel[]>([]);
  const [searchQuery, setSearchQuery] = useState("");
  const [isSearchFocused, setIsSearchFocused] = useState(false);
  const [isFetchingModels, setIsFetchingModels] = useState(false);
  const searchRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    // Close search results on click outside
    const handleClickOutside = (event: MouseEvent) => {
        if (searchRef.current && !searchRef.current.contains(event.target as Node)) {
            setIsSearchFocused(false);
        }
    };
    document.addEventListener("mousedown", handleClickOutside);
    return () => document.removeEventListener("mousedown", handleClickOutside);
  }, []);

  // Auto-fetch models on interaction if cache is empty
  const fetchModels = async (force = false) => {
      // If we already have models and not forcing, don't fetch
      if (discoveredModels.length > 0 && !force) return;
      if (isFetchingModels) return;

      setIsFetchingModels(true);
      try {
        const response = await axios.get(`/api/v1/discover-models/${id}`);
        const data = response.data;
        
        let models: LlmModel[] = [];
        if (data && Array.isArray(data.data)) {
            models = data.data.map((m: any) => ({
                model_id: m.id,
                name: m.name || m.id,
                is_active: true
            }));
        } else if (Array.isArray(data)) {
            models = data.map((m: any) => ({
                model_id: m.id,
                name: m.name || m.id,
                is_active: true
            }));
        }

        setDiscoveredModels(models);

        if (models.length === 0) {
             // Silent fail or minimal toast?
             // toast({ title: "Info", description: "No models found from provider" });
        } else {
            toast({ title: "Models Discovered", description: `Found ${models.length} available models for autocomplete.` });
        }
      } catch (err) {
          console.error(err);
          toast({ title: "Discovery Error", description: "Failed to fetch model list for autocomplete", type: "error" });
      } finally {
          setIsFetchingModels(false);
      }
  }

  const handleInputFocus = () => {
      setIsSearchFocused(true);
      if (discoveredModels.length === 0) {
          fetchModels();
      }
  }

  const handleAddModel = (model: LlmModel) => {
      // Check if already exists
      if (provider.models.some(m => m.model_id === model.model_id)) {
          toast({ title: "Info", description: "Model already added" });
          setSearchQuery("");
          setIsSearchFocused(false);
          return;
      }

      const updatedProvider = {
          ...provider,
          models: [...provider.models, model]
      };
      // Pass false to suppress generic toast since we show a specific one here
      onUpdate(updatedProvider, false); 
      setSearchQuery("");
      setIsSearchFocused(false);
      toast({ title: "Success", description: `Added ${model.name || model.model_id}` });
  }

  const handleManualAdd = () => {
      if (!searchQuery.trim()) return;
      const newModel = {
          model_id: searchQuery,
          name: searchQuery,
          is_active: true
      };
      handleAddModel(newModel);
  }

  const handleRemoveModel = (modelId: string) => {
      const updatedProvider = {
          ...provider,
          models: provider.models.filter(m => m.model_id !== modelId)
      };
      onUpdate(updatedProvider);
  }

  const handleClearModels = () => {
      if (provider.models.length === 0) return;
      if (confirm("确定要清空所有已添加的模型吗？")) {
          const updatedProvider = {
              ...provider,
              models: []
          };
          onUpdate(updatedProvider, false);
          toast({ title: "Success", description: "已清空所有模型" });
      }
  }

  const filteredModels = searchQuery 
    ? discoveredModels.filter(m => 
        (m.name?.toLowerCase().includes(searchQuery.toLowerCase()) || m.model_id.toLowerCase().includes(searchQuery.toLowerCase()))
      )
    : [];

  return (
    <Card>
      <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
        <div className="space-y-1">
          <CardTitle className="text-xl">{provider.name}</CardTitle>
          <CardDescription className="font-mono text-xs truncate max-w-[250px]">
            {provider.api_base_url}
          </CardDescription>
        </div>
        <Badge variant="outline">{provider.models.length} Models</Badge>
      </CardHeader>
      <CardContent className="space-y-4 mt-4">
        <div className="space-y-2">
          <Label className="text-xs text-muted-foreground">API KEY</Label>
          <div className="flex items-center space-x-2">
            <Input 
              type={showKey ? "text" : "password"} 
              value={provider.api_key} 
              readOnly 
              className="h-8 font-mono text-xs bg-muted/50" 
            />
            <Button 
              variant="ghost" 
              size="icon" 
              className="h-8 w-8"
              onClick={() => setShowKey(!showKey)}
            >
              {showKey ? <EyeOff className="h-4 w-4" /> : <Eye className="h-4 w-4" />}
            </Button>
          </div>
        </div>

        <div className="space-y-2">
            <div className="flex items-center justify-between">
                <Label className="text-xs text-muted-foreground">ACTIVE MODELS</Label>
                <div className="flex gap-1">
                    {provider.models.length > 0 && (
                        <Button 
                            variant="ghost" 
                            size="sm" 
                            className="h-6 text-xs px-2 text-destructive hover:text-destructive hover:bg-destructive/10"
                            onClick={handleClearModels}
                        >
                            <Trash2 className="mr-1 h-3 w-3" /> 清空配置
                        </Button>
                    )}
                </div>
            </div>

            {/* Search / Add Input */}
            <div className="relative" ref={searchRef}>
                <div className="relative">
                    <Search className="absolute left-2 top-2.5 h-4 w-4 text-muted-foreground" />
                    <Input
                        placeholder="Search or enter model ID (auto-completes from provider)..."
                        value={searchQuery}
                        onChange={(e) => setSearchQuery(e.target.value)}
                        onFocus={handleInputFocus}
                        className="pl-8 h-9 text-sm"
                    />
                    {isFetchingModels && (
                        <div className="absolute right-8 top-2.5">
                            <Loader2 className="h-4 w-4 animate-spin text-muted-foreground" />
                        </div>
                    )}
                    {searchQuery && !isFetchingModels && (
                        <Button 
                            size="sm" 
                            variant="ghost" 
                            className="absolute right-1 top-1 h-7 px-2 text-xs"
                            onClick={handleManualAdd}
                        >
                            <Plus className="h-3 w-3 mr-1" /> Add "{searchQuery}"
                </Button>
                    )}
                </div>

                {/* Autocomplete Dropdown */}
                {isSearchFocused && searchQuery && discoveredModels.length > 0 && (
                    <div className="absolute z-10 w-full mt-1 bg-popover border rounded-md shadow-md max-h-[200px] overflow-y-auto">
                        {filteredModels.length > 0 ? (
                            filteredModels.map((model) => (
                                <button
                                    key={model.model_id}
                                    className="w-full text-left px-3 py-2 text-sm hover:bg-accent hover:text-accent-foreground flex items-center justify-between"
                                    onClick={() => handleAddModel(model)}
                                >
                                    <span className="truncate">{model.name || model.model_id}</span>
                                    {provider.models.some(m => m.model_id === model.model_id) && (
                                        <Badge variant="outline" className="text-[10px]">Added</Badge>
                                    )}
                                </button>
                            ))
                        ) : (
                             <div className="px-3 py-2 text-xs text-muted-foreground">
                                No discovered models match "{searchQuery}". Click 'Add' to add manually.
                            </div>
                        )}
                    </div>
                )}
            </div>

            {/* Active Models List */}
            <div className="flex flex-wrap gap-2 max-h-[150px] overflow-y-auto p-1 border rounded-md bg-muted/10 mt-2">
                {provider.models.length === 0 && <span className="text-xs text-muted-foreground p-2">No active models.</span>}
                {provider.models.map(model => (
                    <Badge key={model.model_id} variant="secondary" className="text-xs font-normal flex items-center gap-1 pr-1">
                        {model.name || model.model_id}
                        <button 
                            onClick={() => handleRemoveModel(model.model_id)}
                            className="ml-1 hover:text-destructive focus:outline-none"
                        >
                            <X className="h-3 w-3" />
                        </button>
                    </Badge>
                ))}
            </div>
        </div>
      </CardContent>
      <CardFooter className="justify-end pt-2">
         <Button 
            variant="ghost" 
            size="sm" 
            className="text-destructive hover:text-destructive hover:bg-destructive/10"
            onClick={onDelete}
         >
            <Trash2 className="mr-2 h-4 w-4" /> 删除
         </Button>
      </CardFooter>
    </Card>
  )
}
