import { Context } from "koa";
import { getRoleInfoById,getGuildInfoById } from "../mongo/mongodb";
import { getServerList } from "../utils/common";
import axios from "axios";

const logger = require("../utils/log");

// 导入小程序配置
import {
  MINI_APP_DOMAIN,
  MINI_APP_PRIVATE_KEY,
  MINI_APP_GAME_ID,
  MINI_APP_API_KEY,
  MINI_APP_STAT_API_KEY,
  Account
} from "../config/thirdParams";

// 导入渠道处理器和配置
import { channelFactory } from "../channels/factory/ChannelFactory";
import { channelConfigs } from "../config/channelConfig";
import Msg from "../utils/msg";

/**
 * 小程序控制器
 * 处理内容安全审核和角色名称修改上报功能
 */
class MiniappController {
  constructor() {
    // 初始化配置
  }

  /**
   * 获取小程序渠道处理器
   * @returns 渠道处理器实例
   */
  private static getChannelHandler() {
    return channelFactory.getHandler(11); // 小程序渠道ID
  }

  /**
   * 获取小程序渠道配置
   * @returns 渠道配置
   */
  private static getChannelConfig() {
    return channelConfigs[11]; // 小程序渠道ID
  }

  /**
   * 内容安全审核接口
   * @param ctx Koa上下文
   */
  async contentSecurityCheck(ctx: Context) {
    try {
      const handler = MiniappController.getChannelHandler();
      const config = MiniappController.getChannelConfig();
      console.log("MiniappController contentSecurityCheck config:", config);
      if (!handler) {
        ctx.body = {
          code: -1,
          msg: "渠道处理器未找到",
          data: null
        };
        return;
      }

      // 调用渠道处理器的内容安全审核方法
      const result = await (handler as any).contentSecurityCheck(ctx, config);
      ctx.body = result;

    } catch (error) {
      logger.error("内容安全审核出错:", error);
      ctx.body = {
        code: -1,
        msg: "内容安全审核失败",
        data: null
      };
    }
  }

  /**
   * 角色名称修改上报
   * @param ctx Koa上下文
   */
  async editUserRoleInfo(ctx: Context) {
    try {
      const handler = MiniappController.getChannelHandler();
      const config = MiniappController.getChannelConfig();
      
      if (!handler) {
        ctx.body = {
          error: -1,
          errmsg: "渠道处理器未找到"
        };
        return;
      }

      // 调用渠道处理器的角色名称修改上报方法
      const result = await (handler as any).editUserRoleInfo(ctx, config);
      
      // 转换返回格式：handler返回 { code, msg, data }，需要转换为 { error, errmsg }
      if (result.code === -1) {
        // 失败情况（包括内容安全审核失败）
        ctx.body = {
          code: -1,
          msg: result.msg || "角色名称修改失败"
        };
      } else {
        // 成功情况
        ctx.body = {
          code: 0,
          msg: result.msg || "修改成功"
        };
      }

    } catch (error) {
      logger.error("角色名称修改上报出错:", error);
      ctx.body = {
        code: -1,
        msg: error.message || "角色名称修改失败"
      };
    }
  }

  /**
   * 禁言接口
   * @param ctx Koa上下文
   */
  async forbidChat(ctx: Context) {
    try {
      const data = ctx.request.body as any;
      logger.info("禁言接口请求参数:", data);

      // 验证必要参数
      const requiredParams = ['gameid', 'openid', 'accountid', 'roleid', 'forbidDays', 'reason', 'time', 'sign'];
      for (const param of requiredParams) {
        if (!data[param]) {
          logger.error(`缺少必要参数: ${param}`);
          ctx.body = {
            error: -1,
            errmsg: `缺少必要参数: ${param}`
          };
          return;
        }
      }

      const handler = MiniappController.getChannelHandler();
      const expectedSignature = (handler as any).generateCommonSignature(
        data, 
        MINI_APP_STAT_API_KEY, 
        ['sign'],
        false // 禁言接口签名不需要URL编码
      );
      // 验证签名
      if (expectedSignature !== data.sign) {
        logger.error("禁言接口签名验证失败");
        ctx.body = {
          error: -1,
          errmsg: "签名验证失败"
        };
        return;
      }

      // 验证禁言天数
      const forbidDays = parseInt(data.forbidDays);
      if (forbidDays < -1 || forbidDays === 0 || forbidDays > 30) {
        logger.error("禁言天数参数错误:", forbidDays);
        ctx.body = {
          error: -1,
          errmsg: "禁言天数参数错误，应为1-30天或-1(永久)"
        };
        return;
      }

      // 调用游戏服禁言接口
      const gameResult = await MiniappController.callGameForbidChat(data);
      
      if (gameResult) {
        ctx.body = {
          error: 0,
          errmsg: ""
        };
      } else {
        ctx.body = {
          error: -1,
          errmsg: "禁言失败"
        };
      }

    } catch (error) {
      logger.error("禁言接口出错:", error);
      ctx.body = {
        error: -1,
        errmsg: "禁言失败"
      };
    }
  }


  /**
   * 解除禁言接口
   * @param ctx Koa上下文
   */
  async freeChat(ctx: Context) {
    try {
      const data = ctx.request.body as any;
      logger.info("解除禁言接口请求参数:", data);

      // 验证必要参数
      const requiredParams = ['gameid', 'openid', 'accountid', 'roleid', 'time', 'sign'];
      for (const param of requiredParams) {
        if (!data[param]) {
          logger.error(`缺少必要参数: ${param}`);
          ctx.body = {
            error: -1,
            errmsg: `缺少必要参数: ${param}`
          };
          return;
        }
      }

      const handler = MiniappController.getChannelHandler();
      const expectedSignature = (handler as any).generateCommonSignature(
        data, 
        MINI_APP_STAT_API_KEY, 
        ['sign'],
        false // 解除禁言接口签名不需要URL编码
      );
      
      // 验证签名
      if (expectedSignature !== data.sign) {
        logger.error("解除禁言接口签名验证失败");
        ctx.body = {
          code: -1,
          msg: "签名验证失败"
        };
        return;
      }

      // 调用游戏服解除禁言接口
      const gameResult = await MiniappController.callGameFreeChat(data);
      
      if (gameResult) {
        ctx.body = {
          code: 0,
          msg: ""
        };
      } else {
        ctx.body = {
          code: -1,
          msg: "解除禁言失败"
        };
      }

    } catch (error) {
      logger.error("解除禁言接口出错:", error);
      ctx.body = {
        error: -1,
        errmsg: "解除禁言失败"
      };
    }
  }

  /**
   * 角色查询接口
   * @param ctx Koa上下文
   */
  async roleQuery(ctx: Context) {
    try {
      const data = ctx.request.body as any;
      logger.info("角色查询接口请求参数:", data);

      // 验证必要参数
      const requiredParams = ['gameid', 'serverid', 'openid', 'accountid', 'roleid', 'time', 'sign'];
      for (const param of requiredParams) {
        if (!data[param]) {
          logger.error(`缺少必要参数: ${param}`);
          ctx.body = {
            error: -1,
            errmsg: `缺少必要参数: ${param}`
          };
          return;
        }
      }

      const handler = MiniappController.getChannelHandler();
      const expectedSignature = (handler as any).generateCommonSignature(
        data, 
        MINI_APP_STAT_API_KEY, 
        ['sign'],
        false // 角色查询接口签名不需要URL编码
      );
      
      // 验证签名
      if (expectedSignature !== data.sign) {
        logger.error("角色查询接口签名验证失败");
        ctx.body = {
          error: -1,
          errmsg: "签名验证失败"
        };
        return;
      }

      // 调用游戏服角色查询接口
      const roleData = await MiniappController.callGameRoleQuery(data);
      
      if (roleData) {
        ctx.body = {
          error: 0,
          errmsg: "",
          role: roleData
        };
      } else {
        ctx.body = {
          error: -1,
          errmsg: "角色查询失败"
        };
      }

    } catch (error) {
      logger.error("角色查询接口出错:", error);
      ctx.body = {
        error: -1,
        errmsg: "角色查询失败"
      };
    }
  }

  /**
   * 调用游戏服禁言接口
   * @param data 禁言数据
   * @returns 调用结果
   */
  private static callGameForbidChat(data: any): boolean {
    try {
      logger.info("调用游戏服禁言接口:", {
        gameid: data.gameid,
        openid: data.openid,
        accountid: data.accountid,
        roleid: data.roleid,
        forbidDays: data.forbidDays,
        reason: data.reason,
        ext: data.ext
      });

      let url = getServerList(data.serverId, data.channel_id || 1);
      if (!url) {
        logger.error("区服id错误，无法获取游戏服地址:", data.serverId);
        return;
      }
      //调用游戏服禁言接口
      let param = JSON.stringify({
        uuid: data.roleid,
        type: "forbidChat",
        time: data.forbidDays,
        reason: data.reason
      });
      let sendMsg = new Msg();
      sendMsg.connect(url, Account);
      new Promise((resolve) => {
        setTimeout(async () => {
          sendMsg.CG_TEST_PROTO(data.accountid, param);
        }, 1000);
      });
      return true

    } catch (error) {
      logger.error("调用游戏服禁言接口出错:", error);
      return false
    }
  }

  /**
   * 调用游戏服解除禁言接口
   * @param data 解除禁言数据
   * @returns 调用结果
   */
  private static callGameFreeChat(data: any): boolean {
    try {
      
      logger.info("调用游戏服解除禁言接口:", {
        gameid: data.gameid,
        openid: data.openid,
        accountid: data.accountid,
        roleid: data.roleid,
        ext: data.ext
      });
      let url = getServerList(data.serverId, data.channel_id || 1);
      if (!url) {
        logger.error("区服id错误，无法获取游戏服地址:", data.serverId);
        return;
      }
      //调用游戏服禁言接口
      let param = JSON.stringify({
        uuid: data.roleid,
        type: "freeChat",
      });
      let sendMsg = new Msg();
      sendMsg.connect(url, Account);
      new Promise((resolve) => {
        setTimeout(async () => {
          sendMsg.CG_TEST_PROTO(data.accountid, param);
        }, 1000);
      });
      return true

    } catch (error) {
      logger.error("调用游戏服解除禁言接口出错:", error);
      return false
    }
  }

  /**
   * 调用游戏服角色查询接口
   * @param data 角色查询数据
   * @returns 角色数据
   */
  private static async callGameRoleQuery(data: any): Promise<any> {
    try {
      
     logger.info("调用游戏服角色查询接口:", {
        gameid: data.gameid,
        serverid: data.serverid,
        openid: data.openid,
        accountid: data.accountid,
        roleid: data.roleid,
        ext: data.ext
      });
       
      // 根据服务器ID生成数据库名称
      let dbName = "ckwy_fy_S"+(String(350001+parseInt(data.serverid)).padStart(3,'0'));
      
      // 从MongoDB查询角色信息
      const roleInfo = await getRoleInfoById(dbName, data.roleid);
      
      if (roleInfo) {
        // 如果找到角色信息，返回格式化的数据
        const data =  {
          rolename: roleInfo.name || "未知角色",
          rolelv: roleInfo.lv || 1,
          rolepwr: roleInfo.rolepwr || 0, //战力
          viplv: roleInfo.viplv || 0, //vip等级
          alliance: roleInfo.alliance || "", //帮派
          paymoney: roleInfo.topupAcount || 0 //累计充值金额
        };
        if(roleInfo.guildId){
        const guildInfo = await getGuildInfoById(dbName, roleInfo.guildId);
        if (guildInfo) {
            data.alliance = guildInfo.name;
          }
        }
        return data;

      } else {
        // 如果没有找到角色信息，返回默认数据
        logger.warn(`未找到角色信息: ${data.roleid}`);
        return {
          rolename: "未知角色",
          rolelv: 1,
          rolepwr: 0,
          viplv: 0,
          alliance: "",
          paymoney: 0
        };
      }

    } catch (error) {
      logger.error("调用游戏服角色查询接口出错:", error);
      return null;
    }
  }

  /**
   * 游戏圈发货接口
   * @param ctx Koa上下文
   */
  async deliverGoods(ctx: Context) {
    try {
      const handler = MiniappController.getChannelHandler();
      const config = MiniappController.getChannelConfig();

      if (!handler) {
        ctx.body = { errcode: -1, errmsg: "渠道处理器未找到" };
        return;
      }

      const result = await (handler as any).deliverGoods(ctx, config);
      if (result.code === -1) {
        ctx.body = { errcode: -1, errmsg: result.msg || "发货失败" };
      } else {
        ctx.body = { errcode: 0, errmsg: "ok" };
      }

    } catch (error) {
      logger.error("游戏圈发货出错:", error);
      ctx.body = { errcode: 0, errmsg: "ok" };
    }
  }

  /**
   * 订单校验接口
   * @param ctx Koa上下文
   */
  async verifyOrder(ctx: Context) {
    try {
      const handler = MiniappController.getChannelHandler();
      const config = MiniappController.getChannelConfig();
      
      if (!handler) {
        ctx.body = {
          success: false,
          message: "渠道处理器未找到"
        };
        return;
      }

      // 调用渠道处理器的订单校验方法
      const result = await (handler as any).verifyOrder(ctx, config);
      ctx.body = result;

    } catch (error) {
      logger.error("订单校验出错:", error);
      ctx.body = {
        success: false,
        message: "订单校验失败"
      };
    }
  }

  /**
   * 账号状态上报接口
   * GET请求：只处理查询，如果不存在则自动创建一条记录（默认status=0）
   * POST请求：只处理存储/更新状态
   * @param ctx Koa上下文
   */
  async accountStatusReport(ctx: Context) {
    try {
      const AccountStatusModel = require("../model/AccountStatusModel");
      const isGet = ctx.method === 'GET';
      
      // GET请求从query参数获取，POST请求从body获取
      const account = isGet ? ctx.query.account : (ctx.request.body as any).account;
      const channelId = isGet ? ctx.query.channelId : (ctx.request.body as any).channelId;
      const status = isGet ? undefined : (ctx.request.body as any).status;

      logger.info("账号状态上报接口请求参数:", { 
        method: ctx.method,
        account, 
        channelId, 
        status 
      });

      // 验证必要参数
      if (!account) {
        ctx.body = {
          code: -1,
          msg: "缺少必要参数: account"
        };
        return;
      }

      if (!channelId) {
        ctx.body = {
          code: -1,
          msg: "缺少必要参数: channelId"
        };
        return;
      }

      // GET请求：只处理查询，如果不存在则自动创建
      if (isGet) {
        let accountStatus = await AccountStatusModel.getAccountStatus(account, parseInt(channelId as string));
        
        // 如果不存在，自动创建一条记录（默认status=0）
        if (!accountStatus) {
          logger.info("查询记录不存在，自动创建:", { account, channelId });
          await AccountStatusModel.upsertAccountStatus(account, parseInt(channelId as string), 0);
          // 重新查询获取创建后的记录
          accountStatus = await AccountStatusModel.getAccountStatus(account, parseInt(channelId as string));
        }
        
        if (accountStatus) {
          ctx.body = {
            code: 0,
            msg: "查询成功",
            data: {
              account: accountStatus.account,
              channelId: accountStatus.channel_id,
              status: accountStatus.status,
              createdAt: accountStatus.created_at,
              updatedAt: accountStatus.updated_at
            }
          };
        } else {
          ctx.body = {
            code: -1,
            msg: "查询失败"
          };
        }
      } 
      // POST请求：只处理存储/更新
      else {
        if (status === undefined || status === null) {
          ctx.body = {
            code: -1,
            msg: "POST请求缺少必要参数: status"
          };
          return;
        }

        // 验证status参数（应该是数字）
        const statusNum = parseInt(status);
        if (isNaN(statusNum)) {
          ctx.body = {
            code: -1,
            msg: "参数错误: status必须是数字"
          };
          return;
        }

        // 保存或更新状态
        await AccountStatusModel.upsertAccountStatus(account, parseInt(channelId), statusNum);
        
        logger.info("账号状态保存成功:", { account, channelId, status: statusNum });
        
        ctx.body = {
          code: 0,
          msg: "保存成功",
          data: {
            account,
            channelId: parseInt(channelId),
            status: statusNum
          }
        };
      }

    } catch (error: any) {
      logger.error("账号状态上报接口出错:", error);
      ctx.body = {
        code: -1,
        msg: error.message || "操作失败"
      };
    }
  }
  
}

module.exports = new MiniappController();