import React, { useState, useEffect, useCallback } from 'react';
import axios from 'axios';

// ─── Combat helpers (mirrors DeathwatchRoller) ───
function d100() { return Math.floor(Math.random() * 100) + 1; }
function degrees(target, roll) {
  const success = roll <= target;
  if (success) { const diff = target - roll; return { success, dos: 1 + Math.floor(diff / 10), dof: 0 }; }
  const diff = roll - target; return { success, dos: 0, dof: 1 + Math.floor(diff / 10) };
}
function hitsFromDoS(mode, dos, rof) {
  const r = rof && rof > 0 ? rof : 1;
  if (mode === 'single') return Math.min(1, r);
  if (mode === 'semi') return Math.max(1, Math.min(1 + Math.floor(dos / 2), r));
  return Math.max(1, Math.min(1 + dos, r));
}
function hitLocationFromRoll(roll) {
  const rev = Number(String(roll).padStart(2, '0').split('').reverse().join(''));
  if (rev >= 1 && rev <= 10) return 'Head';
  if (rev <= 20) return 'Right Arm';
  if (rev <= 30) return 'Left Arm';
  if (rev <= 70) return 'Body';
  if (rev <= 85) return 'Right Leg';
  return 'Left Leg';
}
function mitigateDamage(dmg, tb, armour) { return Math.max(0, dmg - tb - armour); }
function rollDie(faces) { return Math.floor(Math.random() * faces) + 1; }
function rollDice(terms, opts) {
  const tearing = !!(opts && opts.tearing);
  const proven = Math.max(0, opts && typeof opts.proven === 'number' ? opts.proven : 0);
  const out = [];
  for (const t of terms) {
    for (let i = 0; i < t.count; i++) {
      let r = rollDie(t.faces);
      if (tearing) { const alt = rollDie(t.faces); r = Math.max(r, alt); }
      if (proven > 0 && t.faces === 10) r = Math.max(r, proven);
      out.push(r);
    }
  }
  return { rolls: out, total: out.reduce((a, b) => a + b, 0) };
}
function parseDice(spec) {
  const s = String(spec || '').replace(/\s+/g, '').toLowerCase();
  const parts = s.split('+');
  let flat = 0;
  let terms = [];
  for (const p of parts) {
    if (!p) continue;
    const m = p.match(/^(\d+)d(\d+)$/);
    if (m) { const c = parseInt(m[1], 10); const f = parseInt(m[2], 10); if (!Number.isFinite(c) || !Number.isFinite(f) || c < 1 || f < 2) throw new Error('Invalid dice bounds'); terms.push({ count: c, faces: f }); }
    else { const n = Number(p); if (!Number.isNaN(n)) flat += n; else throw new Error(`Invalid dice term: ${p}`); }
  }
  if (terms.length === 0) terms = [{ count: 1, faces: 10 }];
  return { terms, flat };
}

// ─── Enemy data ───
const ENEMY_TYPES = [
  { name: 'Custom/None', tb: 4, armour: 5, wounds: 20 },
  { name: 'Imperial Guardsman', tb: 3, armourByLoc: { 'Head': 4, 'Body': 4, 'Left Arm': 4, 'Right Arm': 4, 'Left Leg': 4, 'Right Leg': 4 }, wounds: 10 },
  { name: 'Chaos Space Marine', tb: 8, armourByLoc: { 'Head': 8, 'Body': 10, 'Left Arm': 8, 'Right Arm': 8, 'Left Leg': 8, 'Right Leg': 8 }, wounds: 29 },
  { name: 'Tyranid Warrior', tb: 10, armourByLoc: { 'Head': 8, 'Body': 8, 'Left Arm': 8, 'Right Arm': 8, 'Left Leg': 8, 'Right Leg': 8 }, wounds: 48 },
  { name: 'Hormagaunt', tb: 3, armourByLoc: { 'Head': 3, 'Body': 3, 'Left Arm': 3, 'Right Arm': 3, 'Left Leg': 3, 'Right Leg': 3 }, wounds: 9 },
  { name: 'Termagant', tb: 3, armourByLoc: { 'Head': 3, 'Body': 3, 'Left Arm': 3, 'Right Arm': 3, 'Left Leg': 3, 'Right Leg': 3 }, wounds: 9 },
  { name: 'Hive Tyrant', tb: 15, armourByLoc: { 'Head': 10, 'Body': 10, 'Left Arm': 10, 'Right Arm': 10, 'Left Leg': 10, 'Right Leg': 10 }, wounds: 120 },
  { name: 'Tau Commander (Crisis Suit)', tb: 10, armourByLoc: { 'Head': 9, 'Body': 9, 'Left Arm': 9, 'Right Arm': 9, 'Left Leg': 9, 'Right Leg': 9 }, wounds: 90 },
  { name: 'Industrial Servitor', tb: 5, armourByLoc: { 'Head': 7, 'Body': 7, 'Left Arm': 7, 'Right Arm': 7, 'Left Leg': 7, 'Right Leg': 7 }, wounds: 20 },
  { name: 'Ork Boy', tb: 5, armour: 3, wounds: 13 },
  { name: 'Ork Nob', tb: 6, armour: 4, wounds: 22 },
  { name: 'Genestealer', tb: 6, armour: 6, wounds: 22 }
];

const ENEMY_THEMES = {
  tyranid: {
    label: 'Tyranid Swarm',
    enemies: ['Hormagaunt', 'Termagant', 'Tyranid Warrior', 'Hive Tyrant'],
    flavor: 'The swarm descends upon you, a tide of chitin and chitin-clawed hunger.',
    sceneNames: ['The Swarm Approaches', 'First Contact', 'The Hive Mind Awakens', 'The Tyrant Rises', 'Extermination', 'The Last Stand'],
    descriptions: [
      'A distant tremor grows into a roar - the swarm is upon you. Wave after wave of chitin and claws, driven by a hunger older than the Imperium itself.',
      'The first wave hits with terrifying speed. Hormagaunts pour over the ridge, their screeching filling the air as they close in from every direction.',
      'Through the chaos, a larger shape emerges - a Tyranid Warrior, its carapace gleaming with the intelligence of the Hive Mind. It directs the swarm with terrifying purpose.',
      'The ground shakes as the Hive Tyrant rises to its full height. A creature of pure destruction, it commands the swarm with the full might of the Hive Mind.',
      'The swarm thins, but the Tyrant remains. Its carapace is thick, its claws deadly. The Astartes stand firm, but the cost of victory will be high.',
      'One by one, the creatures fall. The swarm is broken. But the Hive Mind will send more. The Astartes stand victorious, but the war is far from over.'
    ]
  },
  chaos: {
    label: 'Chaos Forces',
    enemies: ['Chaos Space Marine', 'Industrial Servitor'],
    flavor: 'The corrupted ones march forth, their weapons raised against the light of the Emperor.',
    sceneNames: ['The Enemy Rises', 'First Blood', 'The Battle Intensifies', 'The Champion Falls', 'The Last Stand', 'Victory'],
    descriptions: [
      'The enemy emerges from the shadows, their corrupted armor gleaming with the taint of the Ruinous Powers. They march with purpose, their weapons raised against the light of the Emperor.',
      'The first exchange of fire is brutal. Chaos Space Marines return fire with devastating accuracy, their bolters roaring as they push forward.',
      'The battle intensifies as more enemies pour through the breach. The Astartes hold the line, but the cost of holding the position grows with each passing moment.',
      'A Chaos Champion steps forward, his power weapon crackling with dark energy. He challenges the Astartes to single combat, his eyes burning with corrupted fervor.',
      'The Champion falls, his corrupted armor shattered. But the battle is far from over - more enemies pour through the breach, their numbers seemingly endless.',
      "The last of the corrupted ones falls. The Astartes stand victorious, but the cost of victory is high. The Emperor's light shines through the darkness."
    ]
  },
  xenos: {
    label: 'Xenos Threat',
    enemies: ['Tau Commander (Crisis Suit)', 'Industrial Servitor'],
    flavor: 'The alien threat emerges from the shadows, their weapons trained on the Astartes.',
    sceneNames: ['The Alien Threat', 'First Contact', 'The Battle Begins', 'The Commander Falls', 'The Last Stand', 'Victory'],
    descriptions: [
      'The alien threat emerges from the shadows, their weapons trained on the Astartes. The Tau Commander stands at the head of his forces, his Crisis Suit gleaming with advanced technology.',
      'The first exchange of fire is brutal. The Tau Commander\'s Crisis Suit returns fire with devastating accuracy, its plasma cannon roaring as it pushes forward.',
      'The battle intensifies as more enemies pour through the breach. The Astartes hold the line, but the cost of holding the position grows with each passing moment.',
      'The Tau Commander falls, his Crisis Suit shattered. But the battle is far from over - more enemies pour through the breach, their numbers seemingly endless.',
      'The last of the xenos falls. The Astartes stand victorious, but the cost of victory is high. The Emperor\'s light shines through the darkness.',
      'The alien threat is broken. The Astartes stand victorious, but the war is far from over. The Emperor\'s light shines through the darkness.'
    ]
  },
  ork: {
    label: 'Ork Waaagh!',
    enemies: ['Ork Boy', 'Ork Nob'],
    flavor: 'The Orks charge forth, their Waaagh! echoing across the battlefield.',
    sceneNames: ['The Waaagh! Begins', 'First Blood', 'The Battle Intensifies', 'The Nob Falls', 'The Last Stand', 'Victory'],
    descriptions: [
      'The Orks charge forth, their Waaagh! echoing across the battlefield. They come in waves, their crude weapons raised against the Astartes.',
      'The first exchange of fire is brutal. Ork Boys return fire with devastating accuracy, their shootas roaring as they push forward.',
      'The battle intensifies as more Orks pour through the breach. The Astartes hold the line, but the cost of holding the position grows with each passing moment.',
      'An Ork Nob steps forward, his power klaw crackling with dark energy. He challenges the Astartes to single combat, his eyes burning with Ork fervor.',
      'The Nob falls, his power klaw shattered. But the battle is far from over - more Orks pour through the breach, their numbers seemingly endless.',
      'The last of the Orks falls. The Astartes stand victorious, but the cost of victory is high. The Emperor\'s light shines through the darkness.'
    ]
  }
};

const SCENE_TYPES = ['Ambush', 'Assault', 'Defense', 'Infiltration', 'Search', 'Escort'];
const THREAT_LEVELS = ['Low', 'Medium', 'High', 'Extreme'];

function uid() { return Math.random().toString(36).slice(2) + Date.now().toString(36); }

// ─── Copilot integration ───
async function callCopilot(prompt, systemPrompt = 'You are a Warhammer 40k Deathwatch RPG narrator. Write in the style of a grimdark tabletop RPG. Keep responses concise (2-3 sentences). Use vivid, atmospheric language appropriate to the Warhammer 40k universe.') {
  try {
    const res = await fetch('https://copilot-api.github.com/v1/chat/completions', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${process.env.REACT_APP_COPILOT_API_KEY || ''}`
      },
      body: JSON.stringify({
        model: 'gpt-4.1',
        messages: [
          { role: 'system', content: systemPrompt },
          { role: 'user', content: prompt }
        ],
        max_tokens: 300,
        temperature: 0.8
      })
    });
    if (res.ok) {
      const data = await res.json();
      return data.choices?.[0]?.message?.content?.trim() || '';
    }
  } catch (e) {
    console.warn('Copilot call failed:', e.message);
  }
  return null;
}

function storyHookForScene({ theme, missionName, sceneName, sceneType, index, sceneCount }) {
  const enemyLabel = theme.label.toLowerCase();
  const nextStep = index < sceneCount - 1
    ? `points toward ${theme.sceneNames[index + 1] || `Scene ${index + 2}`}`
    : 'confirms the final objective and extraction vector';
  const hooks = [
    {
      thread: `Primary thread for ${missionName || 'this mission'}`,
      clue: `The first contact carries signs that this is not a random ${enemyLabel} attack.`,
      secret: `A hidden command signal links this scene to the mission's central threat.`,
      gmAction: 'On a successful Awareness, Tactics, or Scrutiny test, reveal the command pattern and show where it leads.',
    },
    {
      thread: `Primary thread for ${missionName || 'this mission'}`,
      clue: `Battle damage, spoor, or vox fragments show the enemy is being drawn toward a specific objective.`,
      secret: `The enemy movement is masking a deeper strike against the mission target.`,
      gmAction: 'On a successful Tactics or Tech-Use test, tell the players what the enemy wants and give them a better route.',
    },
    {
      thread: `Primary thread for ${missionName || 'this mission'}`,
      clue: `A survivor, corpse, data-cache, or xenos sign reveals why this location matters.`,
      secret: `This scene contains the proof needed to identify the real priority target.`,
      gmAction: 'On a successful Medicae, Search, Awareness, or Inquiry-style test, reveal the proof and name the next decision.',
    },
    {
      thread: `Primary thread for ${missionName || 'this mission'}`,
      clue: `The enemy commits resources here because the main objective is now exposed.`,
      secret: `If the team ignores the clue, the final encounter begins with the enemy prepared.`,
      gmAction: 'On a successful Command or Tactics test, let the squad convert the clue into positioning, cover, or surprise.',
    },
    {
      thread: `Primary thread for ${missionName || 'this mission'}`,
      clue: `The final opposition reveals the complete pattern behind the mission.`,
      secret: `The victory condition is not only killing enemies; the team must secure proof, cleanse the site, or deny escape.`,
      gmAction: 'On success, state the final truth and offer a debrief hook for the next mission.',
    },
  ];
  const base = hooks[Math.min(index, hooks.length - 1)];
  return {
    ...base,
    sceneType,
    transition: `This discovery ${nextStep}.`,
    failForward: 'On failed checks, reveal a partial clue anyway, then add time pressure, enemy preparation, fatigue, or lost requisition opportunity.',
  };
}

function generatedChecksForScene(sceneType, storyHook) {
  const tactical = {
    name: 'Read the mission thread',
    skill: 'Tactics',
    characteristic: 'Int',
    target: 45,
    modifier: 0,
    reward: `${storyHook.clue} ${storyHook.transition}`,
  };
  const type = String(sceneType || '').toLowerCase();
  if (type.includes('infiltration') || type.includes('search')) {
    return [
      tactical,
      { name: 'Find the hidden proof', skill: 'Awareness', characteristic: 'Per', target: 45, modifier: 0, reward: storyHook.secret },
      { name: 'Exploit the evidence', skill: 'Tech-Use', characteristic: 'Int', target: 45, modifier: -10, reward: storyHook.transition },
    ];
  }
  if (type.includes('escort') || type.includes('defense')) {
    return [
      tactical,
      { name: 'Hold the story asset', skill: 'Command', characteristic: 'Fel', target: 45, modifier: 0, reward: storyHook.clue },
      { name: 'Spot the real threat', skill: 'Awareness', characteristic: 'Per', target: 45, modifier: 0, reward: storyHook.transition },
    ];
  }
  return [
    tactical,
    { name: 'Identify priority target', skill: 'Awareness', characteristic: 'Per', target: 45, modifier: 0, reward: storyHook.clue },
    { name: 'Force momentum', skill: 'Command', characteristic: 'Fel', target: 45, modifier: 0, reward: storyHook.transition },
  ];
}

function generatedComplicationsForScene(storyHook) {
  return [
    storyHook.failForward,
    'Enemy reinforcements arrive before the clue can be fully exploited.',
    'The squad gets the information, but a civilian, asset, or relic is put at risk.',
  ];
}

// ─── Mission generation ───
function buildGeneratedMission(config) {
  const theme = ENEMY_THEMES[config.theme] || ENEMY_THEMES.tyranid;
  const sceneCount = config.sceneCount;
  const enemyCount = config.enemyCount;
  const threatMod = THREAT_MODIFIERS[config.threat];

  const scenes = [];
  for (let i = 0; i < sceneCount; i++) {
    const sceneType = SCENE_TYPES[i % SCENE_TYPES.length];
    const sceneEnemies = [];

    for (let j = 0; j < enemyCount; j++) {
      const baseEnemy = ENEMY_TYPES.find(e => e.name === theme.enemies[j % theme.enemies.length]) || ENEMY_TYPES[1];
      const wounds = Math.floor(baseEnemy.wounds * (1 + threatMod.enemyBonus / 100));
      sceneEnemies.push({
        ...baseEnemy,
        id: uid(),
        currentWounds: wounds,
        maxWounds: wounds,
        name: `${baseEnemy.name} #${j + 1}`
      });
    }

    const name = theme.sceneNames[i] || `Scene ${i + 1}`;
    const storyHook = storyHookForScene({
      theme,
      missionName: config.missionName,
      sceneName: name,
      sceneType,
      index: i,
      sceneCount,
    });

    scenes.push({
      id: uid(),
      number: i + 1,
      type: sceneType,
      name,
      title: name,
      description: theme.descriptions[i] || `Scene ${i + 1} of the mission.`,
      objectives: [
        `Resolve ${name}.`,
        storyHook.transition,
      ],
      checks: generatedChecksForScene(sceneType, storyHook),
      complications: generatedComplicationsForScene(storyHook),
      storyHook,
      secret: storyHook.secret,
      gmNotes: `${storyHook.gmAction} ${storyHook.failForward}`,
      enemies: sceneEnemies,
      completed: false,
      result: null,
      threatMod: threatMod.sceneBonus
    });
  }

  return scenes;
}

const THREAT_MODIFIERS = {
  'Low': { enemyBonus: -10, sceneBonus: 0 },
  'Medium': { enemyBonus: 0, sceneBonus: 0 },
  'High': { enemyBonus: 10, sceneBonus: 1 },
  'Extreme': { enemyBonus: 20, sceneBonus: 2 }
};

function MissionTab({ authedPlayer }) {
  const [scenes, setScenes] = useState([]);
  const [currentScene, setCurrentScene] = useState(0);
  const [threat, setThreat] = useState('Medium');
  const [missionName, setMissionName] = useState('');
  const [combatLog, setCombatLog] = useState([]);
  const [sceneComplete, setSceneComplete] = useState(false);
  const [sceneResult, setSceneResult] = useState(null);
  const [showSetup, setShowSetup] = useState(true);
  const [showCombat, setShowCombat] = useState(false);
  const [showResults, setShowResults] = useState(false);
  const [copilotText, setCopilotText] = useState('');
  const [copilotLoading, setCopilotLoading] = useState(false);

  // Setup state
  const [sceneCount, setSceneCount] = useState(4);
  const [enemyTheme, setEnemyTheme] = useState('tyranid');
  const [enemyCount, setEnemyCount] = useState(3);
  const [playerCount, setPlayerCount] = useState(3);

  // Combat state
  const [selectedEnemy, setSelectedEnemy] = useState(null);
  const [selectedPlayer, setSelectedPlayer] = useState(null);

  // History
  const [history, setHistory] = useState([]);
  const [showHistory, setShowHistory] = useState(false);
  const [loadingHistory, setLoadingHistory] = useState(false);

  // Load mission history
  useEffect(() => {
    async function loadHistory() {
      setLoadingHistory(true);
      try {
        const res = await axios.get('/api/missions');
        setHistory(res.data || []);
      } catch (e) {
        console.warn('Failed to load missions:', e.message);
      }
      setLoadingHistory(false);
    }
    loadHistory();
  }, []);

  // Save mission to DB when it completes
  useEffect(() => {
    if (showResults && scenes.length > 0) {
      const missionData = {
        name: missionName || 'Untitled Mission',
        theme: enemyTheme,
        sceneCount,
        enemyCount,
        threatLevel: threat,
        playerCount,
        scenes,
        gmPlayer: authedPlayer
      };
      async function saveMission() {
        try {
          await axios.post('/api/missions', missionData);
        } catch (e) {
          console.warn('Failed to save mission:', e.message);
        }
      }
      saveMission();
    }
  }, [showResults]);

  // Preload Copilot text on mission generation
  useEffect(() => {
    if (showCombat && scenes.length > 0 && !copilotText) {
      const scene = scenes[currentScene];
      if (scene) {
        setCopilotLoading(true);
        callCopilot(
          `Write a 2-3 sentence opening description for this Deathwatch mission scene:\n\nMission: ${missionName || 'Untitled'}\nScene: ${scene.name}\nType: ${scene.type}\nEnemies: ${scene.enemies.map(e => e.name).join(', ')}\nTheme: ${ENEMY_THEMES[enemyTheme]?.label || 'Unknown'}\n\nWrite in the style of a grimdark tabletop RPG narrator.`,
          'You are a Warhammer 40k Deathwatch RPG narrator. Write in the style of a grimdark tabletop RPG. Keep responses concise (2-3 sentences). Use vivid, atmospheric language appropriate to the Warhammer 40k universe.'
        ).then(text => {
          if (text) setCopilotText(text);
          setCopilotLoading(false);
        });
      }
    }
  }, [showCombat, currentScene, scenes.length]);

  function handleGenerateMission() {
    const config = {
      theme: enemyTheme,
      missionName,
      sceneCount,
      enemyCount,
      threat
    };
    const newScenes = buildGeneratedMission(config);
    setScenes(newScenes);
    setCurrentScene(0);
    setCombatLog([]);
    setSceneComplete(false);
    setSceneResult(null);
    setCopilotText('');
    setShowSetup(false);
    setShowCombat(true);
  }

  function runCombat() {
    const scene = scenes[currentScene];
    if (!scene) return;

    const log = [];
    let totalDamage = 0;
    let enemiesDefeated = 0;

    for (let round = 1; round <= 3; round++) {
      for (const enemy of scene.enemies) {
        if (enemy.currentWounds <= 0) {
          enemiesDefeated++;
          continue;
        }

        const playerBS = 50 + Math.floor(Math.random() * 20);
        const attack = d100();
        const dg = degrees(playerBS, attack);

        if (dg.success) {
          const hits = hitsFromDoS('single', dg.dos, 1);
          const dmgSpec = parseDice('1d10+5');
          const r = rollDice(dmgSpec.terms, {});
          const damage = Math.max(0, r.total + dmgSpec.flat - enemy.armour);
          enemy.currentWounds = Math.max(0, enemy.currentWounds - damage);
          totalDamage += damage;
          log.push(`Round ${round}: ${selectedPlayer} hits ${enemy.name} for ${damage} damage`);

          if (enemy.currentWounds <= 0) {
            enemiesDefeated++;
            log.push(`  ${enemy.name} defeated!`);
          }
        } else {
          log.push(`Round ${round}: ${selectedPlayer} misses ${enemy.name}`);
        }
      }
    }

    setCombatLog(log);
    setSceneComplete(true);
    setSceneResult({
      damage: totalDamage,
      enemiesDefeated,
      totalEnemies: scene.enemies.length
    });
  }

  function completeScene() {
    const newScenes = [...scenes];
    newScenes[currentScene] = {
      ...newScenes[currentScene],
      completed: true,
      result: sceneResult
    };
    setScenes(newScenes);

    if (currentScene < sceneCount - 1) {
      setCurrentScene(currentScene + 1);
      setSceneComplete(false);
      setSceneResult(null);
      setCombatLog([]);
      setCopilotText('');
    } else {
      setShowCombat(false);
      setShowResults(true);
    }
  }

  function resetMission() {
    setShowSetup(true);
    setShowCombat(false);
    setShowResults(false);
    setScenes([]);
    setCurrentScene(0);
    setCombatLog([]);
    setSceneComplete(false);
    setSceneResult(null);
    setCopilotText('');
  }

  if (!authedPlayer) {
    return (
      <section className="min-h-screen bg-gradient-to-br from-slate-900 via-slate-800 to-slate-900 text-slate-100 p-4 md:p-8">
        <div className="mx-auto max-w-5xl">
          <div className="text-center">
            <h1 className="text-2xl font-bold mb-4">Mission</h1>
            <p className="text-slate-400">Please log in to access mission simulation</p>
          </div>
        </div>
      </section>
    );
  }

  return (
    <section className="min-h-screen bg-gradient-to-br from-slate-900 via-slate-800 to-slate-900 text-slate-100 p-4 md:p-8">
      <div className="mx-auto max-w-5xl space-y-6">
        <div className="flex items-center justify-between">
          <h1 className="text-3xl font-bold">Mission</h1>
          <div className="flex gap-2">
            {showSetup && (
              <button onClick={handleGenerateMission} className="px-4 py-2 bg-blue-600 hover:bg-blue-500 rounded-lg">
                Generate Mission
              </button>
            )}
            {showResults && (
              <button onClick={resetMission} className="px-4 py-2 bg-green-600 hover:bg-green-500 rounded-lg">
                New Mission
              </button>
            )}
            <button
              onClick={() => setShowHistory(!showHistory)}
              className="px-4 py-2 bg-slate-700 hover:bg-slate-600 rounded-lg"
            >
              {showHistory ? 'Hide History' : 'Mission History'}
            </button>
          </div>
        </div>

        {/* Setup Panel */}
        {showSetup && (
          <div className="rounded-xl bg-slate-800 border border-slate-700 p-6 space-y-4">
            <h2 className="text-xl font-semibold">Mission Setup</h2>
            <div className="grid grid-cols-2 md:grid-cols-4 gap-4">
              <div>
                <label className="text-xs uppercase opacity-70">Mission Name</label>
                <input
                  className="w-full rounded-lg border border-slate-600 bg-slate-800 px-3 py-2"
                  value={missionName}
                  onChange={e => setMissionName(e.target.value)}
                  placeholder="Mission Name"
                />
              </div>
              <div>
                <label className="text-xs uppercase opacity-70">Scenes</label>
                <select
                  className="w-full rounded-lg border border-slate-600 bg-slate-800 px-3 py-2"
                  value={sceneCount}
                  onChange={e => setSceneCount(parseInt(e.target.value))}
                >
                  {[4, 5, 6].map(n => <option key={n} value={n}>{n} scenes</option>)}
                </select>
              </div>
              <div>
                <label className="text-xs uppercase opacity-70">Enemy Theme</label>
                <select
                  className="w-full rounded-lg border border-slate-600 bg-slate-800 px-3 py-2"
                  value={enemyTheme}
                  onChange={e => setEnemyTheme(e.target.value)}
                >
                  {Object.entries(ENEMY_THEMES).map(([key, theme]) => (
                    <option key={key} value={key}>{theme.label}</option>
                  ))}
                </select>
              </div>
              <div>
                <label className="text-xs uppercase opacity-70">Enemy Count</label>
                <select
                  className="w-full rounded-lg border border-slate-600 bg-slate-800 px-3 py-2"
                  value={enemyCount}
                  onChange={e => setEnemyCount(parseInt(e.target.value))}
                >
                  {[1, 2, 3, 4, 5, 6].map(n => <option key={n} value={n}>{n}</option>)}
                </select>
              </div>
            </div>
            <div className="grid grid-cols-2 gap-4">
              <div>
                <label className="text-xs uppercase opacity-70">Threat Level</label>
                <select
                  className="w-full rounded-lg border border-slate-600 bg-slate-800 px-3 py-2"
                  value={threat}
                  onChange={e => setThreat(e.target.value)}
                >
                  {THREAT_LEVELS.map(t => <option key={t} value={t}>{t}</option>)}
                </select>
              </div>
              <div>
                <label className="text-xs uppercase opacity-70">Player Count</label>
                <select
                  className="w-full rounded-lg border border-slate-600 bg-slate-800 px-3 py-2"
                  value={playerCount}
                  onChange={e => setPlayerCount(parseInt(e.target.value))}
                >
                  {[1, 2, 3, 4, 5, 6].map(n => <option key={n} value={n}>{n}</option>)}
                </select>
              </div>
            </div>
          </div>
        )}

        {/* Combat Panel */}
        {showCombat && scenes.length > 0 && (
          <div className="space-y-6">
            {/* Scene Progress */}
            <div className="rounded-xl bg-slate-800 border border-slate-700 p-4">
              <div className="flex items-center justify-between mb-3">
                <h2 className="text-xl font-semibold">
                  Scene {currentScene + 1}: {scenes[currentScene]?.name}
                </h2>
                <div className="flex gap-2">
                  {scenes.map((s, i) => (
                    <div
                      key={s.id}
                      className={`w-8 h-8 rounded-full flex items-center justify-center text-sm ${
                        i === currentScene ? 'bg-blue-600' :
                        s.completed ? 'bg-green-600' : 'bg-slate-700'
                      }`}
                    >
                      {s.completed ? '✓' : i + 1}
                    </div>
                  ))}
                </div>
              </div>
            </div>

            {/* Copilot Narrative */}
            <div className="rounded-xl bg-slate-800 border border-slate-700 p-4">
              <div className="flex items-center justify-between mb-2">
                <h3 className="text-lg font-semibold">Narrative</h3>
                {copilotLoading && <span className="text-xs text-slate-400">Loading...</span>}
              </div>
              <div className="text-sm text-slate-300 italic leading-relaxed">
                {copilotText || (copilotLoading ? 'Generating...' : scenes[currentScene]?.description || '')}
              </div>
              {scenes[currentScene]?.storyHook && (
                <div className="mt-3 rounded border border-amber-700/40 bg-amber-950/20 p-3 text-xs text-amber-100">
                  <div className="font-semibold text-amber-300">GM Story Hook</div>
                  <div>{scenes[currentScene].storyHook.clue}</div>
                  <div className="mt-1 text-amber-200">{scenes[currentScene].storyHook.transition}</div>
                </div>
              )}
            </div>

            {/* Enemy List */}
            <div className="rounded-xl bg-slate-800 border border-slate-700 p-4">
              <h3 className="text-lg font-semibold mb-3">Enemies</h3>
              <div className="grid grid-cols-1 md:grid-cols-2 gap-3">
                {scenes[currentScene]?.enemies.map(enemy => (
                  <div
                    key={enemy.id}
                    className={`p-3 rounded-lg border ${
                      enemy.currentWounds <= 0 ? 'bg-red-900/20 border-red-600' : 'bg-slate-700 border-slate-600'
                    }`}
                  >
                    <div className="flex items-center justify-between">
                      <span className="font-medium">{enemy.name}</span>
                      <span className="text-red-400">
                        {enemy.currentWounds}/{enemy.maxWounds} W
                      </span>
                    </div>
                    <div className="mt-2">
                      <div className="h-2 bg-slate-800 rounded overflow-hidden">
                        <div
                          className="h-2 bg-red-500"
                          style={{ width: `${(enemy.currentWounds / enemy.maxWounds) * 100}%` }}
                        />
                      </div>
                    </div>
                  </div>
                ))}
              </div>
            </div>

            {/* Combat Controls */}
            <div className="rounded-xl bg-slate-800 border border-slate-700 p-4">
              <h3 className="text-lg font-semibold mb-3">Combat</h3>
              <div className="grid grid-cols-2 gap-4 mb-4">
                <div>
                  <label className="text-xs uppercase opacity-70">Attacker</label>
                  <select
                    className="w-full rounded-lg border border-slate-600 bg-slate-800 px-3 py-2"
                    value={selectedPlayer || ''}
                    onChange={e => setSelectedPlayer(e.target.value)}
                  >
                    <option value="">Select Player</option>
                    {Array.from({ length: playerCount }, (_, i) => (
                      <option key={i} value={`Player ${i + 1}`}>Player {i + 1}</option>
                    ))}
                  </select>
                </div>
                <div>
                  <label className="text-xs uppercase opacity-70">Target</label>
                  <select
                    className="w-full rounded-lg border border-slate-600 bg-slate-800 px-3 py-2"
                    value={selectedEnemy || ''}
                    onChange={e => setSelectedEnemy(e.target.value)}
                  >
                    <option value="">Select Enemy</option>
                    {scenes[currentScene]?.enemies.map(enemy => (
                      <option key={enemy.id} value={enemy.name} disabled={enemy.currentWounds <= 0}>
                        {enemy.name} {enemy.currentWounds <= 0 ? '(Defeated)' : ''}
                      </option>
                    ))}
                  </select>
                </div>
              </div>
              <div className="flex gap-2">
                <button
                  onClick={runCombat}
                  disabled={!selectedPlayer || !selectedEnemy}
                  className="px-4 py-2 bg-blue-600 hover:bg-blue-500 rounded-lg disabled:opacity-50"
                >
                  Run Combat
                </button>
                {sceneComplete && (
                  <button
                    onClick={completeScene}
                    className="px-4 py-2 bg-green-600 hover:bg-green-500 rounded-lg"
                  >
                    Complete Scene
                  </button>
                )}
              </div>
            </div>

            {/* Combat Log */}
            {combatLog.length > 0 && (
              <div className="rounded-xl bg-slate-800 border border-slate-700 p-4">
                <h3 className="text-lg font-semibold mb-3">Combat Log</h3>
                <div className="space-y-1 text-sm font-mono">
                  {combatLog.map((entry, i) => (
                    <div key={i} className="text-slate-300">{entry}</div>
                  ))}
                </div>
              </div>
            )}
          </div>
        )}

        {/* Results Panel */}
        {showResults && (
          <div className="rounded-xl bg-slate-800 border border-slate-700 p-6">
            <h2 className="text-2xl font-bold mb-4">Mission Complete</h2>
            <div className="grid grid-cols-2 md:grid-cols-4 gap-4">
              <div className="bg-slate-700 rounded-lg p-4 text-center">
                <div className="text-sm text-slate-300">Scenes</div>
                <div className="text-2xl font-bold">{scenes.length}</div>
              </div>
              <div className="bg-slate-700 rounded-lg p-4 text-center">
                <div className="text-sm text-slate-300">Completed</div>
                <div className="text-2xl font-bold text-green-400">
                  {scenes.filter(s => s.completed).length}
                </div>
              </div>
              <div className="bg-slate-700 rounded-lg p-4 text-center">
                <div className="text-sm text-slate-300">Total Damage</div>
                <div className="text-2xl font-bold text-red-400">
                  {scenes.reduce((sum, s) => sum + (s.result?.damage || 0), 0)}
                </div>
              </div>
              <div className="bg-slate-700 rounded-lg p-4 text-center">
                <div className="text-sm text-slate-300">Enemies Defeated</div>
                <div className="text-2xl font-bold text-yellow-400">
                  {scenes.reduce((sum, s) => sum + (s.result?.enemiesDefeated || 0), 0)}
                </div>
              </div>
            </div>
          </div>
        )}

        {/* History Panel */}
        {showHistory && (
          <div className="rounded-xl bg-slate-800 border border-slate-700 p-6">
            <h2 className="text-xl font-semibold mb-4">Mission History</h2>
            {loadingHistory ? (
              <p className="text-slate-400">Loading...</p>
            ) : history.length === 0 ? (
              <p className="text-slate-400">No missions yet.</p>
            ) : (
              <div className="space-y-3">
                {history.map(m => (
                  <div key={m.id} className="p-3 rounded-lg bg-slate-700 border border-slate-600">
                    <div className="flex items-center justify-between">
                      <div>
                        <span className="font-medium">{m.name}</span>
                        <span className="ml-2 text-xs text-slate-400">
                          {m.theme} · {m.threat_level} · {m.scene_count} scenes
                        </span>
                      </div>
                      <span className="text-xs text-slate-500">
                        {new Date(m.created_at).toLocaleDateString('da-DK')}
                      </span>
                    </div>
                  </div>
                ))}
              </div>
            )}
          </div>
        )}
      </div>
    </section>
  );
}

export default MissionTab;
