using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using Cmdjy.Bll;
using Cmdjy.Dal;
using CommonHelper;
using Newtonsoft.Json;
using WsdInterfaceModels;

namespace Cmdjy.Controllers
{
    public class WsdInterfaceController:ControllerBase
    {
        public Lazy<DjyDbContext> Db { get; set; }

        public ActionResult Index() {
            var model = new WsdRequest {
                StartNo = "0",MaxCount = "10",
                CompanyCode = "1",CompanyName = "万仕诚代煎药",
            };
            return PartialView(model);
        }

        public ActionResult GetData(WsdRequest info,string noDes,string needNull) {
            var result = new WsdResult {
                Code = EnumCode.Success,
            };
            string cKey = null;
            var db = this.Db.Value;
            var companyInfo = db.CompanyInfos.Where(m => m.Id.ToString() == info.CompanyCode);
            if(companyInfo.Any()) {
                cKey = companyInfo.First().SecurityKey;
            }
            if(string.IsNullOrEmpty(cKey)) {
                result.Code = EnumCode.Exception;
                result.Msg = "CompanyCode值错误或平台未注册该机构";
            }
            //获取数据
            int start = 0;
            if(!int.TryParse(info.StartNo,out start)) {
                result.Code = EnumCode.Exception;
                result.Msg = "Start值错误";
            }
            int count = 0;
            if(!int.TryParse(info.MaxCount,out count)) {
                result.Code = EnumCode.Exception;
                result.Msg = "MaxCount值错误";
            }
            if(count <= 0) {
                result.Code = EnumCode.Exception;
                result.Msg = "Count值错误。";
            }
            DateTime sd = DateTime.MinValue;
            if(!string.IsNullOrEmpty(info.StartDate) && !DateTime.TryParse(info.StartDate,out sd)) {
                result.Code = EnumCode.Exception;
                result.Msg = "StartDate值格式错误，请修改正确格式或不提供该值。";
            }
            sd = new DateTime(sd.Year,sd.Month,sd.Day,0,0,0);//起始时间
            int i = start;//起始编号
            int maxId = db.PrescriptionInfos.Max(m => m.Id);//最大Id
            count = Math.Min(WebSettings.WsdMaxCount,count);//最大获取数量
            result.MaxId = maxId.ToString();//处方最大Id
            result.Prescriptions = new List<WsdPrescriptionInfo>();
            var cache = CacheFactory.Cache;
            while(result.Code != EnumCode.Exception && i <= maxId && result.Prescriptions.Count < count) {
                var pkey = $"Company:Id:{info.CompanyCode}:Pre:Id:{i}";
                var one = cache.GetData<WsdPrescriptionInfo>(pkey);
                if(one == null) {
                    //从数据库获取处方信息
                    one = getPrescriptionInfoFromDb(info.CompanyCode,i);
                    //判断是否为
                    //获取药品信息
                    if(one != null) one.Drugs = getDrugInfoFromDb(one.Id);
                    //存缓存
                    if(one != null) cache.SetData(pkey,one);
                }
                if(one != null) {
                    //处方日期要大于起始日期
                    if(DateTime.TryParse(one.PrescriptionDatatime,out DateTime odt)) {
                        if(odt < sd) {
                            one = null;
                        }
                    }
                    else {
                        result.Code = EnumCode.Exception;
                        result.Msg = $"处方({i})中PrescriptionDatatime错误。";
                        break;
                    }
                }
                if(one != null) {
                    result.Prescriptions.Add(one);
                }
                i++;
            }
            if(result.Code != EnumCode.Exception) {
                result.Code = EnumCode.Success;
                result.Count = result.Prescriptions.Where(m => m.Type != WsdPrescriptionType.NullOrder).Count();
                result.Msg = "";
                result.More = db.PrescriptionInfos.Max(m => m.Id) > (start + count);
            }
            //编码：json串 +  加密信息
            if(noDes == null) {
                var resStr = JsonConvert.SerializeObject(result);
                var mw = DesHelper.GetHelper().Encrypty(cKey,resStr);
                logWsdRequest(info,result,resStr,mw);
                return Content(mw);
            }
            else {
                return Json(result,JsonRequestBehavior.AllowGet);
            }
        }
        /// <summary>
        /// 记录日志
        /// </summary>
        /// <param name="info">请求信息</param>
        /// <param name="result">响应对象</param>
        /// <param name="resStr">响应字符串</param>
        /// <param name="mw">响应密文</param>
        private void logWsdRequest(WsdRequest info,WsdResult result,string resStr,string mw) {
            var db = this.Db.Value;
            if(result != null && result.Prescriptions != null) {
                foreach(var p in result.Prescriptions) {
                    if(p.Drugs != null) {
                        foreach(var d in p.Drugs) {
                            db.WsdRequestLogs.Add(new Dal.Tables.WsdRequestLog {
                                StartNo = info.StartNo,MaxCount = info.MaxCount,
                                ClientAddress = Request.UserHostAddress,
                                LogDatatime = DateTime.Now,DrugId = d.Id.ToString(),
                                PrescriptionId = p.Id.ToString(),
                                Code = result.Code.ToString(),Msg = result.Msg,
                            });
                        }
                    }
                }
            }
            db.SaveChanges();
        }

        /// <summary>
        /// 从数据库获取药品列表
        /// </summary>
        /// <param name="id">处方号</param>
        private List<WsdDrugInfo> getDrugInfoFromDb(int id) {
            List<WsdDrugInfo> result = null;
            var db = this.Db.Value;
            var qu = db.DrugInfos.Where(m => m.PrescriptionId == id);
            if(qu.Any()) {
                result = new List<WsdDrugInfo>();
                foreach(var item in qu) {
                    var od = new WsdDrugInfo();
                    od.CopyFrom(item);
                    od.PrescriptionId = item.PrescriptionId.ToString();
                    result.Add(od);
                }
            }
            return result;
        }
        /// <summary>
        /// 从数据库获取处方
        /// </summary>
        /// <param name="i">处方号</param>
        private WsdPrescriptionInfo getPrescriptionInfoFromDb(string cId,int i) {
            WsdPrescriptionInfo result = null;
            var db = this.Db.Value;
            var qu = db.PrescriptionInfos
                .Where(m => m.Id == i && m.CompanyCode == cId)
                .Where(m => m.Type == Dal.Tables.PrescriptionType.Order || m.Type == Dal.Tables.PrescriptionType.CancelOrder);
            if(qu.Any()) {
                var fir = qu.First();
                result = new WsdPrescriptionInfo();
                result.CopyFrom(fir);
                result.Type =
                    fir.Type == Dal.Tables.PrescriptionType.Order ? WsdPrescriptionType.Order :
                    fir.Type == Dal.Tables.PrescriptionType.CancelOrder ? WsdPrescriptionType.CancelOrder :
                    fir.Type == Dal.Tables.PrescriptionType.TestOrder ? WsdPrescriptionType.TestOrder :
                    WsdPrescriptionType.NullOrder;
            }
            return result;
        }

    }
}