"use client"

import { useEffect, useState } from "react"
import { ExternalLink, Plus, Trash2 } from "lucide-react"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select"
import { FieldGroup } from "@/components/admin/settings/field-group"
import { TechBrandSelectLabel } from "@/components/admin/settings/tech-brand-select-label"
import { AutomationTabMasonry } from "@/components/gmail/settings/automation/automation-tab-masonry"
import type { ApiLLMProvider, ApiLLMProviderType } from "@/lib/contacts/discovery-types"
import {
  emptyLlmProvider,
  inferLlmProviderType,
  isLlmProviderConfigured,
  llmCatalogEntry,
  LLM_PROVIDER_CATALOG,
  normalizeLlmProvider,
} from "@/lib/llm/llm-provider-catalog"
import { cn } from "@/lib/utils"

type LlmProviderSecrets = Record<string, { configured?: boolean } | undefined>

export type LlmProvidersEditorProps = {
  providers: ApiLLMProvider[]
  defaultProviderId: string
  onProvidersChange: (providers: ApiLLMProvider[]) => void
  onDefaultProviderIdChange: (id: string) => void
  className?: string
  columns?: 1 | 2
  providerSecrets?: LlmProviderSecrets
  renderDefaultModelInput?: (props: {
    provider: ApiLLMProvider
    index: number
    onChange: (default_model: string) => void
  }) => React.ReactNode
}

function providerOptions(
  providers: ApiLLMProvider[],
  providerSecrets?: LlmProviderSecrets,
) {
  return providers.map((provider) => ({
    provider: normalizeLlmProvider(provider),
    configured: isLlmProviderConfigured(provider, {
      apiKeyConfigured: providerSecrets?.[provider.id]?.configured,
    }),
  }))
}

export function LlmProvidersEditor({
  providers,
  defaultProviderId,
  onProvidersChange,
  onDefaultProviderIdChange,
  className,
  columns = 2,
  providerSecrets,
  renderDefaultModelInput,
}: LlmProvidersEditorProps) {
  const options = providerOptions(providers, providerSecrets)
  const [editingProviderId, setEditingProviderId] = useState<string | null>(null)

  useEffect(() => {
    if (editingProviderId && !providers.some((provider) => provider.id === editingProviderId)) {
      setEditingProviderId(null)
    }
  }, [editingProviderId, providers])

  function commit(nextProviders: ApiLLMProvider[]) {
    onProvidersChange(nextProviders.map(normalizeLlmProvider))
  }

  function updateProvider(index: number, patch: Partial<ApiLLMProvider>) {
    const next = [...providers]
    next[index] = { ...next[index], ...patch }
    commit(next)
  }

  function setProviderType(index: number, type: ApiLLMProviderType) {
    const current = providers[index]
    const entry = llmCatalogEntry(type)
    const next = {
      ...emptyLlmProvider(type),
      id: current?.id ?? emptyLlmProvider(type).id,
      api_key: current?.api_key ?? "",
    }
    const updated = [...providers]
    updated[index] = next
    commit(updated)
  }

  function addProvider() {
    const provider = emptyLlmProvider("openai")
    commit([...providers, provider])
    setEditingProviderId(provider.id)
    if (!defaultProviderId) {
      onDefaultProviderIdChange(provider.id)
    }
  }

  function removeProvider(index: number) {
    const removed = providers[index]
    if (editingProviderId === removed?.id) {
      setEditingProviderId(null)
    }
    const nextProviders = providers.filter((_, i) => i !== index)
    const remaining = providerOptions(nextProviders, providerSecrets)
    let nextDefaultId = defaultProviderId
    if (nextDefaultId === removed?.id) {
      nextDefaultId =
        remaining.find((entry) => entry.configured)?.provider.id ??
        nextProviders[0]?.id ??
        ""
    }
    onProvidersChange(nextProviders.map(normalizeLlmProvider))
    onDefaultProviderIdChange(nextDefaultId)
  }

  return (
    <div className={cn("w-full space-y-4", className)}>
      {providers.length > 0 ? (
        <FieldGroup>
          <Label className="text-xs">Fournisseur par défaut</Label>
          <Select
            value={defaultProviderId || providers[0]?.id || "__none__"}
            onValueChange={(id) =>
              onDefaultProviderIdChange(id === "__none__" ? "" : id)
            }
          >
            <SelectTrigger className="h-9 w-full min-w-0">
              <SelectValue placeholder="Choisir…" />
            </SelectTrigger>
            <SelectContent>
              {options.map(({ provider, configured }) => {
                const type = inferLlmProviderType(provider)
                const entry = llmCatalogEntry(type)
                return (
                  <SelectItem
                    key={provider.id}
                    value={provider.id}
                    disabled={!configured}
                  >
                    <TechBrandSelectLabel
                      brand={type}
                      icon={entry.icon}
                      suffix={!configured ? " (incomplet)" : undefined}
                    >
                      {provider.name || entry.label}
                    </TechBrandSelectLabel>
                  </SelectItem>
                )
              })}
            </SelectContent>
          </Select>
          {options.some((entry) => !entry.configured) ? (
            <p className="text-xs text-muted-foreground">
              Les fournisseurs incomplets restent visibles mais ne peuvent pas être sélectionnés
              par défaut.
            </p>
          ) : null}
        </FieldGroup>
      ) : null}

      <AutomationTabMasonry columns={columns}>
        {providers.map((provider, index) => {
          const normalized = normalizeLlmProvider(provider)
          const type = inferLlmProviderType(normalized)
          const entry = llmCatalogEntry(type)
          const apiKeyConfigured = providerSecrets?.[provider.id]?.configured ?? false
          const configured = isLlmProviderConfigured(provider, { apiKeyConfigured })
          const isEditing = editingProviderId === provider.id
          const displayName =
            normalized.name || entry.label || `Fournisseur ${index + 1}`

          if (!isEditing) {
            return (
              <div
                key={provider.id}
                className="flex w-full items-center justify-between gap-3 rounded-lg border border-border px-4 py-3"
              >
                <TechBrandSelectLabel
                  brand={type}
                  icon={entry.icon}
                  className="min-w-0 text-sm font-medium"
                >
                  {displayName}
                </TechBrandSelectLabel>
                <Button
                  type="button"
                  variant="outline"
                  size="sm"
                  onClick={() => setEditingProviderId(provider.id)}
                >
                  Modifier
                </Button>
              </div>
            )
          }

          return (
            <div key={provider.id} className="w-full rounded-lg border border-border py-4">
              <div className="flex items-start justify-between gap-2 px-4">
                <div className="min-w-0">
                  <TechBrandSelectLabel
                    brand={type}
                    icon={entry.icon}
                    className="text-sm font-medium"
                  >
                    {displayName}
                  </TechBrandSelectLabel>
                  {!configured ? (
                    <p className="mt-1 text-xs text-muted-foreground">Configuration incomplète</p>
                  ) : apiKeyConfigured && !(provider.api_key ?? "").trim() ? (
                    <p className="mt-1 text-xs text-muted-foreground">
                      Clé API enregistrée sur le serveur
                    </p>
                  ) : null}
                </div>
                <div className="flex shrink-0 items-center gap-1">
                  <Button
                    type="button"
                    variant="ghost"
                    size="sm"
                    onClick={() => setEditingProviderId(null)}
                  >
                    Fermer
                  </Button>
                  <Button
                    type="button"
                    variant="ghost"
                    size="icon"
                    aria-label="Supprimer le fournisseur"
                    onClick={() => removeProvider(index)}
                  >
                    <Trash2 className="size-4" />
                  </Button>
                </div>
              </div>

              <div className="mt-4 space-y-4 border-t px-4 pt-4">
                <FieldGroup>
                  <Label className="text-xs">Fournisseur</Label>
                  <Select
                    value={type}
                    onValueChange={(value) =>
                      setProviderType(index, value as ApiLLMProviderType)
                    }
                  >
                    <SelectTrigger className="h-9 w-full min-w-0">
                      <SelectValue>
                        <TechBrandSelectLabel brand={type} icon={entry.icon}>
                          {entry.label}
                        </TechBrandSelectLabel>
                      </SelectValue>
                    </SelectTrigger>
                    <SelectContent className="max-h-72">
                      {LLM_PROVIDER_CATALOG.map((item) => (
                        <SelectItem key={item.type} value={item.type}>
                          <TechBrandSelectLabel brand={item.type} icon={item.icon}>
                            {item.label}
                          </TechBrandSelectLabel>
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                  <p className="text-xs text-muted-foreground">{entry.description}</p>
                  {entry.docsUrl ? (
                    <a
                      href={entry.docsUrl}
                      target="_blank"
                      rel="noopener noreferrer"
                      className="inline-flex items-center gap-1 text-xs text-muted-foreground hover:underline"
                    >
                      Documentation
                      <ExternalLink className="size-3" />
                    </a>
                  ) : null}
                </FieldGroup>

                <FieldGroup>
                  <Label className="text-xs">Nom affiché</Label>
                  <Input
                    className="h-9"
                    value={provider.name}
                    onChange={(e) => updateProvider(index, { name: e.target.value })}
                    placeholder={entry.label}
                  />
                </FieldGroup>

                <FieldGroup>
                  <Label className="text-xs">URL de base</Label>
                  <Input
                    className="h-9"
                    value={provider.base_url}
                    onChange={(e) => updateProvider(index, { base_url: e.target.value })}
                    placeholder={entry.baseURLPlaceholder ?? entry.defaultBaseURL}
                  />
                </FieldGroup>

                {type !== "ollama" ? (
                  <FieldGroup>
                    <Label className="text-xs">Clé API</Label>
                    <Input
                      className="h-9"
                      type="password"
                      autoComplete="off"
                      value={provider.api_key ?? ""}
                      onChange={(e) => updateProvider(index, { api_key: e.target.value })}
                      placeholder={
                        apiKeyConfigured && !(provider.api_key ?? "").trim()
                          ? "•••••••• (laisser vide pour conserver)"
                          : type === "openai"
                            ? "sk-…"
                            : undefined
                      }
                    />
                  </FieldGroup>
                ) : null}

                <FieldGroup>
                  <Label className="text-xs">Modèle par défaut</Label>
                  {renderDefaultModelInput ? (
                    renderDefaultModelInput({
                      provider,
                      index,
                      onChange: (default_model) => updateProvider(index, { default_model }),
                    })
                  ) : (
                    <Input
                      className="h-9"
                      value={provider.default_model}
                      onChange={(e) => updateProvider(index, { default_model: e.target.value })}
                      placeholder={entry.defaultModel || "gpt-4o-mini"}
                    />
                  )}
                </FieldGroup>
              </div>
            </div>
          )
        })}
      </AutomationTabMasonry>

      <Button type="button" variant="outline" size="sm" onClick={addProvider}>
        <Plus className="mr-2 size-4" />
        Ajouter un fournisseur
      </Button>
    </div>
  )
}

export { emptyLlmProvider }
