using Microsoft.AspNetCore.Mvc;
using Nirvana.Common;
using Nirvana.Common.ApiBase;
using Senparc.CO2NET.AspNet.HttpUtility;
using Senparc.Weixin.MP.MessageHandlers;
using Senparc.Weixin.Open.ComponentAPIs;
using Senparc.Weixin.Open.Containers;
using Senparc.Weixin.Open.Entities.Request;
using Senparc.Weixin.Open.MessageHandlers;
using System;
using System.Threading.Tasks;
using YBDevice.Core;
using YBDevice.WX.MessageHandlers;
using YBDevice.WX.MessageHandlers.CustomMessageHandler;

namespace YBDevice.WX.Controllers
{
    /// <summary>
    /// 公众号授权
    /// </summary>
    public class OpenController : BaseController
    {
        private readonly ILoggerService _loggerService;
        public OpenController(ILoggerService loggerService)
        {
            _loggerService = loggerService;
        }
        /// <summary>
        /// 发起授权页的体验URL
        /// </summary>
        /// <returns></returns>
        public async Task<IActionResult> OAuth(string id = "")
        {
            //获取预授权码
            var preAuthCode = await ComponentContainer.TryGetPreAuthCodeAsync(component_AppId, component_Secret, true);
            var callbackUrl = Configs.GetString("callbackUrl");//成功回调地址
            callbackUrl = $"{callbackUrl}/{id}";
            var url = ComponentApi.GetComponentLoginPageUrl(component_AppId, preAuthCode, callbackUrl);
            return Redirect(url);
        }

        /// <summary>
        /// 获取预授权码以及跳转地址
        /// </summary>
        /// <returns></returns>
        public async Task<IActionResult> GetOAuth(string userid, string type)
        {
            try
            {
                if (RedisHelpers.Exists($"authpage_{userid}"))
                {
                    var userinfo = RedisHelpers.stringGet($"authpage_{userid}");
                    var arr = userinfo.Split('|');
                    if(arr.Length == 4)
                    {
                        return Json(new
                        {
                            code = ResultState.SUCCESS,
                            message = "success",
                            data = new
                            {
                                preAuthCode = arr[2],
                                url = arr[3]
                            }
                        });
                    }
                }
                //获取预授权码
                var preAuthCode = await ComponentContainer.TryGetPreAuthCodeAsync(component_AppId, component_Secret, true);
                var callbackUrl = Configs.GetString("callbackUrl");//成功回调地址
                var url = ComponentApi.GetComponentLoginPageUrl(component_AppId, preAuthCode, callbackUrl);
                //保存授权信息,10分钟内有效
                RedisHelpers.Insert($"authpage_{userid}", $"{userid}|{type}|{preAuthCode}|{url}", 600);
                callbackUrl = $"{callbackUrl}/{userid}";
                return Json(new
                {
                    code = ResultState.SUCCESS,
                    message="success",
                    data = new
                    {
                        preAuthCode = preAuthCode,
                        url = url
                    }
                });
            }
            catch (Exception ex)
            {
                _loggerService.AddErrorLogger(ex, $"userid={userid},type={type}", "获取预授权码以及跳转地址");
                return Json(new { code = ResultState.FAIL, message = ex.Message});
            }
        }

        /// <summary>
        /// 获取公众号可用的token
        /// </summary>
        /// <param name="appid">公众号appid</param>
        /// <returns></returns>
        public async Task<IActionResult> GetAccessToken(string appid)
        {
            try
            {
                var accesstoken = await AuthorizerContainer.TryGetAuthorizerAccessTokenAsync(component_AppId, appid);
                return Json(new { status = "success", accesstoken = accesstoken });
            }
            catch (Exception ex)
            {
                var msg = $"appid={appid}";
                _loggerService.AddErrorLogger(ex, msg, "获取公众号可用的token");
                return Json(new { status = "fail", accesstoken = "", errmsg = ex.Message });
            }
        }

        /// <summary>
        /// 微信服务器会不间断推送最新的Ticket（10分钟一次），需要在此方法中更新缓存
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public ActionResult Notice(PostModel postModel)
        {
            try
            {
                //var logPath = ServerUtility.ContentRootMapPath(string.Format("~/App_Data/Open/{0}/", SystemTime.Now.ToString("yyyy-MM-dd")));
                //if (!Directory.Exists(logPath))
                //{
                //    Directory.CreateDirectory(logPath);
                //}
                postModel.Token = component_Token;
                postModel.EncodingAESKey = component_EncodingAESKey;
                postModel.AppId = component_AppId;
                ThirdPartyMessageHandler messageHandler = new CustomThirdPartyMessageHandler(Request.GetRequestMemoryStream(), postModel);

                //记录RequestMessage日志（可选）
              //  messageHandler.EcryptRequestDocument.Save(Path.Combine(logPath, string.Format("{0}_Request.txt", SystemTime.Now.Ticks)));
              //  messageHandler.RequestDocument.Save(Path.Combine(logPath, string.Format("{0}_Request_{1}.txt", SystemTime.Now.Ticks, messageHandler.RequestMessage.AppId)));
                messageHandler.Execute();//执行
                                         //记录ResponseMessage日志（可选）
                //using (TextWriter tw = new StreamWriter(Path.Combine(logPath, string.Format("{0}_Response_{1}.txt", SystemTime.Now.Ticks, messageHandler.RequestMessage.AppId))))
                //{
                //    tw.WriteLine(messageHandler.ResponseMessageText);
                //    tw.Flush();
                //    tw.Close();
                //}
                return Content(messageHandler.ResponseMessageText);
            }
            catch (Exception ex)
            {
                var msg = $"{postModel.ToJson()}";
                _loggerService.AddErrorLogger(ex, msg, "微信服务器会不间断推送最新的Ticket");
                return Content("");
            }
        }

        /// <summary>
        /// 授权事件接收URL
        /// </summary>
        /// <param name="appId"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IActionResult> Callback(Senparc.Weixin.MP.Entities.Request.PostModel postModel)
        {
            //此处的URL格式类型为：http://sdk.weixin.senparc.com/Open/Callback/$APPID$， 在RouteConfig中进行了配置，你也可以用自己的格式，只要和开放平台设置的一致。

            //处理微信普通消息，可以直接使用公众号的MessageHandler。此处的URL也可以直接填写公众号普通的URL，如本Demo中的/Weixin访问地址

            //记录数据
            //new LoggerApplication().InsertErrorLog(postModel.ToJson());

            postModel.Token = component_Token;
            postModel.EncodingAESKey = component_EncodingAESKey; //根据自己后台的设置保持一致
            postModel.AppId = component_AppId; //根据自己后台的设置保持一致

            var maxRecordCount = 10;
            MessageHandler<CustomMessageContext> messageHandler = null;

            try
            {
                var checkPublish = CheckPublish(postModel); //是否在“全网发布”阶段
                if (checkPublish)
                {
                    messageHandler = new OpenCheckMessageHandler(Request.GetRequestMemoryStream(), postModel, 10);
                }
                else
                {
                    messageHandler = new CustomMessageHandler(Request.GetRequestMemoryStream(), postModel, maxRecordCount);
                }
                if(messageHandler != null)
                {
                    await messageHandler.ExecuteAsync(new System.Threading.CancellationToken());//执行微信处理过程（关键）
                }
                return new FixWeixinBugWeixinResult(messageHandler);
            }
            catch (Exception ex)
            {
                var msg = $",model={postModel.ToJson()}";
                if (messageHandler != null && messageHandler.ResponseDocument != null)
                {
                    msg = $"{messageHandler.ResponseDocument.ToString()},model={postModel.ToJson()}";
                }
                _loggerService.AddErrorLogger(ex, msg, "授权事件接收URL");
                return Content("");
            }
        }

        private bool CheckPublish(Senparc.Weixin.MP.Entities.Request.PostModel postModel)
        {
            //小白商户助手
            return postModel.AppId == "wxd5c9b0640e178bf2";
        }
    }
}
