/**
 * 화면 94(수주), 124(수주목록 리스트) 검증 스크립트
 * - 로그인 후 각 화면 접속
 * - 컴포넌트 배치, 테이블/필터/버튼, 가로 레이아웃 확인
 */

import { chromium } from "playwright";
import * as path from "path";
import * as fs from "fs";

const BASE_URL = "http://localhost:9771";
const SCREENSHOT_DIR = path.join(__dirname, "../verification-screenshots");

interface ScreenResult {
  screenId: number;
  name: string;
  componentsOk: boolean;
  tableVisible: boolean;
  filterVisible: boolean;
  buttonsVisible: boolean;
  layoutHorizontal: boolean;
  noError: boolean;
  success: boolean;
}

type ScreenType = "form" | "list";

async function verifyScreen(page: any, screenId: number, name: string, type: ScreenType): Promise<ScreenResult> {
  console.log(`\n--- 화면 ${screenId} (${name}) 검증 ---`);
  await page.goto(`${BASE_URL}/screens/${screenId}`, { waitUntil: "domcontentloaded", timeout: 20000 });
  // 로딩 완료 대기: "로딩중" 텍스트 사라질 때까지 최대 12초
  await page.getByText("로딩중", { exact: false }).waitFor({ state: "hidden", timeout: 12000 }).catch(() => {});
  // 리스트 화면: 테이블 로딩 대기. 폼 화면: 버튼/input 대기
  if (type === "list") {
    await page.waitForSelector("table, [role='grid'], thead, tbody", { timeout: 8000 }).catch(() => {});
  } else {
    await page.waitForSelector("button, input", { timeout: 5000 }).catch(() => {});
  }
  await page.waitForTimeout(2000);

  const result: ScreenResult = {
    screenId,
    name,
    componentsOk: false,
    tableVisible: false,
    filterVisible: false,
    buttonsVisible: false,
    layoutHorizontal: false,
    noError: false,
    success: false,
  };

  // 404/에러 메시지 확인
  const has404 = (await page.locator('text="화면을 찾을 수 없습니다"').count()) > 0;
  const hasError = (await page.locator('text="오류 발생"').count()) > 0;
  result.noError = !has404;

  // 테이블
  const tableSelectors = ["table", "[role='grid']", "thead", "tbody", ".table-mobile-fixed"];
  for (const sel of tableSelectors) {
    if ((await page.locator(sel).count()) > 0) {
      result.tableVisible = true;
      break;
    }
  }

  // 필터/검색
  const filterSelectors = ["input", "select", "button:has-text('검색')", "button:has-text('필터')"];
  for (const sel of filterSelectors) {
    if ((await page.locator(sel).count()) > 0) {
      result.filterVisible = true;
      break;
    }
  }

  // 버튼 (사이드바 포함, 화면에 버튼이 있으면 OK)
  const buttonCount = await page.locator("button, [role='button']").count();
  result.buttonsVisible = buttonCount > 0;

  // 가로 레이아웃: 사이드바+메인 구조, flex/grid, 또는 테이블이 있으면 가로 배치로 간주
  const hasFlexRow = (await page.locator(".flex-row, .md\\:flex-row, .flex").count()) > 0;
  const hasGrid = (await page.locator(".grid, [class*='grid-cols']").count()) > 0;
  const hasMain = (await page.locator("main, [role='main'], .flex-1, [class*='flex-1']").count()) > 0;
  const hasSidebar = (await page.getByText("현재 관리 회사").count()) > 0 || (await page.getByText("VEXPLOR").count()) > 0;
  result.layoutHorizontal = (hasMain && (hasFlexRow || hasGrid || result.tableVisible)) || hasSidebar;

  // 컴포넌트 정상 배치 (테이블, 버튼, 또는 input/필터 중 하나라도 있으면 OK)
  result.componentsOk = result.tableVisible || result.buttonsVisible || result.filterVisible;

  // 성공: 폼 화면은 테이블 불필요, 리스트 화면은 테이블 필수
  const baseOk = result.componentsOk && result.filterVisible && result.buttonsVisible && result.layoutHorizontal && result.noError;
  result.success = type === "form" ? baseOk : baseOk && result.tableVisible;

  return result;
}

async function main() {
  const browser = await chromium.launch({ headless: true });
  const context = await browser.newContext({ viewport: { width: 1280, height: 900 } });
  const page = await context.newPage();

  const results: ScreenResult[] = [];

  try {
    // 로그인 (Playwright는 새 브라우저이므로)
    console.log("로그인...");
    await page.goto(`${BASE_URL}/login`, { waitUntil: "domcontentloaded", timeout: 15000 });
    await page.waitForTimeout(1000);
    await page.fill("#userId", "wace");
    await page.fill("#password", "qlalfqjsgh11");
    await page.locator('button[type="submit"]').first().click();
    await page.waitForURL((url) => !url.includes("/login"), { timeout: 15000 }).catch(() => {});
    await page.waitForTimeout(3000);

    // 화면 94
    await page.screenshot({
      path: path.join(SCREENSHOT_DIR, "s94-01-before.png"),
      fullPage: true,
    });
    const r94 = await verifyScreen(page, 94, "수주", "form");
    results.push(r94);
    await page.screenshot({
      path: path.join(SCREENSHOT_DIR, "s94-02-after.png"),
      fullPage: true,
    });

    // 화면 124
    await page.screenshot({
      path: path.join(SCREENSHOT_DIR, "s124-01-before.png"),
      fullPage: true,
    });
    const r124 = await verifyScreen(page, 124, "수주목록 리스트", "list");
    results.push(r124);
    await page.screenshot({
      path: path.join(SCREENSHOT_DIR, "s124-02-after.png"),
      fullPage: true,
    });

    // 결과 출력
    console.log("\n=== 검증 결과 ===");
    results.forEach((r) => {
      console.log(
        `화면 ${r.screenId} (${r.name}): ${r.success ? "성공" : "실패"}` +
          ` | 테이블:${r.tableVisible ? "O" : "X"} 필터:${r.filterVisible ? "O" : "X"} 버튼:${r.buttonsVisible ? "O" : "X"} 레이아웃:${r.layoutHorizontal ? "O" : "X"} 에러없음:${r.noError ? "O" : "X"}`
      );
    });

    const allSuccess = results.every((r) => r.success);
    console.log(`\n최종 판정: ${allSuccess ? "성공" : "실패"}`);

    fs.writeFileSync(
      path.join(SCREENSHOT_DIR, "s94-124-result.json"),
      JSON.stringify({ results, finalSuccess: allSuccess ? "성공" : "실패" }, null, 2)
    );
  } catch (error: any) {
    console.error("오류:", error.message);
    await page.screenshot({ path: path.join(SCREENSHOT_DIR, "s94-124-error.png"), fullPage: true }).catch(() => {});
  } finally {
    await browser.close();
  }
}

main();
