using MediII.Adapter.ReceiveToKCModel;
using MediII.Adapter.Scanner;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Practices.EnterpriseLibrary.Data;
using NHapi.Base.Parser;
using MediII.Adapter.BizComponent.Base;
using System.Data;
using System.Diagnostics;
using IL.Common;

namespace MediII.Adapter.BizComponent.UE
{
    public abstract class DefaultDBScanner : DBScaner
    {
        private int SearchNum
        {
            get
            {
                var searchNum = System.Configuration.ConfigurationManager.AppSettings["SearchNum"];
                int num = 0;
                if (!int.TryParse(searchNum, out num))
                {
                    num = 10;
                }
                return num;
            }
        }
        /// <summary>
        /// 门诊定时类型，0=正常；>0  隔N天
        /// </summary>
        private int OutSearchType
        {
            get
            {
                var type = System.Configuration.ConfigurationManager.AppSettings["OutSearchType"];
                int rtn = 0;
                if (!int.TryParse(type, out rtn))
                {
                    rtn = 0;
                }
                return rtn;
            }
        }

        private int DFTSearchType
        {
            get
            {
                var type = System.Configuration.ConfigurationManager.AppSettings["DFTSearchType"];
                int rtn = 30;
                if (!int.TryParse(type, out rtn))
                {
                    rtn = 30;
                }
                return rtn;
            }
        }
        /// <summary>
        /// 住院定时类型，0=正常；>0 隔N天
        /// </summary>
        private int InSearchType
        {
            get
            {
                var type = System.Configuration.ConfigurationManager.AppSettings["InSearchType"];
                int rtn = 0;
                if (!int.TryParse(type, out rtn))
                {
                    rtn = 0;
                }
                return rtn;
            }
        }

        protected override long OnDo(DateTime dtEventTime, Action<LogModel> setLog)
        {

            Stopwatch stopwatch = new Stopwatch();


            var type = GetMessageType();
            stopwatch.Start();
            try
            {

                if (setLog != null)
                    setLog(new LogModel { Message = "开始一次消息处理扫描 消息类型:" + type });

                if (type == "DFT^B01") //字典解析
                {
                    var sql = @" SELECT ID,SeqNo,ChartNo,VisitNo,OtherNo1,OtherNo2,OtherNo3,OtherName,TaskType,TaskStatus,
              UpdateUser,UpdateTime,Reserve1,Reserve2,Reserve3,IP,MAC,BeginTime,EndTime,Result,TaskMsg,ResultTime
              FROM dbo.HL7_Scan WITH(NOLOCK)  
              WHERE TaskStatus=1 AND TaskType='{0}' AND OtherNo1 <=(GETDATE()-{1})
              ORDER BY SeqNo ASC";

                    sql = string.Format(sql, type, DFTSearchType);
                    try
                    {
                        var listRow = SqlDataAccess.ExecuteSqlStringAccessor<HL7_ScanEntity>(ctx, sql).Take(1).ToList();
                        if (listRow.Count() > 0)
                        {
                            Process(listRow, setLog, type);
                        }
                    }
                    catch (Exception ex)
                    {
                        LogHelper.LogError(ex, LogCatagories.AdapterScan);
                        throw ex;
                    }
                }
                else
                {
                    RunExec(type, setLog);
                } 
            }
            finally
            {
                stopwatch.Stop();

                //LogHelper.LogError(string.Format("{0}耗时{1}-->{2}", type, stopwatch.Elapsed, stopwatch.ElapsedTicks), LogCatagories.AdapterScan);
            }

            return 1;
        }

        private void RunExec(string type, Action<LogModel> setLog)
        {
            var num = SearchNum;
            var orderSeq = string.Empty;
            var timeSeq = string.Empty;
            if (type == "MFN")
            {
                orderSeq = " Sequeue ASC,";
            }
            if (type.Substring(0, 7) == "ADT^A01" || type.Substring(0, 7) == "ADT^A02")
            {
                if (InSearchType > 0)
                {
                    timeSeq = string.Format(" AND OtherNo1 <=(GETDATE()-{0})", InSearchType);
                }
            }
            if (type.Substring(0, 7) == "ADT^A04" || type.Substring(0, 7) == "ADT^A05")
            {
                if (OutSearchType > 0)
                {
                    timeSeq = string.Format(" AND OtherNo1 <=(GETDATE()-{0})", OutSearchType);
                }
            }
            //var sql = @"SELECT top {0} ID , SeqNo , SourceID ,MsgConID ,  MsgContent ,ReplyMsg ,   ReceivingTime ,       IP ,TaskStatus ,StartTime ,EndTime ,TaskIP , TaskMac ,TaskMsg ,MessageID ,MessageType ,Remark ,Sequeue  FROM dbo.HL7_Receive WITH(NOLOCK)  WHERE TaskStatus='1' and MessageID='{1}' ORDER BY {2} SeqNo ASC ";
            var sql = @" SELECT TOP {0} ID,SeqNo,ChartNo,VisitNo,OtherNo1,OtherNo2,OtherNo3,OtherName,TaskType,TaskStatus,
              UpdateUser,UpdateTime,Reserve1,Reserve2,Reserve3,IP,MAC,BeginTime,EndTime,Result,TaskMsg,ResultTime
              FROM dbo.HL7_Scan WITH(NOLOCK)  
              WHERE TaskStatus=1 AND IP IS null  AND MAC IS NULL AND TaskType='{1}'  {3}
              ORDER BY {2} SeqNo ASC";

            sql = string.Format(sql, num, type, orderSeq, timeSeq);
            try
            {
                var listRow = SqlDataAccess.ExecuteSqlStringAccessor<HL7_ScanEntity>(ctx, sql).Take(num).ToList();
                if (listRow.Count() > 0)
                {
                    Process(listRow, setLog, type);
                }
            }
            catch (Exception ex)
            {
                LogHelper.LogError(ex, LogCatagories.AdapterScan);
                throw ex;
            }
        }

        private void Process(IEnumerable<HL7_ScanEntity> listRow, Action<LogModel> setLog,string msgType)
        {
            listRow.ToList().ForEach(o =>
            {

                //验证
                var model = GetListRow(o.ID);
                if (null != model)
                {
                    try
                    {
                        if (setLog != null)
                            setLog(new LogModel { Message = o.VisitNo, MessageID = o.TaskType });


                        SetStartBiz(o.ID);
                        //PipeParser parser = new PipeParser();
                        //string mesStruct = parser.GetMessageStructure(o.MsgContent).Substring(0, 3);

                        //var behavior = BizComponentFactory.GetBizComponent(mesStruct);
                        var behavior = BizComponentFactory.GetBizComponent(msgType.Substring(0,msgType.IndexOf('^')));
                        var errMsg = behavior.Process(o.VisitNo, o.TaskType,o.ID);
                        SetEndBiz(o.ID, errMsg);

                    }
                    catch (Exception ex)
                    {
                        if (setLog != null)
                            setLog(new LogModel { Message = o.VisitNo, MessageID = o.TaskType, ErrorMsg = "消息处理错误 :" + ex.Message });
                        SetEndBiz(o.ID, ex.Message);
                    }

                }
            });
        }


        /// <summary>
        /// 获取消息类型
        /// </summary>
        /// <returns></returns>
        protected abstract string GetMessageType();



        /// <summary>
        /// 获取当前记录
        /// </summary>
        /// <param name="id">id</param>
        /// <returns></returns>
        protected HL7_ScanEntity GetListRow(string id)
        {
            var sql = "SELECT *  FROM dbo.HL7_Scan  WHERE TaskStatus='1'  and ID='" + id + "'";
            var model = SqlDataAccess.ExecuteSqlStringAccessor<HL7_ScanEntity>(ctx, sql).Take(1).FirstOrDefault();
            return model;

        }


        //开始时间
        protected int SetStartBiz(string id)
        {
            var sql = "UPDATE dbo.HL7_Scan SET BeginTime=GETDATE() , TaskStatus='2',IP=@TaskIP,Mac=@TaskMac WHERE  ID=@ID";
            var cmd = SqlDataAccess.GetSqlStringCommand(ctx, sql);
            SqlDataAccess.AddInParameter(ctx, cmd, "ID", DbType.String, id);
            SqlDataAccess.AddInParameter(ctx, cmd, "TaskIP", DbType.String, NetHelper.GetIP());
            SqlDataAccess.AddInParameter(ctx, cmd, "TaskMac", DbType.String, NetHelper.GetMacAddress());
            return SqlDataAccess.ExecuteNonQuery(ctx, cmd);
        }


        //结束时间
        protected int SetEndBiz(string id, string errMsg)
        {
            var sql = "UPDATE dbo.HL7_Scan SET EndTime=GETDATE(),TaskStatus=@TaskStatus,TaskMsg=@TaskMsg WHERE  ID=@ID";
            var cmd = SqlDataAccess.GetSqlStringCommand(ctx, sql);
            SqlDataAccess.AddInParameter(ctx, cmd, "ID", DbType.String, id);
            if (!string.IsNullOrEmpty(errMsg))
            {
                SqlDataAccess.AddInParameter(ctx, cmd, "TaskMsg", DbType.String, errMsg);
                SqlDataAccess.AddInParameter(ctx, cmd, "TaskStatus", DbType.Int32, 3);
            }
            else
            {
                SqlDataAccess.AddInParameter(ctx, cmd, "TaskMsg", DbType.String, DBNull.Value);
                SqlDataAccess.AddInParameter(ctx, cmd, "TaskStatus", DbType.Int32, 4);
            }

            return SqlDataAccess.ExecuteNonQuery(ctx, cmd);
        }

        public void DebugMsg(IEnumerable<HL7_ReceiveEntity> list,string msgType)
        {
            //Process(list, null,msgType);
        }

    }
}
