using Microsoft.Extensions.FileProviders; // 정적파일 관련
using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Mvc;
using StackExchange.Redis;
using bitforum.Middleware;
using bitforum.Repository;
using bitforum.Services;
using bitforum.Workers;
using bitforum.Extensions;

var builder = WebApplication.CreateBuilder(args);

// Add http context accessor
builder.Services.AddHttpContextAccessor();

// ModelState 자동 검증 비활성화
builder.Services.Configure<ApiBehaviorOptions>(options =>
{
    options.SuppressModelStateInvalidFilter = true;
});

/**
 * =======================================================================================================================================================
 */

// SQL 연결 설정
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<DefaultDbContext>(options => options.UseSqlServer(connectionString));
builder.Services.AddDbContext<UserContext>(options => options.UseSqlServer(connectionString));

// Redis 연결 설정
var redisConfig = builder.Configuration.GetSection("Redis").Get<RedisConfig>();
var redisConnectionString = $"{redisConfig.Host}:{redisConfig.Port},password={redisConfig.Password}";
builder.Services.AddSingleton<IConnectionMultiplexer>(ConnectionMultiplexer.Connect(redisConnectionString));

/**
 * =======================================================================================================================================================
 */

builder.Services.ConfigureIdentity(builder.Configuration); // Identity 인증 전달자 (관리자)
builder.Services.ConfigureAuthentication(builder.Configuration); //JWT 인증 전달자 (사용자)
builder.Services.ConfigureCors(builder.Configuration); // CORS 설정

/**
 * =======================================================================================================================================================
 * Repository, Service 추가
 */

builder.Services.AddSingleton<IRedisRepository, RedisRepository>();
builder.Services.AddSingleton<IConfigRepository, ConfigRepository>();
builder.Services.AddSingleton<ISetupService, SetupService>();
builder.Services.AddSingleton<IConfigService, ConfigService>();
builder.Services.AddScoped<IEmailVerifyTokenRepository, EmailVerifyTokenRepository>();
builder.Services.AddScoped<IEmailVerifyNumberRepository, EmailVerifyNumberRepository>();
builder.Services.AddScoped<IMemberRepository, MemberRepository>();
builder.Services.AddScoped<IJwtAuthService, JwtAuthService>();
builder.Services.AddScoped<IFileUploadService, FileUploadService>();
builder.Services.AddScoped<IEmailSender, EmailSender>();
builder.Services.AddScoped<IMailService, MailService>();
builder.Services.AddHostedService<MailQueueWorker>();

/**
 * =======================================================================================================================================================
 * Add services to the container.
 */

builder.Services.AddControllersWithViews(); // MVC 패턴 활성화
builder.Services.AddRazorPages(); // Razor Pages 활성화
builder.Services.AddControllers(); // Web API 컨트롤러 활성화

builder.Logging.ClearProviders(); // 기본 로깅 제공자를 모두 삭제
builder.Logging.AddConsole(); // 터미널에 로그 출력
builder.Logging.AddDebug(); // 디버깅 창에 로그 출력

var app = builder.Build();

/**
 * =======================================================================================================================================================
 */

app.UseCors("AllowFrontend");
app.UseMiddleware<Common>();
app.UseMiddleware<IPFilter>();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

/**
 * =======================================================================================================================================================
 */

app.UseHttpsRedirection();

// 정적 파일을 제공하는 미들웨어 추가
app.UseStaticFiles();
app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "node_modules")),
    RequestPath = "/node_modules"
});

/**
 * =======================================================================================================================================================
 */

// 환경변수 불러오기
var env = Environment.GetEnvironmentVariable("environmentVariables");

// 환경변수를 static 변수로 저장
app.Use(async (context, next) =>
{
    context.Items["env"] = env;
    await next();
});

/*
app.Use(async (context, next) =>
{
    Console.WriteLine("요청 수신됨: " + context.GetClientIP());
    Console.WriteLine("요청 수신됨: " + context.Request.Host.Value);
    Console.WriteLine("요청 수신됨: " + context.Request.Path);
    Console.WriteLine("요청 헤더: " + context.Request.Headers["Authorization"]);
    Console.WriteLine("요청 쿠키: " + context.Request.Headers["Cookie"]);
    Console.WriteLine("요청 쿠키: " + context.Request.Headers["Host"]);

    var clientIp = context.Connection.RemoteIpAddress?.ToString();
    var clientPort = context.Connection.RemotePort;
    var forwardedIp = context.Request.Headers["X-Forwarded-For"].ToString();
    var host = context.Request.Host.Value;

    Console.WriteLine($"요청 수신됨 - IP: {clientIp}:{clientPort}, 프록시 IP: {forwardedIp}, 호스트: {host}");
    Console.WriteLine("요청 Origin" + context.Request.Headers["Origin"].ToString());

    await next();
    Console.WriteLine("응답 헤더 (Set-Cookie): " + context.Response.Headers["Set-Cookie"]);
});
*/

/**
 * =======================================================================================================================================================
 */

app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.MapRazorPages();

// MVC 라우팅
app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}"
);

// API 라우팅
app.MapControllers();
app.Run();
