﻿/**
 * @vitest-environment happy-dom
 */
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { cleanup, render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { MemoryRouter } from 'react-router-dom';
import MissionDeckPage from './MissionDeckPage';
import { ForgeProvider } from '../context/ForgeContext';
import { routerFuture } from '../routerFuture';
import { mockServerConfig, mockServerInfo } from '../test/fixtures';
import { api } from '../api/client';

vi.mock('../context/PresenceContext', () => ({
  usePresence: () => ({
    othersOnPage: [],
    comrades: [],
    comradesHere: () => [],
    othersOnline: false,
  }),
}));

function renderMissionDeck() {
  return render(
    <MemoryRouter initialEntries={['/mission-deck']} future={routerFuture}>
      <ForgeProvider>
        <MissionDeckPage />
      </ForgeProvider>
    </MemoryRouter>,
  );
}

describe('MissionDeckPage', () => {
  beforeEach(() => {
    vi.clearAllMocks();
    localStorage.clear();
    vi.spyOn(api, 'getConfig').mockResolvedValue(mockServerConfig());
    vi.spyOn(api, 'getServerInfo').mockResolvedValue(mockServerInfo);
    vi.spyOn(api, 'listBuilds').mockResolvedValue([]);
    vi.spyOn(api, 'buildAgent').mockResolvedValue({
      success: true,
      build_id: 'deck-build-1',
      file_name: 'worker-deck.exe',
      file_size: 4096,
      download_url: '/api/v1/builds/deck-build-1/download',
    });
    vi.spyOn(api, 'exportSpreadKit').mockResolvedValue(undefined);
    vi.stubGlobal('navigator', {
      clipboard: { writeText: vi.fn().mockResolvedValue(undefined) },
    });
  });

  afterEach(() => {
    vi.unstubAllGlobals();
    cleanup();
  });

  it('shows loading state then mission deck hero', async () => {
    renderMissionDeck();
    expect(screen.getByText(/Loading loadout defaults/)).toBeInTheDocument();
    expect(await screen.findByRole('heading', { level: 1, name: /Mission Deck/i })).toBeInTheDocument();
    expect(screen.getByText('FAST PATH')).toBeInTheDocument();
    expect(await screen.findByText(/Pick a preset loadout/i)).toBeInTheDocument();
  });

  it('renders Ghost / Loud / Spread mode chips in loadout layout', async () => {
    renderMissionDeck();
    await screen.findByRole('region', { name: 'Mission loadout' });
    expect(screen.getByRole('region', { name: 'Mission loadout' })).toBeInTheDocument();
    const loadout = screen.getByRole('region', { name: 'Mission loadout' });
    expect(loadout).toHaveTextContent('Ghost');
    expect(loadout).toHaveTextContent('Loud');
    expect(loadout).toHaveTextContent('Spread');
    expect(screen.getByRole('heading', { level: 2, name: /Ghost|Loud|Spread/ })).toBeInTheDocument();
  });

  it('shows spread profile chips and campaign slug on the right panel', async () => {
    renderMissionDeck();
    await screen.findByRole('region', { name: 'Mission loadout' });
    expect(screen.getByRole('heading', { level: 3, name: /Spread profile/i })).toBeInTheDocument();
    expect(screen.getByRole('button', { name: 'LAN Kindling' })).toBeInTheDocument();
    expect(document.getElementById('md-campaign')).toBeInTheDocument();
  });

  it('links to Forge, Emberwake, Builds, and field guide', async () => {
    renderMissionDeck();
    await screen.findByRole('region', { name: 'Mission loadout' });
    expect(screen.getAllByRole('link', { name: /^Forge$/i }).length).toBeGreaterThan(0);
    expect(screen.getAllByRole('link', { name: /^Emberwake$/i }).length).toBeGreaterThan(0);
    expect(screen.getAllByRole('link', { name: /^Builds$/i }).length).toBeGreaterThan(0);
    expect(screen.getByRole('link', { name: /Field guide/i })).toHaveAttribute('href', '/docs/#mission-deck');
    expect(screen.getByRole('link', { name: /Full Forge/i })).toHaveAttribute('href', '/forge');
  });

  it('equips and strikes using runForgeMission pipeline', async () => {
    const user = userEvent.setup();
    const buildSpy = vi.spyOn(api, 'buildAgent');
    const exportSpy = vi.spyOn(api, 'exportSpreadKit');
    renderMissionDeck();
    await screen.findByRole('region', { name: 'Mission loadout' });
    await user.click(screen.getByRole('button', { name: 'LAN Kindling' }));
    await user.click(screen.getByRole('button', { name: /Equip & Strike/i }));
    await waitFor(() => {
      expect(buildSpy).toHaveBeenCalled();
    });
    expect(exportSpy).toHaveBeenCalled();
    expect(await screen.findByText(/Forge complete/i)).toBeInTheDocument();
    expect(screen.getByRole('link', { name: /View install commands in Builds/i })).toHaveAttribute('href', '/builds');
  });
});

