using ASHermed.SinoInterface.Api.IRepository;
using ASHermed.SinoInterface.Api.IService.OnlineAptInfo;
using ASHermed.SinoInterface.ContractModel;
using System;
using System.Collections.Generic;
using System.Text;
using PoJun.Util.Maps;
using System.Threading.Tasks;
using ASHermed.SinoInterface.Api.ContractModel;
using ASHermed.SinoInterface.Api.ContractModel.App;
using ASHermed.SinoInterface.Api.IService;
using Newtonsoft.Json;
using System.Linq;
using ASHermed.SinoInterface.IFramework;
using Microsoft.Extensions.Logging;
using ASHermed.SinoInterface.Api.ContractModel.Internet;
using ASHermed.SinoInterface.Api.IRepository.App;
using ASHermed.SinoInterface.Api.ContractModel.Online.Entity;
using ASHermed.SinoInterface.Tools;
using System.Net;
using ASHermed.SinoInterface.Api.IService.App;
using ASHermed.SinoInterface.Enum;

namespace ASHermed.SinoInterface.Api.Service.OnlineAptInfo
{

    /// <summary>
    /// 预约
    /// </summary>
    public class OnlineAptInfoService : BaseService, IOnlineAptInfoService
    {
        #region 初始化
        private readonly IOnlineAptInfoRepository _onlineAptInfoRepository;
        private readonly IOnlineOrderRepository _onlineOrderRepository;
        private readonly IPrescriptionInfoRepository _prescriptionInfoRepository;
        private readonly ITCService _tCService;
        private readonly IPubPatInfoRepository _pubPatInfoRepository;
        private readonly IZhuTongSMSService _zhuTongSMSService;
        private readonly ILogger<OnlineAptInfoService> _logger;
        private readonly ISysRepository _sysRepository;
        private readonly IDicDoctorRepository _dicDoctorRepository;
        private readonly IPubMapUserPatRepository _pubMapUserPatRepository;
        private readonly IPubMessageService _pubMessageService;
        private readonly IPubUserInfoRepository _pubUserInfoRepository;
        private readonly IOnlineLinKingIMrRepository _onlineLinKingIMrRepository;
        private readonly IOnlineEvaluationRepository _onlineEvaluationRepository;
        private readonly IVerifyCodeLogService _verifyCodeLogService;
        private readonly IPubMessageInfoRepository _pubMessageInfoRepository;
        private readonly IJpushService _jpushService;
        private readonly ITCPatInfoService _tCPatInfoService;
        private readonly IFileService _fileService;
        private readonly IAuthorizationService _authorizationService;
        /// <summary>
        /// 初始化
        /// </summary>
        public OnlineAptInfoService(IOnlineAptInfoRepository onlineAptInfoRepository, IOnlineOrderRepository onlineOrderRepository, IPrescriptionInfoRepository prescriptionInfoRepository, ITCService tCService, IPubPatInfoRepository pubPatInfoRepository, IZhuTongSMSService zhuTongSMSService, ILogger<OnlineAptInfoService> logger, ISysRepository sysRepository, IDicDoctorRepository dicDoctorRepository, IPubMapUserPatRepository pubMapUserPatRepository, IPubMessageService pubMessageService, IPubUserInfoRepository pubUserInfoRepository, IOnlineLinKingIMrRepository onlineLinKingIMrRepository, IOnlineEvaluationRepository onlineEvaluationRepository, IVerifyCodeLogService verifyCodeLogService, IPubMessageInfoRepository pubMessageInfoRepository, IJpushService jpushService, ITCPatInfoService tCPatInfoService, IFileService fileService, IAuthorizationService authorizationService)
        {
            _onlineAptInfoRepository = onlineAptInfoRepository;
            _prescriptionInfoRepository = prescriptionInfoRepository;
            _tCService = tCService;
            _pubPatInfoRepository = pubPatInfoRepository;
            _zhuTongSMSService = zhuTongSMSService;
            _onlineOrderRepository = onlineOrderRepository;
            _logger = logger;
            _sysRepository = sysRepository;
            _dicDoctorRepository = dicDoctorRepository;
            _pubMapUserPatRepository = pubMapUserPatRepository;
            _pubMessageService = pubMessageService;
            _pubUserInfoRepository = pubUserInfoRepository;
            _onlineLinKingIMrRepository = onlineLinKingIMrRepository;
            _onlineEvaluationRepository = onlineEvaluationRepository;
            _verifyCodeLogService = verifyCodeLogService;
            _pubMessageInfoRepository = pubMessageInfoRepository;
            _jpushService = jpushService;
            _tCPatInfoService = tCPatInfoService;
            _fileService = fileService;
            _authorizationService = authorizationService;
        }
        #endregion

        /// <summary>
        /// 添加修改在线预约信息
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        public async Task<BaseResponse<int>> AddOnlineAppointment(OnlineAptParam param, int language)
        {
            var resu = new BaseResponse<int>();
            if (string.IsNullOrEmpty(GetBaseUserInfo().U_Id))
            {
                //授权验证
                var auTick = _authorizationService.IsHasAuth(GetBaseUserInfo().ID, param.PatId, (int)AuthType.ONLINE, language);
                if (!string.IsNullOrEmpty(auTick))
                {
                    resu.Code = 0;
                    resu.Msg = auTick;
                    return resu;
                }
            }

            //同一个患者，一天最多预约两个科室；  同一个患者，同一个科室一天最多只能预约一次
            //var lockUsrnList = _onlineAptInfoRepository.GetAptLockUsrnList(param.PatId);//获取占号
            //if (lockUsrnList != null && lockUsrnList.Count > 0)
            //{
            //    //同天同科室
            //    var conf = lockUsrnList.FindAll(p=> Convert.ToDateTime(p.AptTime).ToString("yyyy-MM-dd") == Convert.ToDateTime(param.AptTime).ToString("yyyy-MM-dd") && p.DeptId == param.DeptId);
            //    if (conf != null)
            //    {
            //        resu.Code = 0;
            //        resu.Msg = "同一个科室一天最多只能预约一次";
            //        return resu;
            //    }
            //    //一天最多预约两个科室
            //    conf = lockUsrnList.FindAll(p => Convert.ToDateTime(p.AptTime).ToString("yyyy-MM-dd") == Convert.ToDateTime(param.AptTime).ToString("yyyy-MM-dd"));
            //    if (conf != null && conf.Count >= 2)
            //    {
            //        resu.Code = 0;
            //        resu.Msg = "一天最多预约两个科室";
            //        return resu;
            //    }
            //}
            var docSlot = _dicDoctorRepository.GetDocSlot(param.DocId);
            if (docSlot != null && docSlot.Count > 0)
            {
                param.DeptId = docSlot[0].DeptId;
                if (docSlot[0].DeptId == 1055 || docSlot[0].DeptId == 1065)//儿科眼科
                {
                    var aptCount = _onlineAptInfoRepository.GetTodayAptCountByDept(docSlot[0].DeptId, Convert.ToDateTime(param.AptTime).ToString("yyyy-MM-dd"));
                    if (aptCount >= 5)
                    {
                        resu.Code = 0;
                        if (language == 1)
                        {
                            resu.Msg = "该日预约已满，请选择其他日期";
                        }
                        else
                        {
                            resu.Msg = "This date is fully booked. Please select another one";
                        }
                        return resu;
                    }
                }
            }
            //验证保险用户是否有未签名订单
            if (!string.IsNullOrEmpty(GetBaseUserInfo().U_Id))
            {
                var signOrder = _onlineOrderRepository.GetUserSignOrders(GetBaseUserInfo().ID);
                if (signOrder != null)
                {
                    resu.Msg = "You have a Claim Form need to be signed. Please sign Claim Form before making a new appointment. ";
                    return resu;
                }
            }
            //绑定临时就诊人 推送至TC
            //var pat = _pubPatInfoRepository.SelectById(param.PatId);
            //if (string.IsNullOrEmpty(pat.Pat_ID))
            //{
            //    //推TC
            //    _tCService.AddTcPatInfo(pat);
            //    //更新就诊信息
            //    var tcPat = _tCService.GetPat(pat.Phone_NO, pat.Birthday);
            //    if (tcPat != null && tcPat.Count > 0)
            //    {
            //        pat.Pat_ID = tcPat[0].PAPERRowId;
            //        pat.Pat_MRN = tcPat[0].PAPMINo;
            //        _tCService.UpdatePatientPortalLink("", pat.Pat_MRN, true);
            //        _pubPatInfoRepository.UpdatePubPatInfo(pat);
            //        _tCPatInfoService.SavePatMrn(pat.Id);
            //    }
            //    else
            //    {
            //        resu.Code = 0;
            //        if (language == 1)
            //        {
            //            resu.Msg = "该就诊人添加失败，无法支付，如需咨询请联系客服小影。";
            //        }
            //        else { resu.Msg = "Failure in adding information.   Please ask customer service YING for help. "; }
            //        return resu;
            //    }
            //}
            //var pubMapUserPat = _pubMapUserPatRepository.GetUserPat(GetBaseUserInfo().ID, param.PatId);
            //if (pubMapUserPat.Relation_Ship != 1)
            //{
            //    //修改就诊人关系
            //    pubMapUserPat.Relation_Ship = 1;
            //    _pubMapUserPatRepository.UpdatePubMapUserPat(pubMapUserPat);
            //}

            var aptusrn = _onlineAptInfoRepository.GetAptInfoForUsrn(param.AptUsrn);
            if (aptusrn.Any())
            {
                resu.Code = 0;
                if (language == 1)
                {
                    resu.Msg = "预约时间被占用，请选择其他预约时间";
                }
                else { resu.Msg = "Appointment time is occupied, please choose another appointment time"; }
                return resu;
            }
            param.ApplyUserId = GetBaseUserInfo() == null ? 0 : GetBaseUserInfo().ID;
            param.Status = 0;
            param.InnerStatus = 0;
            param.CreateTime = DateTime.Now;
            var id = _onlineAptInfoRepository.InsertOnlineApt(param);
            //TC锁号//(移至付款后)//又移到这里了,不要问为什么
            var res = _tCService.LockAptSave(param.AptUsrn, param.AptUsrn, "L");
            _logger.LogInformation("LockAptSave:" + param.AptUsrn + "--Mode: L " + res + "  paramAPTID " + param.Id);
            resu.Data = id;
            resu.Code = 1;
            resu.Msg = "";
            return resu;
        }

        public BaseResponse ConfirmPrescription(PrescriptionReq req)
        {
            BaseResponse res = new BaseResponse();
            var orderinfo = _onlineOrderRepository.GetOrderByNo(req.OutRecordNo);
            //先插处方详情表
            if (string.IsNullOrEmpty(req.PID) || req.PID == "P0")
            {
                var patinfo = _pubPatInfoRepository.SelectById(orderinfo.PatId);
                req.PatId = orderinfo.PatId;
                req.PatientBirthday = patinfo.Birthday;
            }
            else
            {
                var patinfo = _pubPatInfoRepository.SelectByMrn(req.PID);
                req.PatId = patinfo == null ? 0 : patinfo.Id;
                req.PatientBirthday = patinfo.Birthday;
            }
            req.DiagnosticInstructionsDetailStr = JsonConvert.SerializeObject(req.DiagnosticInstructionsDetail);
            var result = _prescriptionInfoRepository.InsertPrescriptionInfo(req);
            if (req.DrugList != null && req.DrugList.Count > 0)
            {
                DrugsInfo drug = null;
                foreach (var item in req.DrugList)
                {
                    drug = new DrugsInfo();
                    drug.Cnt = item.Cnt;
                    drug.DosageUnit = item.DosageUnit;
                    drug.DrugName = item.DrugName;
                    drug.DrugSpec = item.DrugSpec;
                    drug.Frequency = item.Frequency;
                    drug.PackageUnit = item.PackageUnit;
                    drug.PrescriptionNo = req.PrescriptionNo;
                    drug.SingleDosage = item.SingleDosage;
                    drug.Usage = item.Usage;
                    drug.UseDaySize = item.UseDaySize;
                    drug.UseInfo = item.UseInfo;
                    drug.UniqueCode = item.UniqueCode;
                    drug.PackageUnitCode = item.PackageUnitCode;
                    drug.FrequencyCode = item.FrequencyCode;
                    drug.DosageUnitCode = item.DosageUnitCode;
                    drug.UsageCode = item.UsageCode;
                    drug.Remark = item.Remark;
                    drug.UseDaySizeUnit = item.UseDaySizeUnit;
                    //再插处方 药表
                    _prescriptionInfoRepository.InsertPrescriptionDrug(drug);
                }
            }

            if (result > 0)
            {
                var mhelper = _sysRepository.GetSysHelpers("药助")?.FirstOrDefault();
                if (orderinfo.IsInsuranceUser)
                {
                    _onlineOrderRepository.UpdateOrder(orderinfo.OrderNo, 13);//保险下完处方单-->挂号订单 到 药房审核
                    _verifyCodeLogService.SendCignaSMS(mhelper.Phone, "您收到一笔新的互联网医院待审方订单，请及时处理(保险客户)");
                }
                else
                {
                    _zhuTongSMSService.SendSMS(mhelper.Phone, "您收到一笔新的互联网医院待审方订单，请及时处理", true);
                    var openHelperId = _pubUserInfoRepository.GetMHelper("药助");
                    if (!string.IsNullOrEmpty(openHelperId))
                    {
                        _pubMessageService.SendOnlineWxMsg(req.OutRecordNo, openHelperId, "您收到一笔新的互联网医院待审方订单，请及时处理", "请及时前往[互联网医院工作站]审核处方");
                    }
                }

                res.Code = 1;
                res.Msg = "操作成功";
            }
            return res;
        }

        public BaseResponse UpdatePrescription(string prescription)
        {
            BaseResponse res = new BaseResponse();
            var result = _prescriptionInfoRepository.UpdatePrescription(prescription);
            if (result > 0)
            {
                res.Code = 1;
                res.Msg = "操作成功";
            }
            return res;
        }

        public BaseResponse<int> UpdateAptStatus(int aptId, int status)
        {
            BaseResponse<int> response = new BaseResponse<int>();
            var aptInfo = _onlineAptInfoRepository.GetAptInfo(aptId);
            response.Data = _onlineAptInfoRepository.UpdateAptStatus(aptId, status);
            response.Msg = "成功";
            response.Code = 1;
            return response;
        }

        public BaseResponse<List<GetMyOnlineApt>> GetMyOnlineApt(int type, int language)
        {
            BaseResponse<List<GetMyOnlineApt>> response = new BaseResponse<List<GetMyOnlineApt>>();
            if (type == 1)
            {
                response.Data = _onlineAptInfoRepository.GetMyOnlineVideoApt(GetBaseUserInfo().ID, type, language);
                if (response.Data != null && response.Data.Count > 0)
                {
                    var msgList = _pubMessageInfoRepository.GetPatUnReadMsg(GetBaseUserInfo().ID);
                    foreach (var item in response.Data)
                    {
                        item.MsgCount = 0;
                        var count = msgList.FindAll(p => p.Pat_Id == item.PatId && p.Service_Id == item.DocId.ToString())?.Count;
                        if (count > 0)
                        {
                            item.MsgCount = count.ToInt();
                        }
                    }
                }

            }
            else
            {
                var data = _onlineAptInfoRepository.GetMyOnlineApt(GetBaseUserInfo().ID, type, language);
                var helper = _sysRepository.GetSysHelpers("医助")?.FirstOrDefault();
                foreach (var item in data)
                {
                    item.HelperIMID = helper.ImId;
                }
                response.Data = data;
            }
            //更新是否已读
            UpdatePubUserInfoIsRead(type);
            response.Data.ForEach(w =>
            {
                w.AptTimeStr = w.AptTime.ToString("yyyy-MM-dd HH:mm");

                //如果linking状态为进行中，预约状态为已确认，那么预约单状态改为就诊中
                if (w.LinKingAptStatus == 8 && (w.Status == 2 || w.Status == 4))
                {
                    w.Status = 6;
                }
            });
            response.Msg = "成功";
            response.Code = 1;
            return response;
        }

        public BaseResponse<List<GetMyOnlineAptNew>> GetMyOnlineAptNew(int language)
        {
            var user = GetBaseUserInfo();

            if (user == null)
            {
                return new BaseResponse<List<GetMyOnlineAptNew>>
                {
                    Data = new List<GetMyOnlineAptNew>(),
                    Code = 1,
                    Msg = "成功"
                };
            }

            user.Language = language;
            BaseResponse<List<GetMyOnlineAptNew>> res = new BaseResponse<List<GetMyOnlineAptNew>>();
            var data = _onlineAptInfoRepository.GetMyOnlineAptNew(user.ID);

            foreach (var item in data)
            {
                item.AptTimeStr = item.AptTime.ToString("yyyy-MM-dd HH:mm");
                if (item.Status == 6)
                {
                    if (user.Language == 1)
                    {
                        item.Describe = "医生正在接诊";
                    }
                    else { item.Describe = "Doctor Await"; }
                }
                else
                {
                    if (user.Language == 1)
                    {
                        item.Describe = "【" + item.AptTime.Month + "月" + item.AptTime.Day + "日" + " " + item.AptTime.Hour + ":" + item.AptTime.ToString("mm") + "】" + " 问诊即将开始";
                    }
                    else
                    {
                        item.Describe = "【" + item.AptTime.ToString("MM-dd HH:mm") + "】" + " Consultation will start soon";
                    }
                }
                if (item.AptType == 1 && item.IsRead == false)
                {
                    var msgList = _pubMessageInfoRepository.GetPatUnReadMsg(user.ID, item.DocId);
                    if (msgList != null && msgList.Count > 0)
                    {
                        item.IsRead = true;

                    }
                }
            }
            if (!data.Where(w => w.AptType == 1).Any())
            {
                if (user.Language == 1)
                {
                    data.Add(new ContractModel.App.GetMyOnlineAptNew { AptType = 1, Describe = "暂无新问诊" });
                }
                else
                {
                    data.Add(new ContractModel.App.GetMyOnlineAptNew { AptType = 1, Describe = "No New Consultation" });
                }
            }
            if (!data.Where(w => w.AptType == 2).Any())
            {
                if (user.Language == 1)
                {
                    data.Add(new ContractModel.App.GetMyOnlineAptNew { AptType = 2, Describe = "暂无新问诊" });
                }
                else
                {
                    data.Add(new ContractModel.App.GetMyOnlineAptNew { AptType = 2, Describe = "No New Consultation" });
                }
            }
            data = data.OrderByDescending(w => w.AptType).ToList();
            res.Data = data;
            res.Code = 1;
            res.Msg = "成功";
            return res;
        }


        public string GetAptUsrn(int aptId)
        {
            return _onlineAptInfoRepository.GetAptUsrn(aptId);
        }

        /// <summary>
        /// 修改用户是否已读
        /// 预约类型(1视频预约,2复诊开药)
        /// </summary>
        /// <returns></returns>
        public BaseResponse<bool> UpdatePubUserInfoIsRead(int type)
        {
            BaseResponse<bool> baseResponse = new BaseResponse<bool>();
            bool isOk = _onlineAptInfoRepository.UpdatePubUserInfoIsRead(GetBaseUserInfo().ID, false, type);
            baseResponse.Code = isOk ? 1 : 0;
            baseResponse.Data = isOk;
            return baseResponse;
        }

        public LinKongResponse LinKongOrderComment(LinKongOrderComment request)
        {
            LinKongResponse response = new LinKongResponse();
            var order = _onlineOrderRepository.GetOrderByNo(request.OutRecordNo);
            var pat = _pubPatInfoRepository.SelectById(order.PatId);
            var req = new OrderCommentReq
            {
                UserId = order.PatId,
                Comment = request.WenJuanJsonString.Text,
                DocId = order.DocId,
                IsAnonymous = false,
                OrderNo = order.OrderNo,
                Star = request.WenJuanJsonString.Scode,
                CreateUser = pat.Pat_Name
            };
            var inset = _onlineOrderRepository.CommentOrder(req);
            if (inset <= 0)
            {
                response.ResponseResult.IsSuccess = false;
                response.ResponseResult.Message = "评价失败";
            }
            return response;
        }

        public AptInfo CheckMySoonApt(int language)
        {
            AptInfo ret = new AptInfo();

            if (GetBaseUserInfo() == null)
            {
                return new AptInfo();
            }

            var apt = _onlineOrderRepository.CheckMySoonApt(GetBaseUserInfo().ID, language);
            if (apt != null)
            {
                var list = _dicDoctorRepository.GetAllOnlineDeptDocInfo();
                if (list != null && list.Count > 0)
                {
                    var video = list.Find(p => p.DocId == apt.DocId);
                    if (video != null)
                    {
                        apt.DeptName = language == 1 ? video.DeptNameCn : video.DeptNameEn;
                    }
                    apt.MinutesLeft = GetTimeDefMinutes(apt.AptTime, DateTime.Now);
                    ret = apt;
                }
            }
            var vaccApt = _pubPatInfoRepository.GetUserPatsVaccAptCount(GetBaseUserInfo().ID);
            if (vaccApt != null)
            {
                ret.VaccAptNotice = language == 1 ? "您登记排队的流感疫苗已经到苗可以预约了，请您在" + vaccApt.CreateTime.AddDays(2).ToString("yyyy-MM-dd HH:mm") + "前预约接种时间和门诊，并依据预约信息前往门诊进行接种。" : "Influenza vaccination is available for appointment now, please make the appointment of clinic and the time before " + vaccApt.CreateTime.AddDays(2).ToString("MM dd,yyyy HH:mm") + " . You can go to the clinic for vaccination at your appointed time.";
            }
            return ret;
        }

        /// <summary>
        /// a 是大时间
        /// </summary>
        /// <param name="timea"></param>
        /// <param name="timeb"></param>
        /// <returns></returns>
        private int GetTimeDefMinutes(DateTime timea, DateTime timeb)
        {
            if (timea < timeb)
            {
                return 0;
            }
            var minutesa = timea.Minute;
            var minutesb = timeb.Minute;
            if (minutesa >= minutesb)
            {
                return minutesa - minutesb;
            }
            else
            {
                return minutesa + 60 - minutesb;
            }
        }

        public string CheckMySoonPre(int language)
        {
            var ret = "";

            if (GetBaseUserInfo() == null)
            {
                return ret;
            }

            var preNo = _onlineOrderRepository.CheckMySoonPre(GetBaseUserInfo().ID);
            if (preNo != null)
            {
                ret = preNo;
            }
            return ret;
        }

        public bool AddLinKingIM(LinKingIMRequest request)
        {
            List<OnlineLinkingIM> model = new List<OnlineLinkingIM>();
            var PatId = 0;
            var DocId = 0;
            var order = _onlineOrderRepository.GetOrderByNo(request.OutTradeNo);
            if (order != null)
            {
                PatId = order.PatId;
                DocId = order.DocId;
            }
            foreach (var item in request.Content)
            {
                var content = item.TalkContent;
                if (item.MessageType.ToLower() == "attachment".ToLower())
                {
                    content = JsonConvert.SerializeObject(_fileService.DownLoadAliOSSFileSaveLocalAndDB(item.TalkContent, 4));
                }
                model.Add(new OnlineLinkingIM
                {
                    OrderNo = request.OutTradeNo,
                    PatId = PatId,
                    IsDoctor = item.IsDoctor,
                    Content = content,
                    MessageType = item.MessageType,
                    DocId = DocId,
                    TalkTime = item.TalkTime,
                    TalkName = item.TalkName
                });
            }
            var ret = _onlineLinKingIMrRepository.InsertLinKingIM(model);
            if (ret > 0)
            {
                return true;
            }
            return false;
        }

        public bool CheckAddPatForVaccine(string name)
        {
            var data = _pubPatInfoRepository.GetPubPatUserList(GetBaseUserInfo().ID, name);
            if (data.Where(w => w.Pat_Name.Replace(" ", "") == name.Replace(" ", "")).Any())
            // if (data.Any())
            {
                return false;
            }
            return true;
        }

        public List<Online_Evaluation> GetEvaluation()
        {
            return _onlineEvaluationRepository.GetEvaluation(GetBaseUserInfo().ID);
        }

        public int InsertEvaluation(Online_Evaluation model)
        {
            model.CreateTime = DateTime.Now;
            model.UserId = GetBaseUserInfo().ID;
            var res = _onlineEvaluationRepository.InsertEvaluation(model);
            return res;
        }
    }
}
