/**
 * AI Platform 메뉴 화면 캡처 (Playwright)
 * - 로그인: 운영 URL (PROD 전용 화면)
 * - 나머지: 로컬 SUPER 모드 서버 (인증 없이 캡처)
 * - 대시보드: OPS 세션 쿠키(허용 이메일) 주입 후 캡처
 */
import { chromium } from "playwright";
import crypto from "crypto";
import fs from "fs/promises";
import fsSync from "fs";
import path from "path";
import { fileURLToPath } from "url";

const __dirname = path.dirname(fileURLToPath(import.meta.url));
const OUT_DIR =
  process.env.CAPTURE_OUT_DIR ||
  path.join(__dirname, "..", "docs", "ppt-screenshots");
const LOCAL_BASE = process.env.CAPTURE_BASE_URL || "http://127.0.0.1:8030";
const PROD_BASE = (process.env.CAPTURE_PROD_BASE || "https://ai.xavis.co.kr").replace(/\/$/, "");
const PROD_LOGIN = `${PROD_BASE}/login`;
/** 목록(학습·사례)은 운영 데이터·전체 로드 후 캡처 */
const CAPTURE_LISTS_FROM_PROD = process.env.CAPTURE_LISTS_FROM_PROD !== "0";
/** 일반 사용자 OPS 세션 (관리자·특수 메뉴 쿠키 없음) */
const CAPTURE_USER_EMAIL = (
  process.env.CAPTURE_USER_EMAIL || "employee@ncue.net"
)
  .trim()
  .toLowerCase();
/** general: 가이드봇·WM·대시보드·체크리스트 제외 캡처 */
const CAPTURE_PROFILE = (process.env.CAPTURE_PROFILE || "general").trim().toLowerCase();

const LOCAL_PAGES_ALL = [
  { id: "ai-explore", path: "/ai-explore", waitMs: 800 },
  { id: "meeting-minutes", path: "/ai-explore/meeting-minutes", waitMs: 1200 },
  { id: "task-checklist", path: "/ai-explore/task-checklist", waitMs: 1200 },
  { id: "chat", path: "/ai-explore/chat", waitMs: 800 },
  { id: "fscan", path: "/ai-explore/fscan", waitMs: 2000 },
  { id: "prompts", path: "/ai-explore/prompts", waitMs: 1500 },
  { id: "ax-apply", path: "/ax-apply", waitMs: 1000 },
];

/** 목록 패널 전체(element) 캡처 — viewport 잘림 방지 */
const LIST_PANEL_PAGES = [
  {
    id: "learning",
    path: "/learning",
    selector: "section.panel:has(#lecture-results-root)",
    useProd: true,
    preload: "learning",
  },
  {
    id: "ai-cases",
    path: "/ai-cases",
    selector: "section.panel:has(.success-story-grid)",
    useProd: true,
    preload: "none",
  },
  {
    id: "ai-cases-compose",
    path: "/ai-cases/compose",
    selector: "main.use-case-compose",
    useProd: true,
    preload: "none",
  },
];

const LOCAL_PAGES =
  CAPTURE_PROFILE === "general"
    ? LOCAL_PAGES_ALL.filter(
        (p) => !["task-checklist", "dashboard", "dashboard-business-performance"].includes(p.id)
      )
    : LOCAL_PAGES_ALL;

/** 일반 사용자 좌측 메뉴(가이드봇·WM·대시보드 없음) */
const MENU_OVERVIEW = { id: "menu-overview", path: "/ai-explore", waitMs: 1000 };

function readEnvValue(key) {
  const envPath = path.join(__dirname, "..", ".env");
  try {
    const raw = fsSync.readFileSync(envPath, "utf8");
    const re = new RegExp(`^${key}=(.+)$`, "m");
    const m = raw.match(re);
    if (!m) return "";
    return m[1].split("#")[0].trim().replace(/^["']|["']$/g, "");
  } catch {
    return "";
  }
}

/** ops-auth.js 와 동일한 세션 쿠키 서명 */
function buildOpsSessionCookie(email) {
  const secret = readEnvValue("AUTH_SECRET") || readEnvValue("ADMIN_TOKEN") || "ncue-admin";
  const exp = Number.MAX_SAFE_INTEGER;
  const iat = Date.now();
  const payload = `${email}|${exp}|${iat}`;
  const sig = crypto.createHmac("sha256", secret).update(payload).digest("hex");
  return Buffer.from(JSON.stringify({ email, exp, iat, sig })).toString("base64url");
}

function captureUserEmail() {
  return CAPTURE_USER_EMAIL;
}

async function capturePage(page, url, outPath, waitMs = 1000, fullPage = false) {
  await page.goto(url, { waitUntil: "networkidle", timeout: 90000 });
  await page.waitForTimeout(waitMs);
  await page.screenshot({ path: outPath, fullPage });
  console.log("  saved:", outPath);
}

/** 학습센터 무한 스크롤 — 모든 페이지 로드 */
async function loadAllLearningPages(page) {
  await page.waitForSelector("#lecture-grid", { timeout: 60000 });
  let guard = 0;
  while (guard < 80) {
    guard += 1;
    const state = await page.evaluate(() => {
      const sentinel = document.getElementById("infinite-scroll-sentinel");
      const btn = document.getElementById("lecture-load-more-btn");
      const countEl = document.getElementById("lecture-total-count");
      const cards = document.querySelectorAll("#lecture-grid .lecture-card, #lecture-grid a.lecture-card");
      return {
        hasNext: !!(sentinel && sentinel.getAttribute("data-has-next") === "true"),
        hasBtn: !!btn,
        total: countEl ? countEl.textContent.trim() : "",
        loaded: cards.length,
      };
    });
    if (!state.hasNext) break;
    if (state.hasBtn) {
      await page.locator("#lecture-load-more-btn").click({ timeout: 5000 }).catch(() => {});
    } else {
      await page.evaluate(() => {
        const s = document.getElementById("infinite-scroll-sentinel");
        if (s) s.scrollIntoView({ block: "end", behavior: "instant" });
        window.scrollTo(0, document.body.scrollHeight);
      });
    }
    await page.waitForTimeout(900);
    await page
      .waitForFunction(
        () => {
          const el = document.getElementById("infinite-scroll-loading");
          return !el || el.style.display === "none" || el.style.display === "";
        },
        { timeout: 45000 }
      )
      .catch(() => {});
  }
  const finalCount = await page.evaluate(() => {
    const countEl = document.getElementById("lecture-total-count");
    const cards = document.querySelectorAll("#lecture-grid .lecture-card, #lecture-grid a.lecture-card");
    return { total: countEl ? countEl.textContent.trim() : "?", loaded: cards.length };
  });
  console.log("  learning loaded:", finalCount.loaded, "/ total", finalCount.total);
}

/** 목록 섹션(element) 캡처 — 카드 전체가 포함되도록 */
async function captureListPanel(page, baseUrl, item, outPath) {
  const url = `${baseUrl}${item.path}`;
  await page.goto(url, { waitUntil: "networkidle", timeout: 90000 });
  if (item.preload === "learning") {
    await loadAllLearningPages(page);
  }
  await page.waitForSelector(item.selector, { timeout: 60000 });
  await page.waitForTimeout(600);
  const panel = page.locator(item.selector).first();
  await panel.scrollIntoViewIfNeeded();
  await panel.screenshot({ path: outPath });
  const meta = await page.evaluate((sel) => {
    const cards =
      sel.includes("lecture")
        ? document.querySelectorAll("#lecture-grid .lecture-card, #lecture-grid a.lecture-card").length
        : document.querySelectorAll(".success-story-grid .success-story-card, .success-story-grid a").length;
    const chip = document.querySelector(".count-chip");
    return { cards, chip: chip ? chip.textContent.trim() : "" };
  }, item.selector);
  console.log("  saved:", outPath, meta.chip || "", "visible cards:", meta.cards);
}

async function main() {
  await fs.mkdir(OUT_DIR, { recursive: true });

  const browser = await chromium.launch({ headless: true });
  const context = await browser.newContext({
    viewport: { width: 1440, height: 900 },
    locale: "ko-KR",
  });
  const page = await context.newPage();

  const userEmail = captureUserEmail();
  const opsCookie = buildOpsSessionCookie(userEmail);
  const cookieJar = [
    {
      name: "ops_user_session",
      value: opsCookie,
      url: LOCAL_BASE,
      httpOnly: true,
      sameSite: "Lax",
    },
  ];
  if (CAPTURE_LISTS_FROM_PROD) {
    cookieJar.push({
      name: "ops_user_session",
      value: opsCookie,
      domain: new URL(PROD_BASE).hostname,
      path: "/",
      httpOnly: true,
      secure: true,
      sameSite: "Lax",
    });
  }
  await context.addCookies(cookieJar);
  console.log("Capture persona:", userEmail, "(no admin cookie)", "profile:", CAPTURE_PROFILE);
  console.log("Output dir:", OUT_DIR);

  console.log("[1/4] Login (production)...");
  try {
    await capturePage(
      page,
      PROD_LOGIN,
      path.join(OUT_DIR, "login.png"),
      1500
    );
  } catch (err) {
    console.warn("  login capture failed:", err.message);
  }

  console.log("[2/4] Local menus (PROD + OPS cookie, no admin)...");
  for (const item of LOCAL_PAGES) {
    const outPath = path.join(OUT_DIR, `${item.id}.png`);
    try {
      await capturePage(page, `${LOCAL_BASE}${item.path}`, outPath, item.waitMs);
    } catch (err) {
      console.warn(`  ${item.id} failed:`, err.message);
    }
  }

  console.log("[2b/4] List panels (full load + element capture)...");
  for (const item of LIST_PANEL_PAGES) {
    const outPath = path.join(OUT_DIR, `${item.id}.png`);
    const base = item.useProd && CAPTURE_LISTS_FROM_PROD ? PROD_BASE : LOCAL_BASE;
    try {
      await captureListPanel(page, base, item, outPath);
    } catch (err) {
      console.warn(`  ${item.id} list panel failed (${base}):`, err.message);
      if (base !== LOCAL_BASE) {
        try {
          await captureListPanel(page, LOCAL_BASE, item, outPath);
        } catch (err2) {
          console.warn(`  ${item.id} local fallback failed:`, err2.message);
        }
      }
    }
  }

  console.log("[3/4] Menu overview...");
  try {
    await capturePage(
      page,
      `${LOCAL_BASE}${MENU_OVERVIEW.path}`,
      path.join(OUT_DIR, `${MENU_OVERVIEW.id}.png`),
      MENU_OVERVIEW.waitMs
    );
  } catch (err) {
    console.warn("  menu-overview failed:", err.message);
  }

  if (CAPTURE_PROFILE !== "general") {
    console.log("[4/4] Dashboard (허용 계정:", userEmail, ")...");
    for (const item of [
      { id: "dashboard", path: "/dashboard", waitMs: 1000 },
      { id: "dashboard-business-performance", path: "/dashboard/business-performance", waitMs: 2500 },
    ]) {
      const outPath = path.join(OUT_DIR, `${item.id}.png`);
      try {
        await capturePage(page, `${LOCAL_BASE}${item.path}`, outPath, item.waitMs);
      } catch (err) {
        console.warn(`  ${item.id} failed:`, err.message);
      }
    }
  } else {
    console.log("[4/4] Dashboard skip (general profile)");
  }

  await browser.close();
  console.log("Done. Output:", OUT_DIR);
}

main().catch((err) => {
  console.error(err);
  process.exit(1);
});
