using ExperionCrawler.Core.Application.Interfaces;
using ExperionCrawler.Core.Application.Services;
using ExperionCrawler.Infrastructure.Certificates;
using ExperionCrawler.Infrastructure.Csv;
using ExperionCrawler.Infrastructure.Database;
using ExperionCrawler.Infrastructure.OpcUa;
using Microsoft.EntityFrameworkCore;

var builder = WebApplication.CreateBuilder(args);

// ── MVC / Swagger ─────────────────────────────────────────────────────────────
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(c =>
    c.SwaggerDoc("v1", new() { Title = "ExperionCrawler API", Version = "v1" }));

// ── Infrastructure ────────────────────────────────────────────────────────────
builder.Services.AddSingleton<IExperionCertificateService, ExperionCertificateService>();
builder.Services.AddSingleton<IExperionStatusCodeService, ExperionStatusCodeService>();
builder.Services.AddScoped<IExperionOpcClient,  ExperionOpcClient>();
builder.Services.AddScoped<IExperionCsvService, ExperionCsvService>();
builder.Services.AddScoped<AssetLoader>();

// PostgreSQL – Ubuntu 서버에서 별도 설치 없이 동작
Directory.CreateDirectory("data");
builder.Services.AddDbContext<ExperionDbContext>(opt =>
    opt.UseNpgsql(builder.Configuration.GetConnectionString("DefaultConnection")));
builder.Services.AddScoped<IExperionDbService, ExperionDbService>();

// ── Application Services ──────────────────────────────────────────────────────
builder.Services.AddScoped<ExperionCrawlService>();

// ── Text-to-SQL Service ──────────────────────────────────────────────────────
builder.Services.AddScoped<ITextToSqlService, TextToSqlService>();

// ── Realtime & History BackgroundServices ─────────────────────────────────────
builder.Services.AddSingleton<ExperionRealtimeService>();
builder.Services.AddSingleton<IExperionRealtimeService>(
    sp => sp.GetRequiredService<ExperionRealtimeService>());
builder.Services.AddHostedService(
    sp => sp.GetRequiredService<ExperionRealtimeService>());
builder.Services.AddHostedService<ExperionHistoryService>();

// ── OPC UA Server BackgroundService ──────────────────────────────────────────
builder.Services.AddSingleton<ExperionOpcServerService>();
builder.Services.AddSingleton<IExperionOpcServerService>(
    sp => sp.GetRequiredService<ExperionOpcServerService>());
builder.Services.AddHostedService(
    sp => sp.GetRequiredService<ExperionOpcServerService>());

// ── CORS ──────────────────────────────────────────────────────────────────────
builder.Services.AddCors(opt =>
    opt.AddDefaultPolicy(p => p.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader()));

// ── 포트 설정 (Ubuntu 환경: 기본 5000) ───────────────────────────────────────
builder.WebHost.UseUrls("http://0.0.0.0:5000");

var app = builder.Build();

// ── DB 초기화 ─────────────────────────────────────────────────────────────────
using (var scope = app.Services.CreateScope())
{
    var db = scope.ServiceProvider.GetRequiredService<IExperionDbService>();
    await db.InitializeAsync();
}

// ── Middleware ────────────────────────────────────────────────────────────────
app.UseCors();

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseDefaultFiles();   // index.html
app.UseStaticFiles();    // wwwroot/
app.MapControllers();
app.MapFallbackToFile("index.html");

app.Run();
