using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using EonaCat.LogStack.Status.Data;
using EonaCat.LogStack.Status.Models;
using EonaCat.LogStack.Status.Services;
using Monitor = EonaCat.LogStack.Status.Models.Monitor;

namespace EonaCat.LogStack.Status.Pages;

// 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 IndexModel : PageModel
{
    private readonly DatabaseContext _db;
    private readonly MonitoringService _monSvc;
    private readonly AuthenticationService _authSvc;

    public IndexModel(DatabaseContext db, MonitoringService monSvc, AuthenticationService authSvc)
    {
        _db = db;
        _monSvc = monSvc;
        _authSvc = authSvc;
    }

    public DashboardStats Stats { get; set; } = new();
    public List<Monitor> Monitors { get; set; } = new();
    public List<CertificateEntry> Certificates { get; set; } = new();
    public List<Incident> ActiveIncidents { get; set; } = new();
    public bool IsAdmin { get; set; }
    public bool ShowUptime { get; set; }
    public bool ShowIncidents { get; set; }
    public string SiteName { get; set; } = "Status";
    public Dictionary<int, List<MonitorCheck>> RecentChecks { get; set; } = new();

    public async Task OnGetAsync()
    {
        IsAdmin = HttpContext.Session.GetString("IsAdmin") == "true";
        ShowUptime = (await _authSvc.GetSettingAsync("ShowUptimePublicly", "true")) == "true";
        ShowIncidents = (await _authSvc.GetSettingAsync("ShowIncidentsPublicly", "true")) == "true";
        SiteName = await _authSvc.GetSettingAsync("SiteName", "Status");
        Stats = await _monSvc.GetStatsAsync(IsAdmin);

        var query = _db.Monitors.Where(m => m.IsActive);
        if (!IsAdmin)
        {
            query = query.Where(m => m.IsPublic);
        }

        Monitors = await query.OrderBy(m => m.GroupName).ThenBy(m => m.Name).ToListAsync();

        Certificates = await _db.Certificates.OrderBy(c => c.ExpiresAt).ToListAsync();

        // Active incidents (public or admin)
        var incidentQuery = _db.Incidents
            .Include(i => i.Updates)
            .Where(i => i.Status != IncidentStatus.Resolved);
        if (!IsAdmin)
        {
            incidentQuery = incidentQuery.Where(i => i.IsPublic);
        }

        ActiveIncidents = await incidentQuery.OrderByDescending(i => i.CreatedAt).ToListAsync();

        // Recent checks for uptime bars (last 7 days, up to 90 per monitor)
        var monitorIds = Monitors.Select(m => m.Id).ToList();
        var cutoff = DateTime.UtcNow.AddDays(-7);
        var checks = await _db.MonitorChecks
            .Where(c => monitorIds.Contains(c.MonitorId) && c.CheckedAt >= cutoff)
            .OrderByDescending(c => c.CheckedAt)
            .ToListAsync();

        foreach (var m in Monitors)
        {
            RecentChecks[m.Id] = checks.Where(c => c.MonitorId == m.Id).Take(90).Reverse().ToList();
        }
    }
}
