using Predictalytics.Infrastructure.Logging;
using Serilog;
using Serilog.Events;

namespace Predictalytics.WinFormsHost;

internal static class Program
{
    [STAThread]
    static void Main()
    {
        ApplicationConfiguration.Initialize();

        var mainForm = new MainForm();
        var rtbWriteAction = TerminalHelper.CreateWriteAction(mainForm.Terminal, mainForm);

        // ─── Output template matching terminal format ───
        const string textTemplate =
            "[{Timestamp:yyyy-MM-dd HH:mm:ss}] [{Level:u3}] [{SourceContext}] {Message:lj}{NewLine}{Exception}";

        const string simpleTemplate =
            "[{Timestamp:HH:mm:ss}] [{Level:u3}] {Message:lj}{NewLine}{Exception}";

        // ─── Log directory ───
        var logBaseDir = Path.Combine(AppContext.BaseDirectory, "logs");

        Log.Logger = new LoggerConfiguration()
            .MinimumLevel.Information()
            .MinimumLevel.Override("Microsoft.EntityFrameworkCore", LogEventLevel.Warning)
            .MinimumLevel.Override("Microsoft.AspNetCore", LogEventLevel.Warning)
            .MinimumLevel.Override("Microsoft.Hosting", LogEventLevel.Warning)
            .Enrich.FromLogContext()

            // Suppress duplicate entry EF errors completely from logging
            .Filter.ByExcluding(e => e.Exception != null && e.Exception.ToString().Contains("Duplicate entry"))

            // ── Console (simple) ──
            .WriteTo.Console(outputTemplate: simpleTemplate, restrictedToMinimumLevel: LogEventLevel.Warning)

            // ── RichTextBox Terminal ──
            .WriteTo.Sink(new RichTextBoxSink(rtbWriteAction), restrictedToMinimumLevel: LogEventLevel.Warning)

            // ══════════════════════════════════════════════
            //  FILE SINKS — By Level
            // ══════════════════════════════════════════════

            // ALL levels — complete log (daily rotation)
            .WriteTo.File(
                Path.Combine(logBaseDir, "all", "all-.log"),
                rollingInterval: RollingInterval.Day,
                outputTemplate: textTemplate,
                retainedFileCountLimit: 30,
                fileSizeLimitBytes: 50_000_000,
                shared: true)

            // INFO only
            .WriteTo.Logger(lc => lc
                .Filter.ByIncludingOnly(e => e.Level == LogEventLevel.Information)
                .WriteTo.File(
                    Path.Combine(logBaseDir, "info", "info-.log"),
                    rollingInterval: RollingInterval.Day,
                    outputTemplate: textTemplate,
                    retainedFileCountLimit: 14,
                    shared: true))

            // WARNING only
            .WriteTo.Logger(lc => lc
                .Filter.ByIncludingOnly(e => e.Level == LogEventLevel.Warning)
                .WriteTo.File(
                    Path.Combine(logBaseDir, "warning", "warning-.log"),
                    rollingInterval: RollingInterval.Day,
                    outputTemplate: textTemplate,
                    retainedFileCountLimit: 30,
                    shared: true))

            // ERROR + FATAL
            .WriteTo.Logger(lc => lc
                .Filter.ByIncludingOnly(e => e.Level >= LogEventLevel.Error)
                .WriteTo.File(
                    Path.Combine(logBaseDir, "error", "error-.log"),
                    rollingInterval: RollingInterval.Day,
                    outputTemplate: textTemplate,
                    retainedFileCountLimit: 60,
                    shared: true))

            // ══════════════════════════════════════════════
            //  FILE SINKS — By Platform
            // ══════════════════════════════════════════════

            // Polymarket
            .WriteTo.Logger(lc => lc
                .Filter.ByIncludingOnly(e =>
                    e.Properties.ContainsKey("Platform") &&
                    e.Properties["Platform"].ToString().Contains("Polymarket"))
                .WriteTo.File(
                    Path.Combine(logBaseDir, "platforms", "polymarket-.log"),
                    rollingInterval: RollingInterval.Day,
                    outputTemplate: textTemplate,
                    retainedFileCountLimit: 30,
                    shared: true))

            // Limitless
            .WriteTo.Logger(lc => lc
                .Filter.ByIncludingOnly(e =>
                    e.Properties.ContainsKey("Platform") &&
                    e.Properties["Platform"].ToString().Contains("Limitless"))
                .WriteTo.File(
                    Path.Combine(logBaseDir, "platforms", "limitless-.log"),
                    rollingInterval: RollingInterval.Day,
                    outputTemplate: textTemplate,
                    retainedFileCountLimit: 30,
                    shared: true))

            // Azuro
            .WriteTo.Logger(lc => lc
                .Filter.ByIncludingOnly(e =>
                    e.Properties.ContainsKey("Platform") &&
                    e.Properties["Platform"].ToString().Contains("Azuro"))
                .WriteTo.File(
                    Path.Combine(logBaseDir, "platforms", "azuro-.log"),
                    rollingInterval: RollingInterval.Day,
                    outputTemplate: textTemplate,
                    retainedFileCountLimit: 30,
                    shared: true))

            // ══════════════════════════════════════════════
            //  FILE SINK — Worker / Discovery / Scoring
            // ══════════════════════════════════════════════
            .WriteTo.Logger(lc => lc
                .Filter.ByIncludingOnly(e =>
                    e.Properties.ContainsKey("SourceContext") &&
                    e.Properties["SourceContext"].ToString().Contains("Worker"))
                .WriteTo.File(
                    Path.Combine(logBaseDir, "workers", "workers-.log"),
                    rollingInterval: RollingInterval.Day,
                    outputTemplate: textTemplate,
                    retainedFileCountLimit: 14,
                    shared: true))

            .CreateLogger();

        Log.Warning("══════════════════════════════════════════════════════");
        Log.Warning("  🚀 Predictalytics v1.0 — Data retrieval started!");
        Log.Warning("  📊 First platform report in 5 minutes.");
        Log.Warning("══════════════════════════════════════════════════════");

        mainForm.Initialize();
        System.Windows.Forms.Application.Run(mainForm);

        Log.Information("Application shutting down.");
        Log.CloseAndFlush();
    }
}
