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

using Microsoft.Practices.EnterpriseLibrary.Data;
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;
            }
        }



        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 == "MFN") //字典消息大于20个.一直解析
                {
                    RunExec(type, setLog); //执行一次

                    int num = 20;
                    while (true)
                    { 
                        var sql = @"SELECT top {0} ID FROM dbo.HL7_Receive WITH(NOLOCK)  WHERE TaskStatus='1' and MessageID='MFN'";
                        sql = string.Format(sql, num);
                        var cmd = ctx.DBGetSqlStringCommand(sql);
                        var dt = new DataTable();
                        var dr = ctx.DBExecuteReader(cmd);
                        dt.Load(dr);
                        if (dt.Rows.Count >= num)
                        {
                            RunExec(type, setLog);
                        }
                        else
                        {
                            break;
                        }  
                    } 
                }
                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;
            if (type == "MFN")
            {
                orderSeq = " Sequeue ASC,";
            }

            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 ";
            sql = string.Format(sql, num, type, orderSeq);
            try
            {
                var listRow = SqlDataAccess.ExecuteSqlStringAccessor<HL7_ReceiveEntity>(ctx, sql).Take(num).ToList();
                if (listRow.Count() > 0)
                {
                    Process(listRow, setLog);
                }
            }
            catch (Exception ex)
            {
                LogHelper.LogError(ex, LogCatagories.AdapterScan);
                throw ex;
            }
        }

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

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


                        SetStartBiz(o.ID);
                        string mesStruct = o.MessageID;

                        var behavior = BizComponentFactory.GetBizComponent(mesStruct);
                        var errMsg = behavior.Process(o.MsgContent,o.MessageType);
                        SetEndBiz(o.ID, errMsg);

                    }
                    catch (Exception ex)
                    {
                        if (setLog != null)
                            setLog(new LogModel { Message = o.MsgContent, MessageID = o.MessageID, 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_ReceiveEntity GetListRow(string id)
        {
            var sql = "SELECT *  FROM dbo.HL7_Receive  WHERE TaskStatus='1' and   StartTime is null and ID='" + id + "'";
            var model = SqlDataAccess.ExecuteSqlStringAccessor<HL7_ReceiveEntity>(ctx, sql).Take(1).FirstOrDefault();
            return model;

        }


        //开始时间
        protected int SetStartBiz(string id)
        {
            var sql = "UPDATE dbo.HL7_Receive SET StartTime=GETDATE() , TaskStatus='2',TaskIP=@TaskIP,TaskMac=@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_Receive 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)
        {
            Process(list, null);
        }

    }
}
