"use strict";

/**
 * 抖音用户主页采集（对齐 Electron ipAgent:analyzeDouyinAccount）
 */

const https = require("https");
const { DouyinBrowserManager } = require("./douyin_browser_manager.js");

const PROFILE_URL_RE =
  /douyin\.com\/user|iesdouyin\.com\/share\/user|v\.douyin\.com/i;

const SCRAPE_SCRIPT = `
(() => {
  try {
    let accountName = "";
    const nicknameEl = document.querySelector(
      '[class*="nickname"], [class*="account"], h1'
    );
    if (nicknameEl) accountName = nicknameEl.textContent?.trim() || "";

    if (!accountName) {
      const metaEl = document.querySelector('meta[property="og:title"]');
      if (metaEl) accountName = metaEl.getAttribute("content") || "";
    }

    if (!accountName) {
      const allHeaders = document.querySelectorAll(
        'h1, h2, .dy-name, [data-testid*="name"], [class*="userName"]'
      );
      for (const el of allHeaders) {
        const text = el.textContent?.trim();
        if (text && text.length > 2 && text.length < 30) {
          accountName = text;
          break;
        }
      }
    }

    if (!accountName) {
      const titleText = document.title || "";
      const match = titleText.match(/(.+?)(?:的抖音|抖音号|-)/);
      accountName = match ? match[1].trim() : titleText.split("-")[0]?.trim() || "";
    }

    const videoTitles = [];
    const seenTexts = new Set();
    const excludeWords = [
      "抖音号", "IP属地", "获赞", "粉丝", "关注", "作品", "点赞", "评论",
      "分享", "收藏", "私信", "粉丝团", "加关注", "最新作品", "合作推荐", "喜欢作者",
    ];

    const shouldExclude = (text) => {
      if (!text || text.length < 5 || text.length > 300) return true;
      return excludeWords.some((word) => text.includes(word));
    };

    const allElements = document.querySelectorAll(
      'p, span[class*="desc"], div[class*="title"]'
    );
    allElements.forEach((el) => {
      if (videoTitles.length >= 6) return;
      const text = el.textContent?.trim();
      if (
        text &&
        text.length > 10 &&
        text.length < 500 &&
        !shouldExclude(text) &&
        !seenTexts.has(text)
      ) {
        videoTitles.push(text);
        seenTexts.add(text);
      }
    });

    if (videoTitles.length < 3) {
      const titleSelectors = [
        '[class*="title"]',
        '[class*="desc"]',
        '[class*="caption"]',
        '[data-testid*="title"]',
        '[class*="feed-item"]',
        '[class*="video-item"]',
        ".dy-video-title",
        ".aweme-detail",
        '[class*="aweme"]',
      ];
      for (const selector of titleSelectors) {
        if (videoTitles.length >= 6) break;
        document.querySelectorAll(selector).forEach((el) => {
          if (videoTitles.length >= 6) return;
          const text = el.textContent?.trim();
          if (text && !shouldExclude(text) && text.length > 5 && !seenTexts.has(text)) {
            videoTitles.push(text);
            seenTexts.add(text);
          }
        });
      }
    }

    const cleanTitles = videoTitles
      .map((title) => title.replace(/^\\d+\\s+/, "").trim())
      .filter((t) => t && t.length > 5);

    return {
      accountName: accountName || "未知账号",
      videoTitles: Array.from(new Set(cleanTitles)).slice(0, 6),
      pageTitle: document.title,
      pageUrl: window.location.href,
    };
  } catch (err) {
    return {
      accountName: document.title?.split("-")[0] || "错误",
      videoTitles: [],
      pageTitle: document.title,
      pageUrl: window.location.href,
      error: err.message,
    };
  }
})()
`;

function emitProgress(msg) {
  try {
    globalThis.__native?.emitProgress?.(msg);
  } catch (_) {
    /* ignore */
  }
}

function resolveShortUrl(shortUrl) {
  return new Promise((resolve, reject) => {
    let u;
    try {
      u = new URL(shortUrl);
    } catch (e) {
      reject(e);
      return;
    }
    const opts = {
      hostname: u.hostname,
      path: u.pathname + u.search,
      method: "HEAD",
      headers: {
        "User-Agent":
          "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
      },
      timeout: 30000,
    };
    const req = https.request(opts, (res) => {
      if (
        res.statusCode &&
        res.statusCode >= 300 &&
        res.statusCode < 400 &&
        res.headers.location
      ) {
        resolve(res.headers.location);
      } else {
        resolve(shortUrl);
      }
    });
    req.on("error", reject);
    req.on("timeout", () => {
      req.destroy();
      reject(new Error("短链接解析超时"));
    });
    req.end();
  });
}

async function normalizeProfileUrl(input) {
  let url = String(input || "").trim();
  if (!url) throw new Error("请输入账号主页或分享链接");

  const urlMatch = url.match(/https?:\/\/[^\s\u4e00-\u9fa5"'<>]+/i);
  if (urlMatch) url = urlMatch[0];
  else if (!url.startsWith("http")) url = `https://${url}`;

  if (/v\.douyin\.com|iesdouyin\.com/i.test(url) && !/\/user\//i.test(url)) {
    emitProgress("正在解析分享链接...");
    url = await resolveShortUrl(url);
  }

  if (!PROFILE_URL_RE.test(url)) {
    throw new Error("请输入抖音账号主页或用户分享链接（支持 v.douyin.com 短链）");
  }
  return url;
}

async function scrapeDouyinProfile(profileUrl) {
  const manager = DouyinBrowserManager.getInstance();
  emitProgress("正在打开浏览器并采集数据，请稍候...");
  await manager.initBrowser();
  const page = await manager.newPage();
  try {
    await page.goto(profileUrl, { waitUntil: "domcontentloaded", timeout: 60000 });
    emitProgress("页面已加载，正在提取账号与视频标题...");
    await new Promise((r) => setTimeout(r, 5000));
    const data = await page.evaluate(SCRAPE_SCRIPT);
    if (data?.error) {
      throw new Error(data.error);
    }
    return data;
  } finally {
    try {
      await page.close();
    } catch (_) {
      /* ignore */
    }
  }
}

module.exports = {
  normalizeProfileUrl,
  scrapeDouyinProfile,
};
