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

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 LogsModel : PageModel
{
    private readonly DatabaseContext _db;
    public LogsModel(DatabaseContext db) => _db = db;

    public List<LogEntry> Entries { get; set; } = new();
    public List<string> Sources { get; set; } = new();
    public int TotalCount { get; set; }
    public int TotalPages { get; set; }

    [BindProperty(SupportsGet = true)] public string? Level { get; set; }
    [BindProperty(SupportsGet = true)] public string? Source { get; set; }
    [BindProperty(SupportsGet = true)] public string? Search { get; set; }
    [BindProperty(SupportsGet = true)] public DateTime? FromDate { get; set; }
    [BindProperty(SupportsGet = true)] public DateTime? ToDate { get; set; }
    [BindProperty(SupportsGet = true)] public int PageIndex { get; set; } = 1;

    private const int PageSize = 100;

    public async Task<IActionResult> OnGetAsync()
    {
        if (HttpContext.Session.GetString("IsAdmin") != "true")
        {
            return RedirectToPage("/Admin/Login");
        }

        Sources = await _db.Logs.Select(l => l.Source).Distinct().OrderBy(s => s).ToListAsync();

        var q = _db.Logs.AsQueryable();

        if (!string.IsNullOrWhiteSpace(Level))
        {
            q = q.Where(l => l.Level == Level.ToLower());
        }

        if (!string.IsNullOrWhiteSpace(Source))
        {
            q = q.Where(l => l.Source == Source);
        }

        if (!string.IsNullOrWhiteSpace(Search))
        {
            q = q.Where(l => l.Message.Contains(Search) || (l.Exception != null && l.Exception.Contains(Search)));
        }

        if (FromDate.HasValue)
        {
            q = q.Where(l => l.Timestamp >= FromDate.Value.ToUniversalTime());
        }

        if (ToDate.HasValue)
        {
            q = q.Where(l => l.Timestamp <= ToDate.Value.AddDays(1).ToUniversalTime());
        }

        TotalCount = await q.CountAsync();
        TotalPages = (int)Math.Ceiling((double)TotalCount / PageSize);

        Entries = await q
            .OrderByDescending(l => l.Timestamp)
            .Skip((PageIndex - 1) * PageSize)
            .Take(PageSize)
            .ToListAsync();

        return Page();
    }
}
