/**
 * ONES 旧版 Project API — 经 Browser Bridge 在已登录标签页内 fetch（携带 Cookie）。
 * 文档：https://developer.ones.cn/zh-CN/docs/api/readme/
 */
import { CliError } from '@jackwener/opencli/errors';
export const API_PREFIX = '/project/api/project';
export function getOnesBaseUrl() {
    const u = process.env.ONES_BASE_URL?.trim().replace(/\/+$/, '');
    if (!u) {
        throw new CliError('CONFIG', 'Missing ONES_BASE_URL', 'Set ONES_BASE_URL to your deployment origin, e.g. https://your-team.ones.cn (no trailing slash).');
    }
    return u;
}
export function onesApiUrl(apiPath) {
    const base = getOnesBaseUrl();
    const p = apiPath.replace(/^\/+/, '');
    return `${base}${API_PREFIX}/${p}`;
}
/** 打开 ONES 根地址，确保后续 fetch 与页面同源、带上登录 Cookie */
export async function gotoOnesHome(page) {
    await page.goto(getOnesBaseUrl(), { waitUntil: 'load' });
    await page.wait(2);
}
/**
 * 在页面内发起请求。默认带 credentials；若设置了 ONES_USER_ID + ONES_AUTH_TOKEN，则附加文档要求的 Header（与纯 Cookie 二选一或并存，取决于部署）。
 */
function buildHeaders(auth, includeJsonContentType) {
    const ref = getOnesBaseUrl();
    const out = { Referer: ref };
    if (auth) {
        const uid = process.env.ONES_USER_ID?.trim() ||
            process.env.ONES_USER_UUID?.trim() ||
            process.env.Ones_User_Id?.trim();
        const tok = process.env.ONES_AUTH_TOKEN?.trim() || process.env.Ones_Auth_Token?.trim();
        if (uid && tok) {
            out['Ones-User-Id'] = uid;
            out['Ones-Auth-Token'] = tok;
        }
    }
    if (includeJsonContentType)
        out['Content-Type'] = 'application/json';
    return out;
}
export function summarizeOnesError(status, body) {
    if (body && typeof body === 'object') {
        const o = body;
        const parts = [];
        if (typeof o.type === 'string')
            parts.push(o.type);
        if (typeof o.reason === 'string')
            parts.push(o.reason);
        if (typeof o.errcode === 'string')
            parts.push(o.errcode);
        if (typeof o.message === 'string')
            parts.push(o.message);
        if (o.code !== undefined && o.code !== null)
            parts.push(`code=${String(o.code)}`);
        if (parts.length)
            return parts.filter(Boolean).join(' · ');
    }
    return status === 401 ? 'Unauthorized' : `HTTP ${status}`;
}
/** ONES 部分接口 HTTP 200 但 body 仍为错误（如 reason: ServerError） */
function throwIfOnesPeekBusinessError(apiPath, parsed) {
    if (parsed === null || typeof parsed !== 'object')
        return;
    const o = parsed;
    if (Array.isArray(o.groups))
        return;
    const hasErr = (typeof o.reason === 'string' && o.reason.length > 0) ||
        (typeof o.errcode === 'string' && o.errcode.length > 0) ||
        (typeof o.type === 'string' && o.type.length > 0);
    if (!hasErr)
        return;
    const detail = summarizeOnesError(200, parsed);
    throw new CliError('FETCH_ERROR', `ONES ${apiPath}: ${detail}`, '若 query 不合法会返回 ServerError；可试 opencli ones tasks（空 must）或检查筛选器文档。响应全文可用 -v 或临时打日志。');
}
export async function onesFetchInPageWithMeta(page, apiPath, options = {}) {
    if (!options.skipGoto) {
        await gotoOnesHome(page);
    }
    const url = onesApiUrl(apiPath);
    const method = (options.method ?? 'GET').toUpperCase();
    const auth = options.auth !== false;
    const body = options.body ?? null;
    const includeCt = body !== null || method === 'POST' || method === 'PUT' || method === 'PATCH';
    const headers = buildHeaders(auth, includeCt);
    const urlJs = JSON.stringify(url);
    const methodJs = JSON.stringify(method);
    const headersJs = JSON.stringify(headers);
    const bodyJs = body === null ? 'null' : JSON.stringify(body);
    const raw = await page.evaluate(`
    (async () => {
      const url = ${urlJs};
      const method = ${methodJs};
      const headers = ${headersJs};
      const body = ${bodyJs};
      const init = {
        method,
        headers: { ...headers },
        credentials: 'include',
      };
      if (body !== null) init.body = body;
      const res = await fetch(url, init);
      const text = await res.text();
      let parsed = null;
      try {
        parsed = text ? JSON.parse(text) : null;
      } catch {
        parsed = text;
      }
      return { ok: res.ok, status: res.status, parsed };
    })()
  `);
    return raw;
}
/** 当前操作用户 8 位 uuid（Header 或 GET users/me） */
export async function resolveOnesUserUuid(page, opts) {
    const fromEnv = process.env.ONES_USER_ID?.trim() ||
        process.env.ONES_USER_UUID?.trim() ||
        process.env.Ones_User_Id?.trim();
    if (fromEnv)
        return fromEnv;
    const data = (await onesFetchInPage(page, 'users/me', { skipGoto: opts?.skipGoto }));
    const u = data.user && typeof data.user === 'object' ? data.user : data;
    if (!u || typeof u.uuid !== 'string') {
        throw new CliError('FETCH_ERROR', 'Could not read current user uuid from users/me', 'Set ONES_USER_ID or ensure Chrome is logged in; try: opencli ones me -f json');
    }
    return String(u.uuid);
}
export async function onesFetchInPage(page, apiPath, options = {}) {
    const r = await onesFetchInPageWithMeta(page, apiPath, options);
    if (!r.ok) {
        const detail = summarizeOnesError(r.status, r.parsed);
        const hint = r.status === 401
            ? '在 Chrome 中打开 ONES 并登录；或先执行 opencli ones login 后按提示 export ONES_USER_ID / ONES_AUTH_TOKEN；并确认 ONES_BASE_URL 与浏览器地址一致。'
            : '检查 ONES_BASE_URL、VPN/内网，以及实例是否仍为 Project API 路径。';
        throw new CliError('FETCH_ERROR', `ONES ${apiPath}: ${detail}`, hint);
    }
    if (apiPath.includes('/filters/peek')) {
        throwIfOnesPeekBusinessError(apiPath, r.parsed);
    }
    return r.parsed;
}
