using Microsoft.AspNetCore.Mvc;
using Nirvana.Common;
using Senparc.CO2NET.Utilities;
using Senparc.Weixin.Exceptions;
using Senparc.Weixin.Open.ComponentAPIs;
using Senparc.Weixin.Open.Containers;
using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using YBDevice.Core;
using YBDevice.Entity;
using YBDevice.WXApplication.WXInfo;

namespace YBDevice.WX.Controllers
{
    /// <summary>
    /// 开放平台入口及回调
    /// </summary>
    public class OpenOAuthController : BaseController
    {
        private readonly ILoggerService _loggerService;
        private readonly IWXService _wXService;
        public OpenOAuthController(ILoggerService loggerService, IWXService wXService)
        {
            _loggerService = loggerService;
            _wXService = wXService;
        }
        /// <summary>
        /// OAuthScope.snsapi_userinfo方式回调。请求是/OpenOAuth/OpenOAuthCallback/1
        /// </summary>
        /// <param name="auth_code"></param>
        /// <param name="expires_in"></param>
        /// <param name="appId"></param>
        /// <returns></returns>
        public async Task<ActionResult> OpenOAuthCallbackAsync(string id, string auth_code, int expires_in, string appId)
        {
            var param = $"授权回调,auth_code={auth_code},expires_in={expires_in},appid={appId}";
            try
            {
                #region 使用ComponentContainer

                //获取OAuth授权结果
                QueryAuthResult queryAuthResult;
                try
                {
                    queryAuthResult = ComponentContainer.GetQueryAuthResult(component_AppId, auth_code);
                }
                catch (Exception ex)
                {
                    _loggerService.AddErrorLogger(ex, param);
                    ViewBag.errmsg = ex.Message;
                    return View();
                }
                #endregion

                var authorizerInfoResult = AuthorizerContainer.GetAuthorizerInfoResult(component_AppId,
                    queryAuthResult.authorization_info.authorizer_appid);
                //从redis获取用户信息,过期时间为10分钟,保存格式为userid|type
                var userinfo = RedisHelpers.stringGet($"authpage_{id}");

                #region 记录日志
                var msg = $"{param},result={authorizerInfoResult.ToJson()},userinfo={userinfo},queryauthresult={queryAuthResult.ToJson()}";
                _loggerService.AddLogger(msg, 2);
                #endregion

                if (string.IsNullOrEmpty(userinfo))
                {
                    ViewBag.errmsg = "扫码已过期,请重新进行授权";
                    return View();
                }
                var arr = userinfo.Split('|');
                if (arr.Length != 4)
                {
                    ViewBag.errmsg = "授权信息错误";
                    return View();
                }
                var userid = arr[0];//用户ID,可能为空
                var type = arr[1]; //类型,1-移帮设备平台授权
                var official = new YB_OfficlaAccount
                {
                    authorizer_appid = queryAuthResult.authorization_info.authorizer_appid,
                    componentappid = component_AppId,
                    authorizer_access_token = queryAuthResult.authorization_info.authorizer_access_token,
                    authorizer_refresh_token = queryAuthResult.authorization_info.authorizer_refresh_token,
                    head_img = authorizerInfoResult.authorizer_info.head_img,
                    nick_name = authorizerInfoResult.authorizer_info.nick_name,
                    alias = authorizerInfoResult.authorizer_info.alias,
                    service_type_info = authorizerInfoResult.authorizer_info.service_type_info.id.ToString(),
                    verify_type_info = authorizerInfoResult.authorizer_info.verify_type_info.id.ToString(),
                    func_info = string.Join(",", queryAuthResult.authorization_info.func_info.Select(x => x.funcscope_category.id.ToString()).ToArray()),
                    qrcode_url = authorizerInfoResult.authorizer_info.qrcode_url,
                    createtime = DateTime.Now,
                    isauthorize = 1,
                    user_name = authorizerInfoResult.authorizer_info.user_name,
                    authorizeationcode = "",
                    lastmodifytime = DateTime.Now,
                    type = authorizerInfoResult.authorizer_info.MiniProgramInfo != null ? 2 : 1
                };
                //保存图片
                var filepath = ServerUtility.ContentRootMapPath("~/openqr/qr/");
                if (!Directory.Exists(filepath))
                {
                    Directory.CreateDirectory(filepath);
                }
                var filename = $"{filepath}{official.user_name}.jpg";
                // new WebClient().DownloadFile(authorizerInfoResult.authorizer_info.qrcode_url, filename);
                var url = new Uri(authorizerInfoResult.authorizer_info.qrcode_url);
                WebClient client = new WebClient();
                client.DownloadFileAsync(url, filename);
                await _wXService.InsertOrUpdateAsync(official, userid);
                if (RedisHelpers.Exists($"authpage_{id}"))
                {
                    RedisHelpers.Remove($"authpage_{id}");
                }
                ViewData["nickname"] = official.nick_name;
                return View();
            }
            catch (ErrorJsonResultException ex)
            {
                var msg = $"授权回调,{ex.ToJson()}";
                _loggerService.AddLogger(msg,3);
                ViewBag.errmsg = ex.Message;
                return View();
            }
        }

        /// <summary>
        /// 公众号授权页入口
        /// </summary>
        /// <returns></returns>
        public IActionResult JumpToMpOAuth(string businessid = "", string type = "")
        {
            //保存授权信息,10分钟内有效
            RedisHelpers.Insert($"authpage_{businessid}", $"{businessid}|{type}||", 600);
            ViewData["key"] = businessid;
            return View();
        }
        /// <summary>
        /// 获取授权地址
        /// </summary>
        /// <param name="businessid">客户ID</param>
        /// <param name="type">类型,1-来自移帮设备平台</param>
        /// <returns></returns>
        public IActionResult GetAuthPage(string businessid = "0", string type = "1")
        {
            //保存授权信息,生成一个随机key,10分钟有效
            var key = Guid.NewGuid().ToString("N");
            RedisHelpers.Insert(key, $"{businessid}|{type}", 600);
            var url = $"{Configs.GetString("WXAPIURL")}/open/oauth/{key}";
            var data = new
            {
                code = 0,
                data = url
            };
            return Json(data);
        }

        #region 授权信息

        public async Task<IActionResult> GetAuthorizerInfoResult(string authorizerId)
        {
            var getAuthorizerInfoResult = await AuthorizerContainer.GetAuthorizerInfoResultAsync(component_AppId, authorizerId);
            return Json(getAuthorizerInfoResult);
        }

        public async Task<IActionResult> RefreshAuthorizerAccessToken(string authorizerId)
        {
            var componentAccessToken = await ComponentContainer.GetComponentAccessTokenAsync(component_AppId);
            var authorizationInfo = await AuthorizerContainer.GetAuthorizationInfoAsync(component_AppId, authorizerId);
            if (authorizationInfo == null)
            {
                return Content("授权信息读取失败！");
            }

            var refreshToken = authorizationInfo.authorizer_refresh_token;
            var result = await AuthorizerContainer.RefreshAuthorizerTokenAsync(componentAccessToken, component_AppId, authorizerId,
                refreshToken);
            return Json(result);
        }

        #endregion
    }
}
