import { useEffect, useState } from "react";
import { invoke } from "@tauri-apps/api/core";
import { Trash2 } from "lucide-react";

interface RagSource {
  source: string;
  chunks: number;
}

interface RagHit {
  text: string;
  source: string;
  score: number;
}

export function LorePanel() {
  const [source, setSource] = useState("");
  const [text, setText] = useState("");
  const [sources, setSources] = useState<RagSource[]>([]);
  const [adding, setAdding] = useState(false);
  const [msg, setMsg] = useState("");

  const [query, setQuery] = useState("");
  const [hits, setHits] = useState<RagHit[]>([]);
  const [searching, setSearching] = useState(false);
  const [confirmClear, setConfirmClear] = useState(false);

  async function loadSources() {
    try {
      setSources(await invoke<RagSource[]>("rag_list"));
    } catch (e) {
      console.error(e);
    }
  }

  useEffect(() => {
    loadSources();
  }, []);

  async function add() {
    if (!source.trim() || !text.trim()) return;
    setAdding(true);
    setMsg("");
    try {
      const n = await invoke<number>("rag_add", { req: { source, text } });
      setMsg(`Indexed ${n} chunk${n === 1 ? "" : "s"}`);
      setText("");
      loadSources();
    } catch (e) {
      setMsg(String(e));
    }
    setAdding(false);
    setTimeout(() => setMsg(""), 3000);
  }

  async function clearOne(s: string) {
    await invoke("rag_clear", { source: s });
    loadSources();
  }

  async function clearAll() {
    await invoke("rag_clear", { source: null });
    setConfirmClear(false);
    loadSources();
  }

  async function search() {
    if (!query.trim()) return;
    setSearching(true);
    try {
      setHits(await invoke<RagHit[]>("rag_search", { query, topK: 5 }));
    } catch (e) {
      console.error(e);
    }
    setSearching(false);
  }

  return (
    <div className="flex flex-col gap-4 text-sm">
      {/* Add lore */}
      <div className="flex flex-col gap-2">
        <h3 className="font-heading text-[var(--color-gold-bright)] text-sm">Add to Lore</h3>
        <input
          className="rounded-lg bg-[var(--color-bg-surface)] border border-[var(--color-border-glass)] px-3 py-1.5 text-[var(--color-text-primary)] placeholder-[var(--color-text-dim)] focus:outline-none focus:border-[var(--color-gold-bright)] text-sm"
          value={source}
          onChange={(e) => setSource(e.target.value)}
          placeholder="Source name (e.g. World Bible, Session 3 Notes)"
        />
        <textarea
          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)] text-sm min-h-40 resize-y"
          value={text}
          onChange={(e) => setText(e.target.value)}
          placeholder="Paste lore text. It will be chunked on paragraphs, embedded via nomic-embed-text, and stored locally."
        />
        <button
          onClick={add}
          disabled={adding}
          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"
        >
          {adding ? "Embedding…" : "Add to Lore"}
        </button>
        {msg && <span className="text-xs text-[var(--color-text-secondary)]">{msg}</span>}
      </div>

      {/* Sources */}
      <div className="flex flex-col gap-2">
        <div className="flex items-center justify-between">
          <h3 className="font-heading text-[var(--color-gold-bright)] text-sm">Indexed Sources</h3>
          {sources.length > 0 && (
            confirmClear ? (
              <div className="flex items-center gap-1">
                <span className="text-[10px] text-[var(--color-danger)]">Clear all sources?</span>
                <button
                  onClick={clearAll}
                  className="rounded bg-[var(--color-danger)] text-white px-2 py-0.5 text-[10px] font-semibold cursor-pointer"
                >
                  Yes
                </button>
                <button
                  onClick={() => setConfirmClear(false)}
                  className="rounded bg-[var(--color-bg-surface)] border border-[var(--color-border-subtle)] text-[var(--color-text-dim)] px-2 py-0.5 text-[10px] cursor-pointer"
                >
                  No
                </button>
              </div>
            ) : (
              <button
                onClick={() => setConfirmClear(true)}
                className="text-xs text-[var(--color-text-dim)] hover:text-[var(--color-danger)] cursor-pointer transition-colors"
              >
                clear all
              </button>
            )
          )}
        </div>
        {sources.length === 0 ? (
          <p className="text-xs text-[var(--color-text-dim)]">No lore indexed yet.</p>
        ) : (
          <ul className="flex flex-col gap-1">
            {sources.map((s) => (
              <li key={s.source} className="flex items-center justify-between rounded-lg bg-[var(--color-bg-surface)] border border-[var(--color-border-glass)] px-3 py-1.5">
                <span className="text-[var(--color-text-primary)] text-xs truncate">
                  {s.source} <span className="text-[var(--color-text-dim)]">· {s.chunks} chunks</span>
                </span>
                <button
                  onClick={() => clearOne(s.source)}
                  className="text-[var(--color-text-dim)] hover:text-[var(--color-danger)] cursor-pointer transition-colors shrink-0"
                  title="Clear this source"
                >
                  <Trash2 size={14} />
                </button>
              </li>
            ))}
          </ul>
        )}
      </div>

      {/* Test retrieval */}
      <div className="flex flex-col gap-2 border-t border-[var(--color-border-subtle)] pt-3">
        <h3 className="font-heading text-[var(--color-gold-bright)] text-sm">Test Retrieval</h3>
        <div className="flex gap-2">
          <input
            className="flex-1 rounded-lg bg-[var(--color-bg-surface)] border border-[var(--color-border-glass)] px-3 py-1.5 text-[var(--color-text-primary)] placeholder-[var(--color-text-dim)] focus:outline-none focus:border-[var(--color-gold-bright)] text-sm"
            value={query}
            onChange={(e) => setQuery(e.target.value)}
            onKeyDown={(e) => e.key === "Enter" && search()}
            placeholder="Ask something your lore should answer…"
          />
          <button
            onClick={search}
            disabled={searching}
            className="rounded-lg bg-[var(--color-gold-bright)] text-[var(--color-bg-deep)] px-3 py-1.5 text-sm font-semibold hover:bg-[var(--color-gold-muted)] transition-colors cursor-pointer disabled:opacity-50"
          >
            {searching ? "…" : "Search"}
          </button>
        </div>
        {hits.length > 0 && (
          <ul className="flex flex-col gap-2">
            {hits.map((h, i) => (
              <li key={i} className="rounded-lg bg-[var(--color-bg-surface)] border border-[var(--color-border-glass)] p-2">
                <div className="flex items-center justify-between mb-1">
                  <span className="text-[10px] text-[var(--color-gold-bright)]">{h.source}</span>
                  {/* ponytail: relevance bar instead of a raw cosine score a
                      DM can't read. Clamp 0–1, gold fill. */}
                  <div className="flex items-center gap-1.5">
                    <div className="w-12 h-1 rounded-full bg-[var(--color-bg-deep)] overflow-hidden">
                      <div className="h-full bg-[var(--color-gold-bright)]" style={{ width: `${Math.round(Math.max(0, Math.min(1, h.score)) * 100)}%` }} />
                    </div>
                  </div>
                </div>
                <p className="text-xs text-[var(--color-text-primary)] leading-relaxed whitespace-pre-wrap">{h.text}</p>
              </li>
            ))}
          </ul>
        )}
        {hits.length === 0 && query && !searching && (
          <p className="text-xs text-[var(--color-text-dim)]">No matches.</p>
        )}
      </div>
    </div>
  );
}