'use strict';

// These functions are serialized into the authenticated Selected Alliance page.
// They use the page's own cookies and browser context; no cookie is returned.
async function executeCreatorSearch(browserTask) {
  const startedAt = Date.now();
  const timeoutMs = Math.max(5000, Math.min(60000, Number(browserTask.requestTimeoutMs) || 30000));
  const controller = new AbortController();
  const timer = setTimeout(() => controller.abort(), timeoutMs);
  const cookieValue = (name) => String(document.cookie || '').split(';').map((item) => item.trim()).find((item) => item.startsWith(`${name}=`))?.slice(name.length + 1) || '';
  try {
    const response = await fetch(browserTask.url, {
      method: 'POST',
      credentials: 'include',
      signal: controller.signal,
      headers: {
        Accept: 'application/json, text/plain, */*',
        'Content-Type': 'application/json',
        'x-from-compass': 'false',
        'x-open-client': 'doudian',
        'x-open-microapp': cookieValue('PHPSESSID') || cookieValue('PHPSESSID_SS')
      },
      body: JSON.stringify(browserTask.request)
    });
    const text = await response.text();
    let payload = null;
    try { payload = JSON.parse(text); } catch (_) {}
    const payloadSummary = payload && typeof payload === 'object'
      ? `payload_keys=${Object.keys(payload).slice(0, 12).join(',')}; data_keys=${payload.data && typeof payload.data === 'object' ? Object.keys(payload.data).slice(0, 12).join(',') : typeof payload.data}; code=${payload.code ?? ''}; message=${String(payload.message || payload.msg || payload.status_message || '').slice(0, 160)}`
      : `body=${text.slice(0, 240)}`;
    return {
      version: 1,
      kind: 'creator_search',
      jobId: browserTask.jobId,
      sourceUrl: location.href,
      browser: navigator.userAgent,
      latencyMs: Date.now() - startedAt,
      response: { status: response.status, ok: response.ok, payload, error: payload?.data?.list ? '' : payloadSummary }
    };
  } catch (error) {
    const message = error?.name === 'AbortError' ? `精选联盟达人搜索请求超过 ${timeoutMs}ms` : String(error?.message || error);
    return { version: 1, kind: 'creator_search', jobId: browserTask.jobId, sourceUrl: location.href, browser: navigator.userAgent, latencyMs: Date.now() - startedAt, response: { status: 0, ok: false, payload: null, error: message.slice(0, 240) } };
  } finally { clearTimeout(timer); }
}

async function executeCreatorClassification(task) {
  const uid = new URL(location.href).searchParams.get('uid') || String(task.uid || '');
  const visibleText = String(document.body?.innerText || '').slice(0, 16000);
  const jsonFetch = async (pathname, params) => {
    try {
      const url = new URL(pathname, location.origin);
      Object.entries(params || {}).forEach(([key, value]) => url.searchParams.set(key, String(value)));
      const response = await fetch(url, { credentials: 'include', headers: { Accept: 'application/json, text/plain, */*' } });
      return { status: response.status, payload: await response.json().catch(() => null) };
    } catch (_) { return { status: 0, payload: null }; }
  };
  const findValue = (value, keys, depth = 0) => {
    if (depth > 8 || value == null) return '';
    if (Array.isArray(value)) { for (const item of value) { const found = findValue(item, keys, depth + 1); if (found !== '') return found; } return ''; }
    if (typeof value !== 'object') return '';
    for (const key of keys) if (value[key] != null && value[key] !== '') return value[key];
    for (const child of Object.values(value)) { const found = findValue(child, keys, depth + 1); if (found !== '') return found; }
    return '';
  };
  const authorResponse = await jsonFetch('/square_pc_api/author/detail', { uid });
  const saleResponse = await jsonFetch('/square_pc_api/homePage/sale_analysis/sale_product_list', { uid, date_type: 'd30', room_id: 0, indus_cat: '', brand: '', page: 1, pageSize: 15, match_type: '', sort_type: '' });
  const authorData = authorResponse.payload?.data || authorResponse.payload || {};
  const saleData = saleResponse.payload?.data || saleResponse.payload || {};
  const categories = findValue(authorData, ['main_cate', 'author_cate', 'category', 'categories']);
  const liveSettlement = findValue(authorData, ['live_gmv_30d', 'live_settle_gmv_30d', 'live_settlement', 'liveSettlement']) || findValue(saleData, ['live_gmv_30d', 'live_settle_gmv_30d', 'live_settlement', 'liveSettlement']);
  const videoSettlement = findValue(authorData, ['video_gmv_30d', 'video_settle_gmv_30d', 'video_settlement', 'videoSettlement']) || findValue(saleData, ['video_gmv_30d', 'video_settle_gmv_30d', 'video_settlement', 'videoSettlement']);
  const pictureSettlement = findValue(authorData, ['picture_gmv_30d', 'picture_settle_gmv_30d', 'picture_settlement', 'pictureSettlement']) || findValue(saleData, ['picture_gmv_30d', 'picture_settle_gmv_30d', 'picture_settlement', 'pictureSettlement']);
  const hasValue = (value) => value != null && String(value).trim() !== '' && !/^(无|暂无|-|—|0)$/.test(String(value).trim());
  return {
    version: 1,
    kind: 'wps_creator_classify',
    jobId: task.jobId,
    sourceUrl: location.href,
    browser: navigator.userAgent,
    signals: {
      uid,
      profileText: visibleText,
      categories: Array.isArray(categories) ? categories.map(String).join('/') : String(categories || ''),
      liveSettlement: String(liveSettlement || ''),
      videoSettlement: String(videoSettlement || ''),
      pictureSettlement: String(pictureSettlement || ''),
      hasLiveSettlement: hasValue(liveSettlement) || /直播结算|直播带货/.test(visibleText),
      hasVideoSettlement: hasValue(videoSettlement) || /视频结算|短视频/.test(visibleText),
      hasPictureSettlement: hasValue(pictureSettlement) || /图文结算|图文/.test(visibleText),
      hasCart: /小黄车|挂车|橱窗|购物车/.test(visibleText)
    }
  };
}

async function executeCreatorDetail(task) {
  const startedAt = Date.now();
  const wait = (milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds));
  const textOf = () => String(document.body?.innerText || '');
  const tabText = (label) => {
    const tab = [...document.querySelectorAll('[role="tab"],button,a,[role="button"]')].find((element) => element.textContent?.trim() === label);
    const panelId = tab?.getAttribute('aria-controls');
    const panel = panelId ? document.getElementById(panelId) : null;
    return String(panel?.innerText || textOf());
  };
  const clickLabel = async (label) => {
    const elements = [...document.querySelectorAll('[role="tab"],button,a,[role="button"],div,span')];
    const target = elements.find((element) => element.textContent?.trim() === label);
    if (!target) return false;
    target.click();
    await wait(650);
    return true;
  };
  const jsonFetch = async (pathname, params) => {
    try {
      const url = new URL(pathname, location.origin);
      Object.entries(params || {}).forEach(([key, value]) => url.searchParams.set(key, String(value)));
      const response = await fetch(url, { credentials: 'include', headers: { Accept: 'application/json, text/plain, */*' } });
      const payload = await response.json().catch(() => null);
      return { status: response.status, ok: response.ok, payload };
    } catch (_) { return { status: 0, ok: false, payload: null }; }
  };
  const findValue = (value, keys, depth = 0) => {
    if (depth > 7 || value == null) return '';
    if (Array.isArray(value)) { for (const item of value) { const found = findValue(item, keys, depth + 1); if (found !== '') return found; } return ''; }
    if (typeof value !== 'object') return '';
    for (const key of keys) if (value[key] != null && value[key] !== '') return value[key];
    for (const child of Object.values(value)) { const found = findValue(child, keys, depth + 1); if (found !== '') return found; }
    return '';
  };
  const femaleRatioFrom = (value, depth = 0) => {
    if (depth > 8 || value == null) return null;
    if (typeof value === 'string') {
      const match = value.match(/女性[^\d%]{0,24}(\d+(?:\.\d+)?)\s*%/);
      return match ? Number(match[1]) / 100 : null;
    }
    if (Array.isArray(value)) { for (const item of value) { const ratio = femaleRatioFrom(item, depth + 1); if (ratio != null) return ratio; } return null; }
    if (typeof value !== 'object') return null;
    if (Array.isArray(value.x) && Array.isArray(value.y)) {
      const index = value.x.findIndex((item) => /女性|女|female/i.test(String(item)));
      if (index >= 0 && Number.isFinite(Number(value.y[index]))) return Number(value.y[index]) > 1 ? Number(value.y[index]) / 100 : Number(value.y[index]);
    }
    for (const [key, child] of Object.entries(value)) {
      if (/female|女性/i.test(key)) {
        const number = typeof child === 'object' ? Number(child.value ?? child.percent ?? child.ratio ?? child.y) : Number(child);
        if (Number.isFinite(number)) return number > 1 ? number / 100 : number;
      }
      const ratio = femaleRatioFrom(child, depth + 1);
      if (ratio != null) return ratio;
    }
    return null;
  };
  const originalUrl = location.href;
  const results = [];
  for (const candidate of task.candidates || []) {
    const profileUrl = String(candidate.profileUrl || '').startsWith('https://buyin.jinritemai.com')
      ? candidate.profileUrl
      : `https://buyin.jinritemai.com/dashboard/servicehall/daren-profile?uid=${encodeURIComponent(candidate.id)}&enter_from=1&scene=1&author_type=1`;
    try {
      if (location.href !== profileUrl) { location.href = profileUrl; await wait(1400); }
      const uid = new URL(location.href).searchParams.get('uid') || candidate.id;
      const authorResponse = await jsonFetch('/square_pc_api/author/detail', { uid });
      const saleResponse = await jsonFetch('/square_pc_api/homePage/sale_analysis/sale_product_list', { uid, date_type: 'd30', room_id: 0, indus_cat: '', brand: '', page: 1, pageSize: 15, match_type: '', sort_type: '' });
      const fanResponse = await jsonFetch('/api/authorStatData/playerAnalyzeV2', { uid });
      await clickLabel('带货分析');
      document.documentElement.scrollTop = document.documentElement.scrollHeight;
      await wait(400);
      const saleText = tabText('带货分析');
      await clickLabel('粉丝分析');
      await clickLabel('短视频观众');
      document.documentElement.scrollTop = 0;
      await wait(600);
      const fanText = tabText('粉丝分析');
      const shortVideoText = tabText('短视频观众');
      const authorData = authorResponse.payload?.data || authorResponse.payload || {};
      const saleData = saleResponse.payload?.data || saleResponse.payload || {};
      const fanData = fanResponse.payload?.data || fanResponse.payload || {};
      const rawProducts = saleData.product_info || saleData.products || saleData.product_list || saleData.list || [];
      results.push({ candidateId: String(candidate.id || ''), id: String(candidate.id || ''), name: String(findValue(authorData, ['nickname', 'nick_name']) || candidate.name || ''), douyinId: String(findValue(authorData, ['account_douyin', 'aweme_id', 'unique_id']) || candidate.douyinId || ''), douyinHomepageUrl: String(findValue(authorData, ['web_homepage_url', 'share_url_douyin', 'webHomepageUrl']) || ''), detailUrl: location.href, profileUrl: location.href, location: candidate.location || '', fans: candidate.fans || '', femaleRatio: femaleRatioFrom(fanData) ?? femaleRatioFrom(shortVideoText), femalePayload: fanData, fansText: fanText.slice(0, 6000), shortVideoText: shortVideoText.slice(0, 6000), saleText: saleText.slice(0, 10000), products: rawProducts, source: { authorStatus: authorResponse.status, saleStatus: saleResponse.status, fanStatus: fanResponse.status }, keywords: task.keywords || [] });
    } catch (error) {
      results.push({ candidateId: String(candidate.id || ''), id: String(candidate.id || ''), name: candidate.name || '', douyinId: candidate.douyinId || '', profileUrl, detailUrl: profileUrl, error: String(error?.message || error).slice(0, 240), products: [], femaleRatio: null });
    }
  }
  if (originalUrl.startsWith('https://buyin.jinritemai.com') && location.href !== originalUrl) { location.href = originalUrl; await wait(700); }
  return { version: 1, kind: 'creator_detail', jobId: task.jobId, sourceUrl: originalUrl, browser: navigator.userAgent, latencyMs: Date.now() - startedAt, results };
}

module.exports = { executeCreatorSearch, executeCreatorDetail, executeCreatorClassification };
