import React from 'react';
import { fireEvent, render, screen, waitFor, within } from '@testing-library/react';
import axios from 'axios';
import SimulationTab from '../components/SimulationTab';

jest.mock('axios');

const runResult = {
  id: 91,
  mission_id: 7,
  mission_name: 'Secure the Gene-Vault Under Fire',
  run_date: '2026-07-04T12:00:00.000Z',
  players: ['Chris', 'Rafen'],
  result: 'VICTORY',
  xp_earned: 900,
  total_rounds: 4,
  total_rolls: 9,
  success_rate: 67,
  combat_success_rate: 61,
  puzzle_success_rate: 75,
  difficulty_level: 2,
  enemy_profile: 'balanced',
  findings: [],
  story_hooks: [],
  player_cards: {
    Chris: { name: 'Chris', chapter: 'Ultramarines', spec: 'Tactical', alive: true, woundsRemaining: 15, maxWounds: 20, successCount: 3, failCount: 1, totalRolls: 4, successRate: 75, fateRemaining: 1, fateSpends: 0, combatProfile: 'balanced', conditions: [], heroMoments: [], shameList: [], ammo: [], grade: 'A' },
    Rafen: { name: 'Rafen', chapter: 'Blood Angels', spec: 'Assault', alive: true, woundsRemaining: 14, maxWounds: 20, successCount: 2, failCount: 1, totalRolls: 3, successRate: 67, fateRemaining: 1, fateSpends: 0, combatProfile: 'melee', conditions: [], heroMoments: [], shameList: [], ammo: [], grade: 'B' },
  },
  roll_feed: [
    { player: 'Chris', checkName: 'Attack', result: 32, effective: 55, success: true, dos: 3, category: 'combat' },
  ],
  scene_results: [
    {
      title: 'Gene-Vault Push',
      type: 'combat',
      cleared: true,
      enemiesRemaining: 0,
      battlemap: {
        active: true,
        stationsOnline: 2,
        geneCoreSecuredRounds: 1,
        extractionProgress: 1,
        reinforcementWaves: 1,
        objectivesMet: false,
        gridWidth: 40,
        gridHeight: 30,
        zones: [
          { id: 'extraction', x: 1, y: 11, w: 8, h: 8, tone: 'spawn' },
          { id: 'vault', x: 24, y: 9, w: 10, h: 10, tone: 'vault' },
        ],
        cover: [{ id: 'cover-1', x: 10, y: 10, w: 2, h: 2 }],
        blockers: [],
        positions: {
          'player:Chris': { x: 3, y: 14 },
          'player:Rafen': { x: 5, y: 14 },
          'enemy:Cultist Fire Team': { x: 30, y: 12 },
        },
      },
      events: [
        { type: 'battlemapMove', side: 'player', player: 'Chris', x: 6, y: 14, travelled: 3, target: 'vault' },
        { type: 'battlemapMove', side: 'enemy', actor: 'Cultist Fire Team', x: 27, y: 12, travelled: 3, target: 'Chris' },
        { type: 'battlemapAttack', attacker: 'Cultist Fire Team', target: 'Chris', mode: 'ranged', glyph: 'ranged', weapon: 'Autogun', blocked: true, reasons: ['Blocked by a wall — no line of sight'] },
        { type: 'battlemapAttack', attacker: 'Cultist Fire Team', target: 'Chris', mode: 'ranged', glyph: 'ranged', weapon: 'Autogun', reasons: ['short range', 'light cover'] },
        { type: 'kill', player: 'Chris', target: 'Cultist Fire Team' },
      ],
    },
  ],
};

describe('SimulationTab battlemap replay', () => {
  beforeEach(() => {
    jest.clearAllMocks();
    axios.get.mockImplementation((url) => {
      if (url === '/api/missions') return Promise.resolve({ data: [{ id: 7, name: 'Secure the Gene-Vault Under Fire' }] });
      if (url === '/api/players') return Promise.resolve({ data: [{ name: 'gm' }, { name: 'Chris' }, { name: 'Rafen' }] });
      if (url === '/api/simulations') return Promise.resolve({ data: [] });
      throw new Error(`Unexpected GET ${url}`);
    });
    axios.post.mockResolvedValue({ data: runResult });
  });

  test('shows mapped scenes immediately after running a new simulation', async () => {
    render(<SimulationTab />);

    fireEvent.click(await screen.findByRole('button', { name: /run new simulation/i }));
    fireEvent.click(screen.getByRole('button', { name: /run simulation/i }));

    expect(await screen.findByText('Gene-Vault Push')).toBeInTheDocument();
    expect(screen.getByText(/Battlemap: 2\/3 stations online/i)).toBeInTheDocument();
    const replayMap = screen.getByTestId('simulation-replay-map');
    expect(replayMap).toBeInTheDocument();
    expect(screen.getByText(/Starting positions loaded/i)).toBeInTheDocument();
    expect(within(replayMap).getByText('Chris')).toBeInTheDocument();
    expect(within(replayMap).getByText('Cultist Fire Team')).toBeInTheDocument();

    fireEvent.click(screen.getByRole('button', { name: /step/i }));
    fireEvent.click(screen.getByRole('button', { name: /step/i }));
    fireEvent.click(screen.getByRole('button', { name: /step/i }));

    expect(screen.getByText(/Blocked by a wall/i)).toBeInTheDocument();
    expect(screen.queryByTestId('simulation-attack-marker')).not.toBeInTheDocument();

    fireEvent.click(screen.getByRole('button', { name: /step/i }));

    expect(screen.getByText(/advanced toward vault to 6,14/i)).toBeInTheDocument();
    expect(screen.getByText(/Cultist Fire Team vs Chris \(Autogun\): short range, light cover/i)).toBeInTheDocument();
    expect(screen.getByTestId('simulation-attack-marker')).toBeInTheDocument();

    fireEvent.click(screen.getByRole('button', { name: /step/i }));

    expect(screen.getByTestId('simulation-death-marker-enemy:Cultist Fire Team')).toBeInTheDocument();
    expect(within(replayMap).queryByText('Cultist Fire Team')).not.toBeInTheDocument();
  });
});
