using Microsoft.Extensions.Logging;
using Siger.DataSchedule.Infrastructure.Extend;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Log;
using Siger.Middlelayer.TpmRepository;
using System;
using System.Linq;
using System.Threading;

namespace Siger.Schedule.TpmModule
{
    public class AutoSyncMessage : IScheduleJob
    {
        AutoSyncMessageHelper syncMsgSchedule;
        public void PreInit(ScheduleContext context)
        {
            Logger.RegisterLogEngine(Module.Tpm);
            syncMsgSchedule = new  AutoSyncMessageHelper();
        }
       

        public void Execute(ScheduleContext context)
        {
            syncMsgSchedule.StartTask();
        }

        public void AfterExecute(ScheduleContext context)
        {

        }



        public void Undo()
        {

        }
    }

    public class AutoSyncMessageHelper : IDisposable
    {
        public const int retainNum = 200;

        private static AutoSyncMessageHelper _helper;
        public static AutoSyncMessageHelper Instance = _helper ?? (_helper = new AutoSyncMessageHelper());

        private static ApiTpmDbContext _context;
        public AutoSyncMessageHelper()
        {
            _context = new ApiTpmDbContext();
        }

        public void StartTask()
        {
            try
            {
                //var thread = new Thread(Process)
                //{
                //    IsBackground = true
                //};
                //thread.Start();

                Execute();

                Dispose();
            }
            catch (Exception e)
            {
                Logger.WriteLineError("AutoSyncMessageHelper failed, error:" + e);
            }
        }

        private void Process()
        {
            while (true)
            {
                Thread.Sleep(1000 * 60 * 1); // 1分钟

                var now = DateTime.Now;
                if (now.Minute == 1 && now.Hour == 0)
                {
                    _context = new ApiTpmDbContext();

                    Execute();

                    Dispose();
                }
            }
        }

        private void Execute()
        {
            var projects = _context.siger_project.Where(t => t.status == (int)RowState.Valid).ToList();
            if (projects.Any())
            {
                foreach (var project in projects)
                {
                    ExcuteDeleteMessageHistory(project.id);
                }
            }
        }

        public void ExcuteDeleteMessageHistory(int projectId)
        {
            try
            {
                DeleteMessageHistory(projectId);
            }
            catch (Exception e)
            {
                Logger.WriteLineError("AutoSyncMessageHelper Execute DeleteMessageHistory Timing Task failed" + e);
            }
        }

        private void DeleteMessageHistory(int projectId)
        {
            var users = _context.siger_project_user
                .Where(t => t.projectid == projectId && t.status == (int)RowState.Valid).ToList();
            foreach (var user in users)
            {
                var planMessages = _context.siger_app_project_message.Where(t =>
                        t.projectid == projectId && t.status > 0 && t.tomid == user.mid && t.type == 2)
                    .OrderByDescending(t => t.create_time).Skip(retainNum).ToList();
                if (planMessages.Any())
                {
                    _context.siger_app_project_message.RemoveRange(planMessages);
                    _context.SaveChanges();
                }
                var RepairMessages = _context.siger_app_project_message.Where(t =>
                        t.projectid == projectId && t.status > 0 && t.tomid == user.mid && t.type == 1)
                    .OrderByDescending(t => t.create_time).Skip(retainNum).ToList();
                if (RepairMessages.Any())
                {
                    _context.siger_app_project_message.RemoveRange(RepairMessages);
                    _context.SaveChanges();
                }
            }
        }

        public void Dispose()
        {
            _context?.Dispose();
        }
    }
}
