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

interface Encounter {
  monsters: string[];
  terrain: string;
  difficulty: string;
  loot: string;
}

export function EncounterBuilder() {
  const [partyLevel, setPartyLevel] = useState(5);
  const [partySize, setPartySize] = useState(4);
  const [terrain, setTerrain] = useState("Forest");
  const [encounter, setEncounter] = useState<Encounter | null>(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState("");

  async function generate() {
    setLoading(true);
    setError("");
    setEncounter(null);
    try {
      const result = await invoke<string>("generate", {
        req: {
          prompt: `Generate a D&D 5e encounter for a party of ${partySize} level-${partyLevel} characters in a ${terrain.toLowerCase()} setting.

Provide the response as a JSON object with exactly these keys:
- "monsters": an array of 2-4 monster descriptions with quantities (e.g. "3x Goblin Scouts") — each must be a string, not an object
- "terrain": a brief terrain description with environmental features
- "difficulty": one of Easy/Medium/Hard/Deadly
- "loot": a brief treasure description

IMPORTANT: Return ONLY a raw JSON object. NO markdown fences, NO code blocks, NO extra text. Start with { and end with }.`,
          system: "You are a D&D encounter designer. You MUST respond with ONLY valid JSON. No markdown fences, no code blocks, no explanation. Just the JSON object.",
          temperature: 0.9,
          max_tokens: 400,
        },
      });
      const parsed = parseLlmJson<Encounter>(result);
      if (parsed) {
        setEncounter(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-2 h-full overflow-y-auto">
      <div className="grid grid-cols-2 gap-2">
        <div className="flex flex-col gap-1">
          <label className="text-[var(--color-text-secondary)] text-[10px] font-medium">Party Level</label>
          <input
            type="number"
            min={1}
            max={20}
            value={partyLevel}
            onChange={(e) => setPartyLevel(parseInt(e.target.value) || 1)}
            className="rounded-lg bg-[var(--color-bg-surface)] border border-[var(--color-border-glass)] px-2 py-1 text-[var(--color-text-primary)] focus:outline-none focus:border-[var(--color-gold-bright)] text-xs font-mono"
          />
        </div>
        <div className="flex flex-col gap-1">
          <label className="text-[var(--color-text-secondary)] text-[10px] font-medium">Party Size</label>
          <input
            type="number"
            min={1}
            max={10}
            value={partySize}
            onChange={(e) => setPartySize(parseInt(e.target.value) || 1)}
            className="rounded-lg bg-[var(--color-bg-surface)] border border-[var(--color-border-glass)] px-2 py-1 text-[var(--color-text-primary)] focus:outline-none focus:border-[var(--color-gold-bright)] text-xs font-mono"
          />
        </div>
      </div>

      <div className="flex flex-col gap-1">
        <label className="text-[var(--color-text-secondary)] text-[10px] font-medium">Terrain</label>
        <select
          value={terrain}
          onChange={(e) => setTerrain(e.target.value)}
          className="rounded-lg bg-[var(--color-bg-surface)] border border-[var(--color-border-glass)] px-2 py-1.5 text-[var(--color-text-primary)] focus:outline-none focus:border-[var(--color-gold-bright)] text-xs cursor-pointer"
        >
          {["Forest", "Dungeon", "Urban", "Mountain", "Desert", "Swamp", "Coastal", "Underdark"].map((t) => (
            <option key={t} value={t}>{t}</option>
          ))}
        </select>
      </div>

      <button
        onClick={generate}
        disabled={loading}
        className="rounded-lg bg-[var(--color-gold-bright)] text-[var(--color-bg-deep)] px-4 py-2 text-xs font-semibold hover:bg-[var(--color-gold-muted)] transition-colors cursor-pointer disabled:opacity-50"
      >
        {loading ? "⚔ Generating…" : "⚔ Generate Encounter"}
      </button>

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

      {encounter && (
        <div className="rounded-lg bg-[var(--color-bg-surface)] border border-[var(--color-border-glass)] p-3 flex flex-col gap-2">
          <div className="flex items-center justify-between">
            <span className="font-heading text-[var(--color-gold-bright)] text-xs font-semibold">
              {encounter.difficulty} Encounter
            </span>
            <span className="text-[var(--color-text-dim)] text-[10px]">
              Level {partyLevel} × {partySize}
            </span>
          </div>

          <div>
            <span className="text-[var(--color-text-secondary)] text-[10px] font-medium">Monsters</span>
            <ul className="list-disc list-inside text-[var(--color-text-primary)] text-xs mt-0.5">
              {ensureArray(encounter.monsters).map((m, i) => <li key={i}>{flattenValue(m)}</li>)}
            </ul>
          </div>

          <div>
            <span className="text-[var(--color-text-secondary)] text-[10px] font-medium">Terrain Features</span>
            <p className="text-[var(--color-text-primary)] text-xs mt-0.5">{encounter.terrain}</p>
          </div>

          <div>
            <span className="text-[var(--color-text-secondary)] text-[10px] font-medium">Loot</span>
            <p className="text-[var(--color-gold-bright)] text-xs mt-0.5">{encounter.loot}</p>
          </div>
        </div>
      )}
    </div>
  );
}