"use client"

import { useMemo, useState } from "react"
import { Plus, RefreshCw, Trash2 } from "lucide-react"
import { OrgSettingsSection } from "@/components/admin/settings/org-settings-form"
import { DeployLockedHint } from "@/components/admin/settings/deploy-locked-hint"
import { useDeployFieldLocked } from "@/components/admin/settings/deploy-locked-hint"
import { useOrgSettingsStore } from "@/lib/admin-settings/org-settings-store"
import type { AiModelCatalogEntry } from "@/lib/admin-settings/org-settings-types"
import { useDiscoverOrgLLMModels } from "@/lib/api/hooks/use-admin-llm"
import { Label } from "@/components/ui/label"
import { Switch } from "@/components/ui/switch"
import { Button } from "@/components/ui/button"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
import { Input } from "@/components/ui/input"
import { Badge } from "@/components/ui/badge"
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select"

function emptyModelEntry(): AiModelCatalogEntry {
  return {
    model_id: "",
    label: "",
    enabled: true,
  }
}

export function AiAssistantSection() {
  const aiAssistant = useOrgSettingsStore((s) => s.aiAssistant)
  const setAiAssistant = useOrgSettingsStore((s) => s.setAiAssistant)
  const setPlugins = useOrgSettingsStore((s) => s.setPlugins)
  const plugins = useOrgSettingsStore((s) => s.plugins)
  const llm = useOrgSettingsStore((s) => s.llm)
  const effective = useOrgSettingsStore((s) => s.meta?.effective.ai_assistant)
  const enabledLocked = useDeployFieldLocked("ai_assistant", "enabled")
  const publicPathLocked = useDeployFieldLocked("ai_assistant", "public_path")
  const openwebuiLocked = useDeployFieldLocked("ai_assistant", "openwebui_internal_url")
  const pluginEnabled = plugins.find((p) => p.id === "ai-assistant")?.enabled ?? false
  const runtimeEnabled = effective?.enabled ?? false
  const orgEnabled = aiAssistant.enabled || pluginEnabled

  const [discoverProviderId, setDiscoverProviderId] = useState(llm.default_provider_id)
  const [discoveredModels, setDiscoveredModels] = useState<string[]>([])
  const discoverProvider = useMemo(
    () => llm.providers.find((p) => p.id === discoverProviderId) ?? llm.providers[0],
    [discoverProviderId, llm.providers],
  )
  const discoverModels = useDiscoverOrgLLMModels()

  async function handleDiscoverModels() {
    if (!discoverProvider?.id) return
    setDiscoveredModels([])
    try {
      const result = await discoverModels.mutateAsync(discoverProvider.id)
      setDiscoveredModels(result.models ?? [])
    } catch {
      setDiscoveredModels([])
    }
  }

  function updateModel(index: number, patch: Partial<AiModelCatalogEntry>) {
    const models = aiAssistant.models.map((entry, i) =>
      i === index ? { ...entry, ...patch } : entry,
    )
    setAiAssistant({ models })
  }

  function removeModel(index: number) {
    setAiAssistant({ models: aiAssistant.models.filter((_, i) => i !== index) })
  }

  function addManualModel() {
    setAiAssistant({ models: [...aiAssistant.models, emptyModelEntry()] })
  }

  function addDiscoveredModel(modelId: string) {
    if (aiAssistant.models.some((entry) => entry.model_id === modelId)) return
    setAiAssistant({
      models: [
        ...aiAssistant.models,
        { model_id: modelId, label: modelId, enabled: true },
      ],
    })
  }

  function setUltiAIEnabled(enabled: boolean) {
    setAiAssistant({ enabled })
    setPlugins(
      plugins.map((plugin) =>
        plugin.id === "ai-assistant" ? { ...plugin, enabled } : plugin,
      ),
    )
  }

  return (
    <OrgSettingsSection
      title="UltiAI"
      description="Assistant IA intégré (OpenWebUI) avec gateway LLM, tools et sync Nextcloud."
      policySection={["ai_assistant", "plugins"]}
    >
      <Card>
        <CardHeader className="pb-3">
          <div className="flex items-center justify-between gap-4">
            <div>
              <CardTitle className="text-sm font-medium">Assistant IA</CardTitle>
              <CardDescription>
                Active le plugin UltiAI pour toute l&apos;organisation. Le service OpenWebUI doit
                aussi être déployé.
              </CardDescription>
            </div>
            <Switch
              checked={orgEnabled}
              disabled={enabledLocked}
              onCheckedChange={setUltiAIEnabled}
            />
          </div>
          {enabledLocked ? (
            <DeployLockedHint section="ai_assistant" field="enabled" />
          ) : null}
          <div className="flex flex-wrap gap-2 pt-1">
            <Badge variant={orgEnabled ? "default" : "secondary"}>
              Politique org. {orgEnabled ? "activée" : "désactivée"}
            </Badge>
            <Badge variant={runtimeEnabled ? "default" : "outline"}>
              Runtime Compose {runtimeEnabled ? "actif" : "inactif"}
            </Badge>
          </div>
          {!orgEnabled && !runtimeEnabled ? (
            <p className="text-xs text-muted-foreground">
              Activez le plugin UltiAI dans Administration → Plugins, ou définissez{" "}
              <code className="rounded bg-muted px-1">AI_ASSISTANT_ENABLED=true</code> dans le
              déploiement, puis redémarrez le backend et OpenWebUI.
            </p>
          ) : null}
        </CardHeader>
        <CardContent className="grid gap-4 sm:grid-cols-2">
          <div className="space-y-2 sm:col-span-2">
            <Label>Chemin public (proxy)</Label>
            <Input
              value={aiAssistant.public_path}
              onChange={(e) => setAiAssistant({ public_path: e.target.value })}
              placeholder="/ai"
              disabled={publicPathLocked}
            />
            <DeployLockedHint section="ai_assistant" field="public_path" />
          </div>
          <div className="space-y-2 sm:col-span-2">
            <Label>URL interne OpenWebUI</Label>
            <Input
              value={aiAssistant.openwebui_internal_url}
              onChange={(e) => setAiAssistant({ openwebui_internal_url: e.target.value })}
              placeholder="http://openwebui:8080"
              disabled={openwebuiLocked}
            />
            <DeployLockedHint section="ai_assistant" field="openwebui_internal_url" />
          </div>
          <div className="space-y-2">
            <Label>Modèle par défaut</Label>
            <Input
              value={aiAssistant.default_model}
              onChange={(e) => setAiAssistant({ default_model: e.target.value })}
              placeholder="gpt-4o"
            />
          </div>
          <div className="space-y-2">
            <Label>Chemin historique NC</Label>
            <Input
              value={aiAssistant.chat_nc_path}
              onChange={(e) => setAiAssistant({ chat_nc_path: e.target.value })}
              placeholder="/.ultimail/ai/chats"
            />
          </div>
          <div className="flex items-center justify-between gap-4 sm:col-span-2">
            <div>
              <Label>Embed temporaire par défaut</Label>
              <p className="text-xs text-muted-foreground">
                Les panneaux mail/drive/contacts ne sauvegardent pas l&apos;historique.
              </p>
            </div>
            <Switch
              checked={aiAssistant.embed_default_temporary}
              onCheckedChange={(v) => setAiAssistant({ embed_default_temporary: v })}
            />
          </div>
          <div className="flex items-center justify-between gap-4 sm:col-span-2">
            <div>
              <Label>Sync historique Nextcloud</Label>
              <p className="text-xs text-muted-foreground">
                Pipeline OpenWebUI → fichiers .ultichat.json sur le drive utilisateur.
              </p>
            </div>
            <Switch
              checked={aiAssistant.chat_sync_enabled}
              onCheckedChange={(v) => setAiAssistant({ chat_sync_enabled: v })}
            />
          </div>
        </CardContent>
      </Card>

      <Card>
        <CardHeader className="pb-3">
          <CardTitle className="text-sm font-medium">Modèles autorisés</CardTitle>
          <CardDescription>
            Liste vide = tous les modèles des fournisseurs LLM org. Sinon, seuls les modèles
            autorisés sont visibles pour les utilisateurs. Le surnom remplace le nom technique.
          </CardDescription>
        </CardHeader>
        <CardContent className="space-y-4">
          {llm.providers.length === 0 ? (
            <p className="text-sm text-muted-foreground">
              Configurez d&apos;abord un fournisseur LLM dans Administration → Fournisseurs LLM.
            </p>
          ) : (
            <div className="flex flex-wrap items-end gap-3 rounded-lg border p-3">
              <div className="min-w-[220px] flex-1 space-y-2">
                <Label className="text-xs">Découvrir depuis le fournisseur</Label>
                <Select
                  value={discoverProvider?.id ?? ""}
                  onValueChange={setDiscoverProviderId}
                >
                  <SelectTrigger className="h-9">
                    <SelectValue placeholder="Choisir un fournisseur…" />
                  </SelectTrigger>
                  <SelectContent>
                    {llm.providers.map((provider) => (
                      <SelectItem key={provider.id} value={provider.id}>
                        {provider.name || provider.base_url}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>
              <Button
                type="button"
                variant="outline"
                size="sm"
                disabled={!discoverProvider?.id || discoverModels.isPending}
                onClick={() => void handleDiscoverModels()}
              >
                <RefreshCw
                  className={`mr-2 size-4 ${discoverModels.isPending ? "animate-spin" : ""}`}
                />
                Découvrir les modèles
              </Button>
            </div>
          )}

          {discoverModels.isError ? (
            <p className="text-sm text-destructive">
              {discoverModels.error instanceof Error
                ? discoverModels.error.message
                : "Impossible de lister les modèles sur ce fournisseur. Enregistrez d'abord le fournisseur LLM avec une clé API valide."}
            </p>
          ) : null}

          {discoveredModels.length ? (
            <div className="space-y-2">
              <Label className="text-xs">Modèles disponibles sur l&apos;endpoint</Label>
              <div className="flex flex-wrap gap-2">
                {discoveredModels.map((modelId) => {
                  const alreadyAdded = aiAssistant.models.some(
                    (entry) => entry.model_id === modelId,
                  )
                  return (
                    <Button
                      key={modelId}
                      type="button"
                      size="sm"
                      variant={alreadyAdded ? "secondary" : "outline"}
                      disabled={alreadyAdded}
                      onClick={() => addDiscoveredModel(modelId)}
                    >
                      {alreadyAdded ? "Ajouté" : `+ ${modelId}`}
                    </Button>
                  )
                })}
              </div>
            </div>
          ) : null}

          <div className="flex items-center justify-between">
            <Label>Catalogue organisation</Label>
            <Button type="button" variant="outline" size="sm" onClick={addManualModel}>
              <Plus className="mr-2 size-4" />
              Ajouter manuellement
            </Button>
          </div>

          {aiAssistant.models.length === 0 ? (
            <p className="text-sm text-muted-foreground">
              Aucune restriction — tous les modèles LLM configurés restent disponibles.
            </p>
          ) : (
            <div className="space-y-2">
              {aiAssistant.models.map((entry, index) => (
                <div
                  key={`${entry.model_id}-${index}`}
                  className="grid gap-2 rounded-lg border p-3 sm:grid-cols-[1fr_1fr_auto_auto]"
                >
                  <div className="space-y-1">
                    <Label className="text-xs">ID modèle</Label>
                    <Input
                      className="h-9"
                      value={entry.model_id}
                      onChange={(e) => updateModel(index, { model_id: e.target.value })}
                      placeholder="gpt-4o-mini"
                    />
                  </div>
                  <div className="space-y-1">
                    <Label className="text-xs">Surnom utilisateur</Label>
                    <Input
                      className="h-9"
                      value={entry.label}
                      onChange={(e) => updateModel(index, { label: e.target.value })}
                      placeholder="GPT-4o Mini"
                    />
                  </div>
                  <label className="flex items-center gap-2 self-end pb-1 text-sm">
                    <Switch
                      checked={entry.enabled}
                      onCheckedChange={(enabled) => updateModel(index, { enabled })}
                    />
                    Autorisé
                  </label>
                  <Button
                    type="button"
                    variant="ghost"
                    size="icon"
                    className="self-end"
                    onClick={() => removeModel(index)}
                    aria-label="Supprimer le modèle"
                  >
                    <Trash2 className="size-4" />
                  </Button>
                </div>
              ))}
            </div>
          )}
        </CardContent>
      </Card>
    </OrgSettingsSection>
  )
}
