/**
 * 推广邀请管理控制器（客户端接口）
 * 提供客户端调用的推广邀请相关接口
 */

const Framework = require("../../framework/node-core-framework.js");
const dayjs = require('dayjs');
const email_service = require('../services/email_service.js');
module.exports = {
  /**
   * @swagger
   * /api/invite/info:
   *   post:
   *     summary: 获取邀请信息
   *     description: 根据设备SN码获取邀请码和邀请链接
   *     tags: [前端-推广邀请]
   *     requestBody:
   *       required: true
   *       content:
   *         application/json:
   *           schema:
   *             type: object
   *             required:
   *               - sn_code
   *             properties:
   *               sn_code:
   *                 type: string
   *                 description: 设备SN码
   *     responses:
   *       200:
   *         description: 获取成功
   */
  'POST /invite/info': async (ctx) => {
    try {
      // 从body中获取sn_code
      const body = ctx.getBody();
      const { sn_code } = body;

      if (!sn_code) {
        return ctx.fail('请提供设备SN码');
      }

      const { pla_account } = await Framework.getModels();

      // 根据sn_code查找用户
      const user = await pla_account.findOne({
        where: { sn_code }
      });

      if (!user) {
        return ctx.fail('用户不存在');
      }

      // 生成邀请码（基于用户ID和sn_code）
      const invite_code = `INV${user.id}_${Date.now().toString(36).toUpperCase()}`;
      const invite_link = `https://work.light120.com/invite?code=${invite_code}`;

      // 保存邀请码到用户记录（可以保存到invite_code字段，如果没有则保存到备注或其他字段）
      // 这里暂时不保存到数据库，每次生成新的

      return ctx.success({
        invite_code,
        invite_link,
        user_id: user.id,
        sn_code: user.sn_code
      });
    } catch (error) {
      console.error('获取邀请信息失败:', error);
      return ctx.fail('获取邀请信息失败: ' + error.message);
    }
  },

  /**
   * @swagger
   * /api/invite/statistics:
   *   post:
   *     summary: 获取邀请统计
   *     description: 根据设备SN码获取邀请统计数据
   *     tags: [前端-推广邀请]
   *     requestBody:
   *       required: true
   *       content:
   *         application/json:
   *           schema:
   *             type: object
   *             required:
   *               - sn_code
   *             properties:
   *               sn_code:
   *                 type: string
   *                 description: 设备SN码
   *     responses:
   *       200:
   *         description: 获取成功
   */
  'POST /invite/statistics': async (ctx) => {
    try {
      // 从body中获取sn_code
      const body = ctx.getBody() || {};
      const { sn_code } = body;

      if (!sn_code) {
        return ctx.fail('请提供设备SN码');
      }

      const { pla_account } = await Framework.getModels();

      // 根据sn_code查找用户
      const user = await pla_account.findOne({
        where: { sn_code }
      });

      if (!user) {
        return ctx.fail('用户不存在');
      }

      // 查询邀请统计
      const { invite_record } = await Framework.getModels();

      // 查询总邀请数
      const totalInvites = await invite_record.count({
        where: {
          inviter_id: user.id,
          is_delete: 0
        }
      });

      // 查询已发放奖励的邀请数（活跃邀请）
      const activeInvites = await invite_record.count({
        where: {
          inviter_id: user.id,
          reward_status: 1,
          is_delete: 0
        }
      });

      // 查询总奖励天数
      const rewardRecords = await invite_record.findAll({
        where: {
          inviter_id: user.id,
          reward_status: 1,
          is_delete: 0
        },
        attributes: ['reward_value']
      });

      const totalRewardDays = rewardRecords.reduce((sum, record) => {
        return sum + (record.reward_value || 0);
      }, 0);

      return ctx.success({
        totalInvites: totalInvites || 0
      });
    } catch (error) {
      console.error('获取邀请统计失败:', error);
      return ctx.fail('获取邀请统计失败: ' + error.message);
    }
  },

  /**
   * @swagger
   * /api/invite/generate:
   *   post:
   *     summary: 生成邀请码
   *     description: 为用户生成新的邀请码
   *     tags: [前端-推广邀请]
   *     responses:
   *       200:
   *         description: 生成成功
   */
  'POST /invite/generate': async (ctx) => {
    try {
      // 从body中获取sn_code
      const body = ctx.getBody() || {};
      const { sn_code } = body;

      if (!sn_code) {
        return ctx.fail('请提供设备SN码');
      }

      const { pla_account } = await Framework.getModels();

      // 根据sn_code查找用户
      const user = await pla_account.findOne({
        where: { sn_code }
      });

      if (!user) {
        return ctx.fail('用户不存在');
      }

      // 生成新的邀请码
      const invite_code = `INV${user.id}_${Date.now().toString(36).toUpperCase()}`;
      const invite_link = `https://work.light120.com/register.html?code=${invite_code}`;

      return ctx.success({
        invite_code,
        invite_link
      });
    } catch (error) {
      console.error('生成邀请码失败:', error);
      return ctx.fail('生成邀请码失败: ' + error.message);
    }
  },

  /**
   * @swagger
   * /api/invite/records:
   *   post:
   *     summary: 获取邀请记录列表
   *     description: 根据设备SN码获取邀请记录列表
   *     tags: [前端-推广邀请]
   *     requestBody:
   *       required: true
   *       content:
   *         application/json:
   *           schema:
   *             type: object
   *             required:
   *               - sn_code
   *             properties:
   *               sn_code:
   *                 type: string
   *                 description: 设备SN码
   *               page:
   *                 type: integer
   *                 description: 页码（可选，默认1）
   *               pageSize:
   *                 type: integer
   *                 description: 每页数量（可选，默认20）
   *     responses:
   *       200:
   *         description: 获取成功
   */
  'POST /invite/records': async (ctx) => {
    try {
      const body = ctx.getBody() || {};
      const { sn_code, page = 1, pageSize = 20 } = body;

      if (!sn_code) {
        return ctx.fail('请提供设备SN码');
      }

      const { pla_account, invite_record } = await Framework.getModels();

      // 根据sn_code查找用户
      const user = await pla_account.findOne({
        where: { sn_code }
      });

      if (!user) {
        return ctx.fail('用户不存在');
      }

      // 查询邀请记录列表
      const offset = (page - 1) * pageSize;
      const records = await invite_record.findAll({
        where: {
          inviter_id: user.id,
          is_delete: 0
        },
        order: [['register_time', 'DESC']],
        limit: pageSize,
        offset: offset
      });

      const total = await invite_record.count({
        where: {
          inviter_id: user.id,
          is_delete: 0
        }
      });

      // 格式化记录数据
      const formattedRecords = records.map(record => {
        const recordData = record.toJSON();
        return {
          id: recordData.id,
          invitee_phone: recordData.invitee_phone,
          invite_code: recordData.invite_code,
          register_time: recordData.register_time,
          reward_status: recordData.reward_status,
          reward_value: recordData.reward_value,
          reward_type: recordData.reward_type
        };
      });

      return ctx.success({
        list: formattedRecords,
        total: total,
        page: page,
        pageSize: pageSize
      });
    } catch (error) {
      console.error('获取邀请记录列表失败:', error);
      return ctx.fail('获取邀请记录列表失败: ' + error.message);
    }
  },

  /**
   * @swagger
   * /api/invite/register:
   *   post:
   *     summary: 邀请注册
   *     description: 通过邀请码注册新用户，注册成功后给邀请人增加3天试用期
   *     tags: [前端-推广邀请]
   *     requestBody:
   *       required: true
   *       content:
   *         application/json:
   *           schema:
   *             type: object
   *             required:
   *               - email
   *               - password
   *               - email_code
   *             properties:
   *               email:
   *                 type: string
   *                 description: 邮箱地址
   *                 example: 'user@example.com'
   *               password:
   *                 type: string
   *                 description: 密码
   *                 example: 'password123'
   *               email_code:
   *                 type: string
   *                 description: 验证码
   *                 example: '123456'
   *               invite_code:
   *                 type: string
   *                 description: 邀请码（选填）
   *                 example: 'INV123_ABC123'
   *     responses:
   *       200:
   *         description: 注册成功
   */
  'POST /invite/register': async (ctx) => {
    try {
      const body = ctx.getBody();
      const { email, password, email_code, invite_code } = body;
      const { hashPassword, maskEmail } = require('../utils/crypto_utils');

      // 验证必填参数
      if (!email || !password || !email_code) {
        return ctx.fail('邮箱、密码和验证码不能为空');
      }

      // 验证邮箱格式
      const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
      if (!emailRegex.test(email)) {
        return ctx.fail('邮箱格式不正确');
      }

      // 验证密码长度
      if (password.length < 6 || password.length > 50) {
        return ctx.fail('密码长度必须在6-50位之间');
      }

      // 统一邮箱地址为小写
      const email_normalized = email.toLowerCase().trim();

      // 验证验证码
      const emailVerifyResult = await email_service.verifyEmailCode(email_normalized, email_code);
      if (!emailVerifyResult.success) {
        return ctx.fail(emailVerifyResult.message || '验证码错误或已过期');
      }

      const { pla_account } = await Framework.getModels();

      // 检查邮箱是否已注册（使用统一的小写邮箱）
      const existingUser = await pla_account.findOne({
        where: { login_name: email_normalized }
      });

      if (existingUser) {
        return ctx.fail('该邮箱已被注册');
      }

      // 验证邀请码（如果提供了邀请码）
      let inviter = null;
      let inviter_id = null;

      if (invite_code) {
        // 解析邀请码，获取邀请人ID
        // 邀请码格式：INV{user_id}_{timestamp}
        const inviteMatch = invite_code.match(/^INV(\d+)_/);
        if (!inviteMatch) {
          return ctx.fail('邀请码格式不正确');
        }

        inviter_id = parseInt(inviteMatch[1]);

        // 验证邀请人是否存在
        inviter = await pla_account.findOne({
          where: { id: inviter_id }
        });

        if (!inviter) {
          return ctx.fail('邀请码无效，邀请人不存在');
        }
      }

      // 生成设备SN码（基于邮箱和时间戳）
      const sn_code = `SN${Date.now()}${Math.random().toString(36).substr(2, 6).toUpperCase()}`;

      // 加密密码
      const hashedPassword = await hashPassword(password);

      // 创建新用户（使用统一的小写邮箱和加密密码）
      // 新用户注册赠送3天试用期
      const newUser = await pla_account.create({
        name: email_normalized.split('@')[0], // 默认使用邮箱用户名作为名称
        sn_code: sn_code,
        device_id: '', // 设备ID由客户端登录时提供
        platform_type: 'boss', // 默认平台类型
        login_name: email_normalized,
        pwd: hashedPassword, // 使用加密后的密码
        keyword: '',
        is_enabled: 1,
        is_delete: 0,
        authorization_date: new Date(), // 新用户从注册日期开始
        authorization_days: 3 // 赠送3天试用期
      });

      // 给邀请人增加3天试用期
      if (inviter) {
        const inviterData = inviter.toJSON();
        const currentAuthDate = inviterData.authorization_date;
        const currentAuthDays = inviterData.authorization_days || 0;

        let newAuthDate;
        let newAuthDays;

        // 如果当前没有授权日期，则从今天开始
        if (!currentAuthDate) {
          newAuthDate = new Date();
          newAuthDays = currentAuthDays + 3; // 累加3天
        } else {
          // 检查当前授权是否已过期
          const currentEndDate = dayjs(currentAuthDate).add(currentAuthDays, 'day');
          const now = dayjs();

          if (currentEndDate.isBefore(now)) {
            // 授权已过期，重新激活并给予3天试用期
            newAuthDate = new Date();
            newAuthDays = 3; // 过期后重新激活给3天
          } else {
            // 授权未过期，在现有基础上累加3天
            newAuthDate = currentAuthDate;
            newAuthDays = currentAuthDays + 3; // 累加3天
          }
        }

        // 更新邀请人的授权信息
        await pla_account.update(
          {
            authorization_date: newAuthDate,
            authorization_days: newAuthDays
          },
          { where: { id: inviter_id } }
        );

        // 记录邀请记录
        const { invite_record } = await Framework.getModels();
        await invite_record.create({
          inviter_id: inviter_id,
          inviter_sn_code: inviter.sn_code,
          invitee_id: newUser.id,
          invitee_sn_code: newUser.sn_code,
          invitee_phone: email, // 使用邮箱代替手机号
          invite_code: invite_code,
          register_time: new Date(),
          reward_status: 1, // 已发放
          reward_type: 'trial_days',
          reward_value: 3,
          is_delete: 0
        });

        console.log(`[邀请注册] 用户 ${maskEmail(email_normalized)} 通过邀请码 ${invite_code} 注册成功，邀请人 ${inviter.sn_code} 获得3天试用期`);
      } else {
        console.log(`[邀请注册] 用户 ${maskEmail(email_normalized)} 注册成功（无邀请码）`);
      }

      return ctx.success({
        message: '注册成功',
        user: {
          id: newUser.id,
          sn_code: newUser.sn_code,
          login_name: newUser.login_name
        }
      });
    } catch (error) {
      console.error('邀请注册失败:', error);
      return ctx.fail('注册失败: ' + error.message);
    }
  },

  /**
   * @swagger
   * /api/invite/send_email_code:
   *   post:
   *     summary: 发送验证码
   *     description: 发送验证码到指定邮箱地址
   *     tags: [前端-推广邀请]
   *     requestBody:
   *       required: true
   *       content:
   *         application/json:
   *           schema:
   *             type: object
   *             required:
   *               - email
   *             properties:
   *               email:
   *                 type: string
   *                 description: 邮箱地址
   *                 example: 'user@example.com'
   *     responses:
   *       200:
   *         description: 发送成功
   */
  'POST /invite/send_email_code': async (ctx) => {
    try {
      const body = ctx.getBody();
      const { email } = body;

      if (!email) {
        return ctx.fail('邮箱地址不能为空');
      }

      // 验证邮箱格式
      const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
      if (!emailRegex.test(email)) {
        return ctx.fail('邮箱格式不正确');
      }

      // 统一邮箱地址为小写
      const email_normalized = email.toLowerCase().trim();

      // 发送验证码
      const emailResult = await email_service.sendEmailCode(email_normalized);
      if (!emailResult.success) {
        return ctx.fail(emailResult.message || '发送验证码失败');
      }

      return ctx.success({
        message: '验证码已发送',
        expire_time: emailResult.expire_time || 300 // 默认5分钟过期
      });
    } catch (error) {
      console.error('发送验证码失败:', error);
      return ctx.fail('发送验证码失败: ' + error.message);
    }
  }
};
