using System;
using System.Text;
using Newtonsoft.Json;
using System.IO;
using Quartz;
using Quartz.Impl;
using System.Collections.Specialized;
using System.Threading.Tasks;
using Edu.Module.Course;
using Edu.Module.OKR;
using System.Linq;
using System.Collections.Generic;
using Edu.Module.Finance;
using Edu.Module.QYWeChat;
using System.Web;
using Edu.Common.Plugin;
using Edu.Common;

namespace Edu.Education.Helper
{

    /// <summary>
    /// 定时器
    /// </summary>
    public class QuarzHelper
    {
        /// <summary>
        /// 定时执行教师绩效生成
        /// </summary>
        /// <returns></returns>
        public async Task TeachingPerfTimer()
        {
            string cronExpression = "0 0 1 * * ?"; //每天凌晨1点
            NameValueCollection props = new NameValueCollection
            {
                { "quartz.serializer.type", "binary" }
            };
            StdSchedulerFactory factory = new StdSchedulerFactory(props);
            IScheduler scheduler = await factory.GetScheduler();
            await scheduler.Start();

            IJobDetail job = JobBuilder.Create<CreateTeachingPerf>()
                .WithIdentity("job1", "group1")
                .Build();
            //ITrigger trigger = TriggerBuilder.Create()
            //    .WithIdentity("trigger1", "group1")
            //    .StartNow()
            //    .WithSimpleSchedule(x => x
            //        .WithIntervalInHours(2)
            //        .RepeatForever())
            //    .Build();
            ICronTrigger trigger = (ICronTrigger)TriggerBuilder.Create()
                .WithIdentity("trigger1", "group1")
                .WithCronSchedule(cronExpression)
                .Build();

            await scheduler.ScheduleJob(job, trigger);
        }

        /// <summary>
        /// 定时执行OKR周期生成
        /// </summary>
        /// <returns></returns>
        public async Task OKRPeriodTimer()
        {
            string cronExpression = "0 0 1 * * ?"; //每天凌晨1点 
            NameValueCollection props = new NameValueCollection
            {
                { "quartz.serializer.type", "binary" }
            };
            StdSchedulerFactory factory = new StdSchedulerFactory(props);
            IScheduler scheduler = await factory.GetScheduler();
            await scheduler.Start();

            IJobDetail job = JobBuilder.Create<CreateOKRPeriod>()
                .WithIdentity("job2", "group2")
                .Build();
            //ITrigger trigger = TriggerBuilder.Create()
            //    .WithIdentity("trigger2", "group2")
            //    .StartNow()
            //    .WithSimpleSchedule(x => x
            //        .WithIntervalInHours(2)
            //        .RepeatForever())
            //    .Build();
            ICronTrigger trigger = (ICronTrigger)TriggerBuilder.Create()
                .WithIdentity("trigger2", "group2")
                .WithCronSchedule(cronExpression)
                .Build();

            await scheduler.ScheduleJob(job, trigger);
        }

        /// <summary>
        /// 定时执行OKR规则
        /// </summary>
        /// <returns></returns>
        public async Task OKRPeriodRuleTimer()
        {
            NameValueCollection props = new NameValueCollection
            {
                { "quartz.serializer.type", "binary" }
            };
            StdSchedulerFactory factory = new StdSchedulerFactory(props);
            IScheduler scheduler = await factory.GetScheduler();
            await scheduler.Start();

            IJobDetail job = JobBuilder.Create<CreateOKRPeriodRule>()
                .WithIdentity("job3", "group3")
                .Build();
            ITrigger trigger = TriggerBuilder.Create()
                .WithIdentity("trigger3", "group3")
                .StartNow()
                .WithSimpleSchedule(x => x
                    .WithIntervalInHours(1)
                    .RepeatForever())
                .Build();

            await scheduler.ScheduleJob(job, trigger);
        }

        /// <summary>
        /// 定时执行营收报表
        /// </summary>
        /// <returns></returns>
        public async Task RevenueReportTimer()
        {
            string CronExpression2 = "0 10 8,12,18,22 * * ?";//每天8，12，19，22点触发
            NameValueCollection props = new NameValueCollection
            {
                { "quartz.serializer.type", "binary" }
            };
            StdSchedulerFactory factory = new StdSchedulerFactory(props);
            IScheduler scheduler = await factory.GetScheduler();
            await scheduler.Start();

            IJobDetail job = JobBuilder.Create<CreateRevenueReport>()
                .WithIdentity("job4", "group4")
                .Build();
            //ITrigger trigger = TriggerBuilder.Create()
            //    .WithIdentity("trigger4", "group4")
            //    .StartNow()
            //    .WithSimpleSchedule(x => x
            //        .WithIntervalInHours(1)
            //        .RepeatForever())
            //    .Build();
            ICronTrigger trigger = (ICronTrigger)TriggerBuilder.Create()
                .WithIdentity("trigger4", "group4")
                .WithCronSchedule(CronExpression2)
                .Build();

            await scheduler.ScheduleJob(job, trigger);
        }

        /// <summary>
        /// 定时执行备课检查
        /// </summary>
        /// <returns></returns>
        public async Task CheckPerparingTimer()
        {
            string CronExpression = "0 30 13,18 * * ?";

            NameValueCollection props = new NameValueCollection
            {
                { "quartz.serializer.type", "binary" }
            };
            StdSchedulerFactory factory = new StdSchedulerFactory(props);
            IScheduler scheduler = await factory.GetScheduler();
            await scheduler.Start();

            IJobDetail job = JobBuilder.Create<NotifyTeachPerparing>()
                .WithIdentity("trigger5", "group5")
                .Build();
            ICronTrigger trigger = (ICronTrigger)TriggerBuilder.Create()
                .WithIdentity("trigger5", "group5")
                .WithCronSchedule(CronExpression)
                .Build();

            await scheduler.ScheduleJob(job, trigger);
        }

        /// <summary>
        /// 企业微信渠道活码
        /// </summary>
        /// <returns></returns>
        public async Task WeXinMediumTimer()
        {
            string CronExpression2 = "0 0 * * * ?";//每小时执行的一次 整点整分
            NameValueCollection props = new NameValueCollection
            {
                { "quartz.serializer.type", "binary" }
            };
            StdSchedulerFactory factory = new StdSchedulerFactory(props);
            IScheduler scheduler = await factory.GetScheduler();
            await scheduler.Start();

            IJobDetail job = JobBuilder.Create<CreateWeXinMedium>()
                .WithIdentity("job6", "group6")
                .Build();
            //ITrigger trigger = TriggerBuilder.Create()
            //    .WithIdentity("trigger6", "group6")
            //    .StartNow()
            //    .WithSimpleSchedule(x => x
            //        .WithIntervalInHours(1)
            //        .RepeatForever())
            //    .Build();
            ICronTrigger trigger = (ICronTrigger)TriggerBuilder.Create()
                .WithIdentity("trigger6", "group6")
                .WithCronSchedule(CronExpression2)
                .Build();

            await scheduler.ScheduleJob(job, trigger);
        }

        /// <summary>
        /// 企业微信渠道活码
        /// </summary>
        /// <returns></returns>
        public async Task WeXinChannelTimer()
        {
            string CronExpression2 = "0 0 * * * ?";//每小时执行的一次 整点整分
            NameValueCollection props = new NameValueCollection
            {
                { "quartz.serializer.type", "binary" }
            };
            StdSchedulerFactory factory = new StdSchedulerFactory(props);
            IScheduler scheduler = await factory.GetScheduler();
            await scheduler.Start();

            IJobDetail job = JobBuilder.Create<CreateWeXinChannel>()
                .WithIdentity("job7", "group7")
                .Build();
            //ITrigger trigger = TriggerBuilder.Create()
            //    .WithIdentity("trigger7", "group7")
            //    .StartNow()
            //    .WithSimpleSchedule(x => x
            //        .WithIntervalInHours(1)
            //        .RepeatForever())
            //    .Build();
            ICronTrigger trigger = (ICronTrigger)TriggerBuilder.Create()
                .WithIdentity("trigger7", "group7")
                .WithCronSchedule(CronExpression2)
                .Build();

            await scheduler.ScheduleJob(job, trigger);
        }

        /// <summary>
        /// 教育同业B2B订单超时取消
        /// </summary>
        /// <returns></returns>
        public async Task EduB2BOrderCancelTimer()
        {
            string CronExpression2 = "0 */1 * * * ?";//每1分钟执行的一次
            NameValueCollection props = new NameValueCollection
            {
                { "quartz.serializer.type", "binary" }
            };
            StdSchedulerFactory factory = new StdSchedulerFactory(props);
            IScheduler scheduler = await factory.GetScheduler();
            await scheduler.Start();

            IJobDetail job = JobBuilder.Create<EduB2BOrderCancel>()
                .WithIdentity("job8", "group8")
                .Build();
            //ITrigger trigger = TriggerBuilder.Create()
            //    .WithIdentity("trigger7", "group7")
            //    .StartNow()
            //    .WithSimpleSchedule(x => x
            //        .WithIntervalInHours(1)
            //        .RepeatForever())
            //    .Build();
            ICronTrigger trigger = (ICronTrigger)TriggerBuilder.Create()
                .WithIdentity("trigger8", "group8")
                .WithCronSchedule(CronExpression2)
                .Build();

            await scheduler.ScheduleJob(job, trigger);
        }

        /// <summary>
        /// 教育同业B2B订单佣金发放
        /// </summary>
        /// <returns></returns>
        public async Task EduB2BOrderCommissionTimer()
        {
            string CronExpression2 = "0 1 0 25 * ?";//每月25号 凌晨12.1分执行
            NameValueCollection props = new NameValueCollection
            {
                { "quartz.serializer.type", "binary" }
            };
            StdSchedulerFactory factory = new StdSchedulerFactory(props);
            IScheduler scheduler = await factory.GetScheduler();
            await scheduler.Start();

            IJobDetail job = JobBuilder.Create<EduB2BOrderCommission>()
                .WithIdentity("job9", "group9")
                .Build();
            //ITrigger trigger = TriggerBuilder.Create()
            //    .WithIdentity("trigger7", "group7")
            //    .StartNow()
            //    .WithSimpleSchedule(x => x
            //        .WithIntervalInHours(1)
            //        .RepeatForever())
            //    .Build();
            ICronTrigger trigger = (ICronTrigger)TriggerBuilder.Create()
                .WithIdentity("trigger9", "group9")
                .WithCronSchedule(CronExpression2)
                .Build();

            await scheduler.ScheduleJob(job, trigger);
        }

        /// <summary>
        /// 定时执行滚动开班生成
        /// </summary>
        /// <returns></returns>
        public async Task EduCreateScrollClassTimer()
        {
            string cronExpression = "0 10 0 1 * ?";//每月1号 凌晨10分
            NameValueCollection props = new NameValueCollection
            {
                { "quartz.serializer.type", "binary" }
            };
            StdSchedulerFactory factory = new StdSchedulerFactory(props);
            IScheduler scheduler = await factory.GetScheduler();
            await scheduler.Start();

            IJobDetail job = JobBuilder.Create<CreateScrollClass>()
                .WithIdentity("job10", "group10")
                .Build();
            //ITrigger trigger = TriggerBuilder.Create()
            //    .WithIdentity("trigger10", "group10")
            //    .StartNow()
            //    .WithSimpleSchedule(x => x
            //        .WithIntervalInHours(1)
            //        .RepeatForever())
            //    .Build();
            ICronTrigger trigger = (ICronTrigger)TriggerBuilder.Create()
                .WithIdentity("trigger10", "group10")
                .WithCronSchedule(cronExpression)
                .Build();

            await scheduler.ScheduleJob(job, trigger);
        }

        /// <summary>
        /// 定时执行预约成功生成
        /// </summary>
        /// <returns></returns>
        public async Task EduCreateScrollAppointmentTimer()
        {
            string cronExpression = "0 0 * * * ?";//每小时执行的一次 整点整分
            NameValueCollection props = new NameValueCollection
            {
                { "quartz.serializer.type", "binary" }
            };
            StdSchedulerFactory factory = new StdSchedulerFactory(props);
            IScheduler scheduler = await factory.GetScheduler();
            await scheduler.Start();

            IJobDetail job = JobBuilder.Create<CreateScrollAppointment>()
                .WithIdentity("job11", "group11")
                .Build();
            //ITrigger trigger = TriggerBuilder.Create()
            //    .WithIdentity("trigger11", "group11")
            //    .StartNow()
            //    .WithSimpleSchedule(x => x
            //        .WithIntervalInHours(1)
            //        .RepeatForever())
            //    .Build();
            ICronTrigger trigger = (ICronTrigger)TriggerBuilder.Create()
                .WithIdentity("trigger11", "group11")
                .WithCronSchedule(cronExpression)
                .Build();

            await scheduler.ScheduleJob(job, trigger);
        }
    }



    /// <summary>
    /// 教师绩效生成
    /// </summary>
    public class CreateTeachingPerf : IJob
    {
        /// <summary>
        /// 这里是作业调度每次定时执行方法
        /// </summary>
        /// <param name="context"></param>
        public Task Execute(IJobExecutionContext context)
        {
            try
            {
                LogHelper.Write("教师绩效生成");
                TeachingRewardsModule teachingRewardsModule = new TeachingRewardsModule();
                var glist = teachingRewardsModule.GetGroupList();
                foreach (var item in glist)
                {
                    //查询该集团下 所有的班级
                    var clist = teachingRewardsModule.GetTeachingPerfClassList(item.GId);
                    foreach (var qitem in clist)
                    {
                        try
                        {
                            LogHelper.Write("ClassId：" + qitem.ClassId);
                            string msg = teachingRewardsModule.SetTeachingPerfCreate(0, qitem);
                            if (msg != "")
                            {
                                LogHelper.Write("CreateTeachingPerf【" + qitem.ClassId + "】：" + msg);
                            }
                        }
                        catch (Exception ex)
                        {
                            LogHelper.Write(ex, "CreateTeachingPerf【" + qitem.ClassId + "】");
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                LogHelper.Write(ex, "CreateTeachingPerf");
            }
            return null;
        }
    }

    /// <summary>
    /// 周期生成
    /// </summary>
    public class CreateOKRPeriod : IJob
    {
        /// <summary>
        /// 这里是作业调度每次定时执行方法
        /// </summary>
        /// <param name="context"></param>
        public Task Execute(IJobExecutionContext context)
        {
            try
            {
                LogHelper.Write("周期生成....");
                OKRPeriodModule oKRPeriodModule = new OKRPeriodModule();
                var clist = oKRPeriodModule.GetOKRPeriodConfigList();
                foreach (var dmodel in clist)
                {
                    //查询改配置下当前周期
                    var list = oKRPeriodModule.GetCurrentPeriodList(dmodel.Group_Id);
                    if (list.Any()) {
                        var model = list.FirstOrDefault();
                        //看是否已到可生成下周期时间
                        if (dmodel.BeforeType == 1)
                        {
                            //天
                            var ds = model.EndDate - DateTime.Now;
                            if (ds.TotalDays < dmodel.BeforeNum)
                            {
                                dmodel.EndDate = model.EndDate;
                                //生成下一个周期
                                oKRPeriodModule.CreatePeriodNext(dmodel, true);
                            }
                        }
                        else
                        {
                            //月
                            var ds = DateTime.Now.AddMonths(dmodel.BeforeNum);
                            if (ds > model.EndDate)
                            {
                                dmodel.EndDate = model.EndDate;
                                //生成下一个周期
                                oKRPeriodModule.CreatePeriodNext(dmodel, true);
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                LogHelper.Write(ex, "CreateOKRPeriod");
            }

            try
            {
                LogHelper.Write("开始提醒....");
                //OKRPeriodModule oKRPeriodModule = new OKRPeriodModule();
                //oKRPeriodModule.SendOKRRemid();
            }
            catch (Exception ex)
            {
                LogHelper.Write(ex, "SendOKRRemid");
            }
            return null;
        }
    }

    /// <summary>
    /// 规则更新进度
    /// </summary>
    public class CreateOKRPeriodRule : IJob
    {
        /// <summary>
        /// 这里是作业调度每次定时执行方法
        /// </summary>
        /// <param name="context"></param>
        public Task Execute(IJobExecutionContext context)
        {
            try
            {
                LogHelper.Write("开始执行规则适配....");
                OKRPeriodModule oKRPeriodModule = new OKRPeriodModule();
                var clist = oKRPeriodModule.GetOKRKeyResultList(new Model.ViewModel.OKR.RB_OKR_KeyResult_ViewModel() { IsUseRule = 1 });
                foreach (var item in clist) {
                    oKRPeriodModule.UpdateOKRKeyresultRuleProgress(item);
                }
            }
            catch (Exception ex)
            {
                LogHelper.Write(ex, "CreateOKRPeriodRule");
            }
            return null;
        }
    }

    /// <summary>
    /// 更新营收报表
    /// </summary>
    public class CreateRevenueReport : IJob
    {
        /// <summary>
        /// 这里是作业调度每次定时执行方法
        /// </summary>
        /// <param name="context"></param>
        public Task Execute(IJobExecutionContext context)
        {
            try
            {
                Console.WriteLine("开始执行营收报表....");
                FinanceModule financeModule = new FinanceModule();
                financeModule.SetEduRevenueReport(100000, "2020-01-01", false);
                Console.WriteLine("结束执行营收报表....");
                Console.WriteLine("开始执行简易报表....");
                financeModule.InsertBatchSimple_V2(100000, 2020);
                financeModule.InsertBatchSimple_V2(100000, 2021);
                financeModule.InsertBatchSimple_V2(100000, 2022);
                Console.WriteLine("结束执行简易报表....");
            }
            catch (Exception ex)
            {
                LogHelper.Write(ex, "CreateRevenueReport");
            }
            return null;
        }
    }

    /// 备课检查通知
    /// </summary>
    public class NotifyTeachPerparing : IJob
    {
        public Task Execute(IJobExecutionContext context)
        {
            try
            {   
                Console.WriteLine("开始执行未备课查询....");
                ClassModule classModule = new ClassModule();
                var query = classModule.GetNotPerparingTeachModule();
                if (query != null && query.Count > 0)
                {
                    Console.WriteLine($"未备课查询结果为:{query.Count}....");
                    query.ForEach(x =>
                    {
                        var recipientPath = HttpUtility.UrlEncode($"/teacher/myPrepareLessons?d={HttpUtility.UrlEncode(DateTime.Now.AddDays(1).ToString("yyyy-MM-dd"))}");
                        var content = $"<font color='info'>备课通知</font> 明日还有班级没有完成备课\n>**概要信息** \n>上课日期：<font color='warning'>{DateTime.Now.AddDays(1).ToString("yyyy年MM月dd日")}</font>\n>未备课班级：<font color='comment'>{x.ClassCount}个</font>\n>请点击：[立即备课]({Config.ErpUrl}/autologin?loginId={x.AccountId}&target={recipientPath})";
                        Console.WriteLine($"开始推送内容为：{content}....");
                        PushWorkChatHelper.PushToWorkChat(content, x.WorkUserId, "业务单据驳回通知");
                    });
                }
                else 
                {
                    Console.WriteLine("所有老师完成明日备课....");
                }
            }
            catch (Exception ex)
            {
                LogHelper.Write(ex, "CreateRevenueReport");
            }
            return null;
        }
    }


    /// <summary>
    /// 企业微信素材管理
    /// </summary>
    public class CreateWeXinMedium : IJob
    {
        /// <summary>
        /// 这里是作业调度每次定时执行方法
        /// </summary>
        /// <param name="context"></param>
        public Task Execute(IJobExecutionContext context)
        {
            try
            {
                LogHelper.Write("开始执行企业微信素材上传....");
                QYWeChatModule weChatModule = new QYWeChatModule();
                weChatModule.MediumUpload(100000);
                LogHelper.Write("素材上传结束");
            }
            catch (Exception ex)
            {
                LogHelper.Write(ex, "CreateWeXinMedium");
            }
            return null;
        }
    }

    /// <summary>
    /// 企业微信渠道活码
    /// </summary>
    public class CreateWeXinChannel : IJob
    {
        /// <summary>
        /// 这里是作业调度每次定时执行方法
        /// </summary>
        /// <param name="context"></param>
        public Task Execute(IJobExecutionContext context)
        {
            try
            {
                LogHelper.Write("开始执行企业微信渠道活码....");
                QYWeChatModule weChatModule = new QYWeChatModule();
                weChatModule.UpdateWeChatChannelForTimer(100000);
                LogHelper.Write("渠道活码更新结束");
            }
            catch (Exception ex)
            {
                LogHelper.Write(ex, "CreateWeXinChannel");
            }
            return null;
        }
    }

    /// <summary>
    /// 教育同业B2B订单超时取消
    /// </summary>
    public class EduB2BOrderCancel : IJob
    {
        /// <summary>
        /// 这里是作业调度每次定时执行方法
        /// </summary>
        /// <param name="context"></param>
        public Task Execute(IJobExecutionContext context)
        {
            try
            {
                LogHelper.Write("开始执行教育同业订单超时取消....");
                EduB2BOrderModule EduB2BOrderModule = new EduB2BOrderModule();
                EduB2BOrderModule.SetEduB2BOrderCancel();
                LogHelper.Write("教育同业订单超时取消更新结束");
            }
            catch (Exception ex)
            {
                LogHelper.Write(ex, "EduB2BOrderCancel");
            }
            return null;
        }
    }

    /// <summary>
    /// 教育同业B2B订单佣金发放
    /// </summary>
    public class EduB2BOrderCommission : IJob
    {
        /// <summary>
        /// 这里是作业调度每次定时执行方法
        /// </summary>
        /// <param name="context"></param>
        public Task Execute(IJobExecutionContext context)
        {
            try
            {
                LogHelper.Write("开始执行教育同业订单返佣....");
                EduB2BOrderModule EduB2BOrderModule = new EduB2BOrderModule();
                EduB2BOrderModule.SetEduB2BOrderCommission();
                LogHelper.Write("教育同业订单返佣更新结束");
            }
            catch (Exception ex)
            {
                LogHelper.Write(ex, "EduB2BOrderCommission");
            }
            return null;
        }
    }

    /// <summary>
    /// 滚动开班数据生成
    /// </summary>
    public class CreateScrollClass : IJob
    {
        /// <summary>
        /// 这里是作业调度每次定时执行方法
        /// </summary>
        /// <param name="context"></param>
        public Task Execute(IJobExecutionContext context)
        {
            try
            {
                LogHelper.Write("滚动开班数据生成");
                ScrollClassCommonModule scrollClassModule = new ScrollClassCommonModule();
                scrollClassModule.CreateScrollClass("", 100000);
            }
            catch (Exception ex)
            {
                LogHelper.Write(ex, "CreateScrollClass");
            }
            return null;
        }
    }

    /// <summary>
    /// 滚动开班预约课程生成
    /// </summary>
    public class CreateScrollAppointment : IJob
    {
        /// <summary>
        /// 这里是作业调度每次定时执行方法
        /// </summary>
        /// <param name="context"></param>
        public Task Execute(IJobExecutionContext context)
        {
            try
            {
                LogHelper.Write("滚动开班预约课程生成");
                ScrollClassCommonModule scrollClassModule = new ScrollClassCommonModule();
                scrollClassModule.CreateScrollAppointment(100000);
            }
            catch (Exception ex)
            {
                LogHelper.Write(ex, "CreateScrollAppointment");
            }
            return null;
        }
    }

    public class UpdageHistoryOrderCommissionHelper
    {
        /// <summary>
        /// 更新历史订单提成比例
        /// </summary>
        /// <returns></returns>
        public bool UpdageHistoryOrderCommission() {

            return new ClassModule().UpdateHistoryClassNo();

            //查询出所有的订单
            //return new OrderModule().UpdateClassOrderCommissionRate();
        }
    }
}
