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

// Test data
const TEST_USER = {
  email: 'alice@example.com',
  password: 'password123',
};

// Helper to capture console errors
function setupErrorCapture(page: Page): string[] {
  const errors: string[] = [];
  page.on('console', msg => {
    if (msg.type() === 'error') {
      errors.push(msg.text());
    }
  });
  page.on('pageerror', err => {
    errors.push(err.message);
  });
  return errors;
}

// Helper to filter out expected API errors (backend may not be running)
function filterCriticalErrors(errors: string[]): string[] {
  return errors.filter(e =>
    !e.includes('Failed to load resource') &&
    !e.includes('ERR_CONNECTION_REFUSED') &&
    !e.includes('NetworkError') &&
    !e.includes('net::ERR')
  );
}

test.describe('Home Page Loading', () => {
  test('should load home page without getting stuck in spinner', async ({ page }) => {
    const errors = setupErrorCapture(page);

    await page.goto('/', { waitUntil: 'domcontentloaded' });

    // Wait for initial content
    await page.waitForTimeout(3000);

    // Check H2H branding is visible
    await expect(page.locator('header h1:has-text("H2H")')).toBeVisible({ timeout: 5000 });

    // Page should show content, not just a spinner
    // Either shows loading state briefly or actual content
    const hasContent = await page.locator('main').isVisible() ||
                       await page.locator('[class*="container"]').isVisible();
    expect(hasContent).toBe(true);

    // Check for critical errors (not API errors from missing backend)
    const criticalErrors = filterCriticalErrors(errors);
    expect(criticalErrors).toHaveLength(0);
  });

  test('should show H2H header branding', async ({ page }) => {
    await page.goto('/');
    await expect(page.locator('header h1:has-text("H2H")')).toBeVisible({ timeout: 5000 });
  });

  test('should have navigation links including Rewards', async ({ page }) => {
    await page.goto('/');
    // Check Rewards navigation exists (dropdown button)
    await expect(page.locator('nav button:has-text("Rewards"), nav a:has-text("Rewards")').first()).toBeVisible({ timeout: 5000 });
  });
});

test.describe('Rewards Pages Navigation', () => {
  test('should navigate to /rewards overview page', async ({ page }) => {
    const errors = setupErrorCapture(page);

    await page.goto('/rewards', { waitUntil: 'domcontentloaded' });
    await page.waitForTimeout(2000);

    // Check page title
    await expect(page.locator('h1:has-text("Rewards")')).toBeVisible({ timeout: 5000 });

    // Check for no critical errors
    const criticalErrors = filterCriticalErrors(errors);
    expect(criticalErrors).toHaveLength(0);
  });

  test('should navigate to /rewards/leaderboard page', async ({ page }) => {
    const errors = setupErrorCapture(page);

    await page.goto('/rewards/leaderboard', { waitUntil: 'domcontentloaded' });
    await page.waitForTimeout(2000);

    // Check page title
    await expect(page.locator('h1:has-text("Leaderboard")')).toBeVisible({ timeout: 5000 });

    const criticalErrors = filterCriticalErrors(errors);
    expect(criticalErrors).toHaveLength(0);
  });

  test('should navigate to /rewards/achievements page', async ({ page }) => {
    const errors = setupErrorCapture(page);

    await page.goto('/rewards/achievements', { waitUntil: 'domcontentloaded' });
    await page.waitForTimeout(2000);

    // Check page title
    await expect(page.locator('h1:has-text("Achievements")')).toBeVisible({ timeout: 5000 });

    const criticalErrors = filterCriticalErrors(errors);
    expect(criticalErrors).toHaveLength(0);
  });

  test('should navigate to /rewards/loot-boxes page', async ({ page }) => {
    const errors = setupErrorCapture(page);

    await page.goto('/rewards/loot-boxes', { waitUntil: 'domcontentloaded' });
    await page.waitForTimeout(2000);

    // Check page title
    await expect(page.locator('h1:has-text("Loot Boxes")')).toBeVisible({ timeout: 5000 });

    const criticalErrors = filterCriticalErrors(errors);
    expect(criticalErrors).toHaveLength(0);
  });

  test('should navigate to /rewards/activity page', async ({ page }) => {
    const errors = setupErrorCapture(page);

    await page.goto('/rewards/activity', { waitUntil: 'domcontentloaded' });
    await page.waitForTimeout(2000);

    // Check page title
    await expect(page.locator('h1:has-text("Activity")')).toBeVisible({ timeout: 5000 });

    const criticalErrors = filterCriticalErrors(errors);
    expect(criticalErrors).toHaveLength(0);
  });
});

test.describe('Header Rewards Dropdown', () => {
  test('should show Rewards dropdown button in header', async ({ page }) => {
    await page.goto('/');

    // Find the Rewards dropdown button
    const rewardsButton = page.locator('nav button:has-text("Rewards")').first();
    await expect(rewardsButton).toBeVisible({ timeout: 5000 });
  });

  test('should open dropdown menu when clicking Rewards', async ({ page }) => {
    await page.goto('/');

    // Click Rewards dropdown
    const rewardsButton = page.locator('nav button:has-text("Rewards")').first();
    await rewardsButton.click();

    // Check dropdown menu appears with all options
    await expect(page.locator('a[href="/rewards"]')).toBeVisible({ timeout: 3000 });
    await expect(page.locator('a[href="/rewards/leaderboard"]')).toBeVisible({ timeout: 3000 });
    await expect(page.locator('a[href="/rewards/achievements"]')).toBeVisible({ timeout: 3000 });
    await expect(page.locator('a[href="/rewards/loot-boxes"]')).toBeVisible({ timeout: 3000 });
    await expect(page.locator('a[href="/rewards/activity"]')).toBeVisible({ timeout: 3000 });
  });

  test('should navigate to rewards overview from dropdown', async ({ page }) => {
    await page.goto('/');

    // Click Rewards dropdown
    await page.locator('nav button:has-text("Rewards")').first().click();

    // Click Overview link
    await page.locator('a[href="/rewards"]:has-text("Overview")').click();

    // Verify navigation
    await expect(page).toHaveURL('/rewards');
    await expect(page.locator('h1:has-text("Rewards")')).toBeVisible({ timeout: 5000 });
  });

  test('should navigate to leaderboard from dropdown', async ({ page }) => {
    await page.goto('/');

    await page.locator('nav button:has-text("Rewards")').first().click();
    await page.locator('a[href="/rewards/leaderboard"]').click();

    await expect(page).toHaveURL('/rewards/leaderboard');
    await expect(page.locator('h1:has-text("Leaderboard")')).toBeVisible({ timeout: 5000 });
  });

  test('should close dropdown when clicking outside', async ({ page }) => {
    await page.goto('/');

    // Open dropdown
    await page.locator('nav button:has-text("Rewards")').first().click();
    await expect(page.locator('a[href="/rewards/leaderboard"]')).toBeVisible();

    // Click outside
    await page.locator('header h1:has-text("H2H")').click();

    // Dropdown should close (link should not be visible in dropdown context)
    await page.waitForTimeout(500);
    // The dropdown should be hidden
    const dropdown = page.locator('div.absolute a[href="/rewards/leaderboard"]');
    await expect(dropdown).not.toBeVisible({ timeout: 2000 });
  });
});

test.describe('Theme Consistency - Light Theme', () => {
  test('rewards overview page should have light theme with white backgrounds', async ({ page }) => {
    await page.goto('/rewards');
    await page.waitForTimeout(2000);

    // Check for Header component
    await expect(page.locator('header')).toBeVisible();

    // Check header has white/light background
    const header = page.locator('header');
    await expect(header).toHaveCSS('background-color', 'rgb(255, 255, 255)');

    // Check page background is light (gray-50 = rgb(249, 250, 251))
    const body = page.locator('div.min-h-screen');
    const bgColor = await body.evaluate((el) => window.getComputedStyle(el).backgroundColor);
    expect(['rgb(249, 250, 251)', 'rgb(248, 250, 252)']).toContain(bgColor);
  });

  test('leaderboard page should have light theme', async ({ page }) => {
    await page.goto('/rewards/leaderboard');
    await page.waitForTimeout(2000);

    // Check for Header component
    await expect(page.locator('header')).toBeVisible();

    // Page title should be dark text
    const title = page.locator('h1:has-text("Leaderboard")');
    await expect(title).toHaveCSS('color', 'rgb(17, 24, 39)'); // gray-900
  });

  test('achievements page should have light theme', async ({ page }) => {
    await page.goto('/rewards/achievements');
    await page.waitForTimeout(2000);

    await expect(page.locator('header')).toBeVisible();
    const title = page.locator('h1:has-text("Achievements")');
    await expect(title).toHaveCSS('color', 'rgb(17, 24, 39)');
  });

  test('loot boxes page should have light theme', async ({ page }) => {
    await page.goto('/rewards/loot-boxes');
    await page.waitForTimeout(2000);

    await expect(page.locator('header')).toBeVisible();
    const title = page.locator('h1:has-text("Loot Boxes")');
    await expect(title).toHaveCSS('color', 'rgb(17, 24, 39)');
  });

  test('activity page should have light theme', async ({ page }) => {
    await page.goto('/rewards/activity');
    await page.waitForTimeout(2000);

    await expect(page.locator('header')).toBeVisible();
    const title = page.locator('h1:has-text("Activity")');
    await expect(title).toHaveCSS('color', 'rgb(17, 24, 39)');
  });
});

test.describe('Authentication Gates', () => {
  test('achievements page should show "Sign In Required" when not logged in', async ({ page }) => {
    await page.goto('/rewards/achievements');
    await page.waitForTimeout(2000);

    // Should show sign in required message
    await expect(page.locator('text=Sign In Required')).toBeVisible({ timeout: 5000 });

    // Should have sign in button
    await expect(page.locator('a[href="/login"]:has-text("Sign In")')).toBeVisible();
  });

  test('loot boxes page should show "Sign In Required" when not logged in', async ({ page }) => {
    await page.goto('/rewards/loot-boxes');
    await page.waitForTimeout(2000);

    // Should show sign in required message
    await expect(page.locator('text=Sign In Required')).toBeVisible({ timeout: 5000 });

    // Should have sign in button
    await expect(page.locator('a[href="/login"]:has-text("Sign In")')).toBeVisible();
  });

  test('rewards overview should show "Sign In to Track Progress" when not logged in', async ({ page }) => {
    await page.goto('/rewards');
    await page.waitForTimeout(2000);

    // Should show sign in prompt
    await expect(page.locator('text=Sign In to Track Progress')).toBeVisible({ timeout: 5000 });
  });

  test('leaderboard page should be accessible without auth', async ({ page }) => {
    await page.goto('/rewards/leaderboard');
    await page.waitForTimeout(2000);

    // Should NOT show sign in required
    await expect(page.locator('text=Sign In Required')).not.toBeVisible();

    // Should show leaderboard content area
    await expect(page.locator('h1:has-text("Leaderboard")')).toBeVisible();
  });

  test('activity page should be accessible without auth', async ({ page }) => {
    await page.goto('/rewards/activity');
    await page.waitForTimeout(2000);

    // Should NOT show sign in required
    await expect(page.locator('text=Sign In Required')).not.toBeVisible();

    // Should show activity page
    await expect(page.locator('h1:has-text("Activity")')).toBeVisible();
  });
});

test.describe('Gamification Component Rendering', () => {
  test('Leaderboard component should render on rewards page', async ({ page }) => {
    await page.goto('/rewards');
    await page.waitForTimeout(2000);

    // Should have Leaderboard section with trophy icon/heading
    await expect(page.locator('h3:has-text("Leaderboard")').first()).toBeVisible({ timeout: 5000 });
  });

  test('Leaderboard component should have category tabs', async ({ page }) => {
    await page.goto('/rewards/leaderboard');
    await page.waitForTimeout(2000);

    // Check for category buttons
    await expect(page.locator('button:has-text("Top Earners")').first()).toBeVisible({ timeout: 5000 });
    await expect(page.locator('button:has-text("High Rollers")').first()).toBeVisible();
    await expect(page.locator('button:has-text("Most Wins")').first()).toBeVisible();
  });

  test('WhaleTracker component should render on rewards page', async ({ page }) => {
    await page.goto('/rewards');
    await page.waitForTimeout(2000);

    // WhaleTracker should be visible (may have whale icon or "Whale" text)
    const whaleSection = page.locator('text=/whale/i').first();
    const isVisible = await whaleSection.isVisible().catch(() => false);

    // May show loading or content - just verify the section exists
    expect(isVisible || await page.locator('.bg-white.rounded-xl').count() > 0).toBe(true);
  });

  test('rewards overview should have quick links section', async ({ page }) => {
    await page.goto('/rewards');
    await page.waitForTimeout(2000);

    // Quick links to sub-pages
    await expect(page.locator('a[href="/rewards/leaderboard"]').first()).toBeVisible({ timeout: 5000 });
    await expect(page.locator('a[href="/rewards/achievements"]').first()).toBeVisible();
    await expect(page.locator('a[href="/rewards/loot-boxes"]').first()).toBeVisible();
    await expect(page.locator('a[href="/rewards/activity"]').first()).toBeVisible();
  });

  test('rewards overview should have "How Tiers Work" section', async ({ page }) => {
    await page.goto('/rewards');
    await page.waitForTimeout(2000);

    await expect(page.locator('text=How Tiers Work')).toBeVisible({ timeout: 5000 });
  });

  test('activity page should render ActivityFeed component', async ({ page }) => {
    await page.goto('/rewards/activity');
    await page.waitForTimeout(2000);

    // Activity page should show feed area (may be empty or loading)
    // The page should render without errors
    await expect(page.locator('h1:has-text("Activity")')).toBeVisible();
  });
});

test.describe('Sub-Navigation on Rewards Pages', () => {
  test('rewards pages should have sub-navigation tabs', async ({ page }) => {
    await page.goto('/rewards');
    await page.waitForTimeout(2000);

    // Check for sub-nav with all links
    const subNav = page.locator('nav a[href="/rewards"]');
    await expect(subNav.first()).toBeVisible({ timeout: 5000 });

    await expect(page.locator('nav a[href="/rewards/leaderboard"]').first()).toBeVisible();
    await expect(page.locator('nav a[href="/rewards/achievements"]').first()).toBeVisible();
    await expect(page.locator('nav a[href="/rewards/loot-boxes"]').first()).toBeVisible();
    await expect(page.locator('nav a[href="/rewards/activity"]').first()).toBeVisible();
  });

  test('sub-navigation should highlight active page', async ({ page }) => {
    await page.goto('/rewards/leaderboard');
    await page.waitForTimeout(2000);

    // The Leaderboard tab should have the active styling (border-primary)
    const leaderboardTab = page.locator('nav a[href="/rewards/leaderboard"]').first();
    await expect(leaderboardTab).toHaveClass(/border-primary|text-primary/);
  });

  test('clicking sub-nav should navigate between pages', async ({ page }) => {
    await page.goto('/rewards');
    await page.waitForTimeout(2000);

    // Click Achievements in sub-nav
    await page.locator('nav a[href="/rewards/achievements"]').first().click();
    await expect(page).toHaveURL('/rewards/achievements');
    await expect(page.locator('h1:has-text("Achievements")')).toBeVisible({ timeout: 5000 });

    // Click Activity
    await page.locator('nav a[href="/rewards/activity"]').first().click();
    await expect(page).toHaveURL('/rewards/activity');
    await expect(page.locator('h1:has-text("Activity")')).toBeVisible({ timeout: 5000 });
  });
});

test.describe('Error Handling', () => {
  test('rewards page should handle API errors gracefully', async ({ page }) => {
    const errors = setupErrorCapture(page);

    await page.goto('/rewards');
    await page.waitForTimeout(3000);

    // Page should still render even if API fails
    await expect(page.locator('h1:has-text("Rewards")')).toBeVisible({ timeout: 5000 });

    // Should not have JS errors (API errors are expected)
    const criticalErrors = filterCriticalErrors(errors);
    expect(criticalErrors).toHaveLength(0);
  });

  test('leaderboard should show empty state or loading when API unavailable', async ({ page }) => {
    await page.goto('/rewards/leaderboard');
    await page.waitForTimeout(3000);

    // Should either show loading skeleton, empty state, or actual data
    const hasContent =
      await page.locator('.animate-pulse').count() > 0 ||
      await page.locator('text=No entries').isVisible() ||
      await page.locator('text=/\\#[0-9]+|🥇|🥈|🥉/').count() > 0;

    expect(hasContent).toBe(true);
  });
});
