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;
            }
        }

        private DateTime SetTime
        {
            get
            {
                var SetTime = System.Configuration.ConfigurationManager.AppSettings["SetTime"];
                DateTime now = DateTime.Now;
                SetTime = string.Format("{0}{1}", now.ToString("yyyy-MM"), SetTime);

                return DateTime.Parse(SetTime);
            }
        }

        //private int EndTimeType
        //{
        //    get
        //    {
        //        var etimeType = System.Configuration.ConfigurationManager.AppSettings["EndTimeType"];
        //        int num = 0;
        //        if (!int.TryParse(etimeType, out num))
        //        {
        //            num = 1;
        //        }
        //        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 (DateTime.Now > SetTime)
                {
                    //判断是否需要生成任务
                    if (GetTaskFlag(SetTime,type) <= 0)
                    {
                        DateTime lastDay = new DateTime(DateTime.Now.AddMonths(-1).Year, DateTime.Now.AddMonths(-1).Month, 1).AddMonths(1).AddSeconds(-1);
                        //按月初1号为结尾
                        //if (EndTimeType == 2) {
                        //    lastDay = DateTime.Parse(string.Format("{0}-01 00:00:00", DateTime.Now.ToString("yyyy-MM")));
                        //}
                        
                        //生成任务
                        SetTask(string.Format("{0}-01 00:00:00", DateTime.Now.AddMonths(-1).ToString("yyyy-MM")), lastDay.ToString("yyyy-MM-dd HH:mm:ss"),
                            SetTime.ToString("yyyy-MM-dd HH:mm:ss"), type);
                        
                    }
                }

                //使用任务
                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 No, `TaskID`, `VisitNo`, `TaskType`, `TypeName`, `TaskStatus`, `Parameter1`, `Parameter2`, `Parameter3`, `ErrMsg`, `ErrNm`, `TaskTime`, `Reserve1`, `Reserve2`, `Reserve3`, `UpdateTime` ,SystemTime
from TaskMessage 
where TaskStatus=1 and TaskTime='{0}' and TaskType='{1}' limit {2}";
            sql = string.Format(sql,SetTime.ToString("yyyy-MM-dd HH:mm:ss"), type, num);
            try
            {
                var listRow = MySqlDataAccess.ExecuteSqlStringAccessor<TaskMessage>(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<TaskMessage> listRow, Action<LogModel> setLog)
        {
            listRow.ToList().ForEach(o =>
            {
                //验证
                var model = GetListRow(o.No.ToString());
                if (null != model)
                {
                    try
                    {
                        if (setLog != null)
                            setLog(new LogModel { Message = o.TaskType, MessageID = o.TaskID });

                        SetStartBiz(o.No.ToString());
                        string mesStruct = "ADT";

                        var behavior = BizComponentFactory.GetBizComponent(mesStruct);
                        var errMsg = behavior.Process(o,o.TaskType);
                        SetEndBiz(o.No.ToString(), errMsg);
                    }
                    catch (Exception ex)
                    {
                        if (setLog != null)
                            setLog(new LogModel { Message = o.TaskType, MessageID = o.No.ToString(), ErrorMsg = "消息处理错误 :" + ex.Message });
                        SetEndBiz(o.No.ToString(), ex.Message);
                    }
                }
            });
        }


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



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

        }

        protected int GetTaskFlag(DateTime TaskTime,string TaskType)
        {
            var sql = string.Format(@"select count(1)
from TaskMessage 
where TaskTime='{0}' and TaskType='{1}' ", TaskTime.ToString("yyyy-MM-dd HH:mm:ss"),TaskType);
            var cmd =ctx.DBGetSqlStringCommand(sql);
            var listRow = MySqlDataAccess.DBExecuteDataSet(ctx, cmd);
            var ret=listRow.Tables[0].Rows[0][0].ToString();
            return string.IsNullOrWhiteSpace(ret)?0:int.Parse(ret);
        }

        //开始时间
        protected int SetStartBiz(string id)
        {
            var sql = "UPDATE TaskMessage SET UpdateTime=SYSDATE() , TaskStatus='2' WHERE  No=@ID";
            var cmd = MySqlDataAccess.GetSqlStringCommand(ctx, sql);
            MySqlDataAccess.AddInParameter(ctx, cmd, "ID", DbType.String, id);
            return MySqlDataAccess.ExecuteNonQuery(ctx, cmd);
        }


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

            return MySqlDataAccess.ExecuteNonQuery(ctx, cmd);
        }

        protected int SetTask(string beginTime,string endTime,string taskTime,string TaskType)
        {
            var sql = string.Format(@"INSERT INTO TaskMessage( TaskID, VisitNo, TaskType, TypeName, TaskStatus, Parameter1, Parameter2, Parameter3, ErrMsg, ErrNm, TaskTime, Reserve1, Reserve2, Reserve3, UpdateTime) 
select MD5(UUID()),'',TaskCode,TaskName,1,'{0}','{1}','1',null,0,'{2}',  NULL, NULL, TaskNum,NULL
from TaskConfig 
where TaskType=2 and DelFlag=0 and TaskCode='{3}'", beginTime, endTime, taskTime,TaskType);

            var cmd = MySqlDataAccess.GetSqlStringCommand(ctx, sql);
            //MySqlDataAccess.AddInParameter(ctx, cmd, "TaskStatus", DbType.Int32, 3);
            return MySqlDataAccess.ExecuteNonQuery(ctx, cmd);
        }

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

    }
}
