import { test, expect, type Page } from '@playwright/test';

test.use({
  baseURL: 'http://localhost:3000/',
});

// ─── Helpers ─────────────────────────────────────────────────────────────────

async function waitForMs(page: Page, ms: number) {
  await page.waitForTimeout(ms);
}

async function startFreshGame(page: Page) {
  await page.goto('/');
  await page.evaluate(() => localStorage.clear());
  await page.reload();
  await page.waitForLoadState('networkidle');
  await waitForMs(page, 3000);
}

async function waitForBridge(page: Page) {
  for (let attempt = 0; attempt < 30; attempt++) {
    const ready = await page.evaluate(() => !!(window as any).__TEST__);
    if (ready) return;
    await waitForMs(page, 1000);
  }
  throw new Error('Debug bridge (window.__TEST__) not available after 30s');
}

async function clickTab(page: Page, label: string) {
  const tab = page.getByRole('tab', { name: new RegExp(label, 'i') }).first();
  if (await tab.isVisible({ timeout: 2000 })) {
    await tab.click();
    await waitForMs(page, 400);
    return true;
  }
  return false;
}

// ─── Test Suite ──────────────────────────────────────────────────────────────

test.describe('Mana Loop - Comprehensive Playtest', () => {

  // =========================================================================
  // SECTION 1: Basic UI & Starting State
  // =========================================================================
  test.describe('1 - Basic UI & Starting State', () => {
    test.beforeEach(async ({ page }) => {
      await startFreshGame(page);
    });

    test('game loads without console errors', async ({ page }) => {
      const errors: string[] = [];
      page.on('console', (msg) => {
        if (msg.type() === 'error') errors.push(msg.text());
      });
      await waitForMs(page, 2000);
      const reactErrors = errors.filter(e =>
        e.includes('React') || e.includes('Minified') || e.includes('Error #') || e.includes('Maximum update depth')
      );
      expect(reactErrors, `React errors found: ${JSON.stringify(reactErrors)}`).toHaveLength(0);
    });

    test('ManaDisplay is visible and shows Transference mana', async ({ page }) => {
      await waitForMs(page, 500);
      // Transference starts unlocked but with 0 current mana.
      // The element section only shows elements with current > 0.
      // Click Gather a few times to get raw mana, then check the display.
      const gatherBtn = page.getByRole('button', { name: /gather/i }).first();
      await expect(gatherBtn).toBeVisible({ timeout: 10000 });
      // Gather some mana
      for (let i = 0; i < 5; i++) {
        await gatherBtn.click();
        await waitForMs(page, 100);
      }
      // The raw mana display should be visible
      const bodyText = await page.textContent('body') || '';
      expect(bodyText).toContain('mana');
    });

    test('TimeDisplay shows correct starting time', async ({ page }) => {
      await waitForMs(page, 500);
      const bodyText = await page.textContent('body');
      expect(bodyText).toContain('Day 1');
    });

    test('Activity log is present and shows start message', async ({ page }) => {
      await waitForMs(page, 500);
      const bodyText = await page.textContent('body');
      expect(bodyText).toBeTruthy();
    });
  });

  // =========================================================================
  // SECTION 2 - Stats Tab
  // =========================================================================
  test.describe('2 - Stats Tab', () => {
    test.beforeEach(async ({ page }) => {
      await startFreshGame(page);
    });

    test('navigate to Stats tab', async ({ page }) => {
      await waitForMs(page, 500);
      const visited = await clickTab(page, 'stats');
      expect(visited).toBe(true);
      const bodyText = await page.textContent('body');
      expect(bodyText).toBeTruthy();
    });

    test('Stats tab shows mana-related stats', async ({ page }) => {
      await waitForMs(page, 500);
      const visited = await clickTab(page, 'stats');
      if (visited) {
        const bodyText = await page.textContent('body') || '';
        // Stats tab should show some mana-related content
        expect(bodyText.length).toBeGreaterThan(100);
      }
    });
  });

  // =========================================================================
  // SECTION 3 - Spire / Climbing
  // =========================================================================
  test.describe('3 - Spire / Climbing', () => {
    test.beforeEach(async ({ page }) => {
      await startFreshGame(page);
    });

    test('navigate to Spire tab without crash', async ({ page }) => {
      const errors: string[] = [];
      page.on('console', (msg) => {
        if (msg.type() === 'error') errors.push(msg.text());
      });
      await waitForMs(page, 500);

      const visited = await clickTab(page, 'spire');
      expect(visited).toBe(true);

      await waitForMs(page, 500);
      const reactErrors = errors.filter(e =>
        e.includes('Maximum update depth') || e.includes('Error #185')
      );
      expect(reactErrors, `Spire tab errors: ${JSON.stringify(reactErrors)}`).toHaveLength(0);
    });

    test('Climb the Spire button is visible on main page', async ({ page }) => {
      await waitForMs(page, 500);
      const climbBtn = page.getByRole('button', { name: /climb the spire/i }).first();
      await expect(climbBtn).toBeVisible({ timeout: 10000 });
    });
  });
});
