using System;
using System.Collections.Generic;
using System.Text;
using Hh.Mes.Common.log;
using Hh.Mes.Common.Redis;
using Hh.Mes.Common.Request;
using Hh.Mes.POJO.Entity;
using Hh.Mes.Pojo.System;
using Hh.Mes.Service.Repository;
using SqlSugar;
using Hh.Mes.POJO.Response;

namespace Hh.Mes.Service.Logs
{
    /// <summary>
    /// 日志类
    /// </summary>
   public class LogService : RepositorySqlSugar<sys_interface_log>
    {
        #region 接口日志
        /// <summary>
        /// //获取列表
        /// </summary>
        public Response LoadSysInterLog(PageReq pageReq, sys_interface_log model)
        {
            var result = new Response();

            string orderBy = (pageReq == null || string.IsNullOrEmpty(pageReq.field)) ? " id desc" : $"{pageReq.field} {pageReq.order} ";
            string sqlWhere = SqlSysInterLogWhere(model);
            var stringBuilder = new StringBuilder();
            //页码,页数
            //Exel ture 不分页
            if (!model.Exel && pageReq != null)
            {
                stringBuilder.Append("declare @pageIndex int,@pageSize int,@offset int");
                stringBuilder.AppendLine($"  select @pageIndex={pageReq.page}, @pageSize={pageReq.limit}, @offset=(@pageIndex - 1) * @pageSize");
            }

            stringBuilder.AppendLine($@" select  t1.* 
                                         from [dbo].sys_interface_log t1    with(nolock)
                                         where {sqlWhere}
                                         order by {orderBy} ");

            //Exel ture 不分页
            if (!model.Exel)
            {
                stringBuilder.AppendLine("  offset @offset row fetch next @pageSize row only ");
                stringBuilder.Append($" select rowTotal= count(*) from sys_interface_log  t1  with(nolock) where {sqlWhere}");
            }
            var ds = base.Context.Ado.GetDataSetAll(stringBuilder.ToString(), new List<SugarParameter>(){
                new SugarParameter("@type",model.type),
                new SugarParameter("@name",model.name),
                new SugarParameter("@system",model.system),
                new SugarParameter("@path",model.path),
                new SugarParameter("@actionName",model.actionName),
                new SugarParameter("@beginLogTime",model.BeginLogTime),
                new SugarParameter("@endLogTime",model.EndLogTime),
                new SugarParameter("@response",model.response),

                 new SugarParameter("@request",model.request),
            });

            result.Result = ds.Tables[0];
            result.Count = model.Exel ? (int)result.Result.Rows.Count : (int)ds.Tables[1].Rows[0]["rowTotal"];
            return result;
        }

        private string SqlSysInterLogWhere(sys_interface_log model)
        {
            var stringBuilder = new StringBuilder();
            stringBuilder.Append("1=1");
            if (!string.IsNullOrWhiteSpace(model.type)) stringBuilder.Append(" and  t1.type =@type ");
            if (!string.IsNullOrWhiteSpace(model.name)) stringBuilder.Append(" and  t1.name like  '%'+@name+'%' ");
            if (!string.IsNullOrWhiteSpace(model.system)) stringBuilder.Append(" and  t1.system like  '%'+@system+'%' ");
            if (!string.IsNullOrWhiteSpace(model.path)) stringBuilder.Append(" and  t1.path like  '%'+@path+'%' ");
            if (!string.IsNullOrWhiteSpace(model.actionName)) stringBuilder.Append(" and  t1.actionName like  '%'+@actionName+'%' ");
            if (model.BeginLogTime != null) stringBuilder.Append(" and  t1.logTime > @beginLogTime ");
            if (model.EndLogTime != null) stringBuilder.Append(" and  t1.logTime < @endLogTime ");

            if (model.response != null) stringBuilder.Append(" and  t1.response like  '%'+@response+'%' ");

            if (model.request != null) stringBuilder.Append(" and  t1.request like  '%'+@request+'%' ");
            return stringBuilder.ToString();
        }

        /// <summary>
        /// 新增接口日志  稳定后批量
        /// </summary>
        /// <returns></returns>
        public void InsSysInterLog(List<sys_interface_log> model)
        {
            try
            {
                base.Context.Insertable(model).ExecuteCommand();
            }
            catch (Exception e)
            {
                var actionName = model[0].actionName;
                var apiGroup = model[0].apiGroup;
                var browser = model[0].browser;
                var flag = model[0].flag;
                var logTime = model[0].logTime;
                var method = model[0].method;
                var request = model[0].request;
                var response = model[0].response;
                var server = model[0].server;
                var totalMilliseconds =0;
                var type = model[0].type;
                var queryString = model[0].queryString;
                var name = model[0].name;
                var ip = model[0].ip;
                var path = model[0].path;
                var system = model[0].system;
                var result = model[0].result;
                var remark = model[0].remark;
                var msg = $@"actionName:【{actionName}】,apiGroup:【{apiGroup}】,browser:【{browser}】,flag:【{flag}】,logTime:【{logTime}】,method:【{method}】
                            ,request:【{request}】,response:【{response}】,server:【{server}】,totalMilliseconds:【{totalMilliseconds}】,type:【{type}】,queryString:【{queryString}】
                            ,name:【{name}】,ip:【{ip}】,path:【{path}】,system:【{system}】,result:【{result}】,remark:【{remark}】";
                Log4NetHelper.Instance.Info(msg);
                Log4NetHelper.Instance.Error(e.Message);
            }
        }

        #endregion

        #region 操作日志
        /// <summary>
        /// //获取列表
        /// </summary>
        public Response LoadSysOperLog(PageReq pageReq, sys_oper_log model)
        {
            var result = new Response();

            string orderBy = (pageReq == null || string.IsNullOrEmpty(pageReq.field)) ? " id desc" : $"{pageReq.field} {pageReq.order} ";
            string sqlWhere = SqlSysOperLogWhere(model);
            var stringBuilder = new StringBuilder();
            //页码,页数
            //Exel ture 不分页
            if (!model.Exel && pageReq != null)
            {
                stringBuilder.Append("declare @pageIndex int,@pageSize int,@offset int");
                stringBuilder.AppendLine($"  select @pageIndex={pageReq.page}, @pageSize={pageReq.limit}, @offset=(@pageIndex - 1) * @pageSize");
            }

            stringBuilder.AppendLine($@" select  t1.* 
                                         from [dbo].sys_oper_log t1    with(nolock)
                                         where {sqlWhere}
                                         order by {orderBy} ");

            //Exel ture 不分页
            if (!model.Exel)
            {
                stringBuilder.AppendLine("  offset @offset row fetch next @pageSize row only ");
                stringBuilder.Append($" select rowTotal= count(*) from sys_oper_log  t1  with(nolock) where {sqlWhere}");
            }
            var ds = base.Context.Ado.GetDataSetAll(stringBuilder.ToString(), new List<SugarParameter>(){
                new SugarParameter("@name",model.name),
                new SugarParameter("@operType",model.operType),
                new SugarParameter("@logTime",model.logTime),
            });

            result.Result = ds.Tables[0];
            result.Count = model.Exel ? (int)result.Result.Rows.Count : (int)ds.Tables[1].Rows[0]["rowTotal"];
            return result;
        }

        private string SqlSysOperLogWhere(sys_oper_log model)
        {
            var stringBuilder = new StringBuilder();
            stringBuilder.Append("1=1");
            if (model.logTime!=null) stringBuilder.Append(" and  t1.logTime >=@logTime ");
            if (!string.IsNullOrWhiteSpace(model.name)) stringBuilder.Append(" and  t1.name like  '%'+@name+'%' ");
            if (!string.IsNullOrWhiteSpace(model.operType)) stringBuilder.Append(" and  t1.operType =@operType ");
            return stringBuilder.ToString();
        }
        #endregion

        #region 定时器日志
        /// <summary>
        /// //获取列表
        /// </summary>
        public Response LoadSysJobLog(PageReq pageReq, sys_job_log model)
        {
            var result = new Response();

            string orderBy = (pageReq == null || string.IsNullOrEmpty(pageReq.field)) ? " id desc " : $"{pageReq.field} {pageReq.order} ";
            string sqlWhere = SqlSysJobLogWhere(model);
            var stringBuilder = new StringBuilder();
            //页码,页数
            //Exel ture 不分页
            if (!model.Exel && pageReq != null)
            {
                stringBuilder.Append("declare @pageIndex int,@pageSize int,@offset int");
                stringBuilder.AppendLine($"  select @pageIndex={pageReq.page}, @pageSize={pageReq.limit}, @offset=(@pageIndex - 1) * @pageSize");
            }

            stringBuilder.AppendLine($@" select  t1.* 
                                         from [dbo].sys_job_log t1    with(nolock)
                                         where {sqlWhere}
                                         order by {orderBy} ");

            //Exel ture 不分页
            if (!model.Exel)
            {
                stringBuilder.AppendLine("  offset @offset row fetch next @pageSize row only ");
                stringBuilder.Append($" select rowTotal= count(*) from sys_job_log  t1  with(nolock) where {sqlWhere}");
            }
            var ds = base.Context.Ado.GetDataSetAll(stringBuilder.ToString(), new List<SugarParameter>(){
                new SugarParameter("@jobName",model.jobName),
                new SugarParameter("@createTime",model.createTime)
            });

            result.Result = ds.Tables[0];
            result.Count = model.Exel ? (int)result.Result.Rows.Count : (int)ds.Tables[1].Rows[0]["rowTotal"];
            return result;
        }

        private string SqlSysJobLogWhere(sys_job_log model)
        {
            var stringBuilder = new StringBuilder();
            stringBuilder.Append("1=1");
            if (!string.IsNullOrWhiteSpace(model.jobName)) stringBuilder.Append(" and  t1.jobName =@jobName ");
            if (model.createTime!=null) stringBuilder.Append(" and  t1.createTime >@createTime ");
            return stringBuilder.ToString();
        }


        /// <summary>
        /// 新增 定时器日志 稳定后批量
        /// </summary>
        /// <returns></returns>
        public void InsSysJobLog(List<sys_job_log> model)
        {
            try
            {
                base.Context.Insertable(model).ExecuteCommand();
            }
            catch (Exception e)
            {
                var jobName = model[0].jobName;
                var methodName = model[0].methodName;
                var methodParams = model[0].methodParams;
                var jobMessage = model[0].jobMessage;
                var exceptionInfo = model[0].exceptionInfo;

                var msg = $@"jobName:【{jobName}】,methodName:【{methodName}】,methodParams:【{methodParams}】,
                             jobMessage:【{jobMessage}】,exceptionInfo:【{exceptionInfo}】" ;
                Log4NetHelper.Instance.Info(msg);
                Log4NetHelper.Instance.Error(e.Message);
            }
        }
        #endregion

        #region  在线日志
        /// <summary>
        /// //获取列表
        /// </summary>
        public Response LoadSysUserOnlineLog(PageReq pageReq, sys_user_online model)
        {
            var result = new Response();

            string orderBy = (pageReq == null || string.IsNullOrEmpty(pageReq.field)) ? " id desc " : $"{pageReq.field} {pageReq.order} ";
            string sqlWhere = SqlSysUserOnlineLogWhere(model);
            var stringBuilder = new StringBuilder();
            //页码,页数
            //Exel ture 不分页
            if (!model.Exel && pageReq != null)
            {
                stringBuilder.Append("declare @pageIndex int,@pageSize int,@offset int");
                stringBuilder.AppendLine($"  select @pageIndex={pageReq.page}, @pageSize={pageReq.limit}, @offset=(@pageIndex - 1) * @pageSize");
            }

            stringBuilder.AppendLine($@" select  t1.* 
                                         from [dbo].sys_user_online t1    with(nolock)
                                         where {sqlWhere}
                                         order by {orderBy} ");

            //Exel ture 不分页
            if (!model.Exel)
            {
                stringBuilder.AppendLine("  offset @offset row fetch next @pageSize row only ");
                stringBuilder.Append($" select rowTotal= count(*) from sys_user_online  t1  with(nolock) where {sqlWhere}");
            }
            var ds = base.Context.Ado.GetDataSetAll(stringBuilder.ToString(), new List<SugarParameter>(){
                new SugarParameter("@account",model.account)
            });

            result.Result = ds.Tables[0];
            result.Count = model.Exel ? (int)result.Result.Rows.Count : (int)ds.Tables[1].Rows[0]["rowTotal"];
            return result;
        }

        private string SqlSysUserOnlineLogWhere(sys_user_online model)
        {
            var stringBuilder = new StringBuilder();
            stringBuilder.Append("1=1");
            if (!string.IsNullOrWhiteSpace(model.account)) stringBuilder.Append(" and  t1.account=@account ");
            return stringBuilder.ToString();
        }

        
        public dynamic Logout(List<sys_user_online> model)
        {
            var response = new Response();
            return ExceptionsHelp.Instance.ExecuteT(() =>
            {
                var cli = new RedisBase().redisClient;
                foreach (var item in model)
                {
                    base.Context.Deleteable<sys_user_online>().Where(u => u.id == item.id).AddQueue();
                    cli.Del(item.token);
                }
                if (Context.SaveQueues()<= 0)
                {
                    response.Code = 500;
                    response.Message = SystemVariable.dataActionError;
                    return response;
                }
                return response;
            });

        }

        public dynamic Logout(string token)
        {
            var response = new Response();

            var cl = new RedisBase();
            if (cl.redisClient.Exists(token))
            {
                var userAuthSession = cl.GetT<UserAuthSession>(token);
                if (userAuthSession != null)
                {
                    if (cl.redisClient.Exists(userAuthSession.Account))
                    {
                        cl.redisClient.Del(userAuthSession.Account);
                    }
                }
                cl.redisClient.Del(token);
            }

            Context.Deleteable<sys_user_online>().Where(u => u.token == token).ExecuteCommand();
            return response;
        }
        #endregion

        #region  登入日志
        /// <summary>
        /// //获取列表
        /// </summary>
        public Response LoadSysLoginLog(PageReq pageReq, sys_login_log model)
        {
            var result = new Response();

            string orderBy = (pageReq == null || string.IsNullOrEmpty(pageReq.field)) ? " id desc " : $"{pageReq.field} {pageReq.order} ";
            string sqlWhere = SqlSysLoginLogWhere(model);
            var stringBuilder = new StringBuilder();
            //页码,页数
            //Exel ture 不分页
            if (!model.Exel && pageReq != null)
            {
                stringBuilder.Append("declare @pageIndex int,@pageSize int,@offset int");
                stringBuilder.AppendLine($"  select @pageIndex={pageReq.page}, @pageSize={pageReq.limit}, @offset=(@pageIndex - 1) * @pageSize");
            }

            stringBuilder.AppendLine($@" select  t1.* 
                                         from [dbo].sys_login_log t1    with(nolock)
                                         where {sqlWhere}
                                         order by {orderBy} ");

            //Exel ture 不分页
            if (!model.Exel)
            {
                stringBuilder.AppendLine("  offset @offset row fetch next @pageSize row only ");
                stringBuilder.Append($" select rowTotal= count(*) from sys_login_log  t1  with(nolock) where {sqlWhere}");
            }
            var ds = base.Context.Ado.GetDataSetAll(stringBuilder.ToString(), new List<SugarParameter>(){
                new SugarParameter("@account",model.account)
            });

            result.Result = ds.Tables[0];
            result.Count = model.Exel ? (int)result.Result.Rows.Count : (int)ds.Tables[1].Rows[0]["rowTotal"];
            return result;
        }

        private string SqlSysLoginLogWhere(sys_login_log model)
        {
            var stringBuilder = new StringBuilder();
            stringBuilder.Append("1=1");
            if (!string.IsNullOrWhiteSpace(model.account)) stringBuilder.Append(" and  t1.account=@account ");
            return stringBuilder.ToString();
        }

        #endregion

        #region 登入页面 登入成功之后
        /// <summary>
        /// 是否存在数据 在线用户
        /// </summary>
        /// <returns></returns>
        public bool loginAfter(sys_login_log mode)
        {
            var isExt = base.Context.Queryable<sys_user_online>().Where(x => x.ipaddr == mode.ipaddr && x.account == mode.account).Any();
            var sysUserOnline = new sys_user_online
            {
                token = mode.token,
                userId = mode.id,
                account = mode.account,
                name = mode.name,
                ipaddr = mode.ipaddr,
                browser = mode.browser,
                loginTime = DateTime.Now,
            };
            if (isExt)
            {
                UpdataSysUserOnLine(sysUserOnline);
            }
            else
            {
                InsSysUserOnLine(sysUserOnline);
            }
            InsSysLoginLog(mode);
            base.Context.SaveQueues();
            return isExt;
        }

        /// <summary>
        /// 新增登入日志
        /// </summary>
        /// <returns></returns>
        public void InsSysLoginLog(sys_login_log model)
        {
            model.createBy = model.account;
            model.createTime = DateTime.Now;
            base.Context.Insertable(model).AddQueue();
        }

        /// <summary>
        /// 新增 在线用户
        /// </summary>
        /// <returns></returns>
        public void InsSysUserOnLine(sys_user_online model)
        {
            model.createBy = model.account;
            model.createTime = DateTime.Now;
            base.Context.Insertable(model).AddQueue();
        }


        /// <summary>
        /// 更新在线用户时间、 token 、lastAccessTime
        /// </summary>
        public void UpdataSysUserOnLine(sys_user_online model)
        {
            model.updateBy = model.account;
            model.updateTime = DateTime.Now;
            base.Context.Updateable(model).Where(x => x.ipaddr == model.ipaddr && x.account == model.account)
                .UpdateColumns(x => new { x.token, x.loginTime, x.lastAccessTime }).AddQueue();
        } 
        #endregion

    }
}