using Microsoft.Extensions.Logging;
using Quartz;
using SolarPower.Models;
using SolarPower.Repository.Interface;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace SolarPower.Quartz.Jobs
{
    [DisallowConcurrentExecution]
    public class OperationScheduleJob : IJob
    {
        private readonly ILogger<OperationScheduleJob> logger;
        private IOperationRepository operationRepository;

        public OperationScheduleJob(ILogger<OperationScheduleJob> logger, IOperationRepository operationRepository)
        {
            this.logger = logger;
            this.operationRepository = operationRepository;
        }

        public async Task Execute(IJobExecutionContext context)
        {
            try
            {
                var getTime = await operationRepository.GetOperationSchedules();
                foreach (var a in getTime)
                {
                    //最後製作紀錄時間
                    var useday = a.LastCreateTime;
                    if (a.LastCreateTime == "0001-01-01 00:00:00")
                    {
                        useday = a.StartTime;
                    }

                    #region 產生紀錄
                    DateTime Updatedtime;//下次生成紀錄時間
                    Updatedtime = a.ScheduleType switch
                    {
                        0 => Convert.ToDateTime(useday).AddDays(a.ScheduleNum),
                        1 => Convert.ToDateTime(useday).AddDays(a.ScheduleNum * 7),
                        2 => Convert.ToDateTime(useday).AddMonths(a.ScheduleNum),
                        3 => Convert.ToDateTime(useday).AddMonths(a.ScheduleNum * 3),
                        4 => Convert.ToDateTime(useday).AddYears(a.ScheduleNum),
                        _ => Convert.ToDateTime(useday).AddYears(999)
                    };

                    if (Updatedtime < DateTime.Now)
                    {
                        var now = DateTime.Now.ToString("yyyy-MM-dd");
                        var OperationPlan = new OperationCreatePlan()
                        {
                            Id = a.Id,
                            EmailType = a.EmailType,
                            ScheduleNum = a.ScheduleNum,
                            Description = a.Description,
                            WorkDay = a.WorkDay,
                            ScheduleType = a.ScheduleType,
                            StartTime = useday,
                            PowerStationId = a.PowerStationId,
                            Type = a.Type,
                            UpdatedBy = a.UpdatedBy,
                            LastCreateTime = Updatedtime.ToString("yyyy-MM-dd"),
                            IsDelivery = 0
                        };
                        List<string> properties = new List<string>()
                        {
                            "Id",
                            "EmailType",
                            "ScheduleNum",
                            "Description",
                            "WorkDay",
                            "ScheduleType",
                            "StartTime",
                            "PowerStationId",
                            "Type",
                            "UpdatedBy",
                            "LastCreateTime",
                            "IsDelivery"
                        };
                        await operationRepository.UpdateOperationPlan(OperationPlan, properties);



                        string endtime = "";
                        switch (a.ScheduleType)
                        {
                            case 0:
                                endtime = (Convert.ToDateTime(Updatedtime.ToString("yyyy-MM-dd")).AddDays(a.ScheduleNum)).ToString("yyyy-MM-dd 00:00:00"); break;
                            case 1:
                                endtime = (Convert.ToDateTime(Updatedtime.ToString("yyyy-MM-dd")).AddDays(a.ScheduleNum * 7)).ToString("yyyy-MM-dd 00:00:00"); break;
                            case 2:
                                endtime = (Convert.ToDateTime(Updatedtime.ToString("yyyy-MM-dd")).AddMonths(a.ScheduleNum)).ToString("yyyy-MM-dd 00:00:00"); break;
                            case 3:
                                endtime = (Convert.ToDateTime(Updatedtime.ToString("yyyy-MM-dd")).AddMonths(a.ScheduleNum * 3)).ToString("yyyy-MM-dd 00:00:00"); break;
                            case 4:
                                endtime = (Convert.ToDateTime(Updatedtime.ToString("yyyy-MM-dd")).AddYears(a.ScheduleNum * 3)).ToString("yyyy-MM-dd 00:00:00"); break;
                        }
                        var record = new PlanToRecord()
                        {
                            WorkType = a.Type,
                            PowerStationId = a.PowerStationId,
                            StartTime = a.StartTime,
                            CreatedBy = a.CreatedBy,
                            EndTime = endtime
                        };
                        List<string> properties2 = new List<string>()
                        {
                            "WorkType",
                            "PowerStationId",
                            "StartTime",
                            "CreatedBy",
                            "EndTime"
                        };

                        await operationRepository.AddToRecord(record, properties2);

                    }

                    #endregion




                    #region 發送Email
                    DateTime EmailNoticeDay;
                    string noticeName;
                    EmailNoticeDay = a.EmailType switch
                    {
                        0 => Updatedtime,
                        1 => Updatedtime.AddDays(-1),
                        2 => Updatedtime.AddDays(-2),
                        3 => Updatedtime.AddDays(-3),
                        4 => Updatedtime.AddDays(-7),
                        _ => Updatedtime.AddYears(999)
                    };
                    noticeName = a.EmailType switch
                    {
                        0 => "此紀錄於當天建立",
                        1 => "此紀錄於一天後建立",
                        2 => "此紀錄於兩天後建立",
                        3 => "此紀錄於三天後建立",
                        4 => "此紀錄於一週後建立",
                        _ => "此紀錄不建立"
                    };
                    string WorkType = a.Type switch
                    {
                        0 => "清洗",
                        1 => "巡檢",
                        _ => "維修"
                    };
                    if(EmailNoticeDay < DateTime.Now && a.IsDelivery == 0)
                    {
                        //Get所有運維人員
                        var personal = await operationRepository.GetOperationPersonnel(a.PowerStationId);
                        var Title = $@"編號:{a.PlanId} - {WorkType}單 - 作業紀錄建立通知";
                        var content = $@" {noticeName}  {Environment.NewLine} 內容描述:{a.Description}";
                        await operationRepository.InsertNoticeSchedule(personal, Title, content);

                        var OperationPlans = new OperationCreatePlan()
                        {
                            Id = a.Id,
                            IsDelivery = 1
                        };
                        List<string> propertiess = new List<string>()
                        {
                            "Id",
                            "IsDelivery"
                        };
                        await operationRepository.UpdateOperationPlan(OperationPlans, propertiess);
                    }

                    
                    #endregion


                }
            }
            catch (Exception exception)
            {
                logger.LogError("【{0}】{1}", nameof(logger), exception.Message);
            }
        }

        /// <summary>
        /// 取得最新的流水號
        /// </summary>
        /// <param name="current">當前的</param>
        /// <param name="pad"></param>
        /// <param name="direction">0: PadLeft；1: PadRight</param>
        /// <returns></returns>
        public string GetLastSerialNumber(string current = "", int pad = 4, byte direction = 0)
        {
            var tempSerialNumber = 0;
            if (!string.IsNullOrEmpty(current))
            {
                tempSerialNumber = Convert.ToInt32(current) + 1;
            }
            else
            {
                tempSerialNumber = 1;
            }

            if (direction == 0)
            {
                return tempSerialNumber.ToString().Trim().PadLeft(pad, '0');
            }
            else
            {
                return tempSerialNumber.ToString().Trim().PadRight(pad, '0');
            }
        }
    }
}
