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

namespace Cmdjy.ws
{
    /// <summary>
    /// 万仕达，服务调用接口
    /// </summary>
    [WebService(Namespace = "http://Djy.wondersgroup.com/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    // 若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务，请取消注释以下行。 
    // [System.Web.Script.Services.ScriptService]
    public class WsdInterface:WebService
    {

        [WebMethod(Description = "获取代煎药处方信息")]
        public string GetData(WsdRequest info) {
            var result = new WsdResult {
                Code = EnumCode.Success,
            };
            string cKey = null;
            using(var db = DbContextFactory.CreateDbContext()) {
                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值错误。";
            }
            if(result.Code != EnumCode.Exception) {
                result.Prescriptions = new List<WsdPrescriptionInfo>();
                count = count > WebSettings.WsdMaxCount ? WebSettings.WsdMaxCount : count;
                var cache = CacheFactory.Cache;
                for(int i = start;i < start + count;i++) {
                    //从缓存获取
                    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) {
                        one = new WsdPrescriptionInfo {
                            Type = WsdPrescriptionType.NullOrder,Id = i,
                        };
                    }
                    result.Prescriptions.Add(one);
                }
                result.Code = EnumCode.Success;
                result.Count = result.Prescriptions.Where(m => m.Type != WsdPrescriptionType.NullOrder).Count();
                result.Msg = "";
                using(var db = DbContextFactory.CreateDbContext()) {
                    result.More = db.PrescriptionInfos.Max(m => m.Id) > (start + count);
                }
            }
            //编码：json串 +  加密信息
            try {
                var resStr = JsonConvert.SerializeObject(result);
                var mw = DesHelper.GetHelper().Encrypty(cKey,resStr);
                logWsdRequest(info,result,resStr,mw);
                return mw;
            }
            catch(Exception ex) {
                return ex.ToString();
            }
        }
        /// <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) {
            using(var db = DbContextFactory.CreateDbContext()) {
                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 = this.Context.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 static List<WsdDrugInfo> getDrugInfoFromDb(int id) {
            List<WsdDrugInfo> result = null;
            using(var db = DbContextFactory.CreateDbContext()) {
                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);
                        result.Add(od);
                    }
                }
            }
            return result;
        }
        /// <summary>
        /// 从数据库获取处方
        /// </summary>
        /// <param name="i">处方号</param>
        private static WsdPrescriptionInfo getPrescriptionInfoFromDb(string cId,int i) {
            WsdPrescriptionInfo result = null;
            using(var db = DbContextFactory.CreateDbContext()) {
                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);
                }
            }
            return result;
        }
    }

    /// <summary>
    /// 第三方请求数据
    /// </summary>
    public class WsdRequest
    {
        /// <summary>
        /// 代煎药厂商编码。
        /// </summary>
        public string CompanyCode { get; set; }
        /// <summary>
        /// 代煎药厂商名称
        /// </summary>
        public string CompanyName { get; set; }
        /// <summary>
        /// 处方起始流水号。按照数字从1开始累加。返回结果包含此编号的处方。
        /// </summary>
        public string StartNo { get; set; }
        /// <summary>
        /// 最大本次获取的处方数量。根据客户网络和服务器配置情况自行调整
        /// </summary>
        public string MaxCount { get; set; }
    }
    /// <summary>
    /// 服务器响应数据
    /// </summary>
    public class WsdResult
    {
        /// <summary>
        /// 返回信息代码
        /// </summary>
        public EnumCode Code { get; set; }
        /// <summary>
        /// 返回信息
        /// </summary>
        public string Msg { get; set; }
        /// <summary>
        /// 本次发送的处方数
        /// </summary>
        public int Count { get; set; }
        /// <summary>
        /// 是否还有处方未下载。不已历史是否下载为准，只计算此次下载后是否剩余未下载。
        /// </summary>
        public bool More { get; set; }
        /// <summary>
        /// 处方信息
        /// </summary>
        public List<WsdPrescriptionInfo> Prescriptions { get; set; }
    }

    /// <summary>
    /// 返回信息代码
    /// </summary>
    [Flags]
    public enum EnumCode
    {
        /// <summary>
        /// 执行成功。
        /// </summary>
        Success = 1,
        /// <summary>
        /// 发生异常，异常信息见msg参数。
        /// </summary>
        Exception = 2,
    }

    /// <summary>
    /// 处方信息
    /// </summary>
    public class WsdPrescriptionInfo
    {
        /// <summary>
        /// 处方流水号
        /// </summary>
        public int Id { get; set; }
        /// <summary>
        /// 处方类型
        /// </summary>
        public WsdPrescriptionType Type { get; set; }
        /// <summary>
        /// 如果为退方，这里传要退的处方流水号。此编号在下单应答消息中提供
        /// </summary>
        public string RawRecordId { get; set; }
        /// <summary>
        /// 药品明细数量
        /// </summary>
        public string DrugCount { get; set; }
        /// <summary>
        /// 处方备注
        /// </summary>
        public string Remark { get; set; }
        /// <summary>
        /// 带回病房 否
        /// </summary>
        public string TakeBack { get; set; }
        /// <summary>
        /// "操作类型": "煎药自取", or "操作类型": "煎药快递", or "操作类型": "配药快递"
        /// </summary>
        public string OpType { get; set; }
        /// <summary>
        /// 操作员
        /// </summary>
        public string OpUser { get; set; }
        /// <summary>
        /// 病区
        /// </summary>
        public string Area { get; set; }
        /// <summary>
        /// 病床号
        /// </summary>
        public string Bed { get; set; }
        /// <summary>
        /// 操作时间
        /// </summary>
        public string OpDatatime { get; set; }
        /// <summary>
        /// 处方号
        /// </summary>
        public string PrescriptionNo { get; set; }
        /// <summary>
        /// 处方日期
        /// </summary>
        public string PrescriptionDatatime { get; set; }
        /// <summary>
        /// 单位编号 医疗机构编号
        /// </summary>
        public string HosNo { get; set; }
        /// <summary>
        /// 医疗机构名称
        /// </summary>
        public string HosName { get; set; }
        /// <summary>
        /// 发票号
        /// </summary>
        public string InvoiceNo { get; set; }
        /// <summary>
        /// 病人编号
        /// </summary>
        public string PatientNo { get; set; }
        /// <summary>
        /// 病人卡号
        /// </summary>
        public string CardNo { get; set; }
        /// <summary>
        /// 科室名称
        /// </summary>
        public string DepName { get; set; }
        /// <summary>
        /// 病人年龄
        /// </summary>
        public string PatientAge { get; set; }
        /// <summary>
        /// 病人生日
        /// </summary>
        public string PatientBrithday { get; set; }
        /// <summary>
        /// 病人手机号码
        /// </summary>
        public string PatientMobile { get; set; }
        /// <summary>
        /// 病人电话
        /// </summary>
        public string PatientPhone { get; set; }
        /// <summary>
        /// 所在区县街道
        /// </summary>
        public string District { get; set; }
        /// <summary>
        /// 送货地址
        /// </summary>
        public string PostAddress { get; set; }
        /// <summary>
        /// 送货时间
        /// </summary>
        public string PostDatatime { get; set; }
        /// <summary>
        /// 贴数
        /// </summary>
        public string UseCount { get; set; }
        /// <summary>
        /// 病人性别
        /// </summary>
        public string PatientSex { get; set; }
        /// <summary>
        /// 病人姓名
        /// </summary>
        public string PatientName { get; set; }
        /// <summary>
        /// 医生姓名
        /// </summary>
        public string DoctorName { get; set; }
        /// <summary>
        /// 诊断
        /// </summary>
        public string Diagnosis { get; set; }
        /// <summary>
        /// 用法
        /// </summary>
        public string Usage { get; set; }
        /// <summary>
        /// 治疗号
        /// </summary>
        public string Zlh { get; set; }
        /// <summary>
        /// 收费序号
        /// </summary>
        public int Sfxh { get; set; }
        /// <summary>
        /// 收费费用序号
        /// </summary>
        public string Sffyxh { get; set; }
        /// <summary>
        /// 处方对应药品
        /// </summary>
        public List<WsdDrugInfo> Drugs { get; set; }
    }

    /// <summary>
    /// 药品信息
    /// </summary>
    public class WsdDrugInfo
    {
        /// <summary>
        /// 药品流水号
        /// </summary>
        public int Id { get; set; }
        /// <summary>
        /// 处方流水号
        /// </summary>
        public string PrescriptionId { get; set; }
        /// <summary>
        /// "药品医保代码":"YP0306401000650",
        /// </summary>
        public string DrugNo { get; set; }
        /// <summary>
        /// 药品单价 0.085
        /// </summary>
        public string Price { get; set; }
        /// <summary>
        /// 单贴数量
        /// </summary>
        public string Count { get; set; }
        /// <summary>
        /// 单位 克
        /// </summary>
        public string Unit { get; set; }
        /// <summary>
        /// 单项总价
        /// </summary>
        public string Sum { get; set; }
        /// <summary>
        /// 规格  15.00000000
        /// </summary>
        public string DrugType { get; set; }
        /// <summary>
        /// 药品编码
        /// </summary>
        public string DrugLocalNo { get; set; }
        /// <summary>
        /// 药品名称
        /// </summary>
        public string DrugName { get; set; }
        /// <summary>
        /// 特殊要求
        /// </summary>
        public string Remark { get; set; }
    }

    /// <summary>
    /// 处方类型
    /// </summary>
    [Flags]
    public enum WsdPrescriptionType
    {
        /// <summary>
        /// 订单
        /// </summary>
        Order = 1,
        /// <summary>
        /// 撤销订单，退单
        /// </summary>
        CancelOrder = 2,
        /// <summary>
        /// 测试方。无效处方，测试用
        /// </summary>
        TestOrder = 4,
        /// <summary>
        /// 空处方，无此处方，调用方应该跳过该处方
        /// </summary>
        NullOrder = 8,
    }

}
