using DataSharing.LuZhou.Encrypt;
using DataSharing.LuZhou.LuZhou110;
using DataSharing.LuZhou.LZ110;
using DataSharing.Share.Dtos.LuZhou;
using Hotline.Share.Dtos.Order;
using Hotline.Share.Enums.Order;
using MapsterMapper;
using Microsoft.Extensions.Logging;
using System.Globalization;
using System.Text;
using System.Text.Json;
using System.Text.RegularExpressions;
using XF.Domain.Dependency;
using XF.Domain.Repository;

namespace DataSharing.LuZhou
{
    public class LuZhou110Service : ILuZhou110Service, IScopeDependency
    {
        private readonly IMapper _mapper;
        private readonly ILogger<LuZhou110Service> _logger;
        private readonly IRepository<WaitSendTaskLuzhou110> _waitSendTaskLuZhou110Repository;
        private readonly IRepository<SendTaskLuzhou110> _sendTaskLuZhou110Repository;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="mapper"></param>
        /// <param name="logger"></param>
        /// <param name="waitSendTaskLuZhou110Repository"></param>
        /// <param name="sendTaskLuZhou110Repository"></param>
        public LuZhou110Service(IMapper mapper, ILogger<LuZhou110Service> logger,
            IRepository<WaitSendTaskLuzhou110> waitSendTaskLuZhou110Repository,
            IRepository<SendTaskLuzhou110> sendTaskLuZhou110Repository
            )
        {
            _mapper = mapper;
            _logger = logger;
            _waitSendTaskLuZhou110Repository = waitSendTaskLuZhou110Repository;
            _sendTaskLuZhou110Repository = sendTaskLuZhou110Repository;
        }

        #region  接受数据汇聚 组装基础参数

        /// <summary>
        /// 组装基础参数
        /// </summary>
        /// <param name="dto"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task InitData(OrderFlowDto dto, CancellationToken cancellationToken)
        {
            var order = dto.Order;
            if (order.TransferPhone == "12345")
            {
                // 泸州110接口地址 http://10.41.1.9:50105
                // 泸州边界接口地址 http://59.213.83.7:8123/PSPC/SC/12345/GDLZBL

                // 跨网交互平台    能访问 泸州110接口地址 
                // 泸州110接口地址 能访问 泸州边界平台

                #region 接受数据汇聚 工单基础信息

                var serializeOptions = new JsonSerializerOptions
                {
                    PropertyNamingPolicy = new JsonPascalNamingPolicy(),
                };

                var gender = "";
                if (order.FromGender == EGender.Female)
                    gender = "女";
                if (order.FromGender == EGender.Male)
                    gender = "男";
                LZ110BasicInfoDto basicInfoDto = new LZ110BasicInfoDto()
                {
                    FlowID = order.Id,
                    Code = order.No,
                    PoliceCode = "",
                    AreaName = order.AreaCode.Substring(0, 6),
                    AddDate = order.CreationTime.ToString("yyyy/MM/dd HH:mm:ss"),
                    FromTel = order.FromPhone,
                    CallerName = order.FromName,
                    Gender = gender,
                    ContactTel = order.Contact,
                    IDCard = order.LicenceNo,
                    TelHome = "",
                    Address = order.Province + order.City + order.County + order.Street,
                    WorkUnit = "",
                    Title = order.Title,
                    PurTypeName = order.AcceptType,
                    FromName = order.SourceChannel,
                    ConTypeName = order.HotspotSpliceName,
                    Content = order.Content,
                    IsSecrecy = order.IsSecret == true ? "1" : "0"
                };

                string json = System.Text.Json.JsonSerializer.Serialize(basicInfoDto, serializeOptions);
                json = Unicode2String(json);

                var GDJCXXInfoObject = EncryptHandler.AES(basicInfoDto);
                GDJCXXInfo GDJCXXInfo = new GDJCXXInfo
                {
                    GDJCXXInfoObject = GDJCXXInfoObject
                };

                await InitSendData(order.Id, order.No, "0", LZ110Defaults.SendBasicInfo,
                    json,
                    System.Text.Json.JsonSerializer.Serialize(GDJCXXInfo, serializeOptions),
                    cancellationToken);

                #endregion

                #region 接受数据汇聚 工单流转信息

                var nodeName = "派单组";
                var nodeType = "2";
                if (!string.IsNullOrEmpty(order.ActualHandleOrgName) && order.ActualHandleOrgName != "001")
                {
                    if (order.ActualHandleOrgName.Length == 6)
                    {
                        nodeName = "一级部门受理";
                        nodeType = "4";
                    }
                    else if (order.ActualHandleOrgName.Length == 9)
                    {
                        nodeName = "二级部门办理";
                        nodeType = "4";
                    }
                    else if (order.ActualHandleOrgName.Length == 12)
                    {
                        nodeName = "三级部门办理";
                        nodeType = "4";
                    }
                }

                LZ110FlowedDto flowedDto = new LZ110FlowedDto()
                {
                    RunID = dto.WorkflowTrace.Id,
                    FlowID = order.Id,
                    Code = order.No,
                    NodeName = nodeName,
                    NodeType = nodeType,
                    HandleBMName = order.ActualHandleOrgName,
                    HandleUserName = order.ActualHandlerName,
                    HandleTime = order.ActualHandleTime.HasValue == true ? order.ActualHandleTime.Value.ToString("yyyy/MM/dd HH:mm:ss") : DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"),
                    HandleOpinion = order.ActualOpinion,
                    IsPolice = "0",
                    PoliceCode = string.Empty,
                    HandleState = string.Empty
                };
                json = System.Text.Json.JsonSerializer.Serialize(flowedDto, serializeOptions);
                json = Unicode2String(json);

                var GDLZBLInfoObject = EncryptHandler.AES(flowedDto);
                GDLZBLInfo GDLZBLInfo = new GDLZBLInfo
                {
                    GDLZBLInfoObject = GDLZBLInfoObject
                };
                await InitSendData(order.Id, order.No, "0", LZ110Defaults.SendFlowed,
                    json,
                    JsonSerializer.Serialize(GDLZBLInfo, serializeOptions),
                    cancellationToken);

                #endregion

                #region 接受数据汇聚 工单办理结果

                LZ110HandResultDto handResultDto = new LZ110HandResultDto()
                {
                    Code = order.No,
                    HandleUserName = order.ActualHandlerName,
                    HandleBMName = order.ActualHandleOrgName,
                    HandleTime = order.FiledTime.HasValue == true ? order.FiledTime.Value.ToString("yyyy/MM/dd HH:mm:ss") : DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"),
                    HandleOpinion = order.FileOpinion,
                    HandleState = "办理完成",
                    PoliceCode = "",
                };
                json = System.Text.Json.JsonSerializer.Serialize(handResultDto, serializeOptions);
                json = Unicode2String(json);

                var GDBLJGInfoObject = EncryptHandler.AES(handResultDto);
                GDBLJGInfo GDBLJGInfo = new GDBLJGInfo
                {
                    GDBLJGInfoObject = GDBLJGInfoObject
                };
                await InitSendData(order.Id, order.No, "0", LZ110Defaults.SendHandResult,
                    json,
                    System.Text.Json.JsonSerializer.Serialize(GDBLJGInfo, serializeOptions),
                    cancellationToken);

                #endregion

                #region 接受数据汇聚 工单办理状态

                LZ110UpdateStatusDto updateStatusDto = new LZ110UpdateStatusDto()
                {
                    Code = order.No,
                    FlowID = order.Id,
                    PoliceCode = "",
                    HandleState = "已归档",
                };
                json = System.Text.Json.JsonSerializer.Serialize(updateStatusDto, serializeOptions);
                json = Unicode2String(json);

                var GDBLZTInfoObject = EncryptHandler.AES(updateStatusDto);
                GDBLZTInfo GDBLZTInfo = new GDBLZTInfo
                {
                    GDBLZTInfoObject = GDBLZTInfoObject
                };
                await InitSendData(order.Id, order.No, "0", LZ110Defaults.SendUpdateStatus,
                    json,
                    System.Text.Json.JsonSerializer.Serialize(GDBLZTInfo, serializeOptions),
                    cancellationToken);

                #endregion

                #region 接受数据汇聚 工单延期申请

                if (dto.OrderSearchDelay != null)
                {
                    var orderSearchDelay = dto.OrderSearchDelay;
                    LZ110ExtensionRequestDto extensionRequestDto = new LZ110ExtensionRequestDto()
                    {
                        FlowID = order.Id,
                        Code = order.No,
                        ApplyBMName = orderSearchDelay.ApplyOrgName,
                        ApplyUserName = orderSearchDelay.EmployeeName,
                        ApplyTime = orderSearchDelay.ApplyDelayTime.ToString("yyyy/MM/dd HH:mm:ss"),
                        ApplyTimeLimit = orderSearchDelay.DelayNum.ToString(),
                        ApplyContent = orderSearchDelay.DelayReason,
                        FPID = orderSearchDelay.Id,
                        RunID = orderSearchDelay.WorkflowId,
                    };
                    json = System.Text.Json.JsonSerializer.Serialize(extensionRequestDto, serializeOptions);
                    json = Unicode2String(json);

                    var GDYQSQInfoObject = EncryptHandler.AES(extensionRequestDto);
                    GDYQSQInfo GDYQSQInfo = new GDYQSQInfo
                    {
                        GDYQSQInfoObject = GDYQSQInfoObject
                    };
                    await InitSendData(order.Id, order.No, "0", LZ110Defaults.SendExtensionRequest,
                        json,
                        System.Text.Json.JsonSerializer.Serialize(GDYQSQInfo, serializeOptions),
                        cancellationToken);

                }

                #endregion

            }
        }

        #endregion

        #region 接受数据汇聚 工单回访信息

        /// <summary>
        /// 回访
        /// </summary>
        /// <param name="dto"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task InitVisitData(PublishVisitDto dto, CancellationToken cancellationToken)
        {
            var order = dto.Order;
            if (order != null && order.TransferPhone == "12345")
            {
                #region 接受数据汇聚 工单回访信息

                var serializeOptions = new JsonSerializerOptions
                {
                    PropertyNamingPolicy = new JsonPascalNamingPolicy(),
                };

                var visitMethod = "3";
                if (dto.VisitType == EVisitType.CallVisit)
                    visitMethod = "1";
                else if (dto.VisitType == EVisitType.SmsVisit)
                    visitMethod = "2";

                //坐席
                var seatsContent = "满意";
                var seatsResult = "2";

                //部门
                var bmContent = dto.VisitRemark;
                var bmResult = dto.SubjectResultSatifyCode switch
                {
                    "5" => "1",
                    "4" => "2",
                    "3" => "3",
                    "2" => "4",
                    "1" => "5",
                    _ => "2",
                };

                LZ110CallBackDto callBackDto = new LZ110CallBackDto()
                {
                    VisitTime = dto.VisitTime.Value.ToString("yyyy/MM/dd HH:mm:ss"),
                    FlowID = order.Id,
                    SeatsContent = seatsContent,
                    SeatsResult = seatsResult,
                    Code = order.No,
                    UserName = string.IsNullOrEmpty(dto.VisitName) == true ? "系统管理员" : dto.VisitName,
                    VisitID = dto.No,
                    BMContent = bmContent,
                    BMResult = bmResult,
                    VisitMethod = visitMethod
                };
                string json = System.Text.Json.JsonSerializer.Serialize(callBackDto, serializeOptions);
                json = Unicode2String(json);

                var GDHFXXInfoObject = EncryptHandler.AES(callBackDto);
                GDHFXXInfo GDHFXXInfo = new GDHFXXInfo
                {
                    GDHFXXInfoObject = GDHFXXInfoObject
                };
                await InitSendData(order.Id, order.No, "0", LZ110Defaults.SendCallBack,
                    json,
                    System.Text.Json.JsonSerializer.Serialize(GDHFXXInfo, serializeOptions),
                    cancellationToken);

                #endregion
            }
        }

        #endregion

        #region 写入待推送

        /// <summary>
        /// 
        /// </summary>
        /// <param name="OrderId">工单Id</param>
        /// <param name="No">工单编号</param>
        /// <param name="TaskType">任务类型  0：12345工单推送（汇聚），1：110工单推送</param>
        /// <param name="Path">请求地址</param>
        /// <param name="RequestData">组装参数</param>
        /// <param name="Request">请求参数</param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task<string> InitSendData(string OrderId, string No, string TaskType, string Path, string RequestData, string Request, CancellationToken cancellationToken)
        {
            WaitSendTaskLuzhou110 waitTask = new WaitSendTaskLuzhou110()
            {
                OrderId = OrderId,
                No = No,
                SendTimes = 0,
                TaskType = TaskType,
                HttpMethod = "Post",
                Path = Path,
                RequestData = RequestData,
                Request = Request,
            };
            waitTask.Id = await _waitSendTaskLuZhou110Repository.AddAsync(waitTask, cancellationToken);

            var sendTask = _mapper.Map<SendTaskLuzhou110>(waitTask);
            sendTask.Id = waitTask.Id;
            //写入推送主表
            return await _sendTaskLuZhou110Repository.AddAsync(sendTask, cancellationToken);

        }

        #endregion

        #region Unicode转字符串

        /// <summary>
        /// Unicode转字符串
        /// </summary>
        /// <param name="source">经过Unicode编码的字符串</param>
        /// <returns>正常字符串</returns>
        private string Unicode2String(string source)
        {
            try
            {
                return new Regex(@"\\u([0-9A-F]{4})", RegexOptions.IgnoreCase | RegexOptions.Compiled).Replace(
                             source, x => string.Empty + Convert.ToChar(Convert.ToUInt16(x.Result("$1"), 16)));
            }
            catch (Exception)
            {
                return source;
            }
        }

        #endregion

    }
}
