using Microsoft.EntityFrameworkCore;
using EonaCat.LogStack.Status.Models;
using Monitor = EonaCat.LogStack.Status.Models.Monitor;

namespace EonaCat.LogStack.Status.Data;

// This file is part of the EonaCat project(s) which is released under the Apache License.
// See the LICENSE file or go to https://EonaCat.com/License for full license details.

public class DatabaseContext : DbContext
{
    public DatabaseContext(DbContextOptions<DatabaseContext> options) : base(options) { }

    public DbSet<Monitor> Monitors => Set<Monitor>();
    public DbSet<MonitorCheck> MonitorChecks => Set<MonitorCheck>();
    public DbSet<CertificateEntry> Certificates => Set<CertificateEntry>();
    public DbSet<LogEntry> Logs => Set<LogEntry>();
    public DbSet<AppSettings> Settings => Set<AppSettings>();

    public DbSet<Incident> Incidents => Set<Incident>();
    public DbSet<IncidentUpdate> IncidentUpdates => Set<IncidentUpdate>();
    public DbSet<AlertRule> AlertRules => Set<AlertRule>();

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        // existing indexes
        modelBuilder.Entity<MonitorCheck>().HasIndex(c => new { c.MonitorId, c.CheckedAt });
        modelBuilder.Entity<LogEntry>().HasIndex(l => l.Timestamp);
        modelBuilder.Entity<LogEntry>().HasIndex(l => new { l.Level, l.Source });
        modelBuilder.Entity<AppSettings>().HasIndex(s => s.Key).IsUnique();

        // incident indexes
        modelBuilder.Entity<Incident>().HasIndex(i => i.Status);
        modelBuilder.Entity<Incident>().HasIndex(i => i.CreatedAt);
        modelBuilder.Entity<IncidentUpdate>().HasIndex(u => u.IncidentId);

        // alert rule indexes
        modelBuilder.Entity<AlertRule>().HasIndex(a => a.MonitorId);

        // relationships
        modelBuilder.Entity<Incident>()
            .HasMany(i => i.Updates)
            .WithOne(u => u.Incident)
            .HasForeignKey(u => u.IncidentId)
            .OnDelete(DeleteBehavior.Cascade);

        modelBuilder.Entity<Monitor>()
            .HasMany(m => m.AlertRules)
            .WithOne(a => a.Monitor)
            .HasForeignKey(a => a.MonitorId)
            .OnDelete(DeleteBehavior.Cascade);

        // Seed default settings
        modelBuilder.Entity<AppSettings>().HasData(
            new AppSettings { Id = 1, Key = "AdminPasswordHash", Value = BCrypt.Net.BCrypt.EnhancedHashPassword("adminEonaCat") },
            new AppSettings { Id = 2, Key = "SiteName", Value = "Status" },
            new AppSettings { Id = 3, Key = "ShowLogsPublicly", Value = "false" },
            new AppSettings { Id = 4, Key = "ShowUptimePublicly", Value = "true" },
            new AppSettings { Id = 5, Key = "MaxLogRetentionDays", Value = "30" },
            new AppSettings { Id = 6, Key = "AlertEmail", Value = "" },
            // new settings
            new AppSettings { Id = 7, Key = "AlertWebhookUrl", Value = "" },
            new AppSettings { Id = 8, Key = "ShowIncidentsPublicly", Value = "true" },
            new AppSettings { Id = 9, Key = "AutoCreateIncidents", Value = "false" }
        );
    }
}
