"use strict";

/**
 * 发布用 Puppeteer 浏览器（按平台/账号隔离 userDataDir）
 */
const fs = require("fs");
const path = require("path");
const os = require("os");

const {
  COMMON_BROWSER_ARGS,
  BROWSER_IGNORE_DEFAULT_ARGS,
  STEALTH_INIT_SCRIPT,
  DEFAULT_USER_AGENT,
} = require("./douyin_browser_constants.js");

const browsers = new Map();

function getRuntimeDataPath(...parts) {
  const base = process.env.AICLIENT_DATA_DIR || path.join(os.homedir(), ".aiclient");
  return path.join(base, ...parts);
}

function getChromiumExecutablePath() {
  const fromEnv =
    process.env.AICLIENT_CHROMIUM_PATH || process.env.PUPPETEER_EXECUTABLE_PATH;
  if (fromEnv && fs.existsSync(fromEnv)) return fromEnv;
  const candidates = [];
  if (process.platform === "win32") {
    const pf = process.env.ProgramFiles || "C:\\Program Files";
    const local = process.env.LOCALAPPDATA || "";
    candidates.push(
      path.join(pf, "Google", "Chrome", "Application", "chrome.exe"),
      path.join(local, "Google", "Chrome", "Application", "chrome.exe"),
      path.join(pf, "Microsoft", "Edge", "Application", "msedge.exe"),
    );
  }
  return candidates.find((p) => p && fs.existsSync(p));
}

function loadPuppeteer() {
  try {
    return require("puppeteer-core");
  } catch {
    return require("puppeteer");
  }
}

function contextKey(platform, accountId) {
  return accountId ? `publish_${platform}_${accountId}` : `publish_${platform}`;
}

function userDataDir(platform, accountId) {
  const sub = accountId ? `${platform}_${accountId}` : platform;
  return getRuntimeDataPath("browser-data", "publish", sub);
}

function delay(ms) {
  return new Promise((r) => setTimeout(r, ms));
}

async function getPublishBrowser(platform, accountId) {
  const key = contextKey(platform, accountId);
  const existing = browsers.get(key);
  if (existing && existing.isConnected()) {
    return existing;
  }
  const puppeteer = loadPuppeteer();
  const dir = userDataDir(platform, accountId);
  if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
  const executablePath = getChromiumExecutablePath();
  if (!executablePath) {
    throw new Error(
      "未找到 Chrome/Edge，请安装浏览器或设置 AICLIENT_CHROMIUM_PATH",
    );
  }
  const browser = await puppeteer.launch({
    executablePath,
    headless: false,
    userDataDir: dir,
    args: COMMON_BROWSER_ARGS,
    ignoreDefaultArgs: BROWSER_IGNORE_DEFAULT_ARGS,
    defaultViewport: { width: 1280, height: 900 },
  });
  browser.on("disconnected", () => browsers.delete(key));
  browsers.set(key, browser);
  return browser;
}

async function closeBlankPages(browser, keepPage) {
  try {
    const pages = await browser.pages();
    for (const p of pages) {
      if (keepPage && p === keepPage) continue;
      const u = p.url();
      if (!u || u === "about:blank") {
        try {
          await p.close();
        } catch {
          /* ignore */
        }
      }
    }
  } catch {
    /* ignore */
  }
}

async function newPublishPage(platform, accountId, cookies) {
  const browser = await getPublishBrowser(platform, accountId);
  const pages = await browser.pages();
  let page =
    pages.find((p) => {
      try {
        return p.url() === "about:blank";
      } catch {
        return false;
      }
    }) || null;
  if (!page) {
    page = await browser.newPage();
  }
  await page.setUserAgent(DEFAULT_USER_AGENT);
  await page.evaluateOnNewDocument(STEALTH_INIT_SCRIPT);
  page.setDefaultNavigationTimeout(60000);
  page.setDefaultTimeout(60000);
  if (Array.isArray(cookies) && cookies.length) {
    try {
      await page.setCookie(...cookies);
    } catch (e) {
      console.warn("setCookie 失败:", e.message);
    }
  }
  await closeBlankPages(browser, page);
  return page;
}

async function closePublishBrowser(platform, accountId) {
  const key = contextKey(platform, accountId);
  const browser = browsers.get(key);
  if (!browser) return;
  browsers.delete(key);
  try {
    await browser.close();
  } catch {
    /* ignore */
  }
}

const LOGIN_URLS = {
  douyin: "https://creator.douyin.com/",
  kuaishou: "https://cp.kuaishou.com/",
  shipin: "https://channels.weixin.qq.com/",
  xiaohongshu: "https://creator.xiaohongshu.com/",
};

module.exports = {
  delay,
  getPublishBrowser,
  newPublishPage,
  userDataDir,
  LOGIN_URLS,
  getChromiumExecutablePath,
  closePublishBrowser,
};
