"use client";

import { useState } from "react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import {
  Select,
  SelectContent,
  SelectGroup,
  SelectItem,
  SelectLabel,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { Switch } from "@/components/ui/switch";
import { toast } from "sonner";

type Provider = "openai" | "anthropic" | "openrouter" | "ollama" | "";

type UseCase = {
  key: "text" | "chat" | "vision" | "mealPlan";
  providerSetting: "DEFAULT_TEXT_PROVIDER" | "DEFAULT_CHAT_PROVIDER" | "DEFAULT_VISION_PROVIDER" | "DEFAULT_MEAL_PLAN_PROVIDER";
  modelSetting: "DEFAULT_TEXT_MODEL" | "DEFAULT_CHAT_MODEL" | "DEFAULT_VISION_MODEL" | "DEFAULT_MEAL_PLAN_MODEL";
  label: string;
  description: string;
};

const USE_CASES: UseCase[] = [
  {
    key: "text",
    providerSetting: "DEFAULT_TEXT_PROVIDER",
    modelSetting: "DEFAULT_TEXT_MODEL",
    label: "Text generation",
    description: "Recipe generation, substitutions, pairings, and other text-based AI features.",
  },
  {
    key: "chat",
    providerSetting: "DEFAULT_CHAT_PROVIDER",
    modelSetting: "DEFAULT_CHAT_MODEL",
    label: "Chatbot",
    description: "The general cooking assistant and per-recipe Q&A chat.",
  },
  {
    key: "vision",
    providerSetting: "DEFAULT_VISION_PROVIDER",
    modelSetting: "DEFAULT_VISION_MODEL",
    label: "Vision (photo import/scan)",
    description: "Importing a recipe from a photo and pantry barcode/photo scanning.",
  },
  {
    key: "mealPlan",
    providerSetting: "DEFAULT_MEAL_PLAN_PROVIDER",
    modelSetting: "DEFAULT_MEAL_PLAN_MODEL",
    label: "Meal plan generation",
    description: "Generating a full week's meal plan.",
  },
];

const PRESET_MODELS: Record<string, { label: string; models: { value: string; label: string }[] }> = {
  openai: {
    label: "OpenAI",
    models: [
      { value: "gpt-4o", label: "GPT-4o" },
      { value: "gpt-4o-mini", label: "GPT-4o mini (faster)" },
      { value: "o3-mini", label: "o3-mini (reasoning)" },
      { value: "gpt-4-turbo", label: "GPT-4 Turbo" },
    ],
  },
  anthropic: {
    label: "Anthropic",
    models: [
      { value: "claude-sonnet-4-6", label: "Claude Sonnet 4.6" },
      { value: "claude-opus-4-8", label: "Claude Opus 4.8 (most capable)" },
      { value: "claude-haiku-4-5-20251001", label: "Claude Haiku 4.5 (fastest)" },
    ],
  },
};

type Values = Partial<Record<UseCase["providerSetting"] | UseCase["modelSetting"], string | null>>;

export function AdminDefaultModelForm({
  initialValues,
  initialToolCallingEnabled,
}: {
  initialValues: Values;
  initialToolCallingEnabled: boolean;
}) {
  const [values, setValues] = useState<Values>(initialValues);
  const [toolCallingEnabled, setToolCallingEnabled] = useState(initialToolCallingEnabled);
  const [saving, setSaving] = useState(false);

  function setField(key: UseCase["providerSetting"] | UseCase["modelSetting"], value: string | null) {
    setValues((prev) => ({ ...prev, [key]: value || null }));
  }

  async function handleSave() {
    setSaving(true);
    try {
      const res = await fetch("/api/v1/admin/settings", {
        method: "PUT",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ ...values, AI_TOOL_CALLING_ENABLED: toolCallingEnabled ? null : "false" }),
      });
      if (!res.ok) throw new Error("Save failed");
      toast.success("Default AI providers saved");
    } catch {
      toast.error("Failed to save defaults");
    } finally {
      setSaving(false);
    }
  }

  return (
    <section className="rounded-xl border p-6 space-y-4">
      <div>
        <h2 className="font-semibold text-lg">Default Models</h2>
        <p className="text-sm text-muted-foreground mt-1">
          What to use for a given feature when a user hasn&apos;t set their own model preference and has no personal API key.
          Leave a provider unset to fall back to whichever provider key is configured above.
        </p>
      </div>

      <div className="space-y-3">
        {USE_CASES.map(({ key, providerSetting, modelSetting, label, description }) => {
          const provider = (values[providerSetting] ?? "") as Provider;
          const model = (values[modelSetting] ?? "") as string;
          const presets = provider && PRESET_MODELS[provider]?.models;

          return (
            <div key={key} className="rounded-lg border p-4 space-y-3">
              <div>
                <p className="font-medium text-sm">{label}</p>
                <p className="text-xs text-muted-foreground">{description}</p>
              </div>
              <div className="grid grid-cols-2 gap-3">
                <div className="space-y-1.5">
                  <Label className="text-xs">Provider</Label>
                  <Select
                    value={provider || "default"}
                    onValueChange={(v) => {
                      const val = v === "default" ? null : v;
                      setField(providerSetting, val);
                      setField(modelSetting, null);
                    }}
                  >
                    <SelectTrigger className="h-8 text-sm">
                      <SelectValue />
                    </SelectTrigger>
                    <SelectContent>
                      <SelectItem value="default">
                        <span className="text-muted-foreground">Auto (first configured key)</span>
                      </SelectItem>
                      <SelectItem value="openai">OpenAI</SelectItem>
                      <SelectItem value="anthropic">Anthropic</SelectItem>
                      <SelectItem value="openrouter">OpenRouter</SelectItem>
                      <SelectItem value="ollama">Ollama (local)</SelectItem>
                    </SelectContent>
                  </Select>
                </div>

                <div className="space-y-1.5">
                  <Label className="text-xs">Model</Label>
                  {presets ? (
                    <Select
                      value={model || "default"}
                      onValueChange={(v) => setField(modelSetting, v === "default" ? null : v)}
                    >
                      <SelectTrigger className="h-8 text-sm">
                        <SelectValue placeholder="Provider default" />
                      </SelectTrigger>
                      <SelectContent>
                        <SelectItem value="default">
                          <span className="text-muted-foreground">Provider default</span>
                        </SelectItem>
                        <SelectGroup>
                          <SelectLabel>{PRESET_MODELS[provider]?.label}</SelectLabel>
                          {presets.map((m) => (
                            <SelectItem key={m.value} value={m.value}>{m.label}</SelectItem>
                          ))}
                        </SelectGroup>
                      </SelectContent>
                    </Select>
                  ) : (
                    <Input
                      className="h-8 text-sm"
                      placeholder={provider ? "Model name" : "—"}
                      value={model}
                      onChange={(e) => setField(modelSetting, e.target.value)}
                      disabled={!provider}
                    />
                  )}
                </div>
              </div>

              {key === "chat" && (
                <div className="flex items-center justify-between border-t pt-3">
                  <div>
                    <Label className="text-xs">Tool calling</Label>
                    <p className="text-xs text-muted-foreground">
                      Lets the chatbot draft a recipe or shopping list inline. Turn off for a model that can&apos;t reliably call tools (e.g. some local/Ollama models) — it&apos;ll fall back to plain text answers.
                    </p>
                  </div>
                  <Switch
                    checked={toolCallingEnabled}
                    onCheckedChange={setToolCallingEnabled}
                    className="shrink-0"
                  />
                </div>
              )}
            </div>
          );
        })}
      </div>

      <Button onClick={() => { void handleSave(); }} disabled={saving} size="sm">
        {saving ? "Saving…" : "Save"}
      </Button>
    </section>
  );
}
