const express = require('express');
const router = express.Router();
const axios = require('axios');
const { authenticateUser } = require('../middleware/auth');
const User = require('../models/User');
const env = require('../config/env');

// 缓存 access_token
let accessTokenCache = {
  token: null,
  expiresAt: 0
};

/**
 * 获取微信 access_token
 */
async function getAccessToken() {
  const now = Date.now();
  
  // 如果缓存有效，直接返回
  if (accessTokenCache.token && accessTokenCache.expiresAt > now) {
    return accessTokenCache.token;
  }
  
  // 调用微信API获取 access_token
  const url = 'https://api.weixin.qq.com/cgi-bin/token';
  const response = await axios.get(url, {
    params: {
      grant_type: 'client_credential',
      appid: env.wechat.appId,
      secret: env.wechat.appSecret
    }
  });
  
  if (response.data.errcode) {
    throw new Error(`获取access_token失败: ${response.data.errmsg}`);
  }
  
  // 缓存 token，提前5分钟过期
  accessTokenCache = {
    token: response.data.access_token,
    expiresAt: now + (response.data.expires_in - 300) * 1000
  };
  
  return accessTokenCache.token;
}

/**
 * @swagger
 * /api/v1/qrcode/miniprogram:
 *   post:
 *     summary: 获取小程序码
 *     tags: [QRCode]
 *     security:
 *       - bearerAuth: []
 *     requestBody:
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             properties:
 *               width:
 *                 type: number
 *                 description: 二维码宽度，默认430
 *     responses:
 *       200:
 *         description: 成功返回小程序码图片的base64
 */
router.post('/miniprogram', authenticateUser, async (req, res) => {
  try {
    const userId = req.user.id;
    const { width = 430 } = req.body;
    
    // 获取用户邀请码
    const user = await User.findByPk(userId, {
      attributes: ['id', 'invitationCode']
    });
    
    if (!user) {
      return res.status(404).json({
        code: 404,
        message: 'User not found',
        data: null
      });
    }
    
    // 如果用户没有邀请码，生成一个
    let invitationCode = user.invitationCode;
    if (!invitationCode) {
      invitationCode = generateInvitationCode();
      await user.update({ invitationCode });
    }

    let dataUrl = '';
    
    // 开发环境：尝试生成小程序码，失败则返回邀请码信息供前端生成普通二维码
    try {
      // 获取 access_token
      const accessToken = await getAccessToken();
      
      // 调用微信API生成小程序码（使用 getUnlimited 接口，无数量限制）
      const wxUrl = `https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=${accessToken}`;
      const wxResponse = await axios.post(wxUrl, {
        scene: `inviteCode=${invitationCode}`,  // scene 参数，最长32字符
        page: 'pages/index/index',  // 必须是已发布的小程序页面
        width: width,
        auto_color: false,
        line_color: { r: 0, g: 0, b: 0 },
        is_hyaline: false
      }, {
        responseType: 'arraybuffer'  // 返回的是图片二进制数据
      });
      
      // 检查是否返回错误（错误时返回JSON）
      const contentType = wxResponse.headers['content-type'];
      if (contentType && contentType.includes('application/json')) {
        const errorData = JSON.parse(wxResponse.data.toString());
        console.error('微信小程序码生成失败:', errorData);
        // 小程序未发布，返回邀请码让前端生成普通二维码
        return res.status(200).json({
          code: 0,
          message: 'success',
          data: {
            invitationCode,
            qrcodeUrl: null,  // 无小程序码，前端使用普通二维码
            useLocalQrcode: true,  // 标记使用本地二维码
            qrcodeContent: `/pages/index/index?inviteCode=${invitationCode}`
          }
        });
      }
      
      // 转换为 base64
      const base64Image = Buffer.from(wxResponse.data).toString('base64');
      dataUrl = `data:image/png;base64,${base64Image}`;
    } catch (wxError) {
      console.error('生成小程序码异常:', wxError.message);
      // 返回邀请码让前端生成普通二维码
      return res.status(200).json({
        code: 0,
        message: 'success',
        data: {
          invitationCode,
          qrcodeUrl: null,
          useLocalQrcode: true,
          qrcodeContent: `/pages/index/index?inviteCode=${invitationCode}`
        }
      });
    }
    
    return res.status(200).json({
      code: 0,
      message: 'success',
      data: {
        invitationCode,
        qrcodeUrl: dataUrl  // base64格式的小程序码图片
      }
    });
  } catch (error) {
    console.error('Get miniprogram qrcode error:', error);
    return res.status(200).json({
      code: 500,
      message: error.message || '生成小程序码失败',
      data: null
    });
  }
});

/**
 * 生成邀请码
 */
function generateInvitationCode() {
  const chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789';
  let code = '';
  for (let i = 0; i < 6; i++) {
    code += chars.charAt(Math.floor(Math.random() * chars.length));
  }
  return code;
}

module.exports = router;
