using log4net;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace Ropin.Inspection.Common.Helper
{
    public class WeChatHelper
    {
        private readonly IHttpClientFactory _httpClientFactory;
        private static readonly ILog log = LogManager.GetLogger(typeof(WeChatHelper));
        public WeChatHelper(IHttpClientFactory httpClientFactory)
        {
            _httpClientFactory = httpClientFactory;
        }

        public async Task<string> GetToken()
        {
            string token = null;
            string url = string.Format(WXConstModel.WeChatTokenUrlTemplate, WXConstModel.GZHAppId, WXConstModel.GZHSecret);
            using (var client = _httpClientFactory.CreateClient())
            {
                var request = new HttpRequestMessage(HttpMethod.Get, url);
                request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                try
                {
                    var response = await client.SendAsync(request);
                    response.EnsureSuccessStatusCode(); // 确保响应状态码为成功
                    if (response.IsSuccessStatusCode)
                    {
                        var strReturn = await response.Content.ReadAsStringAsync();
                        TencentAccessToken tencentToken = JsonConvert.DeserializeObject<TencentAccessToken>(strReturn);
                        if (tencentToken != null && !string.IsNullOrEmpty(tencentToken.access_token))
                        {
                            token = tencentToken.access_token;
                        }
                    }
                }
                catch (HttpRequestException ex)
                {
                    log.Info($"微信获取token异常【{ex.Message}】");
                }
                catch (JsonException ex)
                {
                    log.Info($"解析微信Token响应异常【{ex.Message}】");
                }
                catch (Exception ex)
                {
                    log.Info($"获取微信Token时发生未知异常【{ex.Message}】");
                }
            }
            return token;
        }
        /// <summary>
        /// 推送消息-小程序
        /// </summary>
        /// <returns></returns>
        public async void PushMessageToUser(List<string> openIds, object msg, string templateId = null)
        {
            try
            {
                string url = string.Format(WXConstModel.WeChatTokenUrlTemplate, WXConstModel.XCXAppId, WXConstModel.XCXSecret);
                using (var client = _httpClientFactory.CreateClient())
                {
                    var requestt = new HttpRequestMessage(HttpMethod.Get, url);
                    requestt.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                    var response = await client.SendAsync(requestt);
                    if (response.IsSuccessStatusCode)
                    {
                        var strReturn = await response.Content.ReadAsStringAsync();
                        TencentAccessToken tencentToken = JsonConvert.DeserializeObject<TencentAccessToken>(strReturn);
                        if (tencentToken != null && tencentToken.access_token != null)
                        {
                            if (openIds.Any())
                            {
                                foreach (var id in openIds)
                                {
                                    await SubscribeMessageToUser(id, tencentToken.access_token, null, msg, templateId);
                                }
                            }
                        }
                        else
                        {

                        }
                    }
                }
            }
            catch (Exception ex)
            {
                log.Info($"微信推送消息结果异常【用戶openid={openIds},msg={msg},templateId={templateId}】");
            }
        }
        /// <summary>
        /// 小程序
        /// </summary>
        /// <param name="openid"></param>
        /// <param name="accessToken"></param>
        /// <param name="title"></param>
        /// <param name="content"></param>
        /// <param name="templateId"></param>
        /// <returns></returns>
        public async Task<string> SubscribeMessageToUser(string openid, string accessToken, string title = null, object content = null, string templateId = null)
        {
            string strReturn = string.Empty;
            try
            {
                string _url = string.Format("https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token={0}", accessToken);
                //json参数
                string postData = Newtonsoft.Json.JsonConvert.SerializeObject(new
                {
                    touser = openid,//用戶openid
                    template_id = templateId ?? WXConstModel.TemplateId,
                    page = WXConstModel.XCXLoginPage,
                    data = content
                });
                using (var client = _httpClientFactory.CreateClient())
                {

                    var requestt = new HttpRequestMessage(HttpMethod.Post, _url);
                    requestt.Content = new StringContent(postData);
                    requestt.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                    var response = await client.SendAsync(requestt);
                    if (response.IsSuccessStatusCode)
                    {
                        Console.WriteLine(response.IsSuccessStatusCode);
                        strReturn = await response.Content.ReadAsStringAsync();
                        log.Info($"微信发送消息结果返回【用戶openid={openid},strReturn={strReturn}】");
                    }
                }

            }
            catch (Exception ex)
            {
                log.Info($"微信发送消息结果异常【用戶openid={openid},ex={ex.Message}】");
            }
            return strReturn;
        }
        /// <summary>
        /// 小程序-发送消息
        /// </summary>
        /// <param name="openid"></param>
        /// <param name="accessToken"></param>
        /// <param name="title"></param>
        /// <param name="content"></param>
        /// <returns></returns>
        public string SubMessageToUser(string openid, string accessToken, string title = null, object content = null)
        {
            string strReturn = string.Empty;
            try
            {
                string _url = string.Format("https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token={0}", accessToken);
                //json参数
                string postData = Newtonsoft.Json.JsonConvert.SerializeObject(new
                {
                    touser = openid,//用戶openid
                    template_id =  WXConstModel.TemplateId,
                    page = WXConstModel.XCXLoginPage,
                    data = content
                });
                using (var client = _httpClientFactory.CreateClient())
                {

                    var requestt = new HttpRequestMessage(HttpMethod.Post, _url);
                    requestt.Content = new StringContent(postData);
                    requestt.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                    var response =  client.Send(requestt);
                    if (response.IsSuccessStatusCode)
                    {
                        Console.WriteLine(response.IsSuccessStatusCode);
                        strReturn = "";
                    }
                }

            }
            catch (Exception ex)
            {
            }
            return strReturn;
        }

        public async Task<bool> PushGZHMessageToUser(List<string> openIds, string templateId, string url, object data, string miniProgramAppId, string miniProgramPagePath)
        {
            bool result=false;
            string token = await GetToken();
            if (string.IsNullOrEmpty(token))
            {
                log.Info("获取微信Token失败,无法发送模板消息");
            }
            else
            {
                if (openIds.Any())
                {
                    foreach (var id in openIds)
                    {
                       bool bol=  await SendTemplateMessageAsync(id, templateId, url, data, miniProgramAppId, miniProgramPagePath,token);
                        if (bol)
                        {
                            result = true;
                        }
                        else
                        {
                            log.Info($"PushGZHMessageToUser【{id}】发送消息失败");
                        }
                    }
                }
            }
            return result;
        }
        /// <summary>
        /// 推送微信订阅消息
        /// </summary>
        /// <param name="openId">接收人openid</param>
        /// <param name="templateId">模板id</param>
        /// <param name="url">跳转url</param>
        /// <param name="data">模板数据</param>
        /// <param name="miniProgramAppId">小程序appid</param>
        /// <param name="miniProgramPagePath">跳转小程序路径</param>
        /// <param name="token">token</param>
        /// <returns></returns>
        public async Task<bool> SendTemplateMessageAsync(string openId, string templateId, string url, object data, string miniProgramAppId, string miniProgramPagePath,string token)
        {
            bool result=false;
            string messageUrl = string.Format(WXConstModel.WeChatTemplateMessageUrl, token);
            var message = new
            {
                touser = openId,
                template_id = templateId ?? WXConstModel.GZHTemplateId,
                url,
                miniprogram = new
                {
                    appid = miniProgramAppId,
                    pagepath = miniProgramPagePath
                },
                data
            };
            using (var client = _httpClientFactory.CreateClient())
            {
                var sss = JsonConvert.SerializeObject(message);
                var request = new HttpRequestMessage(HttpMethod.Post, messageUrl)
                {
                    Content = new StringContent(JsonConvert.SerializeObject(message), System.Text.Encoding.UTF8, "application/json")
                };
                try
                {
                    var response = await client.SendAsync(request);
                    response.EnsureSuccessStatusCode(); // 确保响应状态码为成功
                    if (response.IsSuccessStatusCode)
                    {
                        var strReturn = await response.Content.ReadAsStringAsync();
                        log.Info($"发送微信模板消息返回数据【strReturn={strReturn}】");
                        var responseMessage = JsonConvert.DeserializeObject<WXResult>(strReturn);
                        if (responseMessage != null && responseMessage.errcode == 0)
                        {
                            result = true;
                        }
                        else
                        {
                            log.Info($"发送微信模板消息失败,错误码: {responseMessage?.errcode}, 错误信息: {responseMessage?.errmsg}");
                        }
                    }
                }
                catch (HttpRequestException ex)
                {
                    log.Info($"发送微信模板消息异常【{ex.Message}】");
                }
                catch (JsonException ex)
                {
                    log.Info($"解析微信模板消息响应异常【{ex.Message}】");
                }
                catch (Exception ex)
                {
                    log.Info($"发送微信模板消息时发生未知异常【{ex.Message}】");
                }
            }       
            return result;
        }

        /// <summary>
        /// 获取微信AccessToken
        /// </summary>
        /// <param name="code"></param>
        /// <returns></returns>
        public async Task<string> GetOpenIdByCodeAsync(string code)
        {
            string url = string.Format(WXConstModel.WeChatAccessTokenUrlTemplate, WXConstModel.GZHAppId, WXConstModel.GZHSecret, code);
            using (var client = _httpClientFactory.CreateClient())
            {
                var request = new HttpRequestMessage(HttpMethod.Get, url);
                request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                try
                {
                    var response = await client.SendAsync(request);
                    response.EnsureSuccessStatusCode(); // 确保响应状态码为成功

                    var strReturn = await response.Content.ReadAsStringAsync();

                    var accessTokenResponse = JsonConvert.DeserializeObject<WeChatAccessTokenResponse>(strReturn);
                    if (accessTokenResponse != null && !string.IsNullOrEmpty(accessTokenResponse.openid))
                    {
                        return accessTokenResponse.openid;
                    }
                    else
                    {
                        throw new Exception("获取微信AccessToken失败");
                    }
                }
                catch (HttpRequestException ex)
                {
                    log.Info($"请求微信AccessToken异常【{ex.Message}】");
                    throw new Exception("获取微信AccessToken失败");
                }
                catch (JsonException ex)
                {
                    log.Info($"解析微信AccessToken响应异常【{ex.Message}】");
                    throw new Exception("获取微信AccessToken失败");
                }
                catch (Exception ex)
                {
                    log.Info($"获取微信AccessToken时发生未知异常【{ex.Message}】");
                    throw new Exception("获取微信AccessToken失败");
                }
            }
            return null;
        }
    }
    /// <summary>
    /// 腾讯Token
    /// </summary>
    public class TencentAccessToken
    {
        public string access_token { get; set; }
        public int expires_in { get; set; }
    }

    /// <summary>
    /// 调用微信接口返回结果
    /// </summary>
    class WXResult
    {
        public int errcode { get; set; }
        public string errmsg { get; set; }
    }
    public class WeChatAccessTokenResponse
    {
        public string access_token { get; set; }
        public int expires_in { get; set; }
        public string refresh_token { get; set; }
        public string openid { get; set; }
        public string scope { get; set; }
        public int errcode { get; set; }
        public string errmsg { get; set; }
    }
    public static class WXConstModel
    {
        public const string XCXLoginPage = "pages/login/login";
        /// <summary>
        /// 手表健康告警提醒-模板ID-长期订阅模板
        /// </summary>
        public const string WatchHealthAlarm_TemplateId = "xVR2kPGC3lCaXqYlEmmlcPdgA8KFstXEC4eC8LWSz0I";
        /// <summary>
        /// 模板ID-短期期订阅模板
        /// </summary>
        public const string TemplateId = "Q4a7suW57aOxTCAo5b-X-kC4DpMvcJXWQqXNqkUeWTg";
        /// <summary>
        /// 小程序-AppId
        /// </summary>
        public const string XCXAppId = "wx40250567e9c14ae6";
        /// <summary>
        /// 小程序-Secret
        /// </summary>
        public const string XCXSecret = "8c1117595f359f4ebc60650ed27e835a";
        /// <summary>
        /// 公众号-AppId//AI:"wx5e59258499b53581";
        /// </summary>
        public const string GZHAppId = "wx0fddd2b0603913e0";
        /// <summary>
        /// 公众号-Secret// AI:"60c43e714f143b31f5528a28fbc19c9d";
        /// </summary>
        public const string GZHSecret = "4e4b16dcf7286261bb60df3fe28395f3";
        /// <summary>
        /// 公众号模板 【设备编号{character_string2.DATA};设备名称{ thing1.DATA};关闭状态{ thing3.DATA};关闭时间{time4.DATA}】
        /// //AI:"KfPCaPhJkUVi3em1baZu1HmsN9qRi-AbOSTo_I3GSfQ";
        /// </summary>
        public const string GZHTemplateId = "_wP22WQxAlfYGfS8zlnHTl_-KgKS8j_FP5HDeqfsPtU";
        /// <summary>
        /// 公众号模板-设备报警【设备名称;设备编号;报警内容;报警时间】
        /// </summary>
        public const string GZHDevAlarmTemplateId = "7eGjzIBAyysTOLfcn-oqkpOCEL_My5ItXHkd_DdniGw";
        /// <summary>
        /// 微信登录
        /// </summary>
        public const string WeChatTokenUrlTemplate = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}";
        /// <summary>
        /// 公众号模板发送url
        /// </summary>
        public const string WeChatTemplateMessageUrl = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token={0}";
        /// <summary>
        /// 三方登录
        /// </summary>
        public const string WeChatAccessTokenUrlTemplate = "https://api.weixin.qq.com/sns/oauth2/access_token?appid={0}&secret={1}&code={2}&grant_type=authorization_code";
    }
}