using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using Edu.Common.Plugin;
using Edu.ThirdCore.QYWinXin.Model;
using Edu.Common;
using Senparc.Weixin.Entities;
using Senparc.Weixin.Work;
using Senparc.Weixin.Work.AdvancedAPIs;
using Senparc.Weixin.Work.AdvancedAPIs.External;
using Senparc.Weixin.Work.AdvancedAPIs.External.ExternalJson;
using Senparc.Weixin.Work.AdvancedAPIs.MailList;
using Senparc.Weixin.Work.AdvancedAPIs.MailList.Member;
using Senparc.Weixin.Work.AdvancedAPIs.Media;
using Senparc.Weixin.Work.CommonAPIs;
using Senparc.Weixin.Work.AdvancedAPIs.OAuth2;
using Senparc.Weixin.Work.Containers;
using Senparc.Weixin.Work.Entities;

namespace Edu.ThirdCore.QYWinXin
{
    /// <summary>
    /// 企业微信处理
    /// </summary>
    public class QYWeiXinHelper
    {
        #region 全局静态

        private static string WORK_KEY = string.Empty;

        #endregion

        #region 令牌

        public static string GetToken(string WX_CorpId, string Employee_Secret, bool newToken=false) 
        {
            if (!string.IsNullOrEmpty(Employee_Secret)) {
                var token = AccessTokenContainer.GetTokenAsync(WX_CorpId, Employee_Secret, newToken);
                return token.Result;
            }
            else 
            {
                return string.Empty;
            }
        }

        #endregion

        /// <summary>
        /// 解析用户信息
        /// </summary>
        /// <param name="groupId"></param>
        /// <param name="code"></param>
        /// <returns></returns>
        public (bool status, GetUserInfoResult result) GetLoginWorkUserInfo(int groupId,string code,string appCode, string token)
        {
            if (!string.IsNullOrEmpty(token))
            {
                var result = Senparc.Weixin.Work.AdvancedAPIs.OAuth2Api.GetUserId(token, code);
                return (true, result);
            }
            else 
            {
                return (false, null);
            }
        }

        /// <summary>
        /// 组装跳转地址
        /// </summary>
        /// <param name="groupId">集团编号</param>
        /// <param name="mark">唯一标识</param>
        /// <returns></returns>
        public string GetUserAuthorizationCodePath(string mark, string CropId, string AppId, string token)
        {
            if (!string.IsNullOrEmpty(token))
            {
                string redirect_uri = $"{Config.WorkAPPDomain}/login";
                string state = mark;
                return Senparc.Weixin.Work.AdvancedAPIs.OAuth2Api.GetCode(CropId, redirect_uri, state, AppId);
            }
            else
            {
                return string.Empty;
            }
        }

        /// <summary>
        /// 获取token
        /// </summary>
        /// <returns></returns>
        public static AccessTokenResult GetToken(string corpId, string corpSecret)
        {
            return CommonApi.GetToken(corpId, corpSecret);
        }

        #region 部门
        /// <summary>
        /// 获取部门列表
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        public static GetDepartmentListResult GetDepartmentList(string token)
        {
            return MailListApi.GetDepartmentList(token);
        }

        /// <summary>
        /// 创建部门
        /// </summary>
        /// <param name="accessTokenOrAppKey"></param>
        /// <param name="name"></param>
        /// <param name="parentId"></param>
        /// <param name="order"></param>
        /// <returns></returns>
        public static CreateDepartmentResult CreateDepartment(string accessTokenOrAppKey, string name, long parentId, int order = 1)
        {
            return MailListApi.CreateDepartment(accessTokenOrAppKey, name, parentId, order);
        }

        /// <summary>
        /// 更新部门
        /// </summary>
        /// <param name="accessTokenOrAppKey"></param>
        /// <param name="id"></param>
        /// <param name="name"></param>
        /// <param name="parentId"></param>
        /// <param name="order"></param>
        /// <returns></returns>
        public static WorkJsonResult UpdateDepartment(string accessTokenOrAppKey, long id, string name, long? parentId = null, int order = 1)
        {
            return MailListApi.UpdateDepartment(accessTokenOrAppKey, id, name, parentId, order);
        }

        /// <summary>
        /// 删除部门
        /// </summary>
        /// <param name="accessTokenOrAppKey"></param>
        /// <param name="id"></param>
        /// <returns></returns>
        public static WorkJsonResult DeleteDepartment(string accessTokenOrAppKey, long id)
        {
            return MailListApi.DeleteDepartment(accessTokenOrAppKey, id);
        }

        #endregion

        #region 人员

        /// <summary>
        /// 获取部门下人员列表
        /// </summary>
        /// <param name="accessTokenOrAppKey"></param>
        /// <param name="departmentId"></param>
        /// <param name="fetchChild"></param>
        /// <returns></returns>
        public static GetDepartmentMemberResult GetDepartmentMember(string accessTokenOrAppKey, long departmentId, int fetchChild)
        {
            return MailListApi.GetDepartmentMember(accessTokenOrAppKey, departmentId, fetchChild);
        }

        /// <summary>
        /// 获取部门下人员 -明细版
        /// </summary>
        /// <param name="accessTokenOrAppKey"></param>
        /// <param name="departmentId"></param>
        /// <param name="fetchChild"></param>
        /// <returns></returns>
        public static GetDepartmentMemberInfoResult GetDepartmentMemberInfo(string accessTokenOrAppKey, long departmentId, int? fetchChild)
        {
            return MailListApi.GetDepartmentMemberInfo(accessTokenOrAppKey, departmentId, fetchChild);
        }

        /// <summary>
        /// 创建人员
        /// </summary>
        /// <param name="accessTokenOrAppKey"></param>
        /// <param name="memberCreateRequest"></param>
        /// <returns></returns>
        public static WorkJsonResult CreateMember(string accessTokenOrAppKey, MemberCreateRequest memberCreateRequest)
        {
            return MailListApi.CreateMember(accessTokenOrAppKey, memberCreateRequest);
        }

        /// <summary>
        /// 获取成员
        /// </summary>
        /// <param name="accessTokenOrAppKey"></param>
        /// <param name="userId"></param>
        /// <returns></returns>
        public static GetMemberResult GetMember(string accessTokenOrAppKey, string userId)
        {
            return MailListApi.GetMember(accessTokenOrAppKey, userId);
        }

        /// <summary>
        /// 获取成员(包含别名)
        /// </summary>
        /// <param name="accessTokenOrAppKey"></param>
        /// <param name="userId"></param>
        /// <returns></returns>
        public static GetMemberResult_V2 GetMember_V2(string accessTokenOrAppKey, string userId) {
            string url = "https://qyapi.weixin.qq.com/cgi-bin/user/get?access_token=" + accessTokenOrAppKey + "&userid=" + userId;
            string Rmsg = HttpHelper.HttpGet(url);
            if (!string.IsNullOrEmpty(Rmsg))
            {
                var rmodel = JsonHelper.DeserializeObject<GetMemberResult_V2>(Rmsg);
                return rmodel;
            }
            return new GetMemberResult_V2()
            {
                errcode = Senparc.Weixin.ReturnCode_Work.系统繁忙,
                errmsg = "未请求到数据"
            };
        }

        /// <summary>
        /// 更新人员
        /// </summary>
        /// <param name="accessTokenOrAppKey"></param>
        /// <param name="memberUpdateRequest"></param>
        /// <returns></returns>
        public static WorkJsonResult UpdateMember(string accessTokenOrAppKey, MemberUpdateRequest memberUpdateRequest)
        {
            return MailListApi.UpdateMember(accessTokenOrAppKey, memberUpdateRequest);
        }

        /// <summary>
        /// 删除人员
        /// </summary>
        /// <param name="accessTokenOrAppKey"></param>
        /// <param name="userId"></param>
        /// <returns></returns>
        public static WorkJsonResult DeleteMember(string accessTokenOrAppKey, string userId)
        {
            return MailListApi.DeleteMember(accessTokenOrAppKey, userId);
        }

        /// <summary>
        /// 根据电话获取用户信息
        /// </summary>
        /// <param name="accessTokenOrAppKey"></param>
        /// <param name="mobile"></param>
        /// <returns></returns>
        public static GetUseridResult GetUserid(string accessTokenOrAppKey, string mobile)
        {
            return MailListApi.GetUserid(accessTokenOrAppKey, mobile);
        }

        #endregion

        #region 客户

        /// <summary>
        /// 获取客户列表
        /// </summary>
        /// <param name="accessTokenOrAppKey">调用接口凭证</param>
        /// <param name="userid">企业成员的userid</param>
        /// <returns></returns>
        public static GetExternalContactListResult GetExternalContactList(string accessTokenOrAppKey, string userid)
        {
            return ExternalApi.GetExternalContactList(accessTokenOrAppKey, userid);
        }

        /// <summary>
        /// 获取客户详情
        /// </summary>
        /// <param name="accessTokenOrAppKey">调用接口凭证</param>
        /// <param name="externalUserId">外部联系人的userid,注意不是企业成员的帐号</param>
        /// <returns></returns>
        public static GetExternalContactResultJson GetExternalContactInfo(string accessTokenOrAppKey, string externalUserId)
        {
            return ExternalApi.GetExternalContactInfo(accessTokenOrAppKey, externalUserId);
        }

        /// <summary>
        /// 批量获取客户详情
        /// </summary>
        /// <param name="accessTokenOrAppKey"></param>
        /// <param name="userid"></param>
        /// <param name="cursor"></param>
        /// <param name="limit"></param>
        /// <param name="timeOut"></param>
        public static GetExternalContactInfoBatchResult_V2 GetExternalContactInfoBatch(string accessTokenOrAppKey, List<string> userid, string cursor = "", int limit = 50)
        {
            string url = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/batch/get_by_user?access_token=" + accessTokenOrAppKey;

            var SendDate = new
            {
                userid_list = userid,
                cursor,
                limit
            };

            var Rmsg = HttpHelper.HttpPost(url, JsonHelper.Serialize(SendDate), "");
            if (!string.IsNullOrEmpty(Rmsg))
            {
                var rmodel = JsonHelper.DeserializeObject<GetExternalContactInfoBatchResult_V2>(Rmsg);
                return rmodel;
            }
            return null;
        }


        /// <summary>
        /// 转移客户
        /// </summary>
        /// <param name="token"></param>
        /// <param name="tList"></param>
        /// <param name="transferUserId"></param>
        /// <param name="receiveUserId"></param>
        /// <returns></returns>
        public static string TransferCostomer(string token, List<string> tList, string transferUserId, string receiveUserId)
        {
            string url = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/transfer_customer?access_token=" + token;
            //组成参数
            var Date = new
            {
                handover_userid = transferUserId,
                takeover_userid = receiveUserId,
                external_userid = tList,
                transfer_success_msg = ""
            };
            return HttpHelper.HttpPost(url, JsonHelper.Serialize(Date), "");
        }

        #region 离职继承

        /// <summary>
        /// 更新企业已配置的「联系我」方式
        /// </summary>
        /// <param name="accessTokenOrAppKey"></param>
        /// <param name="page_id">分页  从0开始</param>
        /// <returns></returns>
        public static GetUnassignedListResult GetUnassignedList(string accessTokenOrAppKey, int page_id)
        {
            string url = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_unassigned_list?access_token=" + accessTokenOrAppKey;

            var rquest = new
            {
                page_id,
                page_size = 1000
            };
            var Rmsg = HttpHelper.HttpPost(url, JsonHelper.Serialize(rquest), "");
            if (!string.IsNullOrEmpty(Rmsg))
            {
                var rmodel = JsonHelper.DeserializeObject<GetUnassignedListResult>(Rmsg);
                return rmodel;
            }
            return new GetUnassignedListResult()
            {
                errcode = Senparc.Weixin.ReturnCode_Work.系统繁忙,
                errmsg = "未请求到数据"
            };
        }

        /// <summary>
        /// 分配离职成员的客户
        /// </summary>
        /// <param name="accessTokenOrAppKey"></param>
        /// <param name="rquest"></param>
        /// <returns></returns>
        public static WorkJsonResult LeaveTransferCustomer(string accessTokenOrAppKey, TransferCustomerRequest rquest)
        {
            string url = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/resigned/transfer_customer?access_token=" + accessTokenOrAppKey;

            var Rmsg = HttpHelper.HttpPost(url, JsonHelper.Serialize(rquest), "");
            if (!string.IsNullOrEmpty(Rmsg))
            {
                var rmodel = JsonHelper.DeserializeObject<WorkJsonResult>(Rmsg);
                return rmodel;
            }
            return new WorkJsonResult()
            {
                errcode = Senparc.Weixin.ReturnCode_Work.系统繁忙,
                errmsg = "未请求到数据"
            };
        }
        #endregion

        #endregion

        #region 素材管理


        /// <summary>
        /// 上传临时媒体文件【QY移植修改】
        /// </summary>
        /// <param name="accessTokenOrAppKey">调用接口凭证(AccessToken)或AppKey(根据AccessTokenContainer.BuildingKey(corpId, corpSecret)方法获得)</param>
        /// <param name="type">媒体文件类型,分别有图片(image)、语音(voice)、视频(video),普通文件(file)</param>
        /// <param name="media">form-data中媒体文件标识,有filename、filelength、content-type等信息</param>
        /// <returns></returns>
        public static UploadTemporaryResultJson MediaUpload(string accessTokenOrAppKey, UploadMediaFileType type, string media)
        {
            return MediaApi.Upload(accessTokenOrAppKey, type, media);
        }

        #endregion

        #region 素材上传——V2  自行封装  盛派的方法用不来
        
        /// <summary>
        /// 上传本地文件至企业微信
        /// </summary>
        /// <param name="accessTokenOrAppKey"></param>
        /// <param name="filepath"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public static string UploadMultimedia(string accessTokenOrAppKey, string filepath, UploadMediaFileType type)
        {
            string result = "";
            string wxurl = "https://qyapi.weixin.qq.com/cgi-bin/media/upload?access_token=" + accessTokenOrAppKey + "&type="+ type.ToString();
            WebClient myWebClient = new WebClient
            {
                Credentials = CredentialCache.DefaultCredentials
            };
            try
            {
                byte[] responseArray = myWebClient.UploadFile(wxurl, "POST", filepath);
                result = Encoding.Default.GetString(responseArray, 0, responseArray.Length);
                return result;
            }
            catch (Exception ex)
            {
                result = "Error:" + ex.Message;
            }
            finally{
                myWebClient.Dispose();
            }
            return result;
        }

        /// <summary>
        /// 创建临时文件
        /// </summary>
        /// <param name="url"></param>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public static string CopyFileByUrl(string url, string fileName)
        {
            string rootBook = AppDomain.CurrentDomain.BaseDirectory;
            string fileFolder = rootBook + "/upfile/temporary";
            string filePath = Path.Combine(fileFolder, fileName);//存放地址就是本地的upload下的同名的文件
            if (!Directory.Exists(fileFolder))
                Directory.CreateDirectory(fileFolder);

            if (File.Exists(filePath))
            {//如果已经存在,那么就不需要拷贝了,如果没有,那么就进行拷贝
                return filePath;
            }
            HttpWebRequest request = HttpWebRequest.Create(url) as HttpWebRequest;
            request.Method = "GET";
            request.ProtocolVersion = new Version(1, 1);
            HttpWebResponse response = request.GetResponse() as HttpWebResponse;
            if (response.StatusCode == HttpStatusCode.NotFound)
            {
                return string.Empty;//找不到则直接返回null
            }
            // 转换为byte类型
            System.IO.Stream stream = response.GetResponseStream();


            //创建本地文件写入流
            Stream fs = new FileStream(filePath, FileMode.Create);
            byte[] bArr = new byte[1024];
            int size = stream.Read(bArr, 0, (int)bArr.Length);
            while (size > 0)
            {
                fs.Write(bArr, 0, size);
                size = stream.Read(bArr, 0, (int)bArr.Length);
            }
            fs.Close();
            stream.Close();
            return filePath;
        }

        #endregion

        #region 客户标签

        /// <summary>
        /// 新增标签/分组
        /// </summary>
        /// <param name="token"></param>
        /// <param name="GROUP_ID"></param>
        /// <param name="GROUP_NAME"></param>
        /// <param name="group_sort"></param>
        /// <param name="TAG_NAME"></param>
        /// <param name="tag_sort"></param>
        /// <returns></returns>
        public static TagGroupModelResult AddCoustmerLable(string token, TagGroupModel groupModel)
        {
            string url = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/add_corp_tag?access_token=" + token;

            var tag = new List<object>();
            if (groupModel.tag.Any())
            {
                foreach (var item in groupModel.tag)
                {
                    tag.Add(
                        new
                        {
                            item.name,
                            item.order
                        }
                    );
                }
            }
            var SendDate = new
            {
                groupModel.group_id,
                groupModel.group_name,
                groupModel.order,
                tag
            };

            var Rmsg = HttpHelper.HttpPost(url, JsonHelper.Serialize(SendDate), "");
            if (!string.IsNullOrEmpty(Rmsg))
            {
                var rmodel = JsonHelper.DeserializeObject<TagGroupModelResult>(Rmsg);
                return rmodel;
            }
            return null;
        }

        /// <summary>
        /// 修改标签/分组
        /// </summary>
        /// <param name="token"></param>
        /// <param name="tagModel"></param>
        /// <returns></returns>
        public static WorkJsonResult UpdateCoustmerLable(string token, TagModel tagModel)
        {
            string url = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/edit_corp_tag?access_token=" + token;

            var SendDate = new
            {
                tagModel.id,
                tagModel.name,
                tagModel.order
            };

            var Rmsg = HttpHelper.HttpPost(url, JsonHelper.Serialize(SendDate), "");
            if (!string.IsNullOrEmpty(Rmsg))
            {
                var rmodel = JsonHelper.DeserializeObject<WorkJsonResult>(Rmsg);
                return rmodel;
            }
            return null;
        }

        /// <summary>
        /// 删除企业微信标签/分组
        /// </summary>
        /// <param name="token"></param>
        /// <param name="tagIdList"></param>
        /// <param name="groupIdList"></param>
        /// <returns></returns>
        public static WorkJsonResult DelCoustmerLable(string token, List<string> tagIdList, List<string> groupIdList)
        {
            string url = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/del_corp_tag?access_token=" + token;
            var SendDate = new object();
            if (tagIdList.Any())
            {
                SendDate = new
                {
                    tag_id = tagIdList
                };
            }
            if (groupIdList.Any())
            {
                SendDate = new
                {
                    group_id = groupIdList
                };
            }

            var Rmsg = HttpHelper.HttpPost(url, JsonHelper.Serialize(SendDate), "");
            if (!string.IsNullOrEmpty(Rmsg))
            {
                var rmodel = JsonHelper.DeserializeObject<WorkJsonResult>(Rmsg);
                return rmodel;
            }
            return null;
        }

        /// <summary>
        /// 获取微信标签列表
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        public static TagGroupListResult GetCustomerLableForQYWeiXin(string token)
        {
            string url = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_corp_tag_list?access_token=" + token;

            var SendDate = new { };

            var Rmsg = HttpHelper.HttpPost(url, JsonHelper.Serialize(SendDate), "");
            if (!string.IsNullOrEmpty(Rmsg))
            {
                var rmodel = JsonHelper.DeserializeObject<TagGroupListResult>(Rmsg);
                return rmodel;
            }
            return null;
        }

        /// <summary>
        /// 给客户打标签
        /// </summary>
        /// <param name="token"></param>
        /// <param name="tagModel"></param>
        /// <returns></returns>
        public static WorkJsonResult SetUserCoustmerLable(string token, string UserId , string ExternalUserId, List<string> LableList)
        {
            string url = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/mark_tag?access_token=" + token;

            var SendDate = new
            {
                userid = UserId,
                external_userid = ExternalUserId,
                add_tag = LableList
            };//remove_tag

            var Rmsg = HttpHelper.HttpPost(url, JsonHelper.Serialize(SendDate), "");
            if (!string.IsNullOrEmpty(Rmsg))
            {
                var rmodel = JsonHelper.DeserializeObject<WorkJsonResult>(Rmsg);
                return rmodel;
            }
            return null;
        }
        #endregion

        #region 渠道码

        /// <summary>
        /// 配置客户联系「联系我」方式
        /// </summary>
        /// <param name="accessTokenOrAppKey">调用接口凭证</param>
        /// <param name="rquest">请求报文</param>
        /// <returns></returns>
        public static AddContactWayResult AddContactWay(string accessTokenOrAppKey, AddContactWayRequest rquest)
        {
            return ExternalApi.AddContactWay(accessTokenOrAppKey, rquest);
        }

        /// <summary>
        /// 更新企业已配置的「联系我」方式
        /// </summary>
        /// <param name="accessTokenOrAppKey"></param>
        /// <param name="rquest"></param>
        /// <returns></returns>
        public static WorkJsonResult UpdateContactWay(string accessTokenOrAppKey, UpdateContactWayRequest rquest)
        {
            string url = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/update_contact_way?access_token=" + accessTokenOrAppKey;

            var Rmsg = HttpHelper.HttpPost(url, JsonHelper.Serialize(rquest), "");
            if (!string.IsNullOrEmpty(Rmsg))
            {
                var rmodel = JsonHelper.DeserializeObject<WorkJsonResult>(Rmsg);
                return rmodel;
            }
            return new WorkJsonResult()
            {
                errcode = Senparc.Weixin.ReturnCode_Work.系统繁忙,
                errmsg = "未请求到数据"
            };
        }

        #endregion
    }
}