using EVCB_OCPP.Domain.Extensions;
using EVCB_OCPP.Service;
using EVCB_OCPP.WSServer.Helper;
using EVCB_OCPP.WSServer.Jobs;
using EVCB_OCPP.WSServer.Message;
using EVCB_OCPP.WSServer.Service;
using EVCB_OCPP.WSServer.Service.WsService;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Quartz;

namespace EVCB_OCPP.WSServer
{
    public static class HostedProtalServer
    {
        public static void AddProtalServer(this IServiceCollection services, IConfiguration configuration)
        {
            services.AddMemoryCache();
            //services.AddSingleton<IMemoryCache, DummyMemoryCache>();

            services.AddPortalServerDatabase(configuration);
            services.AddBusinessServiceFactory();

            services.AddHeaderRecordService();
            services.AddOcppWsServer();

            services.AddSingleton<ServerMessageService>();
            services.AddSingleton<LoadingBalanceService>();
            services.AddSingleton<MeterValueDbService>();
            services.AddSingleton<WebDbService>();
            services.AddSingleton<IMainDbService, MainDbService>();
            services.AddSingleton<IConnectionLogdbService, ConnectionLogdbService>();

            services.AddTransient<ProfileHandler>();

            services.AddSingleton<ProtalServer>();
            services.AddHostedService<ProtalServer>(p => p.GetRequiredService<ProtalServer>());

            services.AddProtalServerJob();
        }

        internal static void AddPortalServerDatabase(this IServiceCollection services, IConfiguration configuration)
        {
            services
                .AddMainDbContext(configuration)
                .AddMeterValueDbContext(configuration)
                .AddConnectionLogDbContext(configuration)
                .AddWebDBConetext(configuration);
        }

        public static void AddProtalServerJob(this IServiceCollection services)
        {
            services.AddQuartz(q => {
                q.UseMicrosoftDependencyInjectionJobFactory();

                q.ScheduleJob<ServerUpdateJob>(trigger =>
                    trigger
                    .WithIdentity("ServerUpdateJobTrigger")
                    .StartNow()
                    .WithSimpleSchedule(x => x
                        .WithIntervalInMinutes(3)
                        .RepeatForever())
                );

                q.ScheduleJob<ServerSetFeeJob>(trigger =>
                    trigger
                    .WithIdentity("ServerSetFeeJobTrigger")
                    .StartNow()
                    .WithSimpleSchedule(x => x
                        .WithIntervalInMinutes(1)
                        .RepeatForever())
                );

                q.ScheduleJob<ServerMessageJob>(trigger =>
                    trigger
                    .WithIdentity("ServerMessageJobTrigger")
                    .StartNow()
                    .WithSimpleSchedule(x => x
                        .WithInterval(TimeSpan.FromMilliseconds(500))
                        .RepeatForever())
                );

                q.ScheduleJob<HeartBeatCheckJob>(trigger => 
                    trigger
                    .WithIdentity("HeartBeatCheckJobTrigger")
                    .StartNow()
                    .WithSimpleSchedule(x => x
                        .WithIntervalInSeconds(30)
                        .RepeatForever())
                );

                q.ScheduleJob<HealthCheckTriggerJob>(trigger =>
                    trigger
                    .WithIdentity("HealthCheckTriggerJobTrigger")
                    .StartNow()
                    .WithSimpleSchedule(x => x
                        .WithIntervalInMinutes(1)
                        .RepeatForever())
                );

                q.ScheduleJob<SmartChargingJob>(trigger =>
                    trigger
                    .WithIdentity("SmartChargingJobTrigger")
                    .StartNow()
                    .WithSimpleSchedule(x => x
                        .WithIntervalInMinutes(1)
                        .RepeatForever())
                );

                q.ScheduleJob<DenyModelCheckJob>(trigger =>
                    trigger
                    .WithIdentity("DenyModelCheckJobTrigger")
                    .StartNow()
                    .WithSimpleSchedule(x => x
                        .WithIntervalInMinutes(5)
                        .RepeatForever())
                );

                //q.ScheduleJob<GoogleCheckJob>(trigger =>
                //    trigger
                //    .WithIdentity("GoogleCheckJobTrigger")
                //    .StartNow()
                //    .WithSimpleSchedule(x => x
                //        .WithIntervalInSeconds(5)
                //        .RepeatForever())
                //);
            });

            services.AddQuartzHostedService(opt =>
            {
                opt.WaitForJobsToComplete = true;
            });
        }
    }
}
