/**
 * 결재함 플로우 E2E 테스트 스크립트
 * 실행: npx tsx scripts/approval-flow-test.ts
 */
import { chromium } from "playwright";

const BASE_URL = "http://localhost:9771";
const LOGIN_ID = "wace";
const LOGIN_PW = "1234";
const FALLBACK_PW = "qlalfqjsgh11"; // 마스터 패스워드 (1234 실패 시)

async function main() {
  const results: string[] = [];
  const consoleErrors: string[] = [];

  const browser = await chromium.launch({ headless: true });
  const context = await browser.newContext({
    viewport: { width: 1280, height: 800 }, // 데스크톱 뷰 (사이드바 표시)
  });
  const page = await context.newPage();

  // 콘솔 에러 수집
  page.on("console", (msg) => {
    const type = msg.type();
    if (type === "error") {
      const text = msg.text();
      consoleErrors.push(text);
    }
  });

  try {
    // 1. http://localhost:9771 이동
    results.push("=== 1. http://localhost:9771 이동 ===");
    await page.goto(BASE_URL, { waitUntil: "networkidle", timeout: 15000 });
    results.push("OK: 페이지 로드 완료");

    // 2. 로그인 여부 확인
    results.push("\n=== 2. 로그인 상태 확인 ===");
    const isLoginPage = await page.locator('#userId, input[name="userId"]').count() > 0;
    if (isLoginPage) {
      results.push("로그인 페이지 감지됨. 로그인 시도...");
      await page.fill('#userId', LOGIN_ID);
      await page.fill('#password', LOGIN_PW);
      await page.click('button[type="submit"]');
      await page.waitForTimeout(4000);

      // 여전히 로그인 페이지면 마스터 패스워드로 재시도
      const stillLoginPage = await page.locator('#userId').count() > 0;
      if (stillLoginPage) {
        results.push("1234 로그인 실패. 마스터 패스워드로 재시도...");
        await page.fill('#userId', LOGIN_ID);
        await page.fill('#password', FALLBACK_PW);
        await page.click('button[type="submit"]');
        await page.waitForTimeout(4000);
      }
      results.push("로그인 폼 제출 완료");
    } else {
      results.push("이미 로그인된 상태로 판단 (로그인 폼 없음)");
    }

    // 3. 사용자 프로필 아바타 클릭 (사이드바 하단)
    results.push("\n=== 3. 사용자 프로필 아바타 클릭 ===");
    await page.waitForTimeout(2000);

    // 사이드바 하단 사용자 프로필 버튼 (border-t border-slate-200 내부의 button)
    const sidebarAvatarBtn = page.locator('aside div.border-t.border-slate-200 button').first();
    let avatarClicked = false;
    if ((await sidebarAvatarBtn.count()) > 0) {
      try {
        // force: true - Next.js dev overlay가 클릭을 가로채는 경우 우회
        await sidebarAvatarBtn.click({ timeout: 5000, force: true });
        avatarClicked = true;
        results.push("OK: 사이드바 하단 아바타 클릭 완료");
        await page.waitForTimeout(500); // 드롭다운 열림 대기
      } catch (e) {
        results.push(`WARN: 사이드바 아바타 클릭 실패 - ${(e as Error).message}`);
      }
    }

    if (!avatarClicked) {
      // 모바일 헤더 아바타 또는 fallback
      const headerAvatar = page.locator('header button:has(div.rounded-full)').first();
      if ((await headerAvatar.count()) > 0) {
        await headerAvatar.click({ force: true });
        avatarClicked = true;
        results.push("OK: 헤더 아바타 클릭 (모바일 뷰?)");
      }
    }

    if (!avatarClicked) {
      results.push("WARN: 아바타 클릭 실패. 직접 /admin/approvalBox로 이동하여 페이지 검증");
      await page.goto(`${BASE_URL}/admin/approvalBox`, { waitUntil: "networkidle", timeout: 10000 });
    }

    await page.waitForTimeout(1000);

    // 4. "결재함" 메뉴 확인 (드롭다운이 열린 경우)
    results.push("\n=== 4. 결재함 메뉴 확인 ===");
    const approvalMenuItem = page.locator('[role="menuitem"]:has-text("결재함"), [data-radix-collection-item]:has-text("결재함")').first();
    const hasApprovalMenu = (await approvalMenuItem.count()) > 0;
    if (hasApprovalMenu) {
      results.push("OK: 결재함 메뉴가 보입니다.");
    } else {
      results.push("FAIL: 결재함 메뉴를 찾을 수 없습니다.");
    }

    // 5. 결재함 메뉴 클릭
    results.push("\n=== 5. 결재함 메뉴 클릭 ===");
    if (hasApprovalMenu) {
      await approvalMenuItem.click({ force: true });
      await page.waitForTimeout(3000);
      results.push("OK: 결재함 메뉴 클릭 완료");
    } else if (!avatarClicked) {
      results.push("(직접 이동으로 스킵 - 이미 approvalBox 페이지)");
    } else {
      results.push("WARN: 드롭다운에서 결재함 메뉴 미발견. 직접 이동...");
      await page.goto(`${BASE_URL}/admin/approvalBox`, { waitUntil: "networkidle", timeout: 10000 });
      await page.waitForTimeout(2000);
    }

    // 6. /admin/approvalBox 페이지 렌더링 확인
    results.push("\n=== 6. /admin/approvalBox 페이지 확인 ===");
    const currentUrl = page.url();
    const isApprovalBoxPage = currentUrl.includes("/admin/approvalBox");
    results.push(`현재 URL: ${currentUrl}`);
    results.push(isApprovalBoxPage ? "OK: approvalBox 페이지에 있습니다." : "FAIL: approvalBox 페이지가 아닙니다.");

    // 제목 "결재함" 확인
    const titleEl = page.locator('h1:has-text("결재함")');
    const hasTitle = (await titleEl.count()) > 0;
    results.push(hasTitle ? "OK: 제목 '결재함' 확인됨" : "FAIL: 제목 '결재함' 없음");

    // 탭 확인: 수신함, 상신함
    const receivedTab = page.locator('button[role="tab"], [role="tab"]').filter({ hasText: "수신함" });
    const sentTab = page.locator('button[role="tab"], [role="tab"]').filter({ hasText: "상신함" });
    const hasReceivedTab = (await receivedTab.count()) > 0;
    const hasSentTab = (await sentTab.count()) > 0;
    results.push(hasReceivedTab ? "OK: '수신함' 탭 확인됨" : "FAIL: '수신함' 탭 없음");
    results.push(hasSentTab ? "OK: '상신함' 탭 확인됨" : "FAIL: '상신함' 탭 없음");

    // 7. 콘솔 에러 확인
    results.push("\n=== 7. 콘솔 에러 확인 ===");
    if (consoleErrors.length === 0) {
      results.push("OK: 콘솔 에러 없음");
    } else {
      results.push(`WARN: 콘솔 에러 ${consoleErrors.length}건 발견:`);
      consoleErrors.slice(0, 10).forEach((err, i) => {
        results.push(`  [${i + 1}] ${err.substring(0, 200)}${err.length > 200 ? "..." : ""}`);
      });
      if (consoleErrors.length > 10) {
        results.push(`  ... 외 ${consoleErrors.length - 10}건`);
      }
    }

    // 스크린샷 저장 (프로젝트 내)
    await page.screenshot({ path: "approval-box-result.png" }).catch(() => {});
  } catch (err: any) {
    results.push(`\nERROR: ${err.message}`);
  } finally {
    await browser.close();
  }

  // 결과 출력
  console.log("\n" + "=".repeat(60));
  console.log("결재함 플로우 테스트 결과");
  console.log("=".repeat(60));
  results.forEach((r) => console.log(r));
  console.log("\n" + "=".repeat(60));
}

main();
