using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using PushPlatform.Common.WeChatService;
using PushPlatform.Common.Model;

namespace PushPlatform.Common.Util
{
    public class WeChatHelper
    {
        public static string OriginalId;

        /// <summary>
        /// 授权跳转链接
        /// </summary>
        private static string snsapi_base = "https://open.weixin.qq.com/connect/oauth2/authorize?appid={0}&redirect_uri={1}&response_type={2}&scope={3}&state={4}#wechat_redirect";

        /// <summary>
        /// 获取access_token链接
        /// </summary>
        private static string access_token = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}";

        /// <summary>
        /// 更新菜单
        /// </summary>
        private static string upload_menu = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token={0}";

        /// <summary>
        /// code换取openId
        /// </summary>
        private static string authorization_code = "https://api.weixin.qq.com/sns/oauth2/access_token?appid={0}&secret={1}&code={2}&grant_type=authorization_code";

        /// <summary>
        /// 发送模板消息
        /// </summary>
        private static string sendTemplateMsg = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token={0}";

        private static string jsapiurl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket ";

        private static string create_qrcode = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token={0}";

        private static string qrcode_picture = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket={0}";

        #region 获取微信Appid
        /// <summary>
        /// 获取微信Appid
        /// </summary>
        /// <returns></returns>
        public static string GetWechatAppId()
        {
            return System.Configuration.ConfigurationManager.AppSettings["WeChatAppid"];
        }
        #endregion

        #region 获取微信密钥
        /// <summary>
        /// 获取微信密钥
        /// </summary>
        /// <returns></returns>
        public static string GetWechatSecret()
        {
            return System.Configuration.ConfigurationManager.AppSettings["WeChatSecret"];
        }
        #endregion

        #region 获取用户信息（公众号）
        /// <summary>
        /// 获取用户信息（公众号）
        /// </summary>
        /// <param name="code"></param>
        /// <returns></returns>
        public static WeChatUser GetWechatUserByCodeMp(string code)
        {
            WeChatUser user = new WeChatUser();
            using (WeChatService.WeChatServiceSoapClient wcs = new WeChatService.WeChatServiceSoapClient())
            {
                string jsonresult = wcs.Get_UserInfo_BY_Original_And_Code(OriginalId, code);
                user = JsonUtil.ConvertToObject<WeChatUser>(jsonresult);
            }
            return user;
        }
        #endregion

        #region 发送模板消息给用户
        /// <summary>
        /// 发送微信模板消息
        /// </summary>
        /// <param name="touser">接收模板消息的用户的openid</param>
        /// <param name="template_id_short">模板库中模板的编号，有“TM**”和“OPENTMTM**”等形式</param>
        /// <param name="templeteid">模板Id</param>
        /// <param name="originalid">公众号原始Id</param>
        /// <param name="data">消息内容JSon字符串，如："data":{"first": {"value":"恭喜你购买成功！","color":"#173177" }}</param>
        /// <param name="url">消息跳转链接</param>
        /// <returns> 1:成功, 0:失败</returns>
        public static APIResult<string> SendMsgWechat(WechatMsgModel msgModel)
        {
            APIResult<string> result = new APIResult<string>();
            result.Result = 1;
            LogHelper.Debug(JsonHelper.ToJson(msgModel));
            try
            {
                string resultstr = "";
                string msg = "";
                using (WeChatServiceSoapClient WinXinMsg = new WeChatServiceSoapClient())
                {
                    var sendResult = WinXinMsg.Send_TempLete_Msg(msgModel.touser, msgModel.template_id_short, msgModel.templeteid, msgModel.originalid, msgModel.data, msgModel.url);
                    resultstr = ObjectHelper.GetPropertyValue(sendResult, "result");
                    msg = ObjectHelper.GetPropertyValue(sendResult, "msg");
                    result.Msg = resultstr;
                    //微信消息模板发送日志
                    LogHelper.Info("消息模板发送结果：" + JsonHelper.ToJson(result));
                    if (resultstr != "1")
                    {
                        result.Result = 0;
                    }
                }
            }
            catch (Exception ex)
            {
                LogHelper.Error(ex);
                result.Result = 0;
                result.code = 1;
                result.Msg = "抛出异常，请查询日志！";
            }
            return result;
        }
        #endregion

        #region 根据code获取openid
        /// <summary>
        /// 根据code获取openid
        /// </summary>
        /// <param name="code"></param>
        /// <returns></returns>
        public static string GetOpenIdByCode(string code)
        {
            string url = string.Format(authorization_code, GetWechatAppId(), GetWechatSecret(), code);
            string result = CreateWebClient(url);
            Snsapi_base_Result scope = JsonUtil.ConvertToObject<Snsapi_base_Result>(result);
            if (scope != null)
                return scope.openid;
            else
                return string.Empty;
        }
        #endregion

        #region 创建访问
        /// <summary>
        /// 创建访问
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        private static string CreateWebClient(string url)
        {
            WebClient myWebClient = new WebClient();
            myWebClient.Encoding = System.Text.Encoding.UTF8;
            string reStr = string.Empty;
            try
            {
                byte[] myDataBuffer = myWebClient.DownloadData(url);
                reStr = Encoding.UTF8.GetString(myDataBuffer);
            }
            catch (Exception ex)
            {
                return ex.ToString();
            }
            finally
            {
                myWebClient.Dispose();
            }

            return reStr;
        }
        #endregion

        #region 直接调用微信
        public static string Get_Access_Token()
        {
            string url = System.Configuration.ConfigurationManager.AppSettings["WechatTokenUrl"] + OriginalId;
            string returnStr = CreateWebClient(url);
            try
            {
                var access_token = JsonHelper.ToObject<ApiResponseModel<string>>(returnStr);
                if (access_token != null && access_token.Result == 1)
                {
                    return access_token.Data;
                }
                else
                    return null;
            }
            catch (Exception ex)
            {
                LogHelper.Error(ex);
                return null;
            }
        }

        #region 发送微信模板消息

        /// <summary>
        /// 发送微信模板消息
        /// </summary>
        /// <param name="msgModel"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        public static APIResult<string> SendTempletMessge(WechatMsgModel msgModel)
        {
            APIResult<string> result = new APIResult<string>();
            result.Result = 1;
            try
            {
                #region 组装信息推送，并返回结果（其它模版消息于此类似）
                string url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + Get_Access_Token();
                string temp = "{\"touser\": \"" + msgModel.touser + "\"," +
                              "\"template_id\": \"" + msgModel.templeteid + "\", " +
                              "\"url\":\"" + msgModel.url + "\"," +
                              "\"topcolor\": \"#FF0000\", " +
                              "\"data\":" + msgModel.data + "}";
                #endregion

                //核心代码
                result.Msg = RequestHelp.GetResponseData(temp, @url);
            }
            catch (Exception ex)
            {
                LogHelper.Error(ex);
                result.Result = 0;
                result.code = 1;
                result.Msg = "抛出异常，请查询日志！";
            }
            return result;
        }
        #endregion
        #endregion
    }

    public class ApiResponseModel<T> where T : class
    {
        /// <summary>调用结果 1=成功，0=失败</summary>
        public int Result { get; set; }
        /// <summary>返回信息</summary>
        public string Msg { get; set; }
        /// <summary>返回代码</summary>
        public int Code { get; set; }
        /// <summary>返回数据</summary>
        public T Data { get; set; }
    }
    public class WXApi
    {
        public string access_token { set; get; }
    }
    /// <summary>
    /// 微信用户
    /// </summary>
    public class WeChatUser
    {
        public WeChatUser()
        {

        }

        public WeChatUser(int subscribe, string openid, string nickname, int sex, string city, string country, string province, string language, string headimgurl, int subscribe_time, string unionid, string remark, int groupid)
        {
            this.subscribe = subscribe;
            this.openid = openid;
            this.nickname = nickname;
            this.sex = sex;
            this.city = city;
            this.country = country;
            this.province = province;
            this.language = language;
            this.headimgurl = headimgurl;
            this.subscribe_time = subscribe_time;
            this.unionid = unionid;
            this.remark = remark;
            this.groupid = groupid;
        }

        /// <summary>
        /// 用户是否订阅该公众号标识，值为1是表示关注，值为0时，代表此用户没有关注该公众号，拉取不到其余信息。
        /// </summary>
        public int subscribe { get; set; }

        /// <summary>
        /// 用户的标识，对当前公众号唯一
        /// </summary>
        public string openid { get; set; }

        /// <summary>
        /// 用户的昵称
        /// </summary>
        public string nickname { get; set; }

        /// <summary>
        /// 用户的性别，值为1时是男性，值为2时是女性，值为0时是未知
        /// </summary>
        public int sex { get; set; }

        /// <summary>
        /// 用户所在城市
        /// </summary>
        public string city { get; set; }

        /// <summary>
        /// 用户所在国家
        /// </summary>
        public string country { get; set; }

        /// <summary>
        /// 用户所在省份
        /// </summary>
        public string province { get; set; }

        /// <summary>
        /// 用户的语言，简体中文为zh_CN
        /// </summary>
        public string language { get; set; }

        /// <summary>
        /// 用户头像，最后一个数值代表正方形头像大小（有0、46、64、96、132数值可选，0代表640*640正方形头像），
        /// 用户没有头像时该项为空。若用户更换头像，原有头像URL将失效。
        /// </summary>
        public string headimgurl { get; set; }

        /// <summary>
        /// 用户关注时间，为时间戳。如果用户曾多次关注，则取最后关注时间
        /// </summary>
        public int subscribe_time { get; set; }

        /// <summary>
        /// 只有在用户将公众号绑定到微信开放平台帐号后，才会出现该字段。
        /// 详见：获取用户个人信息（UnionID机制）
        /// </summary>
        public string unionid { get; set; }

        /// <summary>
        /// 公众号运营者对粉丝的备注，公众号运营者可在微信公众平台用户管理界面对粉丝添加备注
        /// </summary>
        public string remark { get; set; }

        /// <summary>
        /// 用户所在的分组ID
        /// </summary>
        public int groupid { get; set; }
    }

    public class Snsapi_base_Result
    {
        //网页授权接口调用凭证,注意：此access_token与基础支持的access_token不同
        public string access_token { set; get; }
        //access_token接口调用凭证超时时间，单位（秒）
        public string expires_in { set; get; }
        //用户刷新access_token
        public string refresh_token { set; get; }
        //用户唯一标识，请注意，在未关注公众号时，用户访问公众号的网页，也会产生一个用户和公众号唯一的OpenID
        public string openid { set; get; }
        //用户授权的作用域，使用逗号（,）分隔
        public string scope { set; get; }
        //只有在用户将公众号绑定到微信开放平台帐号后，才会出现该字段。
        public string unionid { set; get; }
    }
}
