// POST /api/sync — 接收 EternalAI 的同步请求
// 流程：验证 sync_token → 回调拉取 SOUL.md + config.yaml → 创建/更新 profile → 生成二维码 → 返回

const express = require('express');
const { verifySyncToken } = require('../lib/sync-token-verify');
const { pullRoleFiles } = require('../lib/eternalai-client');
const { generateProfileId, createProfile, findByRoleId, deleteProfile } = require('../lib/profile-store');
const { generateAndSaveQrCode } = require('../lib/qrcode-gen');

const router = express.Router();

// P2 修复：输入校验
const MAX_PROFILE_NAME_LEN = 128;

// 来源 IP 白名单检查（P1 修复：使用 socket.remoteAddress 而非可伪造的 req.ip）
function checkSourceIp(req, res, next) {
  const allowedIps = process.env.ALLOWED_SOURCE_IPS;
  if (!allowedIps) return next();

  // 使用 socket 远程地址，不受 X-Forwarded-For 影响
  const clientIp = (req.socket.remoteAddress || '').replace(/^::ffff:/, '');
  if (!clientIp) {
    return res.status(403).json({ error: '无法确定来源 IP' });
  }
  const allowed = allowedIps.split(',').map((ip) => ip.trim());
  if (!allowed.includes(clientIp)) {
    return res.status(403).json({ error: '来源 IP 不在白名单中' });
  }
  next();
}

router.post('/sync', checkSourceIp, async (req, res) => {
  try {
    const {
      profileName,
      modelKey,
      provider,
      multimediaModelKey,
      multimediaProvider,
      enableSchedule,
      syncToken,
      roleId,
    } = req.body;

    // 参数校验
    if (!syncToken || !roleId || !profileName) {
      return res.status(400).json({ error: '缺少必要参数（syncToken, roleId, profileName）' });
    }

    // P2 修复：profileName 长度限制
    if (profileName.length > MAX_PROFILE_NAME_LEN) {
      return res.status(400).json({ error: `profileName 过长（上限 ${MAX_PROFILE_NAME_LEN} 字符）` });
    }

    // 验证 sync_token
    const payload = verifySyncToken(syncToken);
    if (!payload) {
      return res.status(401).json({ error: 'sync_token 无效或已过期' });
    }

    // 验证 roleId 匹配
    if (payload.roleId !== roleId) {
      return res.status(403).json({ error: 'roleId 与 sync_token 不匹配' });
    }

    // P1 修复：幂等去重 — 若该 roleId 已有 profile，先删除旧的再创建新的
    const existing = findByRoleId(roleId);
    if (existing) {
      deleteProfile(existing.profileId);
    }

    // 回调 EternalAI 拉取 SOUL.md 和 config.yaml
    // P0 修复：使用环境变量 ETERNALAI_BASE_URL，不信任请求体中的 filePullBaseUrl
    const { soulMd, configYaml } = await pullRoleFiles(roleId, syncToken);

    // P2 修复：校验两个文件都非空
    if (!soulMd || soulMd.length === 0) {
      return res.status(400).json({ error: '拉取的 SOUL.md 为空' });
    }
    if (!configYaml || configYaml.length === 0) {
      return res.status(400).json({ error: '拉取的 config.yaml 为空' });
    }

    // 创建 profile
    const profileId = generateProfileId();
    const baseUrl = process.env.HERMES_BASE_URL || `http://localhost:${process.env.PORT || 3002}`;
    const bindUrl = `${baseUrl}/api/bind/${profileId}`;

    // P2 修复：先创建 profile，再生成二维码（避免孤儿文件）
    // 先用 null 作为 qrCodeUrl 创建 profile
    const meta = createProfile({
      profileId,
      profileName,
      roleId,
      sourceBaseUrl: process.env.ETERNALAI_BASE_URL || 'unknown',
      modelKey,
      provider,
      multimediaModelKey,
      multimediaProvider,
      enableSchedule: !!enableSchedule,
      soulMd,
      configYaml,
      qrCodeUrl: null, // 稍后更新
    });

    // 生成二维码
    try {
      const qrFilename = await generateAndSaveQrCode(profileId, bindUrl);
      const qrCodeUrl = `${baseUrl}/api/qrcodes/${qrFilename}`;
      // 更新 meta 中的 qrCodeUrl（通过重新写入 meta.json）
      const { getProfileMeta } = require('../lib/profile-store');
      const updatedMeta = getProfileMeta(profileId);
      if (updatedMeta) {
        updatedMeta.qrCodeUrl = qrCodeUrl;
        const fs = require('fs');
        const path = require('path');
        const metaPath = path.join(__dirname, '..', '..', 'data', 'profiles', profileId, 'meta.json');
        fs.writeFileSync(metaPath, JSON.stringify(updatedMeta, null, 2));
      }
      meta.qrCodeUrl = qrCodeUrl;
    } catch (qrErr) {
      console.error('[Hermes] 二维码生成失败:', qrErr.message);
      // 二维码生成失败不阻塞 profile 创建，但返回中不包含 qrCodeUrl
    }

    console.log(`[Hermes] Profile 创建成功: ${profileId} (name=${profileName}, roleId=${roleId})`);

    res.json({
      qrCodeUrl: meta.qrCodeUrl,
      profileId,
      message: 'Profile 创建成功',
    });
  } catch (err) {
    console.error('[Hermes] 同步失败:', err.message);
    // P3 修复：区分已知错误类型
    if (err.message.includes('超时')) {
      return res.status(504).json({ error: '拉取文件超时，请检查 EternalAI 服务状态' });
    }
    if (err.message.includes('ETERNALAI_BASE_URL')) {
      return res.status(500).json({ error: 'Hermes Server 未配置 ETERNALAI_BASE_URL' });
    }
    if (err.message.includes('拉取') && err.message.includes('失败')) {
      return res.status(502).json({ error: '拉取文件失败，请检查 EternalAI 服务是否正常' });
    }
    res.status(500).json({ error: '同步失败，请稍后重试' });
  }
});

module.exports = router;
