'use strict';

const DEFAULT_API_BASE = 'https://api.bgm.tv';
let apiBase = DEFAULT_API_BASE;
// Set by runSync from settings.bgmApiBase (sync is locked/serial, so a module-level value is safe).
function setApiBase(base) { apiBase = (typeof base === 'string' && base.trim()) ? base.trim().replace(/\/+$/, '') : DEFAULT_API_BASE; }

const sleep = (ms) => new Promise(r => setTimeout(r, ms));

async function bgmFetch(path, token) {
  const res = await fetch(apiBase + path, {
    headers: {
      'Accept': 'application/json',
      'User-Agent': 'BangumiVaultDocker/1.0',
      ...(token ? { 'Authorization': 'Bearer ' + String(token).trim() } : {})
    }
  });
  if (!res.ok) {
    const t = await res.text().catch(() => res.statusText);
    throw new Error(`HTTP ${res.status}: ${String(t).slice(0, 200)}`);
  }
  return res.json();
}

async function fetchMe(token) {
  return bgmFetch('/v0/me', token);
}

async function fetchCollectionAll(username, st, ct, token, onPage) {
  const limit = 50; let offset = 0; let total = Infinity; let page = 0; const out = [];
  while (offset < total) {
    const path = `/v0/users/${encodeURIComponent(username)}/collections?subject_type=${st}&type=${ct}&limit=${limit}&offset=${offset}`;
    const js = await bgmFetch(path, token); const data = Array.isArray(js) ? js : (js.data || []);
    total = Number.isFinite(js.total) ? js.total : (offset + data.length + (data.length === limit ? limit : 0));
    out.push(...data.map(x => ({ ...x, __fallback: { subject_type: st, collection_type: ct } }))); page++;
    if (onPage) onPage(page, out.length);
    if (!data.length || data.length < limit) break;
    offset += limit; await sleep(110);
  }
  return out;
}

async function fetchCollectionRecent(username, st, ct, token, cutoff, onPage) {
  const limit = 50; let offset = 0; let total = Infinity; let page = 0; const out = []; const cutoffMs = cutoff.getTime();
  while (offset < total) {
    const path = `/v0/users/${encodeURIComponent(username)}/collections?subject_type=${st}&type=${ct}&limit=${limit}&offset=${offset}`;
    const js = await bgmFetch(path, token); const data = Array.isArray(js) ? js : (js.data || []);
    total = Number.isFinite(js.total) ? js.total : (offset + data.length + (data.length === limit ? limit : 0));
    const decorated = data.map(x => ({ ...x, __fallback: { subject_type: st, collection_type: ct } }));
    const recent = decorated.filter(x => { const t = Date.parse(x.updated_at || x.updatedAt || ''); return !Number.isFinite(t) || t >= cutoffMs; });
    out.push(...recent); page++;
    const stopByTime = data.length > 0 && recent.length === 0 && data.every(x => { const t = Date.parse(x.updated_at || x.updatedAt || ''); return Number.isFinite(t) && t < cutoffMs; });
    if (onPage) onPage(page, out.length, stopByTime);
    if (!data.length || data.length < limit || stopByTime) break;
    offset += limit; await sleep(80);
  }
  return out;
}

async function fetchSubjectDetail(subjectId, token) {
  try {
    return await bgmFetch(`/v0/subjects/${encodeURIComponent(subjectId)}`, token || '');
  } catch {
    return null;
  }
}

module.exports = { DEFAULT_API_BASE, setApiBase, sleep, bgmFetch, fetchMe, fetchCollectionAll, fetchCollectionRecent, fetchSubjectDetail };
