import { parseLlmJson, ensureArray, flattenValue } from "../lib/llm-parse";
import { useState } from "react";
import { invoke } from "@tauri-apps/api/core";

interface NpcResponse {
  bio: string;
  personality: string[];
  goals: string[];
}

const RACES = ["Human", "Elf", "Dwarf", "Halfling", "Orc", "Tiefling", "Dragonborn", "Gnome"];
const ALIGNMENTS = ["Lawful Good", "Neutral Good", "Chaotic Good", "Lawful Neutral", "True Neutral", "Chaotic Neutral", "Lawful Evil", "Neutral Evil", "Chaotic Evil"];

export function NpcGenerator() {
  const [race, setRace] = useState("Dwarf");
  const [charClass, setCharClass] = useState("Artisan");
  const [alignment, setAlignment] = useState("Chaotic Good");
  const [name, setName] = useState("");
  const [npc, setNpc] = useState<NpcResponse | null>(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState("");

  async function generate() {
    setLoading(true);
    setError("");
    setNpc(null);
    try {
      const prompt = `Create a detailed NPC for a fantasy RPG:
${name ? `Name: ${name}` : "Name: (generate one)"}
Race: ${race}
Class: ${charClass}
Alignment: ${alignment}

Provide the response as a JSON object with exactly these keys:
- "bio": a 2-3 sentence backstory
- "personality": an array of 3-5 personality traits (each trait must be a string, not an object)
- "goals": an array of 2-3 goals or motivations (each goal must be a string, not an object)

IMPORTANT: Return ONLY a raw JSON object. NO markdown fences, NO code blocks, NO extra text. Start with { and end with }.`;

      const result = await invoke<string>("generate", {
        req: { prompt, system: "You are a creative D&D dungeon master. You MUST respond with ONLY valid JSON. No markdown fences, no code blocks, no explanation. Just the JSON object.", temperature: 0.8, max_tokens: 512 },
      });

      // Try to parse JSON from the response
      const parsed = parseLlmJson<NpcResponse>(result);
      if (parsed) {
        setNpc(parsed);
      } else {
        setError("Could not parse LLM response. Try again or check your LLM connection.");
      }
    } catch (e) {
      setError(String(e));
    }
    setLoading(false);
  }

  return (
    <div className="flex flex-col gap-3 h-full overflow-y-auto">
      {/* Controls */}
      <div className="grid grid-cols-2 gap-2">
        <div className="flex flex-col gap-1">
          <label className="text-[var(--color-text-secondary)] text-xs font-medium">Name</label>
          <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={name}
            onChange={(e) => setName(e.target.value)}
            placeholder="Random"
          />
        </div>
        <div className="flex flex-col gap-1">
          <label className="text-[var(--color-text-secondary)] text-xs font-medium">Race</label>
          <select
            className="rounded-lg bg-[var(--color-bg-surface)] border border-[var(--color-border-glass)] px-3 py-1.5 text-[var(--color-text-primary)] focus:outline-none focus:border-[var(--color-gold-bright)] text-sm cursor-pointer"
            value={race}
            onChange={(e) => setRace(e.target.value)}
          >
            {RACES.map((r) => <option key={r} value={r}>{r}</option>)}
          </select>
        </div>
        <div className="flex flex-col gap-1">
          <label className="text-[var(--color-text-secondary)] text-xs font-medium">Class</label>
          <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={charClass}
            onChange={(e) => setCharClass(e.target.value)}
          />
        </div>
        <div className="flex flex-col gap-1">
          <label className="text-[var(--color-text-secondary)] text-xs font-medium">Alignment</label>
          <select
            className="rounded-lg bg-[var(--color-bg-surface)] border border-[var(--color-border-glass)] px-3 py-1.5 text-[var(--color-text-primary)] focus:outline-none focus:border-[var(--color-gold-bright)] text-sm cursor-pointer"
            value={alignment}
            onChange={(e) => setAlignment(e.target.value)}
          >
            {ALIGNMENTS.map((a) => <option key={a} value={a}>{a}</option>)}
          </select>
        </div>
      </div>

      <button
        onClick={generate}
        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"
      >
        {loading ? "✨ Generating…" : "✨ Generate NPC"}
      </button>

      {/* Result */}
      {error && (
        <div className="rounded-lg bg-[var(--color-danger)]/10 border border-[var(--color-danger)]/30 p-3 text-[var(--color-danger)] text-xs overflow-x-auto">
          {error}
        </div>
      )}

      {npc && (
        <div className="rounded-lg bg-[var(--color-bg-surface)] border border-[var(--color-border-glass)] p-3 flex flex-col gap-2">
          <h3 className="font-heading text-[var(--color-gold-bright)] text-sm">
            {name || "NPC"}
          </h3>
          <p className="text-[var(--color-text-primary)] text-sm leading-relaxed">{npc.bio}</p>
          <div>
            <span className="text-[var(--color-text-secondary)] text-xs font-medium">Personality:</span>
            <div className="flex flex-wrap gap-1 mt-1">
              {ensureArray(npc.personality).map((p, i) => (
                <span key={i} className="rounded-full bg-[var(--color-gold-glow)] text-[var(--color-gold-bright)] px-2 py-0.5 text-xs">
                  {flattenValue(p)}
                </span>
              ))}
            </div>
          </div>
          <div>
            <span className="text-[var(--color-text-secondary)] text-xs font-medium">Goals:</span>
            <ul className="list-disc list-inside text-[var(--color-text-primary)] text-xs mt-1">
              {ensureArray(npc.goals).map((g, i) => <li key={i}>{flattenValue(g)}</li>)}
            </ul>
          </div>
        </div>
      )}
    </div>
  );
}