using AutoMapper;
using Hangfire;
using Lada.Framework.Data.Domains.Identity;
using Lada.Framework.Data.Mappings.DbContexts;
using Ladaer.BackEnd.Infrastructures.AppSettings;
using Ladaer.BackEnd.Infrastructures.DTO;
using Ladaer.BackEnd.Infrastructures.Services;
using Microsoft.AspNetCore.Identity;
using Microsoft.Data.SqlClient;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System.Data;

namespace Ladaer.BackEnd.Infrastructures.Startup
{
    /// <summary>
    /// Lớp mở rộng để đăng ký các dịch vụ và cấu hình ứng dụng.
    /// </summary>
    public static class GeneralRegister
    {
        private static readonly string policyName = "default";

        /// <summary>
        /// Đăng ký các dịch vụ chung.
        /// </summary>
        /// <param name="services">Đối tượng IServiceCollection.</param>
        /// <param name="Configuration">Đối tượng IConfiguration.</param>
        public static void RegisterGeneralServices(this IServiceCollection services, IConfiguration Configuration)
        {
            services.AddControllers()
                .AddNewtonsoftJson(x =>
                {
                    x.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
                    x.SerializerSettings.ContractResolver = new DefaultContractResolver();
                });

            string connectionString = Configuration.GetConnectionString("LadaConnection");

            services.AddDbContext<LadaDbContext>(options =>
                        options.UseSqlServer(connectionString, b => b.MigrationsAssembly("Ladaer.BackEnd")), ServiceLifetime.Scoped);




            // Khai báo Dapper
            services.AddTransient<IDbConnection>((sp) => new SqlConnection(connectionString));

            services.AddMemoryCache();

            services.AddCors(options =>
            {
                options.AddPolicy(policyName, builder => builder.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod());
            });

            services.AddHangfire(x => x.UseSqlServerStorage(Configuration.GetConnectionString("LadaConnection")));
            services.AddHangfireServer();
        }

        /// <summary>
        /// Cấu hình và chạy ứng dụng.
        /// </summary>
        /// <param name="app">Đối tượng WebApplication.</param>
        public static void ConfigAndRunApp(this WebApplication app)
        {
            // Configure the HTTP request pipeline.
            if (app.Environment.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler(appBuilder =>
                {
                    appBuilder.Run(async context =>
                    {
                        context.Response.StatusCode = 500;
                        context.Response.ContentType = "application/json";

                        var error = context.Features.Get<Microsoft.AspNetCore.Diagnostics.IExceptionHandlerFeature>();
                        if (error != null)
                        {
                            var response = new
                            {
                                error = "Internal Server Error",
                                message = error.Error.Message
                            };
                            await context.Response.WriteAsync(System.Text.Json.JsonSerializer.Serialize(response));
                        }
                    });
                });
                app.UseHsts();
            }

            app.UseSwagger();
            app.UseSwaggerUI();
            app.UseHangfireDashboard("/hangfire");

            app.UseCors(policyName);

            app.UseHttpsRedirection();
            app.UseStaticFiles();

            app.UseAuthentication();
            app.UseAuthorization();

            app.MapControllers();

            AutoMapperConfig.Init();

            // Đăng ký Hangfire recurring job cho VAT Invoice sync
            RecurringJob.AddOrUpdate<Infrastructures.Jobs.VatInvoiceSyncJob>(
                "vat-invoice-sync",
                job => job.Execute(),
                "0 3 * * *",  // Cron: 3:00 AM hàng ngày
                new RecurringJobOptions
                {
                    TimeZone = TimeZoneInfo.FindSystemTimeZoneById("SE Asia Standard Time")
                });

            // Đăng ký Hangfire recurring job cho Auto Penalty
            RecurringJob.AddOrUpdate<Infrastructures.Jobs.AutoPenaltyJob>(
                "auto-penalty-check",
                job => job.Execute(),
                "30 10 * * *",  // Cron: 10:30 AM hàng ngày (sau CutoffTime mặc định 10:00 AM)
                new RecurringJobOptions
                {
                    TimeZone = TimeZoneInfo.FindSystemTimeZoneById("SE Asia Standard Time")
                });

            app.Run();
        }
    }
}
