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

test.describe('Blog Listing Tests', () => {
  test.beforeEach(async ({ page }) => {
    await page.goto('/blog');
  });

  test('blog page displays posts', async ({ page }) => {
    // Look for blog post cards/articles
    const posts = page.locator('article, [class*="post"], [class*="card"], [class*="blog"]').filter({ hasText: /./ });
    const count = await posts.count();
    expect(count).toBeGreaterThan(0);
  });

  test('blog posts have required elements', async ({ page }) => {
    const firstPost = page.locator('article, [class*="post"], [class*="card"]').first();

    if (await firstPost.isVisible()) {
      // Check for title
      const title = firstPost.locator('h1, h2, h3, [class*="title"]');
      await expect(title).toBeVisible();

      // Check for date or metadata
      const hasMeta = await firstPost.locator('time, [class*="date"], [class*="meta"]').count() > 0;
      expect(hasMeta).toBeTruthy();
    }
  });

  test('blog posts link to detail pages', async ({ page }) => {
    const postLink = page.locator('article a, [class*="post"] a, [class*="card"] a').first();

    if (await postLink.isVisible()) {
      const href = await postLink.getAttribute('href');
      expect(href).toContain('/blog/');
    }
  });

  test('clicking blog post navigates to detail', async ({ page }) => {
    const postLink = page.locator('article a, [class*="post"] a, [class*="card"] a').first();

    if (await postLink.isVisible()) {
      await postLink.click();
      await expect(page).toHaveURL(/\/blog\//);
    }
  });
});

test.describe('Blog Post Detail Tests', () => {
  test('blog post page renders markdown content', async ({ page }) => {
    // Navigate directly to a known blog post
    await page.goto('/blog/getting-started-with-astro');

    // Check for article content
    const article = page.locator('article, main, [class*="content"], [class*="prose"]').first();
    await expect(article).toBeVisible();

    // Check for heading
    const heading = page.locator('h1');
    await expect(heading).toBeVisible();

    // Check for paragraphs (markdown content)
    const paragraphs = page.locator('p');
    const pCount = await paragraphs.count();
    expect(pCount).toBeGreaterThan(0);
  });

  test('blog post has proper typography', async ({ page }) => {
    // Navigate directly to a known blog post
    await page.goto('/blog/getting-started-with-astro');

    // Check for prose or typography classes
    const proseContent = page.locator('[class*="prose"], [class*="typography"], article').first();
    await expect(proseContent).toBeVisible();

    // Check text is readable (not too small)
    const paragraph = page.locator('p').first();
    if (await paragraph.isVisible()) {
      const fontSize = await paragraph.evaluate((el) => {
        return parseFloat(window.getComputedStyle(el).fontSize);
      });
      expect(fontSize).toBeGreaterThanOrEqual(14); // Minimum readable size
    }
  });

  test('code blocks render correctly', async ({ page }) => {
    // Navigate directly to a known blog post that should have code blocks
    await page.goto('/blog/getting-started-with-astro');

    // Check for code blocks (if present in the post)
    const codeBlocks = page.locator('pre, code, [class*="shiki"], [class*="highlight"]');
    const codeCount = await codeBlocks.count();

    if (codeCount > 0) {
      // Code blocks should have monospace font
      const fontFamily = await codeBlocks.first().evaluate((el) => {
        return window.getComputedStyle(el).fontFamily;
      });

      expect(fontFamily.toLowerCase()).toMatch(/mono|consolas|courier|ui-monospace/);
    }
  });

  test('blog post images load', async ({ page }) => {
    // Navigate directly to a known blog post
    await page.goto('/blog/getting-started-with-astro');

    // Wait for page to fully load
    await page.waitForLoadState('networkidle');

    // Check for any visible images on the blog post page
    const images = page.locator('img');
    const imgCount = await images.count();

    // Check at least some images exist
    expect(imgCount).toBeGreaterThan(0);

    // Verify first visible image loads correctly
    for (let i = 0; i < Math.min(imgCount, 3); i++) {
      const img = images.nth(i);
      const isVisible = await img.isVisible();

      if (isVisible) {
        // Wait for image to complete loading
        await img.evaluate((el: HTMLImageElement) => {
          return new Promise((resolve) => {
            if (el.complete) {
              resolve(true);
            } else {
              el.onload = () => resolve(true);
              el.onerror = () => resolve(false);
            }
          });
        });
        break; // Found at least one visible image
      }
    }
  });
});

test.describe('Blog Category Tests', () => {
  test('posts show category badges', async ({ page }) => {
    await page.goto('/blog');

    const categoryBadges = page.locator('[class*="category"], [class*="tag"], [class*="badge"]');
    const badgeCount = await categoryBadges.count();

    // Categories should be displayed
    expect(badgeCount).toBeGreaterThanOrEqual(0);
  });
});

test.describe('Blog Responsive Tests', () => {
  test('blog listing adapts to mobile', async ({ page }) => {
    await page.setViewportSize({ width: 375, height: 667 });
    await page.goto('/blog');

    // Posts should stack on mobile
    const posts = page.locator('article, [class*="post"], [class*="card"]');
    await expect(posts.first()).toBeVisible();

    // No horizontal scroll
    const bodyWidth = await page.evaluate(() => document.body.scrollWidth);
    expect(bodyWidth).toBeLessThanOrEqual(395);
  });

  test('blog post detail is readable on mobile', async ({ page }) => {
    await page.setViewportSize({ width: 375, height: 667 });

    // Navigate directly to a known blog post
    await page.goto('/blog/getting-started-with-astro');

    // Content should not overflow (small tolerance for scrollbar)
    const bodyWidth = await page.evaluate(() => document.body.scrollWidth);
    expect(bodyWidth).toBeLessThanOrEqual(400);

    // Text should be readable
    const content = page.locator('article, [class*="prose"], [class*="content"]').first();
    await expect(content).toBeVisible();
  });
});
