"use client";

import { useState, useEffect } from "react";
import { Cpu, Save, Loader2, ArrowUp, ArrowDown, X, Plus, RefreshCw } from "lucide-react";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { useNotification } from "@/components/ui/notification";
import { ModelCombobox, ModelOption } from "@/components/ui/model-combobox";
import { useTranslationStore } from "@/lib/store";
import { API_BASE } from "@/lib/config";
import { useI18n } from "@/lib/i18n";
import { LLM_CHANNEL_OPTIONS, channelLabelKey } from "../constants";
import type { AiTierRoute, AiTierSettings, AiTiersSettings } from "../types";

interface FullSettings {
  [key: string]: unknown;
}

const getToken = () => useTranslationStore.getState().settings.adminToken ?? "";

/** L'ancien format (chaînes OpenRouter) est converti en routes à l'affichage. */
function toRoutes(tier: AiTierSettings): AiTierRoute[] {
  if (tier.routes && tier.routes.length > 0) return tier.routes;
  const legacy: AiTierRoute[] = [];
  if (tier.default_model) legacy.push({ provider: "openrouter", model: tier.default_model });
  for (const m of tier.models || []) {
    if (m && !legacy.some((r) => r.model === m)) legacy.push({ provider: "openrouter", model: m });
  }
  return legacy;
}

/** À la sauvegarde : routes multi-canaux + miroir hérité (modèles openrouter). */
function fromRoutes(routes: AiTierRoute[], previous: AiTierSettings): AiTierSettings {
  const openrouterModels = routes.filter((r) => r.provider === "openrouter").map((r) => r.model);
  const defaultRoute = routes[0];
  const legacyDefault =
    defaultRoute?.provider === "openrouter"
      ? defaultRoute.model
      : (previous.default_model || "");
  return {
    routes,
    models: openrouterModels,
    default_model: legacyDefault,
  };
}

/** Éditeur d'un palier : liste ordonnée de routes (ordre = priorité de secours). */
function TierEditor({
  tier,
  onChange,
  catalog,
  onLoadCatalog,
  catalogLoading,
}: {
  tier: AiTierSettings;
  onChange: (next: AiTierSettings) => void;
  catalog: ModelOption[];
  onLoadCatalog: () => void;
  catalogLoading: boolean;
}) {
  const { t } = useI18n();
  const { error } = useNotification();
  const [adding, setAdding] = useState(false);
  const [newProvider, setNewProvider] = useState("openrouter");
  const [newModel, setNewModel] = useState("");

  const routes = toRoutes(tier);

  const setRoutes = (next: AiTierRoute[]) => onChange(fromRoutes(next, tier));

  /** Vrai si un couple canal+modèle existe déjà ailleurs dans la liste. */
  const isDuplicate = (provider: string, model: string, exceptIndex = -1): boolean =>
    routes.some(
      (r, i) =>
        i !== exceptIndex && r.provider === provider && r.model === model
    );

  const move = (index: number, dir: -1 | 1) => {
    const next = [...routes];
    const target = index + dir;
    if (target < 0 || target >= next.length) return;
    [next[index], next[target]] = [next[target], next[index]];
    setRoutes(next);
  };

  const remove = (index: number) => {
    setRoutes(routes.filter((_, i) => i !== index));
  };

  /** Par défaut = première route essayée : cliquer le radio met la route en tête. */
  const setDefault = (index: number) => {
    if (index === 0) return;
    const next = [...routes];
    const [route] = next.splice(index, 1);
    setRoutes([route, ...next]);
  };

  const add = () => {
    const model = newModel.trim();
    if (!model) return;
    if (isDuplicate(newProvider, model)) {
      error({ title: t("admin.models.duplicateRouteTitle"), description: t("admin.models.duplicateRouteDesc") });
      return;
    }
    setRoutes([...routes, { provider: newProvider, model }]);
    setNewModel("");
    setAdding(false);
  };

  return (
    <div className="space-y-2">
      {routes.map((route, i) => {
        const isDefault = i === 0;
        return (
          <div
            key={`${route.provider}/${route.model}`}
            className={
              "flex flex-wrap items-center gap-2 rounded-lg border px-3 py-2 " +
              (isDefault ? "border-accent/50 bg-accent/5" : "border-border/60 bg-card")
            }
          >
            <button
              type="button"
              role="radio"
              aria-checked={isDefault}
              aria-label={t("admin.models.setDefault", { model: `${route.provider}/${route.model}` })}
              onClick={() => setDefault(i)}
              className={
                "flex size-4 shrink-0 items-center justify-center rounded-full border " +
                (isDefault ? "border-accent" : "border-muted-foreground/40")
              }
            >
              {isDefault && <span className="size-2 rounded-full bg-accent" />}
            </button>
            <Select
              value={route.provider}
              onValueChange={(value) => {
                if (isDuplicate(value, route.model, i)) {
                  error({ title: t("admin.models.duplicateRouteTitle"), description: t("admin.models.duplicateRouteDesc") });
                  return;
                }
                const next = [...routes];
                next[i] = { ...route, provider: value };
                setRoutes(next);
              }}
            >
              <SelectTrigger className="h-7 w-44 shrink-0 text-xs">
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                {LLM_CHANNEL_OPTIONS.map((p) => (
                  <SelectItem key={p.id} value={p.id} className="text-xs">
                    {t(p.labelKey)}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
            <span className="flex-1 cursor-pointer font-mono text-xs" onClick={() => setDefault(i)}>
              {route.model}
              {isDefault ? (
                <Badge variant="secondary" className="ms-2 font-sans text-[10px]">
                  {t("admin.models.defaultBadge")}
                </Badge>
              ) : null}
              {isDefault ? (
                <span className="ms-2 font-sans text-[10px] font-bold uppercase tracking-wider text-muted-foreground">
                  {t("admin.models.fallbackFirst")}
                </span>
              ) : null}
            </span>
            <Button
              variant="ghost"
              size="sm"
              className="h-6 w-6 p-0"
              onClick={() => move(i, -1)}
              disabled={i === 0}
              aria-label={t("admin.models.moveUp")}
            >
              <ArrowUp className="size-3" />
            </Button>
            <Button
              variant="ghost"
              size="sm"
              className="h-6 w-6 p-0"
              onClick={() => move(i, 1)}
              disabled={i === routes.length - 1}
              aria-label={t("admin.models.moveDown")}
            >
              <ArrowDown className="size-3" />
            </Button>
            <Button
              variant="ghost"
              size="sm"
              className="h-6 w-6 p-0 text-red-500"
              onClick={() => remove(i)}
              aria-label={t("admin.models.remove")}
            >
              <X className="size-3" />
            </Button>
          </div>
        );
      })}

      {routes.length === 0 && (
        <p className="text-xs text-muted-foreground">{t("admin.models.emptyTier")}</p>
      )}

      {adding ? (
        <div className="space-y-2 rounded-lg border border-dashed border-border p-3">
          <div className="grid gap-2 sm:grid-cols-[auto_1fr]">
            <Select value={newProvider} onValueChange={setNewProvider}>
              <SelectTrigger className="w-44 text-xs">
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                {LLM_CHANNEL_OPTIONS.map((p) => (
                  <SelectItem key={p.id} value={p.id} className="text-xs">
                    {t(p.labelKey)}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
            {newProvider === "openrouter" ? (
              <ModelCombobox
                value={newModel}
                onChange={setNewModel}
                models={catalog}
                isLoading={catalogLoading}
                onFetchModels={onLoadCatalog}
                providerLabel="OpenRouter"
                placeholder="provider/nom-du-modèle"
              />
            ) : (
              <ModelCombobox
                value={newModel}
                onChange={setNewModel}
                models={[]}
                isLoading={false}
                onFetchModels={() => {}}
                providerLabel={t(channelLabelKey(newProvider))}
                placeholder={t("admin.models.customModelPlaceholder")}
              />
            )}
          </div>
          <p className="text-xs text-muted-foreground">{t("admin.models.routeHint")}</p>
          <div className="flex gap-2">
            <Button variant="outline" size="sm" onClick={add} disabled={!newModel.trim()}>
              {t("admin.models.addRouteConfirm")}
            </Button>
            <Button variant="ghost" size="sm" onClick={() => setAdding(false)}>
              {t("admin.models.cancel")}
            </Button>
          </div>
        </div>
      ) : (
        <div className="flex items-center gap-2 pt-1">
          <Button variant="outline" size="sm" onClick={() => setAdding(true)} className="gap-1.5">
            <Plus className="size-3" /> {t("admin.models.addModel")}
          </Button>
          <Button
            variant="ghost"
            size="sm"
            onClick={onLoadCatalog}
            disabled={catalogLoading}
            className="h-7 gap-1.5 px-2 text-xs text-muted-foreground"
          >
            {catalogLoading ? (
              <Loader2 className="size-3 animate-spin" />
            ) : (
              <RefreshCw className="size-3" />
            )}
            {t("admin.models.catalog")}
          </Button>
        </div>
      )}
    </div>
  );
}

export default function AdminModelsPage() {
  const { t } = useI18n();
  const { success, error } = useNotification();
  const [aiTiers, setAiTiers] = useState<AiTiersSettings | null>(null);
  const [fullSettings, setFullSettings] = useState<FullSettings>({});
  const [isLoading, setIsLoading] = useState(true);
  const [isSaving, setIsSaving] = useState(false);
  const [catalog, setCatalog] = useState<ModelOption[]>([]);
  const [catalogLoading, setCatalogLoading] = useState(false);

  useEffect(() => {
    loadSettings();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  const loadSettings = async () => {
    setIsLoading(true);
    try {
      const response = await fetch(`${API_BASE}/api/v1/admin/settings`, {
        headers: { Authorization: `Bearer ${getToken()}` },
      });
      if (response.ok) {
        const envelope = await response.json();
        const payload = envelope.data ?? envelope;
        setFullSettings(payload);
        if (payload.ai_tiers) {
          setAiTiers({
            essential: { models: [], default_model: "", routes: [], ...payload.ai_tiers.essential },
            premium: { models: [], default_model: "", routes: [], ...payload.ai_tiers.premium },
          });
        }
      } else {
        error({
          title: t("admin.models.loadErrorTitle"),
          description: t("admin.models.loadErrorDesc", { status: response.status }),
        });
      }
    } catch {
      error({ title: t("admin.models.networkTitle"), description: t("admin.models.networkDesc") });
    } finally {
      setIsLoading(false);
    }
  };

  const loadCatalog = async () => {
    setCatalogLoading(true);
    try {
      const response = await fetch(`${API_BASE}/api/v1/admin/providers/openrouter/models`, {
        headers: { Authorization: `Bearer ${getToken()}` },
      });
      if (response.ok) {
        const data = await response.json();
        setCatalog(data.data || []);
      } else {
        error({
          title: t("admin.models.catalogErrorTitle"),
          description: t("admin.models.loadErrorDesc", { status: response.status }),
        });
      }
    } catch {
      error({
        title: t("admin.models.catalogErrorTitle"),
        description: t("admin.models.catalogErrorDesc"),
      });
    } finally {
      setCatalogLoading(false);
    }
  };

  const save = async () => {
    if (!aiTiers) return;
    setIsSaving(true);
    try {
      const body = { ...fullSettings, ai_tiers: aiTiers };
      const response = await fetch(`${API_BASE}/api/v1/admin/settings`, {
        method: "PUT",
        headers: {
          Authorization: `Bearer ${getToken()}`,
          "Content-Type": "application/json",
        },
        body: JSON.stringify(body),
      });
      if (response.ok) {
        const envelope = await response.json();
        const payload = envelope.data ?? envelope;
        if (payload?.ai_tiers) {
          setAiTiers({
            essential: { models: [], default_model: "", routes: [], ...payload.ai_tiers.essential },
            premium: { models: [], default_model: "", routes: [], ...payload.ai_tiers.premium },
          });
        }
        success({
          title: t("admin.models.savedTitle"),
          description: t("admin.models.savedDesc"),
        });
      } else {
        const detail = await response.json().catch(() => ({}));
        error({
          title: t("admin.models.saveErrorTitle"),
          description: detail.detail || detail.message || t("admin.models.loadErrorDesc", { status: response.status }),
        });
      }
    } catch {
      error({ title: t("admin.models.networkTitle"), description: t("admin.models.saveNetworkDesc") });
    } finally {
      setIsSaving(false);
    }
  };

  if (isLoading) {
    return (
      <div className="flex items-center justify-center py-12">
        <Loader2 className="size-8 animate-spin text-muted-foreground" />
      </div>
    );
  }

  if (!aiTiers) {
    return (
      <Card>
        <CardContent className="py-8 text-center text-sm text-muted-foreground">
          {t("admin.models.missingConfig")}
        </CardContent>
      </Card>
    );
  }

  return (
    <div className="space-y-6">
      <div className="flex items-start justify-between gap-4">
        <div className="flex items-center gap-3">
          <div className="w-10 h-10 bg-blue-600/20 rounded-lg flex items-center justify-center">
            <Cpu className="w-5 h-5 text-blue-400" />
          </div>
          <div>
            <h1 className="text-xl font-semibold text-foreground">{t("admin.models.title")}</h1>
            <p className="text-sm text-muted-foreground">{t("admin.models.subtitle")}</p>
          </div>
        </div>
        <Button onClick={save} disabled={isSaving}>
          {isSaving ? (
            <>
              <Loader2 className="me-2 size-4 animate-spin" /> {t("admin.models.saving")}
            </>
          ) : (
            <>
              <Save className="me-2 size-4" /> {t("admin.models.save")}
            </>
          )}
        </Button>
      </div>

      <Card className="overflow-visible">
        <CardHeader>
          <CardTitle className="text-base">{t("admin.models.matrixTitle")}</CardTitle>
          <CardDescription>{t("admin.models.matrixDesc")}</CardDescription>
        </CardHeader>
        <CardContent className="space-y-4">
          {/* Forfait Pro — palier Essentielle */}
          <div className="rounded-xl border border-border/60 p-4">
            <div className="mb-3 flex flex-wrap items-center gap-2">
              <Badge className="bg-accent/10 text-accent border-accent/30">{t("admin.models.proBadge")}</Badge>
              <Badge variant="secondary">{t("admin.models.essentialBadge")}</Badge>
              <span className="text-xs text-muted-foreground">{t("admin.models.essentialCost")}</span>
            </div>
            <TierEditor
              tier={aiTiers.essential}
              onChange={(next) => setAiTiers({ ...aiTiers, essential: next })}
              catalog={catalog}
              onLoadCatalog={loadCatalog}
              catalogLoading={catalogLoading}
            />
            <p className="mt-3 text-xs text-muted-foreground">{t("admin.models.sharedTierNote")}</p>
          </div>

          {/* Forfait Business — palier Premium */}
          <div className="rounded-xl border border-accent/30 p-4">
            <div className="mb-3 flex flex-wrap items-center gap-2">
              <Badge className="bg-blue-500/10 text-blue-600 border-blue-500/30 dark:text-blue-300">
                {t("admin.models.businessBadge")}
              </Badge>
              <Badge variant="secondary">{t("admin.models.premiumBadge")}</Badge>
              <span className="text-xs text-muted-foreground">{t("admin.models.premiumCost")}</span>
            </div>
            <TierEditor
              tier={aiTiers.premium}
              onChange={(next) => setAiTiers({ ...aiTiers, premium: next })}
              catalog={catalog}
              onLoadCatalog={loadCatalog}
              catalogLoading={catalogLoading}
            />
            <p className="mt-3 text-xs text-muted-foreground">{t("admin.models.premiumReservedNote")}</p>
          </div>

          {/* Forfait Enterprise — lecture seule */}
          <div className="rounded-xl border border-border/40 p-4">
            <div className="mb-1 flex flex-wrap items-center gap-2">
              <Badge variant="outline">{t("admin.models.enterpriseBadge")}</Badge>
              <Badge variant="secondary">{t("admin.models.customBadge")}</Badge>
            </div>
            <p className="text-xs text-muted-foreground">{t("admin.models.customNote")}</p>
          </div>
        </CardContent>
      </Card>
    </div>
  );
}
