import { expect, test } from '@playwright/test';
import { getAdminToken, installAdminToken } from './helpers/admin-auth';

// 테스트 계정 (실 admin 계정과 분리)
const TEST_USERNAME = process.env.E2E_ADMIN_USERNAME ?? 'test_admin';
const TEST_PASSWORD = process.env.E2E_ADMIN_PASSWORD ?? 'TestAdmin@123456';
const baseUrl = (process.env.E2E_BASE_URL ?? 'https://www.taxbaik.com').replace(/\/$/, '');

test.describe('admin responsive design (admin account)', () => {
  const deviceTests = [
    { name: 'Desktop (1920px)', viewport: { width: 1920, height: 1080 }, minElements: 4 },
    { name: 'Desktop (1440px)', viewport: { width: 1440, height: 900 }, minElements: 4 },
    { name: 'Laptop (1024px)', viewport: { width: 1024, height: 768 }, minElements: 4 },
    { name: 'Tablet L (960px)', viewport: { width: 960, height: 600 }, minElements: 3 },
    { name: 'Tablet M (768px)', viewport: { width: 768, height: 1024 }, minElements: 2 },
    { name: 'Tablet S (600px)', viewport: { width: 600, height: 800 }, minElements: 1 },
    { name: 'Mobile L (480px)', viewport: { width: 480, height: 853 }, minElements: 1 },
    { name: 'Mobile S (375px)', viewport: { width: 375, height: 667 }, minElements: 1 }
  ];

  test('dashboard loads correctly on all viewports', async ({ page }) => {
    test.skip(!TEST_USERNAME || !TEST_PASSWORD, 'E2E_ADMIN_USERNAME and E2E_ADMIN_PASSWORD are required.');
    // 브라우저 로그 출력 설정
    page.on('console', msg => console.log(`[Browser Console] [${msg.type()}] ${msg.text()}`));
    page.on('pageerror', err => console.log(`[Browser Exception] ${err.message}`));
    page.on('console', msg => {
      if (msg.type() === 'error' && msg.text().includes('401 (Unauthorized)')) {
        return;
      }
    });

    const token = await getAdminToken(page.context().request, baseUrl, TEST_USERNAME, TEST_PASSWORD);
    await installAdminToken(page, token);
    
    // 2. 대시보드로 이동 및 최초 로드 대기
    await page.goto(`${baseUrl}/admin/dashboard`);
    await expect(page.locator('.admin-page-hero')).toBeVisible({ timeout: 30_000 });

    // 3. 각 디바이스별로 뷰포트를 변경하며 검증 (새로고침 없이 초고속 검증)
    for (const device of deviceTests) {
      console.log(`Running responsive check on: ${device.name}`);
      await page.setViewportSize(device.viewport);
      await page.waitForTimeout(150); // 레이아웃 렌더링 안정화 대기

      // 대시보드 요소 확인
      await expect(page.locator('.admin-page-hero')).toBeVisible();
      await expect(page.locator('.admin-page-title')).toContainText(/대시보드|Dashboard/i);

      // 메트릭 카드/요약 패널 존재 확인
      const metricCards = page.locator('.admin-metric-card');
      const summaryPanels = page.locator('.mud-card, .admin-surface, .mud-paper');
      const metricCount = await metricCards.count();
      const panelCount = await summaryPanels.count();
      expect(metricCount + panelCount, `Expected dashboard cards on ${device.name}`).toBeGreaterThanOrEqual(1);

      // 메트릭 카드가 있으면 가시성도 확인
      for (let i = 0; i < Math.min(metricCount, device.minElements); i++) {
        await expect(metricCards.nth(i)).toBeVisible();
      }

      // 테이블 체크
      const tables = page.locator('.admin-table');
      if (await tables.count() > 0) {
        for (let i = 0; i < await tables.count(); i++) {
          const table = tables.nth(i);
          const headerCells = table.locator('thead th');
          expect(await headerCells.count()).toBeGreaterThan(0);
        }
      }

      // 오버플로우 체크
      const bodyBounds = await page.evaluate(() => {
        const docWidth = document.documentElement.scrollWidth;
        const winWidth = window.innerWidth;
        return docWidth <= winWidth + 1;
      });
      if (device.viewport.width >= 960) {
        expect(bodyBounds, `No horizontal scroll on ${device.name}`).toBe(true);
      } else {
        expect(typeof bodyBounds).toBe('boolean');
      }

      // 텍스트 가독성
      const textElements = page.locator('p, span, .mud-typography');
      for (let i = 0; i < Math.min(5, await textElements.count()); i++) {
        const fontSize = await textElements.nth(i).evaluate((el) => {
          return window.getComputedStyle(el).fontSize;
        });
        const size = parseFloat(fontSize);
        expect(size).toBeGreaterThanOrEqual(8.5);
      }
    }
  });

  // 드로어 반응형 테스트
  test('drawer responsiveness on mobile', async ({ page }) => {
    test.skip(!TEST_USERNAME || !TEST_PASSWORD, 'E2E_ADMIN_USERNAME and E2E_ADMIN_PASSWORD are required.');
    const token = await getAdminToken(page.context().request, baseUrl, TEST_USERNAME, TEST_PASSWORD);
    await installAdminToken(page, token);
    
    await page.setViewportSize({ width: 375, height: 667 });
    await page.goto(`${baseUrl}/admin/dashboard`);
    await expect(page.locator('.admin-page-hero')).toBeVisible({ timeout: 30_000 });

    // 모바일에서는 메뉴 토글 버튼이 있어야 함
    const menuButton = page.locator('.admin-menu-button');
    await expect(menuButton).toBeVisible();

    // 토글 버튼 클릭 후 drawer 제어 가능 여부 확인
    await menuButton.click();
    expect(await menuButton.isVisible()).toBe(true);
  });

  // 폼 요소 반응형 테스트
  test('form inputs are accessible on mobile', async ({ page }) => {
    test.skip(!TEST_USERNAME || !TEST_PASSWORD, 'E2E_ADMIN_USERNAME and E2E_ADMIN_PASSWORD are required.');
    const token = await getAdminToken(page.context().request, baseUrl, TEST_USERNAME, TEST_PASSWORD);
    await installAdminToken(page, token);
    
    await page.setViewportSize({ width: 480, height: 853 });
    await page.goto(`${baseUrl}/admin/faqs/create`);
    await expect(page.locator('.admin-page-hero')).toBeVisible({ timeout: 30_000 });

    const inputs = page.locator('input, textarea, [role="textbox"]');
    const inputCount = await inputs.count();

    if (inputCount > 0) {
      const width = await inputs.first().evaluate((el) => {
        return el.getBoundingClientRect().width;
      });
      expect(width).toBeGreaterThan(200);

      await inputs.first().scrollIntoViewIfNeeded();
      await expect(inputs.first()).toBeInViewport();
    }
  });

  // 버튼 접근성 테스트
  test('buttons are clickable on all viewports', async ({ page }) => {
    test.skip(!TEST_USERNAME || !TEST_PASSWORD, 'E2E_ADMIN_USERNAME and E2E_ADMIN_PASSWORD are required.');
    const token = await getAdminToken(page.context().request, baseUrl, TEST_USERNAME, TEST_PASSWORD);
    await installAdminToken(page, token);
    
    const viewports = [
      { width: 1920, height: 1080 },
      { width: 768, height: 1024 },
      { width: 375, height: 667 }
    ];

    for (const viewport of viewports) {
      await page.setViewportSize(viewport);
      await page.goto(`${baseUrl}/admin/dashboard`);
      await expect(page.locator('.admin-page-hero')).toBeVisible({ timeout: 30_000 });
      await expect(page.locator('.admin-topbar-status')).toContainText(/현재:/, { timeout: 30_000 });

      const logoutButton = page.locator('a:has-text("로그아웃"), button:has-text("로그아웃")').first();
      if (await logoutButton.count() > 0) {
        const box = await logoutButton.boundingBox();
        expect(box).not.toBeNull();
        expect(box?.width).toBeGreaterThan(20);
        expect(box?.height).toBeGreaterThan(20);
      }
    }
  });
});
