import { useEffect, useState } from "react";
import { invoke } from "@tauri-apps/api/core";
import { useToast } from "./Toast";

interface LlmConfig {
  api_url: string;
  api_key: string;
  model: string;
  temperature: number;
  max_tokens: number;
  top_p: number;
  image_model: string;
  embed_model: string;
}

export function SettingsPanel() {
  const [config, setConfig] = useState<LlmConfig | null>(null);
  const [loading, setLoading] = useState(false);
  const [saved, setSaved] = useState(false);
  const [showKey, setShowKey] = useState(false);
  const [error, setError] = useState("");
  const [testing, setTesting] = useState(false);
  const [conn, setConn] = useState<{ ok: boolean; models: string[]; error: string } | null>(null);
  const { addToast } = useToast();

  // ponytail: auto-load on mount so users don't see a gate before the form.
  useEffect(() => {
    (async () => {
      try {
        const c = await invoke<LlmConfig>("get_llm_config");
        setConfig(c);
      } catch (e) {
        setError(String(e));
      }
    })();
  }, []);

  async function saveConfig() {
    if (!config) return;
    setLoading(true);
    try {
      await invoke("set_llm_config", { config });
      setSaved(true);
      setTimeout(() => setSaved(false), 2000);
      addToast("Settings saved", "success");
    } catch (e) {
      addToast(`Save failed: ${e}`, "error");
    }
    setLoading(false);
  }

  // ponytail: probe the configured endpoint for a model list. Ollama uses
  // /api/tags, OpenAI-compatible uses /v1/models. The Rust side branches.
  async function testConnection() {
    if (!config) return;
    setTesting(true);
    setConn(null);
    try {
      // Save first so the backend uses the latest URL/key.
      await invoke("set_llm_config", { config });
      const result = await invoke<{ ok: boolean; models: string[]; error: string }>("test_connection");
      setConn(result);
      if (result.ok) addToast(`Connected — ${result.models.length} models`, "success");
      else addToast(`Connection failed: ${result.error}`, "error");
    } catch (e) {
      setConn({ ok: false, models: [], error: String(e) });
      addToast(`Connection failed: ${e}`, "error");
    }
    setTesting(false);
  }

  // ponytail: provider presets fill in the API URL pattern + default model.
  const PRESETS: { label: string; url: string; model: string; key?: boolean }[] = [
    { label: "Ollama", url: "http://localhost:11434", model: "llama3.2" },
    { label: "LM Studio", url: "http://localhost:1234/v1", model: "local-model" },
    { label: "OpenAI", url: "https://api.openai.com", model: "gpt-4o-mini", key: true },
    { label: "Custom", url: "", model: "" },
  ];
  function applyPreset(p: { url: string; model: string }) {
    if (!config) return;
    setConfig({ ...config, api_url: p.url, model: p.model });
    setConn(null);
  }

  // ponytail: reset to the backend's default config. The Rust Default impl
  // is the single source of truth; we just set an empty config and let the
  // backend re-default on save — but we can't send a partial, so mirror the
  // known defaults here and toast.
  const DEFAULTS: LlmConfig = {
    api_url: "http://localhost:11434",
    api_key: "",
    model: "llama3.2",
    temperature: 0.7,
    max_tokens: 512,
    top_p: 0.9,
    image_model: "x/flux2-klein:4b",
    embed_model: "nomic-embed-text",
  };
  function resetDefaults() {
    setConfig({ ...DEFAULTS });
    setConn(null);
    addToast("Reset to defaults — click Save to apply", "info");
  }

  if (!config) {
    return (
      <div className="flex flex-col items-center justify-center h-full gap-3">
        <p className="text-[var(--color-text-secondary)] text-sm">Loading settings…</p>
        {error && (
          <p className="text-[var(--color-danger)] text-xs">Failed to load: {error}</p>
        )}
      </div>
    );
  }

  return (
    <div className="flex flex-col gap-4 text-sm">
      <h3 className="font-heading text-[var(--color-gold-bright)] text-xs font-semibold uppercase tracking-wider border-b border-[var(--color-border-subtle)] pb-1 mb-1">LLM Connection</h3>
      {/* Provider presets */}
      <div className="flex flex-col gap-1">
        <label className="text-[var(--color-text-secondary)] text-xs font-medium">Provider</label>
        <div className="flex flex-wrap gap-1.5">
          {PRESETS.map((p) => (
            <button
              key={p.label}
              type="button"
              onClick={() => applyPreset(p)}
              className={`rounded-lg px-2.5 py-1 text-xs border transition-colors cursor-pointer ${
                config.api_url === p.url
                  ? "bg-[var(--color-gold-glow)] border-[var(--color-gold-bright)] text-[var(--color-gold-bright)]"
                  : "bg-[var(--color-bg-surface)] border-[var(--color-border-glass)] text-[var(--color-text-dim)] hover:text-[var(--color-text-secondary)]"
              }`}
            >
              {p.label}
            </button>
          ))}
        </div>
      </div>

      <div className="flex flex-col gap-1">
        <label className="text-[var(--color-text-secondary)] text-xs font-medium">
          API URL
        </label>
        <input
          className="rounded-lg bg-[var(--color-bg-surface)] border border-[var(--color-border-glass)] px-3 py-2 text-[var(--color-text-primary)] placeholder-[var(--color-text-dim)] focus:outline-none focus:border-[var(--color-gold-bright)]"
          value={config.api_url}
          onChange={(e) => setConfig({ ...config, api_url: e.target.value })}
          placeholder="http://localhost:11434"
        />
      </div>

      <div className="flex flex-col gap-1">
        <label className="text-[var(--color-text-secondary)] text-xs font-medium">
          API Key (optional)
        </label>
        <div className="flex gap-1.5">
          <input
            className="flex-1 rounded-lg bg-[var(--color-bg-surface)] border border-[var(--color-border-glass)] px-3 py-2 text-[var(--color-text-primary)] placeholder-[var(--color-text-dim)] focus:outline-none focus:border-[var(--color-gold-bright)]"
            type={showKey ? "text" : "password"}
            value={config.api_key}
            onChange={(e) => setConfig({ ...config, api_key: e.target.value })}
            placeholder="sk-... (leave blank for local)"
          />
          <button
            type="button"
            onClick={() => setShowKey((s) => !s)}
            className="rounded-lg bg-[var(--color-bg-surface)] border border-[var(--color-border-glass)] px-2 text-[var(--color-text-dim)] hover:text-[var(--color-gold-bright)] hover:border-[var(--color-gold-bright)] transition-colors text-xs cursor-pointer"
            title={showKey ? "Hide" : "Show"}
          >
            {showKey ? "Hide" : "Show"}
          </button>
        </div>
      </div>

      <div className="flex flex-col gap-1">
        <label className="text-[var(--color-text-secondary)] text-xs font-medium">
          Model
        </label>
        <input
          className="rounded-lg bg-[var(--color-bg-surface)] border border-[var(--color-border-glass)] px-3 py-2 text-[var(--color-text-primary)] placeholder-[var(--color-text-dim)] focus:outline-none focus:border-[var(--color-gold-bright)]"
          value={config.model}
          onChange={(e) => setConfig({ ...config, model: e.target.value })}
          placeholder="llama3.2"
          list="model-list"
        />
        <datalist id="model-list">
          {conn?.models.map((m) => (
            <option key={m} value={m} />
          ))}
        </datalist>
      </div>

      {/* Connection test */}
      <div className="flex items-center gap-2">
        <button
          type="button"
          onClick={testConnection}
          disabled={testing}
          className="rounded-lg bg-[var(--color-bg-surface)] border border-[var(--color-border-glass)] px-3 py-1.5 text-xs font-medium text-[var(--color-text-secondary)] hover:border-[var(--color-gold-bright)] hover:text-[var(--color-gold-bright)] transition-colors cursor-pointer disabled:opacity-50"
        >
          {testing ? "Testing…" : "Test connection"}
        </button>
        {conn && (
          <span className={`text-xs ${conn.ok ? "text-[var(--color-success)]" : "text-[var(--color-danger)]"}`}>
            {conn.ok ? `✓ ${conn.models.length} models` : `✕ ${conn.error}`}
          </span>
        )}
      </div>
      {conn?.ok && conn.models.length > 0 && (
        <div className="flex flex-wrap gap-1 max-h-24 overflow-y-auto">
          {conn.models.map((m) => (
            <button
              key={m}
              type="button"
              onClick={() => setConfig({ ...config, model: m })}
              className={`rounded-full px-2 py-0.5 text-[10px] border cursor-pointer transition-colors ${
                config.model === m
                  ? "bg-[var(--color-gold-glow)] border-[var(--color-gold-bright)] text-[var(--color-gold-bright)]"
                  : "bg-[var(--color-bg-deep)] border-[var(--color-border-subtle)] text-[var(--color-text-dim)] hover:text-[var(--color-text-secondary)]"
              }`}
            >
              {m}
            </button>
          ))}
        </div>
      )}

      <h3 className="font-heading text-[var(--color-gold-bright)] text-xs font-semibold uppercase tracking-wider border-b border-[var(--color-border-subtle)] pb-1 mb-1">Image Model</h3>
      <div className="flex flex-col gap-1">
        <label className="text-[var(--color-text-secondary)] text-xs font-medium">
          Image model
        </label>
        <input
          className="rounded-lg bg-[var(--color-bg-surface)] border border-[var(--color-border-glass)] px-3 py-2 text-[var(--color-text-primary)] placeholder-[var(--color-text-dim)] focus:outline-none focus:border-[var(--color-gold-bright)]"
          value={config.image_model}
          onChange={(e) => setConfig({ ...config, image_model: e.target.value })}
          placeholder="x/flux2-klein:4b"
        />
      </div>

      <h3 className="font-heading text-[var(--color-gold-bright)] text-xs font-semibold uppercase tracking-wider border-b border-[var(--color-border-subtle)] pb-1 mb-1">Embedding Model (Lore RAG)</h3>
      <div className="flex flex-col gap-1">
        <label className="text-[var(--color-text-secondary)] text-xs font-medium">
          Embedding model (Lore RAG)
        </label>
        <input
          className="rounded-lg bg-[var(--color-bg-surface)] border border-[var(--color-border-glass)] px-3 py-2 text-[var(--color-text-primary)] placeholder-[var(--color-text-dim)] focus:outline-none focus:border-[var(--color-gold-bright)]"
          value={config.embed_model}
          onChange={(e) => setConfig({ ...config, embed_model: e.target.value })}
          placeholder="nomic-embed-text"
        />
      </div>

      <h3 className="font-heading text-[var(--color-gold-bright)] text-xs font-semibold uppercase tracking-wider border-b border-[var(--color-border-subtle)] pb-1 mb-1">Text Model</h3>
      <div className="grid grid-cols-2 gap-3">
        <div className="flex flex-col gap-1">
          <label className="text-[var(--color-text-secondary)] text-xs font-medium">
            Temperature: {config.temperature}
          </label>
          <input
            type="range"
            min="0"
            max="2"
            step="0.1"
            value={config.temperature}
            onChange={(e) =>
              setConfig({ ...config, temperature: parseFloat(e.target.value) })
            }
            className="accent-[var(--color-gold-bright)]"
          />
        </div>
        <div className="flex flex-col gap-1">
          <label className="text-[var(--color-text-secondary)] text-xs font-medium">
            Max Tokens: {config.max_tokens}
          </label>
          <input
            type="range"
            min="64"
            max="4096"
            step="64"
            value={config.max_tokens}
            onChange={(e) =>
              setConfig({ ...config, max_tokens: parseInt(e.target.value) })
            }
            className="accent-[var(--color-gold-bright)]"
          />
        </div>
      </div>

      <div className="flex gap-2">
        <button
          onClick={saveConfig}
          disabled={loading}
          className="rounded-lg bg-[var(--color-gold-bright)] text-[var(--color-bg-deep)] px-4 py-2 text-sm font-semibold hover:bg-[var(--color-gold-muted)] transition-colors cursor-pointer disabled:opacity-50"
        >
          {saved ? "✓ Saved" : loading ? "Saving…" : "Save Settings"}
        </button>
        <button
          onClick={resetDefaults}
          className="rounded-lg bg-[var(--color-bg-surface)] border border-[var(--color-border-glass)] text-[var(--color-text-dim)] px-4 py-2 text-sm hover:text-[var(--color-danger)] hover:border-[var(--color-danger)] transition-colors cursor-pointer"
        >
          Reset to defaults
        </button>
      </div>
    </div>
  );
}