#!/usr/bin/env node
/**
 * V3 responsive UI smoke.
 *
 * Checks the main Flask pages at desktop and mobile widths:
 * - route renders without 4xx/5xx
 * - route does not fall back to the login form
 * - document body does not create page-level horizontal overflow
 *
 * Usage:
 *   LOGIN_PASSWORD=... BASE_URL=http://127.0.0.1:5003 \
 *   NODE_PATH=/path/to/node_modules node scripts/check_v3_responsive_ui.js
 */

const { chromium } = require('playwright');

const BASE_URL = process.env.BASE_URL || 'http://127.0.0.1:5003';
const LOGIN_PASSWORD = process.env.LOGIN_PASSWORD || 'codex-local-password';
const CHROME_PATH = process.env.PLAYWRIGHT_CHROME_PATH || '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome';

const ROUTES = [
  '/',
  '/edm',
  '/sales_analysis',
  '/daily_sales',
  '/monthly_summary_analysis',
  '/growth_analysis',
  '/ai_recommend',
  '/auto_import',
  '/vendor-stockout/',
  '/vendor-stockout/import',
  '/vendor-stockout/list',
  '/settings',
  '/logs',
  '/observability/overview',
  '/observability/agent_orchestration',
  '/observability/business_intel',
  '/observability/host_health',
  '/observability/ai_calls',
  '/observability/budget',
  '/observability/promotion_review',
  '/observability/rag_queries',
  '/observability/quality_trend',
  '/observability/ppt_audit_history',
];

const VIEWPORTS = [
  { name: 'desktop', width: 1440, height: 1000 },
  { name: 'mobile', width: 390, height: 900 },
];

async function login(context) {
  const page = await context.newPage();
  await page.goto(`${BASE_URL}/login`, { waitUntil: 'domcontentloaded', timeout: 20000 });

  const passwordInput = page.locator('input[name="password"]');
  if ((await passwordInput.count()) === 0) {
    await page.close();
    return;
  }

  await passwordInput.fill(LOGIN_PASSWORD);
  await Promise.all([
    page.waitForNavigation({ waitUntil: 'domcontentloaded', timeout: 15000 }).catch(() => null),
    page.locator('button[type="submit"]').click(),
  ]);
  await page.close();
}

async function inspectRoute(page, route) {
  const response = await page.goto(`${BASE_URL}${route}`, {
    waitUntil: 'domcontentloaded',
    timeout: 25000,
  });
  await page.waitForLoadState('networkidle', { timeout: 8000 }).catch(() => null);

  const metrics = await page.evaluate(() => {
    const maxScroll = Math.max(document.body.scrollWidth, document.documentElement.scrollWidth);
    const client = document.documentElement.clientWidth;
    const localWide = Array.from(document.querySelectorAll('body *'))
      .filter((element) => {
        const rect = element.getBoundingClientRect();
        const style = getComputedStyle(element);
        return rect.width > client + 1 && style.position !== 'fixed' && style.position !== 'absolute';
      })
      .slice(0, 4)
      .map((element) => ({
        tag: element.tagName,
        className: String(element.className || ''),
        width: Math.round(element.getBoundingClientRect().width),
      }));

    return {
      title: document.title,
      finalPath: `${location.pathname}${location.search}`,
      login: Boolean(document.querySelector('form[action="/login"]')),
      clientWidth: client,
      scrollWidth: maxScroll,
      overflow: maxScroll > client + 1,
      localWide,
    };
  });

  return {
    route,
    status: response ? response.status() : null,
    ...metrics,
  };
}

(async () => {
  const browser = await chromium.launch({
    headless: true,
    executablePath: CHROME_PATH,
  });

  const failures = [];
  for (const viewport of VIEWPORTS) {
    const context = await browser.newContext({
      viewport: { width: viewport.width, height: viewport.height },
    });
    await login(context);

    for (const route of ROUTES) {
      const page = await context.newPage();
      try {
        const result = await inspectRoute(page, route);
        const failed = result.status >= 400 || result.login || result.overflow;
        const line = [
          failed ? 'FAIL' : 'PASS',
          viewport.name,
          route,
          `status=${result.status}`,
          `overflow=${result.overflow}`,
          `scroll=${result.scrollWidth}`,
          `client=${result.clientWidth}`,
          `title=${result.title}`,
        ].join(' ');
        console.log(line);
        if (failed) failures.push({ viewport: viewport.name, ...result });
      } catch (error) {
        const failure = { viewport: viewport.name, route, error: error.message.split('\n')[0] };
        failures.push(failure);
        console.log(`FAIL ${viewport.name} ${route} error=${failure.error}`);
      } finally {
        await page.close();
      }
    }

    await context.close();
  }

  await browser.close();

  if (failures.length > 0) {
    console.error(JSON.stringify({ failures }, null, 2));
    process.exit(1);
  }
})();
