using OASystem.Domain.Dtos.CallBack.QiYeWeChat;

namespace OASystem.API.Controllers
{
    /// <summary>
    /// 回调地址
    /// </summary>
    [Route("/callback")]
    public class CallbackController : Controller
    {
        private readonly IMapper _mapper;
        private readonly ILogger<CallbackController> _logger;

        #region 企业微信 通讯录通知回调key And token
        private readonly string _qiYeWechat_Token = "WWiCDK";
        private readonly string _qiYeWechat_EncodingAESKey = "3BWKiWnvp6xJGQ5oD3TBaOKYniNgX1g6kZZEehbM3ym";
        private readonly string _qiYeWechat_CorpId = "wwe978bef5495a0728";
        #endregion

        public CallbackController(IMapper mapper, ILogger<CallbackController> logger)
        {
            _mapper = mapper;
            _logger = logger;
        }

        #region 企业微信回调

        /// <summary>
        /// 回调通知
        /// </summary>
        /// <returns></returns>
        [Route("memberschange")]
        [HttpGet, HttpPost]
        public async Task<ActionResult> ApproveCallBack(string msg_signature, string timestamp, string nonce, string echostr)
        {
            _logger.LogInformation("【企业微信】【通讯录助手】【回调】进入回调");
            ApproveCallBackInputDTO input = new ApproveCallBackInputDTO();
            input.msg_signature = msg_signature;
            input.timestamp = timestamp;
            input.nonce = nonce;
            input.echostr = echostr;
            _logger.LogInformation("【企业微信】【通讯录助手】【回调】【参数】" + input.ToJson());
            if (HttpContext.Request.Method == System.Net.Http.HttpMethod.Get.Method)
            {
                var model = await VerifyURLCallBack(input);
                return Content(model, "text/xml");
            }
            if (HttpContext.Request.Method == System.Net.Http.HttpMethod.Post.Method)
            {
                var stream = Request.Body;
                var model = await ApproveCallBack(stream, input);
                return Content(model, "text/xml");
            }
            _logger.LogInformation("【企业微信】【通讯录助手】【回调】回调成功");
            return Content("ok", "text/xml");
        }

        /// <summary>
        /// 验证URL有效性
        /// </summary>
        /// <returns></returns>
        private async Task<string> VerifyURLCallBack(ApproveCallBackInputDTO input)
        {
            int ret = 0;
            string sEchoStr = "";
            try
            {
                //企业微信官方加解密校验解析类
                Tencent.WXBizMsgCrypt wxcpt = new Tencent.WXBizMsgCrypt(_qiYeWechat_Token, _qiYeWechat_EncodingAESKey, _qiYeWechat_CorpId);
                string sReqMsgSig = input.msg_signature;
                string sReqTimeStamp = input.timestamp;
                string sReqNonce = input.nonce;
                string sReqEchostr = input.echostr;
                //企业微信官方验证URL
                ret = wxcpt.VerifyURL(sReqMsgSig, sReqTimeStamp, sReqNonce, sReqEchostr, ref sEchoStr);
                if (ret != 0)
                {
                    throw new Exception($"ERR: VerifyURL fail, ret: {ret}");
                }
                return sEchoStr;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        /// <summary>
        /// 回调通知处理业务
        /// </summary>
        /// <returns></returns>
        private async Task<string> ApproveCallBack(Stream context, ApproveCallBackInputDTO input)
        {
            var sReqData = "";
            int ret = 0;
            string sMsg = "";
            try
            {
                //企业微信官方加解密校验解析类
                Tencent.WXBizMsgCrypt wxcpt = new Tencent.WXBizMsgCrypt(_qiYeWechat_Token, _qiYeWechat_EncodingAESKey, _qiYeWechat_CorpId);
                string sReqMsgSig = input.msg_signature;
                string sReqTimeStamp = input.timestamp;
                string sReqNonce = input.nonce;
                string sReqEchostr = input.echostr;
                // Post请求的密文数据
                using (var reader = new StreamReader(context))
                {
                    sReqData = await reader.ReadToEndAsync();
                }
                //回调数据
                // 解析之后的明文
                ret = wxcpt.DecryptMsg(sReqMsgSig, sReqTimeStamp, sReqNonce, sReqData, ref sMsg);
                if (ret != 0)
                {
                    throw new Exception($"ERR: Decrypt Fail, ret: {ret}");
                }
                // ret==0表示解密成功,sMsg表示解密之后的明文xml串
                //下一步处理实际业务数据了
                return sMsg;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }



        #endregion
    }
}