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 12 - Debug Tab & Cheats
  // =========================================================================
  test.describe('12 - Debug Tab & Cheats', () => {
    test.beforeEach(async ({ page }) => {
      await startFreshGame(page);
    });

    test('navigate to Debug 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, 'debug');
      expect(visited).toBe(true);

      await waitForMs(page, 500);
      const reactErrors = errors.filter(e =>
        e.includes('React') || e.includes('Minified') || e.includes('Error #')
      );
      expect(reactErrors, `React errors in Debug: ${JSON.stringify(reactErrors)}`).toHaveLength(0);
    });

    test('Debug tab shows Game State section by default', async ({ page }) => {
      await waitForMs(page, 500);
      const visited = await clickTab(page, 'debug');
      if (visited) {
        const bodyText = await page.textContent('body') || '';
        expect(bodyText).toContain('Game State');
      }
    });

    test('Debug tab has Mana Debug buttons', async ({ page }) => {
      await waitForMs(page, 500);
      const visited = await clickTab(page, 'debug');
      if (visited) {
        const fillBtn = page.getByTestId('debug-mana-fill');
        await expect(fillBtn).toBeVisible({ timeout: 5000 });
      }
    });
  });

  // =========================================================================
  // SECTION 13 - Deep Bug Hunting with Debug Bridge
  // =========================================================================
  test.describe('13 - Deep Bug Hunting (Debug Bridge)', () => {
    test.beforeEach(async ({ page }) => {
      await startFreshGame(page);
      await waitForBridge(page);
    });

    test('mana regen values in ManaDisplay are correct', async ({ page }) => {
      await waitForMs(page, 1000);
      const bodyText = await page.textContent('body') || '';
      // Check that mana regen shows positive values for Transference
      const matches = bodyText.match(/\+[\d.]+(\/hr)?/g);
      console.log(`HUNT: Found regen patterns: ${JSON.stringify(matches)}`);
      // Should have at least one positive regen value
      expect(matches && matches.length > 0).toBe(true);
    });

    test('mana values stay consistent after multiple ticks', async ({ page }) => {
      await waitForMs(page, 500);
      // Run 100 ticks via the bridge
      await page.evaluate(() => {
        (window as any).__TEST__.runTicks(100);
      });
      await waitForMs(page, 500);
      // Game should still be running (no crash)
      const bodyAfter = await page.textContent('body') || '';
      expect(bodyAfter).toBeTruthy();
      console.log('HUNT: Game still running after 100 ticks ✓');
    });

    test('debug bridge can read all store states', async ({ page }) => {
      const storeKeys = await page.evaluate(() => {
        const t = (window as any).__TEST__;
        return {
          hasGameStore: !!t.useGameStore,
          hasManaStore: !!t.useManaStore,
          hasCombatStore: !!t.useCombatStore,
          hasCraftingStore: !!t.useCraftingStore,
          hasAttunementStore: !!t.useAttunementStore,
          hasPrestigeStore: !!t.usePrestigeStore,
          hasDisciplineStore: !!t.useDisciplineStore,
          hasUIStore: !!t.useUIStore,
          hasRunTicks: typeof t.runTicks === 'function',
        };
      });
      expect(storeKeys.hasGameStore).toBe(true);
      expect(storeKeys.hasManaStore).toBe(true);
      expect(storeKeys.hasCombatStore).toBe(true);
      expect(storeKeys.hasCraftingStore).toBe(true);
      expect(storeKeys.hasAttunementStore).toBe(true);
      expect(storeKeys.hasPrestigeStore).toBe(true);
      expect(storeKeys.hasDisciplineStore).toBe(true);
      expect(storeKeys.hasUIStore).toBe(true);
      expect(storeKeys.hasRunTicks).toBe(true);
    });

    test('debug bridge runTicks advances game time', async ({ page }) => {
      const dayBefore = await page.evaluate(() =>
        (window as any).__TEST__.useGameStore.getState().day
      );
      await page.evaluate(() => {
        (window as any).__TEST__.runTicks(1200); // ~1 day
      });
      const dayAfter = await page.evaluate(() =>
        (window as any).__TEST__.useGameStore.getState().day
      );
      expect(dayAfter).toBeGreaterThanOrEqual(dayBefore);
    });
  });

  // =========================================================================
  // SECTION 14 - All Tabs Navigation Stress Test
  // =========================================================================
  test.describe('14 - All Tabs Navigation Stress Test', () => {
    test.beforeEach(async ({ page }) => {
      await startFreshGame(page);
    });

    test('all navigations work in sequence without crash', async ({ page }) => {
      const errors: string[] = [];
      page.on('console', (msg) => {
        if (msg.type() === 'error') errors.push(msg.text());
      });
      await waitForMs(page, 500);

      const tabs = [
        'stats', 'disciplines', 'debug', 'attunements', 'achievements',
        'prestige', 'equipment', 'golemancy', 'pacts', 'spire', 'crafting',
      ];

      const visitedTabs: string[] = [];
      const crashTabs: string[] = [];

      for (const tabName of tabs) {
        const tab = page.getByRole('tab', { name: new RegExp(tabName, 'i') });
        if (await tab.isVisible({ timeout: 2000 })) {
          const preErrors = [...errors];
          await tab.click();
          await waitForMs(page, 300);
          const newErrors = errors.filter(e => !preErrors.includes(e));
          const reactErrors = newErrors.filter(e =>
            e.includes('React') || e.includes('Minified') || e.includes('Error #')
          );
          if (reactErrors.length > 0) {
            crashTabs.push(tabName);
          }
          visitedTabs.push(tabName);
        }
      }

      console.log(`HUNT: Visited tabs: ${visitedTabs.join(', ')}`);
      console.log(`HUNT: Tabs with React errors: ${crashTabs.join(', ')}`);

      // All tabs should be visitable without React errors
      expect(crashTabs, `Tabs with React errors: ${JSON.stringify(crashTabs)}`).toHaveLength(0);
      // Should have visited all 11 tabs
      expect(visitedTabs.length).toBe(11);
    });
  });
});
