import { useState } from "react";
import {
  ChevronRight, Check, Plus, Trash2, Pencil, Zap, ZapOff, RefreshCw, Loader2,
} from "lucide-react";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Badge } from "@/components/ui/badge";
import {
  Select, SelectContent, SelectItem, SelectTrigger, SelectValue,
} from "@/components/ui/select";
import {
  AlertDialog, AlertDialogAction, AlertDialogCancel,
  AlertDialogContent, AlertDialogDescription, AlertDialogFooter,
  AlertDialogHeader, AlertDialogTitle,
} from "@/components/ui/alert-dialog";
import { cn } from "@/lib/utils";
import {
  useProviderConfigs, useCreateProvider, useUpdateProvider,
  useDeleteProvider, useTestProvider,
} from "@/api/providers";
import type { CreateProviderRequest, ProviderConfig } from "@/types/api";

// ─── Provider metadata ────────────────────────────────────────────────────────

const PROVIDER_INFO: Record<string, {
  label: string; description: string; needsApiKey: boolean;
  needsResource: boolean; needsBaseUrl: boolean;
}> = {
  openai:    { label: "OpenAI",       description: "GPT-4o, GPT-4o-mini, o1…",             needsApiKey: true,  needsResource: false, needsBaseUrl: false },
  anthropic: { label: "Anthropic",    description: "Claude 3.5 Sonnet, Claude 3 Opus…",    needsApiKey: true,  needsResource: false, needsBaseUrl: false },
  azure:     { label: "Azure OpenAI", description: "Modèles OpenAI hébergés sur Azure",     needsApiKey: true,  needsResource: true,  needsBaseUrl: false },
  mistral:   { label: "Mistral AI",   description: "Mistral Small, Mistral Large…",         needsApiKey: true,  needsResource: false, needsBaseUrl: false },
  ollama:    { label: "Ollama",       description: "Modèles locaux auto-hébergés",          needsApiKey: false, needsResource: false, needsBaseUrl: true  },
};

// ─── Form schemas ─────────────────────────────────────────────────────────────

const providerSchema = z.object({
  provider: z.enum(["openai", "anthropic", "azure", "mistral", "ollama"]),
  display_name: z.string().optional(),
  api_key: z.string().optional(),
  base_url: z.string().optional(),
  resource_name: z.string().optional(),
  deployment_id: z.string().optional(),
  api_version: z.string().optional(),
  model_patterns: z.string().optional(), // comma-separated
});

type ProviderFormValues = z.infer<typeof providerSchema>;

const STEPS = ["Fournisseur", "Connexion", "Confirmation"];

// ─── Wizard ───────────────────────────────────────────────────────────────────

interface WizardProps {
  editTarget?: ProviderConfig;
  onClose: () => void;
}

function ProviderWizard({ editTarget, onClose }: WizardProps) {
  const [step, setStep] = useState(editTarget ? 1 : 0);
  const createMutation = useCreateProvider();
  const updateMutation = useUpdateProvider();
  const isLoading = createMutation.isPending || updateMutation.isPending;
  const [error, setError] = useState<string | null>(null);

  const form = useForm<ProviderFormValues>({
    resolver: zodResolver(providerSchema),
    defaultValues: {
      provider: editTarget?.provider ?? "openai",
      display_name: editTarget?.display_name ?? "",
      api_key: "",  // never pre-fill API key
      base_url: editTarget?.base_url ?? "",
      resource_name: editTarget?.resource_name ?? "",
      deployment_id: editTarget?.deployment_id ?? "",
      api_version: editTarget?.api_version ?? "",
      model_patterns: editTarget?.model_patterns?.join(", ") ?? "",
    },
  });

  const selectedProvider = form.watch("provider");
  const info = PROVIDER_INFO[selectedProvider];
  const formValues = form.watch();

  const handleSubmit = form.handleSubmit(async (data) => {
    setError(null);
    const patterns = data.model_patterns
      ? data.model_patterns.split(",").map((s) => s.trim()).filter(Boolean)
      : [];

    const payload: CreateProviderRequest = {
      provider: data.provider,
      display_name: data.display_name ?? "",
      api_key: data.api_key ?? "",
      base_url: data.base_url ?? "",
      resource_name: data.resource_name ?? "",
      deployment_id: data.deployment_id ?? "",
      api_version: data.api_version ?? "",
      model_patterns: patterns,
    };

    try {
      if (editTarget) {
        await updateMutation.mutateAsync({ id: editTarget.id, data: payload });
      } else {
        await createMutation.mutateAsync(payload);
      }
      onClose();
    } catch (err) {
      setError(err instanceof Error ? err.message : "Erreur lors de la sauvegarde");
    }
  });

  return (
    <div className="space-y-6 max-w-2xl">
      {/* Step indicator */}
      {!editTarget && (
        <div className="flex items-center gap-2">
          {STEPS.map((label, idx) => (
            <div key={label} className="flex items-center gap-2">
              <div className={cn(
                "h-7 w-7 rounded-full flex items-center justify-center text-xs font-semibold",
                idx < step ? "bg-green-100 text-green-700"
                  : idx === step ? "bg-primary text-primary-foreground"
                  : "bg-muted text-muted-foreground"
              )}>
                {idx < step ? <Check className="h-3.5 w-3.5" /> : idx + 1}
              </div>
              <span className={cn("text-sm", idx === step ? "font-medium" : "text-muted-foreground")}>
                {label}
              </span>
              {idx < STEPS.length - 1 && <ChevronRight className="h-4 w-4 text-muted-foreground" />}
            </div>
          ))}
        </div>
      )}

      <form onSubmit={handleSubmit}>
        {/* Step 0: Choose provider */}
        {step === 0 && (
          <div className="space-y-4 rounded-lg border p-6">
            <h3 className="font-semibold">Choisir un fournisseur</h3>
            <div className="grid grid-cols-1 gap-3">
              {Object.entries(PROVIDER_INFO).map(([key, pinfo]) => (
                <label key={key} className={cn(
                  "flex items-center gap-4 p-4 rounded-lg border cursor-pointer transition-colors",
                  selectedProvider === key ? "border-primary bg-primary/5" : "hover:border-muted-foreground/40"
                )}>
                  <input type="radio" value={key} {...form.register("provider")} className="accent-primary" />
                  <div>
                    <p className="font-medium text-sm">{pinfo.label}</p>
                    <p className="text-xs text-muted-foreground">{pinfo.description}</p>
                  </div>
                  {selectedProvider === key && <Badge variant="outline" className="ml-auto">Sélectionné</Badge>}
                </label>
              ))}
            </div>
            <Button type="button" className="w-full" onClick={() => setStep(1)}>
              Suivant <ChevronRight className="h-4 w-4 ml-1" />
            </Button>
          </div>
        )}

        {/* Step 1: Connection details */}
        {step === 1 && (
          <div className="space-y-4 rounded-lg border p-6">
            <h3 className="font-semibold">
              Paramètres — {PROVIDER_INFO[selectedProvider]?.label}
            </h3>

            <div className="space-y-1">
              <Label htmlFor="display_name">Nom d&apos;affichage (optionnel)</Label>
              <Input id="display_name" {...form.register("display_name")} placeholder="Mon OpenAI" />
            </div>

            {info?.needsApiKey && (
              <div className="space-y-1">
                <Label htmlFor="api_key">
                  Clé API {editTarget && <span className="text-muted-foreground">(laisser vide pour conserver)</span>}
                </Label>
                <Input id="api_key" type="password" {...form.register("api_key")} placeholder="sk-..." />
              </div>
            )}

            {info?.needsBaseUrl && (
              <div className="space-y-1">
                <Label htmlFor="base_url">URL de base</Label>
                <Input id="base_url" {...form.register("base_url")} placeholder="http://localhost:11434/v1" />
              </div>
            )}

            {info?.needsResource && (
              <>
                <div className="space-y-1">
                  <Label htmlFor="resource_name">Resource Name (Azure)</Label>
                  <Input id="resource_name" {...form.register("resource_name")} placeholder="my-azure-resource" />
                </div>
                <div className="space-y-1">
                  <Label htmlFor="deployment_id">Deployment ID</Label>
                  <Input id="deployment_id" {...form.register("deployment_id")} placeholder="gpt-4o" />
                </div>
              </>
            )}

            <div className="space-y-1">
              <Label htmlFor="model_patterns">Patterns de modèles (optionnel, séparés par virgule)</Label>
              <Input id="model_patterns" {...form.register("model_patterns")}
                placeholder="tinyllama, deepseek-local, mon-modele" />
              <p className="text-xs text-muted-foreground">
                Noms de modèles supplémentaires à router vers ce fournisseur
              </p>
            </div>

            <div className="flex gap-2">
              {!editTarget && (
                <Button type="button" variant="outline" onClick={() => setStep(0)}>Retour</Button>
              )}
              {editTarget && (
                <Button type="button" variant="outline" onClick={onClose}>Annuler</Button>
              )}
              <Button type="button" className="flex-1" onClick={() => {
                if (editTarget) {
                  void handleSubmit();
                } else {
                  setStep(2);
                }
              }}>
                {editTarget ? "Sauvegarder" : "Suivant"}
                {!editTarget && <ChevronRight className="h-4 w-4 ml-1" />}
              </Button>
            </div>
          </div>
        )}

        {/* Step 2: Confirmation */}
        {step === 2 && !editTarget && (
          <div className="space-y-4 rounded-lg border p-6">
            <h3 className="font-semibold">Confirmation</h3>
            <div className="space-y-2 text-sm">
              <Row label="Fournisseur" value={PROVIDER_INFO[formValues.provider]?.label} />
              {formValues.display_name && <Row label="Nom" value={formValues.display_name} />}
              {formValues.api_key && <Row label="Clé API" value={formValues.api_key.slice(0, 8) + "••••••••"} mono />}
              {formValues.base_url && <Row label="URL" value={formValues.base_url} mono />}
              {formValues.resource_name && <Row label="Resource" value={formValues.resource_name} mono />}
              {formValues.deployment_id && <Row label="Deployment" value={formValues.deployment_id} mono />}
              {formValues.model_patterns && <Row label="Patterns" value={formValues.model_patterns} mono />}
            </div>
            {error && <p className="text-sm text-destructive">{error}</p>}
            <div className="flex gap-2">
              <Button type="button" variant="outline" onClick={() => setStep(1)}>Retour</Button>
              <Button type="submit" className="flex-1" disabled={isLoading}>
                {isLoading ? <Loader2 className="h-4 w-4 animate-spin mr-2" /> : <Check className="h-4 w-4 mr-2" />}
                Confirmer
              </Button>
            </div>
          </div>
        )}
      </form>
    </div>
  );
}

function Row({ label, value, mono }: { label: string; value?: string; mono?: boolean }) {
  if (!value) return null;
  return (
    <div className="flex justify-between py-2 border-b">
      <span className="text-muted-foreground">{label}</span>
      <span className={mono ? "font-mono" : "font-medium"}>{value}</span>
    </div>
  );
}

// ─── Provider card ─────────────────────────────────────────────────────────────

interface ProviderCardProps {
  config: ProviderConfig;
  onEdit: () => void;
  onDelete: () => void;
}

function ProviderCard({ config, onEdit, onDelete }: ProviderCardProps) {
  const testMutation = useTestProvider();
  const [testResult, setTestResult] = useState<{ healthy: boolean; error?: string } | null>(null);

  const handleTest = async () => {
    setTestResult(null);
    try {
      const result = await testMutation.mutateAsync(config.id);
      setTestResult(result);
    } catch {
      setTestResult({ healthy: false, error: "Connexion échouée" });
    }
  };

  const stateColor: Record<string, string> = {
    closed: "bg-green-100 text-green-700",
    open: "bg-red-100 text-red-700",
    half_open: "bg-yellow-100 text-yellow-700",
  };
  const stateLabel: Record<string, string> = {
    closed: "Opérationnel",
    open: "En panne",
    half_open: "Récupération",
  };

  const info = PROVIDER_INFO[config.provider];

  return (
    <div className="rounded-lg border bg-card p-4 flex items-start gap-4">
      <div className="flex-1 min-w-0">
        <div className="flex items-center gap-2 flex-wrap">
          <span className="font-semibold text-sm">
            {config.display_name || info?.label || config.provider}
          </span>
          <Badge variant="outline" className="text-xs capitalize">{config.provider}</Badge>
          {config.state && (
            <span className={cn("text-xs px-2 py-0.5 rounded-full font-medium", stateColor[config.state])}>
              {stateLabel[config.state] ?? config.state}
              {config.failures ? ` (${config.failures} échecs)` : ""}
            </span>
          )}
          {!config.is_active && (
            <Badge variant="secondary" className="text-xs">Inactif</Badge>
          )}
        </div>
        {config.base_url && (
          <p className="text-xs text-muted-foreground mt-1 font-mono truncate">{config.base_url}</p>
        )}
        {config.api_key && (
          <p className="text-xs text-muted-foreground mt-0.5 font-mono">{config.api_key}</p>
        )}
        {config.model_patterns.length > 0 && (
          <p className="text-xs text-muted-foreground mt-0.5">
            Patterns : {config.model_patterns.join(", ")}
          </p>
        )}
        {testResult && (
          <p className={cn("text-xs mt-1 font-medium", testResult.healthy ? "text-green-600" : "text-destructive")}>
            {testResult.healthy ? "✓ Connexion réussie" : `✗ ${testResult.error ?? "Échec"}`}
          </p>
        )}
      </div>

      <div className="flex gap-1 shrink-0">
        <Button
          variant="ghost" size="sm"
          onClick={handleTest}
          disabled={testMutation.isPending}
          title="Tester la connexion"
        >
          {testMutation.isPending
            ? <Loader2 className="h-4 w-4 animate-spin" />
            : testResult?.healthy
            ? <Zap className="h-4 w-4 text-green-600" />
            : testResult
            ? <ZapOff className="h-4 w-4 text-destructive" />
            : <RefreshCw className="h-4 w-4" />}
        </Button>
        <Button variant="ghost" size="sm" onClick={onEdit} title="Modifier">
          <Pencil className="h-4 w-4" />
        </Button>
        <Button variant="ghost" size="sm" onClick={onDelete} className="text-destructive hover:text-destructive" title="Supprimer">
          <Trash2 className="h-4 w-4" />
        </Button>
      </div>
    </div>
  );
}

// ─── Main page ────────────────────────────────────────────────────────────────

export function ProvidersPage() {
  const { data: configs = [], isLoading } = useProviderConfigs();
  const deleteMutation = useDeleteProvider();

  const [showWizard, setShowWizard] = useState(false);
  const [editTarget, setEditTarget] = useState<ProviderConfig | undefined>(undefined);
  const [deleteTarget, setDeleteTarget] = useState<ProviderConfig | null>(null);

  const handleEdit = (cfg: ProviderConfig) => {
    setEditTarget(cfg);
    setShowWizard(true);
  };

  const handleCloseWizard = () => {
    setShowWizard(false);
    setEditTarget(undefined);
  };

  const handleConfirmDelete = async () => {
    if (!deleteTarget) return;
    try {
      await deleteMutation.mutateAsync(deleteTarget.id);
    } finally {
      setDeleteTarget(null);
    }
  };

  if (showWizard) {
    return (
      <div className="space-y-4">
        <div>
          <h2 className="text-xl font-bold">
            {editTarget ? `Modifier — ${PROVIDER_INFO[editTarget.provider]?.label}` : "Ajouter un fournisseur IA"}
          </h2>
          <p className="text-sm text-muted-foreground">
            {editTarget ? "Mettez à jour la configuration du fournisseur" : "Configurez une connexion LLM"}
          </p>
        </div>
        <ProviderWizard editTarget={editTarget} onClose={handleCloseWizard} />
      </div>
    );
  }

  return (
    <div className="space-y-6 max-w-2xl">
      <div className="flex items-center justify-between">
        <div>
          <h2 className="text-xl font-bold">Fournisseurs IA</h2>
          <p className="text-sm text-muted-foreground">
            {configs.length} fournisseur{configs.length !== 1 ? "s" : ""} configuré{configs.length !== 1 ? "s" : ""}
          </p>
        </div>
        <Button onClick={() => { setEditTarget(undefined); setShowWizard(true); }}>
          <Plus className="h-4 w-4 mr-2" /> Ajouter
        </Button>
      </div>

      {isLoading && (
        <div className="flex items-center justify-center py-12 text-muted-foreground">
          <Loader2 className="h-5 w-5 animate-spin mr-2" /> Chargement…
        </div>
      )}

      {!isLoading && configs.length === 0 && (
        <div className="rounded-lg border border-dashed p-12 text-center text-muted-foreground">
          <p className="font-medium">Aucun fournisseur configuré</p>
          <p className="text-sm mt-1">Cliquez sur «&nbsp;Ajouter&nbsp;» pour configurer votre premier fournisseur LLM.</p>
          <Button className="mt-4" onClick={() => setShowWizard(true)}>
            <Plus className="h-4 w-4 mr-2" /> Ajouter un fournisseur
          </Button>
        </div>
      )}

      <div className="space-y-3">
        {configs.map((cfg) => (
          <ProviderCard
            key={cfg.id}
            config={cfg}
            onEdit={() => handleEdit(cfg)}
            onDelete={() => setDeleteTarget(cfg)}
          />
        ))}
      </div>

      {/* Delete confirmation dialog */}
      <AlertDialog open={!!deleteTarget} onOpenChange={(open) => { if (!open) setDeleteTarget(null); }}>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>Supprimer le fournisseur ?</AlertDialogTitle>
            <AlertDialogDescription>
              La configuration de{" "}
              <strong>{deleteTarget ? PROVIDER_INFO[deleteTarget.provider]?.label : ""}</strong> sera supprimée.
              Le proxy reviendra aux paramètres par défaut (variables d&apos;environnement).
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel>Annuler</AlertDialogCancel>
            <AlertDialogAction
              onClick={handleConfirmDelete}
              className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
            >
              Supprimer
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>
    </div>
  );
}
