/**
 * 省胜优铺 · 授权在线复查（退款撤销锁定）模块
 * ============================================
 * 背景：
 *   授权服务器(lic.ssypco.com) 已具备撤销能力（licenses.status=revoked + /api/admin/revoke）。
 *   但买家软件此前只读本地缓存、从不主动联网复查 → 退款后服务端撤了，买家软件仍可继续使用。
 *   本模块补上"客户端周期性在线复查"这一环，实现"退款即锁定"。
 *
 * 设计原则（用户已确认，A档温和）：
 *   1. 仅"付费态"才复查；free 版（交付态）直接跳过，不参与、不影响。
 *   2. 只有服务器【明确返回 status=revoked】才锁定（降级为 free + 清本地授权）。
 *   3. 网络不可达 / 超时 / 响应异常 → 一律维持现状，绝不误伤正常用户（离线照常可用）。
 *   4. 幂等：已处于 free 态则不再重复锁定动作。
 *
 * 可配置（环境变量）：
 *   SSYP_LICENSE_SERVER       授权服务器地址（默认 https://lic.ssypco.com）
 *   SSYP_HEARTBEAT_INTERVAL_MS 心跳间隔（默认 24h = 86400000ms）
 *   SSYP_HEARTBEAT_START_DELAY 启动后首次心跳延迟（默认 10s，避开启动期）
 * ============================================
 */
const ssyp = require('./ssyp-license');

const LICENSE_SERVER = process.env.SSYP_LICENSE_SERVER || 'https://lic.ssypco.com';
const HEARTBEAT_INTERVAL = Number(process.env.SSYP_HEARTBEAT_INTERVAL_MS) || 24 * 60 * 60 * 1000; // 24h
const START_DELAY = Number(process.env.SSYP_HEARTBEAT_START_DELAY) || 10 * 1000;                // 10s
const REQUEST_TIMEOUT = 8000; // 8s 防止网络卡死

let _timer = null;
let _running = false;
let _lockedCount = 0;

/** 是否为需要复查的付费态（排除 free，交付态不参与） */
function isPaidLicense(lic) {
  return !!(lic && lic.activated && lic.type && lic.type !== 'free' && lic.type !== 'FREE');
}

/**
 * 执行一次在线复查。
 * 返回 { action: 'none'|'locked'|'skip'|'error', reason, detail }
 */
async function checkOnce() {
  const lic = ssyp.getLocalLicense();
  // 1. 免费态不复查（交付态保护）
  if (!isPaidLicense(lic)) {
    return { action: 'skip', reason: '非付费态，不生效' };
  }
  // 2. 需要 licenseCode 才能向服务器查询
  if (!lic.licenseCode) {
    return { action: 'skip', reason: '本地无授权码，无法复查（可能已被清空）' };
  }

  // 防止并发重入（定时任务 + 手动触发叠加）
  if (_running) return { action: 'skip', reason: '上一次复查尚未完成' };
  _running = true;
  try {
    const controller = new AbortController();
    const timer = setTimeout(() => controller.abort(), REQUEST_TIMEOUT);
    const resp = await fetch(`${LICENSE_SERVER}/api/status`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ license_code: lic.licenseCode }),
      signal: controller.signal,
    });
    clearTimeout(timer);

    if (!resp.ok) {
      // 服务器业务异常（4xx/5xx）——不因服务器临时故障误锁用户，维持现状
      return { action: 'none', reason: `服务器响应异常 HTTP ${resp.status}，维持现状` };
    }
    const data = await resp.json().catch(() => null);
    if (!data || !data.ok || !data.status) {
      return { action: 'none', reason: '服务器响应无法解析，维持现状' };
    }

    // 3. 关键判断：仅明确 revoked 才锁定
    if (String(data.status).toLowerCase() === 'revoked') {
      return lockNow('服务器返回 revoked（退款/撤销）');
    }
    // activated / issued / 其他 → 正常，不做任何事
    return { action: 'none', reason: `授权状态=${data.status}，正常` };
  } catch (e) {
    // 网络不可达 / 超时 / AbortError → 不误伤，维持现状
    return { action: 'none', reason: '网络不可达或超时，维持现状', detail: e.message };
  } finally {
    _running = false;
  }
}

/**
 * 执行锁定：降级为 free + 清本地 ssyp_license（复用 ssyp-license 的既有 API）。
 */
function lockNow(reason) {
  try {
    // 用 ssyp 的 setLicenseType 降级为 free（混淆原生授权层会同此识别）
    ssyp.setLicenseType('free');
    // 清空本地授权缓存记录（ssyp_license 置空，使 getLocalLicense 回到 free 态）
    try {
      const { run } = require('../utils/db');
      run(
        "INSERT INTO system_config(key, value) VALUES('ssyp_license', '') " +
        "ON CONFLICT(key) DO UPDATE SET value=excluded.value"
      );
    } catch (dbErr) {
      console.error('[license-heartbeat] 清理本地授权失败:', dbErr.message);
    }
    // 使内存缓存失效，确保后续读取拿到 free 态
    try { ssyp.invalidateCache(); } catch (_) {}
    _lockedCount += 1;
    console.warn(`[license-heartbeat] 🔒 授权已锁定：${reason}`);
    return { action: 'locked', reason };
  } catch (e) {
    console.error('[license-heartbeat] 锁定动作失败:', e.message);
    return { action: 'error', reason: '锁定动作执行失败', detail: e.message };
  }
}

/**
 * 启动定时复查（服务启动时调用一次即可）。返回 stop 函数。
 */
function startHeartbeat() {
  if (_timer) return () => stopHeartbeat();

  // 首次延迟启动，避开服务启动期的高并发
  const firstTimer = setTimeout(runScheduled, START_DELAY);

  async function runScheduled() {
    try {
      const r = await checkOnce();
      if (r && r.action === 'locked') {
        console.warn(`[license-heartbeat] 退款锁定已生效（累计 ${_lockedCount} 次）`);
      }
    } catch (e) {
      console.error('[license-heartbeat] 定时复查异常:', e.message);
    } finally {
      // 无论成功失败，都安排下一次（间隔）
      _timer = setTimeout(runScheduled, HEARTBEAT_INTERVAL);
    }
  }

  function stopHeartbeat() {
    clearTimeout(firstTimer);
    if (_timer) clearTimeout(_timer);
    _timer = null;
  }

  return stopHeartbeat;
}

function stopHeartbeat() {
  if (_timer) { clearTimeout(_timer); _timer = null; }
}

module.exports = {
  checkOnce,          // 一次性复查（供手动触发/测试/管理接口调用）
  startHeartbeat,     // 启动定时复查
  stopHeartbeat,      // 停止
  isPaidLicense,
};
