using Microsoft.Extensions.Caching.Memory;
using Nest;
using RestSharp;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Json;
using System.Net.Mail;
using System.Net.Security;
using System.Reflection;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Text.Encodings.Web;
using System.Threading.Tasks;
using System.Web;
using Tea;

namespace XYY.Common.Standard
{
    public interface IWebHook
    {
        void SendMsg(string msg);

        void SendMarkdown(string title, string msg, string msgTypeKey, int expirationSecond);

        Task<string> PostFile(string file);

        void SendFile(string mid);
        void SendMessage(string title, string msg, string[] userId, string link, string pic);
        void SendMarkdownToCustomer(string title, string msg, string[] customerId, string sendUserId);
    }

    public class EMail : IWebHook
    {
        public Task<string> PostFile(string file)
        {
            throw new NotImplementedException();
        }

        private string server, from, cc, userName, pwd;
        public EMail()
        {

        }

        public EMail(string server, string from, string cc, string userName, string pwd)
        {
            this.server = server;
            this.from = from;
            this.cc = cc;
            this.userName = userName;
            this.pwd = pwd;
        }

        public void SendFile(string mid)
        {
            throw new NotImplementedException();
        }

        public void SendMarkdown(string title, string msg, string msgTypeKey, int expirationSecond)
        {
            throw new NotImplementedException();
        }
        public bool RemoteCertificateValidate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
        {
            return true;
        }

        public void SendMessage(string title, string msg, string[] userId, string link, string pic)
        {
            try
            {
                ServicePointManager.ServerCertificateValidationCallback += RemoteCertificateValidate;
                //设置SMTP 验证,端口默认为25，如果需要其他请修改
                SmtpClient mailClient = new SmtpClient(server, 587);
                mailClient.EnableSsl = true;
                //指定如何发送电子邮件。
                //Network   电子邮件通过网络发送到   SMTP   服务器。    
                //PickupDirectoryFromIis   将电子邮件复制到挑选目录，然后通过本地   Internet   信息服务   (IIS)   传送。    
                //SpecifiedPickupDirectory 将电子邮件复制到 SmtpClient.PickupDirectoryLocation 属性指定的目录，然后由外部应用程序传送。  
                mailClient.DeliveryMethod = System.Net.Mail.SmtpDeliveryMethod.Network;
                //创建邮件对象
                if (!string.IsNullOrEmpty(pic))
                {
                    msg = msg + $"<br/><a href = \"{System.Net.WebUtility.UrlEncode(pic)}\" target=\"_blank\"><img src='{System.Net.WebUtility.UrlEncode(pic)}'></a>";
                }
                if (!string.IsNullOrEmpty(link))
                {
                    msg += $"<br/><a href=\"{System.Net.WebUtility.UrlEncode(link)}\">点击查看详细</a>";
                }
                MailMessage mailMessage = new MailMessage(from, string.Join(";", userId), title, msg);
                if (!string.IsNullOrEmpty(cc))
                    mailMessage.CC.Add(cc);
                //定义邮件正文，主题的编码方式
                System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
                mailMessage.BodyEncoding = System.Text.Encoding.GetEncoding("gb2312");
                mailMessage.SubjectEncoding = System.Text.Encoding.GetEncoding("gb2312");
                //mailMessage.BodyEncoding = Encoding.Default;
                //获取或者设置一个值，该值表示电子邮件正文是否为HTML
                mailMessage.IsBodyHtml = true;


                //发件人身份验证,否则163   发不了
                //表示当前登陆用户的默认凭据进行身份验证，并且包含用户名密码
                mailClient.UseDefaultCredentials = false;
                mailClient.Credentials = new System.Net.NetworkCredential(userName, pwd);
                //发送 
                mailClient.Send(mailMessage);
            }
            catch (Exception exp)
            {
                throw exp;
            }
        }

        public void SendMsg(string msg)
        {
            throw new NotImplementedException();
        }

        public void SendMarkdownToCustomer(string title, string msg, string[] customerId, string sendUserId)
        {
            throw new NotImplementedException();
        }
    }

    public class ALISMS : IWebHook
    {
        IMemoryCache memoryCache;
        AlibabaCloud.SDK.Dysmsapi20170525.Client client;
        string tempName = "SMS_460811324", signName = "行运易";
        public ALISMS(string accessKeyId, string accessKeySecret)
        {
            this.memoryCache = new MemoryCache(new MemoryCacheOptions
            {
            });
            AlibabaCloud.OpenApiClient.Models.Config config = new AlibabaCloud.OpenApiClient.Models.Config
            {
                // 您的AccessKey ID
                AccessKeyId = accessKeyId,
                // 您的AccessKey Secret
                AccessKeySecret = accessKeySecret
            };
            config.Endpoint = "dysmsapi.aliyuncs.com";

            client = new AlibabaCloud.SDK.Dysmsapi20170525.Client(config);

        }

        public Task<string> PostFile(string file)
        {
            throw new NotImplementedException();
        }

        public void SendFile(string mid)
        {
            throw new NotImplementedException();
        }

        public void SendMarkdown(string title, string msg, string msgTypeKey, int expirationSecond)
        {
            throw new NotImplementedException();
        }

        public void SendMarkdownToCustomer(string title, string msg, string[] customerId, string sendUserId)
        {
            throw new NotImplementedException();
        }

        public void SendMessage(string title, string msg, string[] userId, string link, string pic)
        {
            AlibabaCloud.SDK.Dysmsapi20170525.Models.SendBatchSmsRequest sendBatchSmsRequest = new AlibabaCloud.SDK.Dysmsapi20170525.Models.SendBatchSmsRequest
            {
                PhoneNumberJson = Newtonsoft.Json.JsonConvert.SerializeObject(userId),
                TemplateCode = tempName,
                SignNameJson = Newtonsoft.Json.JsonConvert.SerializeObject(new string[] { signName }),
                TemplateParamJson = Newtonsoft.Json.JsonConvert.SerializeObject(new dynamic[] { new {
                    name = "细刻",
                    time=DateTime.Now.ToString_yyyyMMdd(),
                    channelName = "Fedex附加费",
                    sealName ="宋小林",
                    phoneNumber="16602045815"
                } })
            };

            AlibabaCloud.TeaUtil.Models.RuntimeOptions runtime = new AlibabaCloud.TeaUtil.Models.RuntimeOptions();
            try
            {
                // 复制代码运行请自行打印 API 的返回值
                var response = client.SendBatchSmsWithOptions(sendBatchSmsRequest, runtime);
                string error = response.Body.Message;
                Console.WriteLine(error);
            }
            catch (TeaException error)
            {
                // 如有需要，请打印 error
                AlibabaCloud.TeaUtil.Common.AssertAsString(error.Message);
            }
            catch (Exception _error)
            {
                TeaException error = new TeaException(new Dictionary<string, object>
                {
                    { "message", _error.Message }
                });
                // 如有需要，请打印 error
                AlibabaCloud.TeaUtil.Common.AssertAsString(error.Message);
            }
        }


        public void SendMsg(string msg)
        {
            throw new NotImplementedException();
        }
    }


    public class QYWXWebHook : IWebHook
    {
        IMemoryCache memoryCache;
        public class FileReult
        {
            /// <summary>
            /// 
            /// </summary>
            public int errcode { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string errmsg { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string type { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string media_id { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string created_at { get; set; }
        }
        public string Url;

        public QYWXWebHook(string url)
        {
            Url = url;
            this.memoryCache = new MemoryCache(new MemoryCacheOptions
            {
            });
        }

        public async Task<string> PostFile(string file)
        {
            Uri uri = new Uri(Url);
            var query = HttpUtility.ParseQueryString(uri.Query);
            string key = query.Get("key");
            string updateUrl = $"https://qyapi.weixin.qq.com/cgi-bin/webhook/upload_media?key={key}&type=file";
            FileInfo fileInfo = new FileInfo(file);

            RestClient restClient = new RestClient(updateUrl);
            RestRequest restRequest = new RestRequest();
            restRequest.AddFile(fileInfo.Name, file, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            var response = restClient.Post<FileReult>(restRequest);

            FileReult fileReult = response.Data;
            if (fileReult.errcode == 0)
            {
                return fileReult.media_id;
            }
            else
            {
                throw new Exception(fileReult.errmsg);
            }

        }

        public void SendFile(string mid)
        {
            string msg = $@"{{
                            ""msgtype"": ""file"",
                            ""file"": {{
                                 ""media_id"": ""{mid}""
                            }}
                        }}";

            SendMsg(msg);
        }

        public void SendMsg(string msg)
        {

            RestClient restClient = new RestClient(Url);
            RestRequest restRequest = new RestRequest();
            restRequest.AddJsonBody(msg);
            var response = restClient.Post(restRequest);
            if (response.IsSuccessful)
            {

            }
        }




        public void SendMarkdown(string title, string msg, string msgTypeKey, int expirationSecond)
        {
            if (!memoryCache.TryGetValue(msgTypeKey, out var memory))
            {
                var msgObj = new
                {
                    msgtype = "markdown",
                    markdown = new
                    {
                        content = $"<font color=\"warning\">{title}</font>\n{msg}"
                    }
                };
                string msgJosn = Newtonsoft.Json.JsonConvert.SerializeObject(msgObj);
                SendMsg(msgJosn);
                //增加内存缓存 
                memoryCache.Set<string>(msgTypeKey, "1", new TimeSpan(0, 0, expirationSecond));
            }
        }

        public void SendMarkdownToCustomer(string title, string msg, string[] customerId, string sendUserId)
        {

            var msgObj = new
            {
                text = new
                {
                    content = $"<font color=\"info\">{title}</font>\n{msg}"
                },
                chat_type = "single",
                external_userid = customerId,
                agentid = agentid,
                sender = sendUserId,
            };
            string msgJosn = Newtonsoft.Json.JsonConvert.SerializeObject(msgObj);
            string token = new QYWXAPI().GetToken();
            string url = $"https://qyapi.weixin.qq.com/cgi-bin/externalcontact/add_msg_template?access_token={token}";
            RestClient client = new RestClient(url);
            RestRequest request = new RestRequest(Method.POST);
            request.AddJsonBody(msgObj);
            var response = client.Execute(request);
            if (!response.IsSuccessful)
            {

                throw new Exception("发送企业微信消息失败:" + (response.ErrorMessage ?? response.Content));
            }
            else
            {
                var result = Newtonsoft.Json.JsonConvert.DeserializeObject<MsgReturn>(response.Content);
                if (result != null && !string.IsNullOrEmpty(result.errmsg) && result.errmsg != "ok")
                {
                    throw new Exception(result.errmsg);
                }
            }
        }

        public void SendMarkdown(string title, string msg, string[] userId)
        {

            var msgObj = new
            {
                msgtype = "markdown",
                markdown = new
                {
                    content = $"<font color=\"info\">{title}</font>\n{msg}"
                },
                touser = string.Join('|', userId),
                agentid = agentid
            };
            string msgJosn = Newtonsoft.Json.JsonConvert.SerializeObject(msgObj);
            string token = new QYWXAPI().GetToken();
            string url = $"https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token={token}";
            RestClient client = new RestClient(url);
            RestRequest request = new RestRequest(Method.POST);
            request.AddJsonBody(msgObj);
            var response = client.Execute(request);
            if (!response.IsSuccessful)
            {

                throw new Exception("发送企业微信消息失败:" + (response.ErrorMessage ?? response.Content));
            }
            else
            {
                var result = Newtonsoft.Json.JsonConvert.DeserializeObject<MsgReturn>(response.Content);
                if (result != null && !string.IsNullOrEmpty(result.errmsg) && result.errmsg != "ok")
                {
                    throw new Exception(result.errmsg);
                }
            }
        }

        public void SendText(string title, string msg, string[] userId)
        {
            var msgObj = new MsgRequ
            {
                msgtype = "text",
                text = new Text
                {
                    content = $"{title}\n{msg}"
                },
                enable_duplicate_check = 1,
                touser = string.Join('|', userId),
                agentid = agentid
            };
            string token = new QYWXAPI().GetToken();
            string url = $"https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token={token}";
            RestClient client = new RestClient(url);
            RestRequest request = new RestRequest(Method.POST);
            request.AddJsonBody(msgObj);
            var response = client.Execute(request);
            if (!response.IsSuccessful)
            {

                throw new Exception("发送企业微信消息失败:" + (response.ErrorMessage ?? response.Content));
            }
            else
            {
                var result = Newtonsoft.Json.JsonConvert.DeserializeObject<MsgReturn>(response.Content);
                if (result != null && !string.IsNullOrEmpty(result.errmsg) && result.errmsg != "ok")
                {
                    throw new Exception(result.errmsg);
                }
            }
        }

        //如果好用，请收藏地址，帮忙分享。
        public class ArticlesItem
        {
            /// <summary>
            /// 中秋节礼品领取
            /// </summary>
            public string title { get; set; }
            /// <summary>
            /// 今年中秋节公司有豪礼相送
            /// </summary>
            public string description { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string url { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string picurl { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string appid { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string pagepath { get; set; }
        }

        public class News
        {
            /// <summary>
            /// 
            /// </summary>
            public List<ArticlesItem> articles { get; set; }
        }

        //如果好用，请收藏地址，帮忙分享。
        public class Text
        {
            /// <summary>
            /// 你的快递已到，请携带工卡前往邮件中心领取。 
            /// </summary>
            public string content { get; set; }
        }

        public class MsgRequ
        {
            /// <summary>
            /// 
            /// </summary>
            public string touser { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string toparty { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string totag { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string msgtype { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public int agentid { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public Text text { get; set; }

            public News news { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public int safe { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public int enable_id_trans { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public int enable_duplicate_check { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public int duplicate_check_interval { get; set; }
        }
        //如果好用，请收藏地址，帮忙分享。
        public class MsgReturn
        {
            /// <summary>
            /// 
            /// </summary>
            public int errcode { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string errmsg { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string invaliduser { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string invalidparty { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string invalidtag { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string unlicenseduser { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string msgid { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string response_code { get; set; }
        }


        //如果好用，请收藏地址，帮忙分享。
        public class TokenResult
        {
            /// <summary>
            /// 
            /// </summary>
            public int errcode { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string errmsg { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string access_token { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public int expires_in { get; set; }
        }
        private int agentid
        {
            get => 1000012;
        }
        public void SendMessage(string title, string msg, string[] userId, string link, string pic)
        {
            var msgObj = new MsgRequ
            {
                msgtype = "text",
                text = new Text
                {
                    content = $"{title}\n{msg}"
                },
                enable_duplicate_check = 1,
                touser = string.Join('|', userId),
                agentid = agentid
            };

            if (!string.IsNullOrEmpty(link))
            {
                msgObj.text.content += $"\n<a href=\"{link}\">点击查看详细</a>";
            }
            if (!string.IsNullOrEmpty(pic))
            {
                msgObj = new MsgRequ
                {
                    msgtype = "news",
                    news = new News
                    {
                        articles = new List<ArticlesItem> { new ArticlesItem
                        {
                            title = title,
                            picurl = pic,
                            description = msg,
                            url = link
                        }
                        }
                    },
                    enable_duplicate_check = 1,
                    touser = string.Join('|', userId),
                    agentid = agentid
                };
            }
            string token = new QYWXAPI().GetToken();
            string url = $"https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token={token}";
            RestClient client = new RestClient(url);
            RestRequest request = new RestRequest(Method.POST);
            request.AddJsonBody(msgObj);
            var response = client.Execute(request);
            if (!response.IsSuccessful)
            {
                throw new Exception("发送企业微信消息失败:" + (response.ErrorMessage ?? response.Content));
            }
            else
            {
                var result = Newtonsoft.Json.JsonConvert.DeserializeObject<MsgReturn>(response.Content);
                if (result != null && !string.IsNullOrEmpty(result.errmsg) && result.errmsg != "ok")
                {
                    throw new Exception(result.errmsg);
                }
            }
        }
    }
}
