/**
 * Content Security API Routes
 * Express routes for content security checking, sensitive words, and reporting.
 */

const express = require('express');
const multer = require('multer');
const ContentSecurityService = require('./contentSecurityService');
const ViolationService = require('./violationService');
const ReportService = require('./reportService');
const sensitiveWords = require('./sensitiveWords');

// Configure multer for image uploads (memory storage, max 1MB)
const upload = multer({
  storage: multer.memoryStorage(),
  limits: { fileSize: 1024 * 1024 }, // 1MB max
});

/**
 * Create and return the content security router.
 * @param {object} options
 * @param {import('./wechatTokenManager')} options.tokenManager - Token manager instance
 * @param {import('./auditLogger')} [options.logger] - Audit logger instance
 * @returns {express.Router}
 */
function createContentSecurityRouter(options = {}) {
  const router = express.Router();
  const contentSecurity = new ContentSecurityService({
    tokenManager: options.tokenManager,
    logger: options.logger,
  });
  const violationService = options.violationService || new ViolationService({
    logger: options.logger,
  });
  const reportService = options.reportService || new ReportService({
    logger: options.logger,
    violationService,
  });

  // ============================================================
  // Middleware: Extract game_id from request
  // Priority: X-Game-Id header > game_id body/query param > DEFAULT_GAME_ID
  // ============================================================
  const DEFAULT_GAME_ID = process.env.DEFAULT_GAME_ID || 'tankwar';

  function extractGameId(req) {
    return req.headers['x-game-id'] || req.body?.game_id || req.query?.game_id || DEFAULT_GAME_ID;
  }

  // ============================================================
  // POST /api/content/check-text - Text content security check
  // ============================================================
  router.post('/check-text', express.json(), async (req, res) => {
    const { openid, content, scene } = req.body;
    const gameId = extractGameId(req);

    // Validate required fields
    if (!openid || typeof openid !== 'string') {
      return res.status(400).json({
        errcode: 40001,
        errmsg: 'openid is required',
      });
    }

    if (!content || typeof content !== 'string') {
      return res.status(400).json({
        errcode: 40002,
        errmsg: 'content is required',
      });
    }

    if (typeof scene !== 'number' || ![1, 2, 3, 4].includes(scene)) {
      return res.status(400).json({
        errcode: 40003,
        errmsg: 'scene must be 1(nickname), 2(chat), 3(signature), or 4(description)',
      });
    }

    try {
      // First, do server-side local sensitive word check
      const localCheck = sensitiveWords.checkText(content);
      if (localCheck.hasViolation) {
        // Auto-record violation
        violationService.recordViolation({
          userId: openid,
          gameId,
          violationType: 'local_sensitive_word',
          contentSummary: content.substring(0, 20),
          scene,
        });

        return res.json({
          pass: false,
          errcode: 0,
          errmsg: '内容违规，请修改',
          suggest: 'risky',
          label: 20000,
          localCheck: true,
          categories: localCheck.categories,
          game_id: gameId,
        });
      }

      // Then, call WeChat msgSecCheck API
      const result = await contentSecurity.checkTextContent(openid, content, scene);

      // Auto-record violation if msgSecCheck rejects
      if (!result.pass && result.label > 0) {
        violationService.recordViolation({
          userId: openid,
          gameId,
          violationType: `wechat_label_${result.label}`,
          contentSummary: content.substring(0, 20),
          scene,
        });
      }

      return res.json({ ...result, game_id: gameId });
    } catch (err) {
      console.error('[API] check-text error:', err.message);
      return res.status(500).json({
        errcode: -1,
        errmsg: '审核服务暂时不可用，请稍后再试',
      });
    }
  });

  // ============================================================
  // POST /api/content/check-image - Image content security check
  // ============================================================
  router.post('/check-image', upload.single('image'), async (req, res) => {
    const gameId = extractGameId(req);

    if (!req.file) {
      return res.status(400).json({
        errcode: 40004,
        errmsg: 'image file is required',
      });
    }

    // Check file size (multer already enforces this, but double-check)
    if (req.file.size > 1024 * 1024) {
      return res.status(400).json({
        errcode: 40005,
        errmsg: '图片大小不能超过1MB',
      });
    }

    try {
      const result = await contentSecurity.checkImageContent(req.file.buffer);

      // Auto-record violation if image is rejected
      if (!result.pass && req.body && req.body.openid) {
        violationService.recordViolation({
          userId: req.body.openid,
          gameId,
          violationType: 'image_violation',
          contentSummary: `image_${req.file.size}bytes`,
          scene: 5,
        });
      }

      return res.json({ ...result, game_id: gameId });
    } catch (err) {
      console.error('[API] check-image error:', err.message);
      return res.status(500).json({
        errcode: -1,
        errmsg: '审核服务暂时不可用，请稍后再试',
      });
    }
  });

  // ============================================================
  // GET /api/content/sensitive-words - Get sensitive word list for client caching
  // ============================================================
  router.get('/sensitive-words', (req, res) => {
    const version = req.query.version;

    // If client sends current version and it matches, return 304
    if (version && version === sensitiveWords.getVersion()) {
      return res.status(304).json({
        version: sensitiveWords.getVersion(),
        updated: false,
      });
    }

    return res.json({
      version: sensitiveWords.getVersion(),
      updated: true,
      words: sensitiveWords.getAllWords(),
      categories: sensitiveWords.getWordsByCategory(),
    });
  });

  // ============================================================
  // GET /api/user/mute-status - Check if a user is muted
  // ============================================================
  router.get('/user/mute-status', (req, res) => {
    const openid = req.query.openid;
    const gameId = extractGameId(req);

    if (!openid || typeof openid !== 'string') {
      return res.status(400).json({
        errcode: 40006,
        errmsg: 'openid is required',
      });
    }

    const status = violationService.getMuteStatus(openid, gameId);
    return res.json({ ...status, game_id: gameId });
  });

  // ============================================================
  // GET /api/user/violation-summary - Get violation summary for a user
  // ============================================================
  router.get('/user/violation-summary', (req, res) => {
    const openid = req.query.openid;
    const gameId = extractGameId(req);

    if (!openid || typeof openid !== 'string') {
      return res.status(400).json({
        errcode: 40006,
        errmsg: 'openid is required',
      });
    }

    const summary = violationService.getViolationSummary(openid, gameId);
    return res.json(summary);
  });

  // ============================================================
  // POST /api/content/report - Submit a content report
  // ============================================================
  router.post('/report', express.json(), (req, res) => {
    const { contentId, targetUserId, contentType, contentSummary, reporterId, reason } = req.body;
    const gameId = extractGameId(req);

    // Validate required fields
    if (!contentId || !targetUserId || !contentType || !reporterId || !reason) {
      return res.status(400).json({
        errcode: 40007,
        errmsg: 'Missing required fields: contentId, targetUserId, contentType, reporterId, reason',
      });
    }

    // Validate reason
    const validReasons = Object.values(ReportService.REPORT_REASONS);
    if (!validReasons.includes(reason)) {
      return res.status(400).json({
        errcode: 40008,
        errmsg: `Invalid reason. Must be one of: ${validReasons.join(', ')}`,
      });
    }

    const result = reportService.submitReport({
      contentId,
      targetUserId,
      contentType,
      contentSummary: contentSummary || '',
      reporterId,
      reason,
      gameId,
    });

    if (!result.success) {
      if (result.reportCount === 0) {
        return res.status(400).json({
          errcode: 40009,
          errmsg: '举报提交失败',
        });
      }
      // Already reported
      return res.json({
        success: false,
        message: '您已举报过该内容',
        reportCount: result.reportCount,
        game_id: gameId,
      });
    }

    return res.json({
      success: true,
      message: '举报已提交',
      reportCount: result.reportCount,
      autoTakenDown: result.autoTakenDown,
      game_id: gameId,
    });
  });

  // ============================================================
  // POST /api/content/check-text - Auto-record violation on reject
  // (Extended: records violation when content is rejected)
  // ============================================================
  // This is already handled in the check-text route above,
  // but we also add violation recording here for server-side content.
  // The check-text endpoint above will auto-record violations
  // when msgSecCheck returns a rejection.

  return router;
}

module.exports = { createContentSecurityRouter };