using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Transactions;
using System.Data;
using System.Data.Common;
using IL.Common;
using System.Xml;
using Microsoft.Practices.EnterpriseLibrary.Data;

namespace MediII.Adapter.BizComponent.ADT
{
    /// <summary>
    /// 门诊就诊记录
    /// </summary>
    public class ADT_A02B01_Handler : ADTHandler
    {
        public override void Handler(string m, string ID)
        {
            var isql = @"insert into dbo.zhuyuan_original(No,patient_zyh,patient_id,RY_DATE,RY_UNIT,RY_BQ,RY_BED,CY_DATE,CY_UNIT,CY_BQ,age,patient_name,Sex,address,JG_DOCT_GH,SZ_DOCT_GH,Nurse_grade,ICD_CODE_RY1,ICD_CODE_RY2,ICD_CODE_RY3,ICD_CODE_RY4,ICD_CODE_CY1,ICD_CODE_CY2,ICD_CODE_CY3,ICD_CODE_CY4,CY_Kind) Value();";

            
           
            //初始化
            var rtnMsg = string.Empty;
            var msgHead = string.Empty;
            var msgBody = string.Empty;
            var resultCode = string.Empty;
            var result = string.Empty;
            WebService server = new WebService();
            OperateXmlUtil xmlHelper = new OperateXmlUtil();
            //读取配置的凭证号
            var cert = System.Configuration.ConfigurationManager.AppSettings["cert"];
            //读取就诊流水号
            //string visitNo = xmlHelper.XpathRead(m, "//*[@root='2.16.156.10011.2.5.1.9']", "extension");
            string visitNo = m;
            //拼接接口访问参数
            msgBody = xmlHelper.GetMsgBody(visitNo);
            msgHead = xmlHelper.GetMsgHead("getInHospitalInfo", cert);
            //接口访问
            rtnMsg = server.TestInterface(msgHead, msgBody);
            //存储访问记录
            MessageHelper.SaveSendMsg(Scanctx, ID, "ADT^A02[B01]", msgHead, msgBody, rtnMsg);
            //消息判断是否成功
            if (!xmlHelper.isSuccess(rtnMsg, ref resultCode, ref result))
            {
                //存储访问记录

                throw new Exception(result);
            }

            //更新发送表，保存留档

            //返回数据解析
            XmlNode root = xmlHelper.GetContentRootNode(rtnMsg);
            XmlNodeList list = root.SelectNodes("//returnContents//returnContent");
            if (list.Count <= 0)
                return;
            /* 获取档案，如果存在出院日，再判断是否有相关消息任务进行中，如有，则不操作，如果没有，插入任务，同时更新档案
               Todo:
             * 1、判断出院日
             * 2、判断是否有相关任务进行中
             * 3、插入医嘱任务、插入费用任务
             * 4、更新档案
             */

            //是否出院
            string CheckOutDate = root.SelectSingleNode("//*[name()='CY_DATE']").InnerText;

            if (!string.IsNullOrWhiteSpace(CheckOutDate))
            {
                try
                {
                    DateTime OutDate = DateTime.Parse(CheckOutDate);
                    if (OutDate < DateTime.Parse("2010-01-01") && OutDate > DateTime.Parse("2050-01-01"))
                    {
                        return;//返回,本次不解析
                    }
                }
                catch
                {
                    return;
                }
            }
            else
            {
                return;
            }
            //入院日期
            string CheckInDate = root.SelectSingleNode("//*[name()='RY_DATE']").InnerText;

            int num = GetOriginalCount(visitNo);
            using (TransactionScope scope = new TransactionScope(TransactionScopeOption.RequiresNew))
            {
                if (num <= 0)
                {
                    var ifsql = @"insert into dbo.zhuyuan_original(patient_zyh,patient_id,RY_DATE,RY_UNIT,RY_BQ,RY_BED,CY_DATE,CY_UNIT,CY_BQ,age,patient_name,Sex,address,JG_DOCT_GH,SZ_DOCT_GH,Nurse_grade,ICD_CODE_RY1,ICD_CODE_RY2,ICD_CODE_RY3,ICD_CODE_RY4,ICD_CODE_CY1,ICD_CODE_CY2,ICD_CODE_CY3,ICD_CODE_CY4,CY_Kind) Values(
@patient_zyh,@patient_id,@RY_DATE,@RY_UNIT,@RY_BQ,@RY_BED,@CY_DATE,@CY_UNIT,@CY_BQ,@age,@patient_name,@Sex,@address,@JG_DOCT_GH,@SZ_DOCT_GH,@Nurse_grade,@ICD_CODE_RY1,@ICD_CODE_RY2,@ICD_CODE_RY3,@ICD_CODE_RY4,@ICD_CODE_CY1,@ICD_CODE_CY2,@ICD_CODE_CY3,@ICD_CODE_CY4,@CY_Kind)";
                    //住院患者基本档
                    foreach (XmlElement xn in list)
                    {
                        var icmd = ctx.DBGetSqlStringCommand(ifsql);
                        SetEntity(ctx, icmd, xn);
                        SqlDataAccess.ExecuteNonQuery(ctx, icmd);
                    }
                }
                else
                {
                    var usql = @"update dbo.zhuyuan_original set RY_DATE=@RY_DATE,
RY_UNIT=@RY_UNIT,
RY_BQ=@RY_BQ,
RY_BED=@RY_BED,
CY_DATE=@CY_DATE,
CY_UNIT=@CY_UNIT,
CY_BQ=@CY_BQ,
age=@age,
patient_name=@patient_name,
Sex=@Sex,
address=@address,
JG_DOCT_GH=@JG_DOCT_GH,
SZ_DOCT_GH=@SZ_DOCT_GH,
Nurse_grade=@Nurse_grade,
ICD_CODE_RY1=@ICD_CODE_RY1,
ICD_CODE_RY2=@ICD_CODE_RY2,
ICD_CODE_RY3=@ICD_CODE_RY3,
ICD_CODE_RY4=@ICD_CODE_RY4,
ICD_CODE_CY1=@ICD_CODE_CY1,
ICD_CODE_CY2=@ICD_CODE_CY2,
ICD_CODE_CY3=@ICD_CODE_CY3,
ICD_CODE_CY4=@ICD_CODE_CY4,
CY_Kind=@CY_Kind where patient_zyh=@patient_zyh and patient_id=@patient_id";
                    foreach (XmlElement xn in list)
                    {
                        var ucmd = ctx.DBGetSqlStringCommand(usql);
                        SetEntity(ctx, ucmd, xn);
                        SqlDataAccess.ExecuteNonQuery(ctx, ucmd);
                    }
                }
                var sql = @"INSERT INTO HL7_Platform.dbo.HL7_Scan  (ID ,ChartNo,VisitNo,OtherNo1,OtherNo2,OtherNo3,OtherName ,  TaskType ,  TaskStatus ,  UpdateUser ,  UpdateTime,Reserve1) VALUES (@ID ,@ChartNo ,@VisitNo ,@OtherNo1 ,  @OtherNo2 ,@OtherNo3 ,@OtherName ,@TaskType ,@TaskStatus , @UpdateUser , GETDATE(),@Reserve1)";
                if (GetScanTaskCount(visitNo, "ADT^A01[B02]") <= 0)
                {
                    //住院处方单
                    var ccmd = Scanctx.DBGetSqlStringCommand(sql);
                    SqlDataAccess.AddInParameter(Scanctx, ccmd, "ID", DbType.AnsiString, Guid.NewGuid().ToString());
                    SqlDataAccess.AddInParameter(Scanctx, ccmd, "ChartNo", DbType.AnsiString, visitNo);
                    SqlDataAccess.AddInParameter(Scanctx, ccmd, "VisitNo", DbType.AnsiString, visitNo);
                    SqlDataAccess.AddInParameter(Scanctx, ccmd, "OtherNo1", DbType.AnsiString, CheckOutDate);
                    SqlDataAccess.AddInParameter(Scanctx, ccmd, "OtherNo2", DbType.AnsiString, "");
                    SqlDataAccess.AddInParameter(Scanctx, ccmd, "OtherNo3", DbType.AnsiString, "");
                    SqlDataAccess.AddInParameter(Scanctx, ccmd, "OtherName", DbType.AnsiString, "住院处方单");
                    SqlDataAccess.AddInParameter(Scanctx, ccmd, "TaskType", DbType.AnsiString, "ADT^A01[B02]");
                    SqlDataAccess.AddInParameter(Scanctx, ccmd, "TaskStatus", DbType.Int32, 1);
                    SqlDataAccess.AddInParameter(Scanctx, ccmd, "UpdateUser", DbType.AnsiString, "9999");
                    SqlDataAccess.AddInParameter(Scanctx, ccmd, "Reserve1", DbType.AnsiString, "");
                    SqlDataAccess.ExecuteNonQuery(Scanctx, ccmd);
                }
                if (GetScanTaskCount(visitNo, "ADT^A01[B03]") <= 0)
                {
                    //住院收费数据明细
                    var fcmd = Scanctx.DBGetSqlStringCommand(sql);
                    SqlDataAccess.AddInParameter(Scanctx, fcmd, "ID", DbType.AnsiString, Guid.NewGuid().ToString());
                    SqlDataAccess.AddInParameter(Scanctx, fcmd, "ChartNo", DbType.AnsiString, visitNo);
                    SqlDataAccess.AddInParameter(Scanctx, fcmd, "VisitNo", DbType.AnsiString, visitNo);
                    SqlDataAccess.AddInParameter(Scanctx, fcmd, "OtherNo1", DbType.AnsiString, CheckOutDate);
                    SqlDataAccess.AddInParameter(Scanctx, fcmd, "OtherNo2", DbType.AnsiString, "");
                    SqlDataAccess.AddInParameter(Scanctx, fcmd, "OtherNo3", DbType.AnsiString, "");
                    SqlDataAccess.AddInParameter(Scanctx, fcmd, "OtherName", DbType.AnsiString, "住院收费数据明细");
                    SqlDataAccess.AddInParameter(Scanctx, fcmd, "TaskType", DbType.AnsiString, "ADT^A01[B03]");
                    SqlDataAccess.AddInParameter(Scanctx, fcmd, "TaskStatus", DbType.Int32, 1);
                    SqlDataAccess.AddInParameter(Scanctx, fcmd, "UpdateUser", DbType.AnsiString, "9999");
                    SqlDataAccess.AddInParameter(Scanctx, fcmd, "Reserve1", DbType.AnsiString, "");
                    SqlDataAccess.ExecuteNonQuery(Scanctx, fcmd);
                }
                if (GetScanTaskCount(visitNo, "ADT^A01[B04]") <= 0)
                {
                    //住院收费数据明细
                    var fcmd = Scanctx.DBGetSqlStringCommand(sql);
                    SqlDataAccess.AddInParameter(Scanctx, fcmd, "ID", DbType.AnsiString, Guid.NewGuid().ToString());
                    SqlDataAccess.AddInParameter(Scanctx, fcmd, "ChartNo", DbType.AnsiString, visitNo);
                    SqlDataAccess.AddInParameter(Scanctx, fcmd, "VisitNo", DbType.AnsiString, visitNo);
                    SqlDataAccess.AddInParameter(Scanctx, fcmd, "OtherNo1", DbType.AnsiString, CheckOutDate);
                    SqlDataAccess.AddInParameter(Scanctx, fcmd, "OtherNo2", DbType.AnsiString, "");
                    SqlDataAccess.AddInParameter(Scanctx, fcmd, "OtherNo3", DbType.AnsiString, "");
                    SqlDataAccess.AddInParameter(Scanctx, fcmd, "OtherName", DbType.AnsiString, "住院转科转床");
                    SqlDataAccess.AddInParameter(Scanctx, fcmd, "TaskType", DbType.AnsiString, "ADT^A01[B04]");
                    SqlDataAccess.AddInParameter(Scanctx, fcmd, "TaskStatus", DbType.Int32, 1);
                    SqlDataAccess.AddInParameter(Scanctx, fcmd, "UpdateUser", DbType.AnsiString, "9999");
                    SqlDataAccess.AddInParameter(Scanctx, fcmd, "Reserve1", DbType.AnsiString, "");
                    SqlDataAccess.ExecuteNonQuery(Scanctx, fcmd);
                }
                scope.Complete(); 
            }


        }

        /// <summary>
        /// 获取门诊就诊次数
        /// </summary> 
        /// <returns></returns>
        private int GetOutNumByChartNo(string chartNo)
        {

            string OutPatientSql = @"select count(1)	 
                                             from HealthCare.dbo.OutPatient a, HealthCare.dbo.VisitRecord b	 
                                             where a.VisitNo = b.VisitNo  AND b.ChartNo= @ChartNo  
                                             AND a.VisitStatus<>'D'  ";
            var cmd = SqlDataAccess.GetSqlStringCommand(ctx, OutPatientSql);
            SqlDataAccess.AddInParameter(ctx, cmd, "ChartNo", DbType.AnsiString, chartNo);
            return int.Parse(StrHelepr.Obj2StrTrim(SqlDataAccess.ExecuteScalar(ctx, cmd)));  //看诊次数 

        }

        /// <summary>
        /// 获取急诊就诊次数
        /// </summary> 
        /// <returns></returns>
        private int GetEmgNumByChartNo(string chartNo)
        {
            string EmgPatientSql = @"select count(1) from HealthCare.dbo.Emergency a, HealthCare.dbo.VisitRecord b	 
                                             where a.VisitNo = b.VisitNo  
                                             AND b.ChartNo= @ChartNo   AND a.VisitStatus<>'D'  ";
            var cmd = SqlDataAccess.GetSqlStringCommand(ctx, EmgPatientSql);
            SqlDataAccess.AddInParameter(ctx, cmd, "ChartNo", DbType.AnsiString, chartNo);
            return int.Parse(StrHelepr.Obj2StrTrim(SqlDataAccess.ExecuteScalar(ctx, cmd)));   //看诊次数 

        }
        private void SetEntity(Database ctx, DbCommand icmd, XmlElement xn)
        {
            SqlDataAccess.AddInParameter(Scanctx, icmd, "patient_zyh", DbType.AnsiString, xn.SelectSingleNode("patient_zyh").InnerText);
            SqlDataAccess.AddInParameter(Scanctx, icmd, "patient_id", DbType.AnsiString, xn.SelectSingleNode("patient_id").InnerText);
            SqlDataAccess.AddInParameter(Scanctx, icmd, "RY_DATE", DbType.AnsiString, xn.SelectSingleNode("RY_DATE").InnerText);
            SqlDataAccess.AddInParameter(Scanctx, icmd, "RY_UNIT", DbType.AnsiString, xn.SelectSingleNode("RY_UNIT").InnerText);
            SqlDataAccess.AddInParameter(Scanctx, icmd, "RY_BQ", DbType.AnsiString, xn.SelectSingleNode("RY_BQ").InnerText);
            SqlDataAccess.AddInParameter(Scanctx, icmd, "RY_BED", DbType.AnsiString, xn.SelectSingleNode("RY_BED").InnerText);
            SqlDataAccess.AddInParameter(Scanctx, icmd, "CY_DATE", DbType.AnsiString, xn.SelectSingleNode("CY_DATE").InnerText);
            SqlDataAccess.AddInParameter(Scanctx, icmd, "CY_UNIT", DbType.AnsiString, xn.SelectSingleNode("CY_UNIT").InnerText);
            SqlDataAccess.AddInParameter(Scanctx, icmd, "CY_BQ", DbType.AnsiString, xn.SelectSingleNode("CY_BQ").InnerText);
            SqlDataAccess.AddInParameter(Scanctx, icmd, "age", DbType.AnsiString, xn.SelectSingleNode("age").InnerText);
            SqlDataAccess.AddInParameter(Scanctx, icmd, "patient_name", DbType.AnsiString, xn.SelectSingleNode("patient_name").InnerText);
            SqlDataAccess.AddInParameter(Scanctx, icmd, "Sex", DbType.AnsiString, xn.SelectSingleNode("Sex").InnerText);
            SqlDataAccess.AddInParameter(Scanctx, icmd, "address", DbType.AnsiString, xn.SelectSingleNode("address").InnerText);
            SqlDataAccess.AddInParameter(Scanctx, icmd, "JG_DOCT_GH", DbType.AnsiString, xn.SelectSingleNode("JG_DOCT_GH").InnerText);
            SqlDataAccess.AddInParameter(Scanctx, icmd, "SZ_DOCT_GH", DbType.AnsiString, xn.SelectSingleNode("SZ_DOCT_GH").InnerText);
            SqlDataAccess.AddInParameter(Scanctx, icmd, "Nurse_grade", DbType.AnsiString, xn.SelectSingleNode("Nurse_grade").InnerText);
            SqlDataAccess.AddInParameter(Scanctx, icmd, "ICD_CODE_RY1", DbType.AnsiString, xn.SelectSingleNode("ICD_CODE_RY1").InnerText);
            SqlDataAccess.AddInParameter(Scanctx, icmd, "ICD_CODE_RY2", DbType.AnsiString, xn.SelectSingleNode("ICD_CODE_RY2").InnerText);
            SqlDataAccess.AddInParameter(Scanctx, icmd, "ICD_CODE_RY3", DbType.AnsiString, xn.SelectSingleNode("ICD_CODE_RY3").InnerText);
            SqlDataAccess.AddInParameter(Scanctx, icmd, "ICD_CODE_RY4", DbType.AnsiString, xn.SelectSingleNode("ICD_CODE_RY4").InnerText);
            SqlDataAccess.AddInParameter(Scanctx, icmd, "ICD_CODE_CY1", DbType.AnsiString, xn.SelectSingleNode("ICD_CODE_CY1").InnerText);
            SqlDataAccess.AddInParameter(Scanctx, icmd, "ICD_CODE_CY2", DbType.AnsiString, xn.SelectSingleNode("ICD_CODE_CY2").InnerText);
            SqlDataAccess.AddInParameter(Scanctx, icmd, "ICD_CODE_CY3", DbType.AnsiString, xn.SelectSingleNode("ICD_CODE_CY3").InnerText);
            SqlDataAccess.AddInParameter(Scanctx, icmd, "ICD_CODE_CY4", DbType.AnsiString, xn.SelectSingleNode("ICD_CODE_CY4").InnerText);
            SqlDataAccess.AddInParameter(Scanctx, icmd, "CY_Kind", DbType.AnsiString, xn.SelectSingleNode("CY_Kind").InnerText);
        }
    }
}
