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

namespace EonaCat.LogStack.Status.Pages.Admin;

// 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 IncidentsModel : PageModel
{
    private readonly DatabaseContext _database;
    public IncidentsModel(DatabaseContext database) => _database = database;

    public List<Incident> Incidents { get; set; } = new();
    public List<Monitor> Monitors { get; set; } = new();
    public string? Message { get; set; }

    [BindProperty] public Incident NewIncident { get; set; } = new();

    public class UpdateDto
    {
        public int IncidentId { get; set; }
        public IncidentStatus Status { get; set; }
        public string Message { get; set; } = "";
    }

    [BindProperty] public UpdateDto UpdateDtoModel { get; set; } = new();

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

        Incidents = await _database.Incidents
            .Include(i => i.Updates)
            .Include(i => i.Monitor)
            .OrderByDescending(i => i.CreatedAt)
            .ToListAsync();

        Monitors = await _database.Monitors.Where(m => m.IsActive).ToListAsync();
        return Page();
    }

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

        NewIncident.CreatedAt = DateTime.UtcNow;
        NewIncident.UpdatedAt = DateTime.UtcNow;
        _database.Incidents.Add(NewIncident);
        await _database.SaveChangesAsync();
        Message = "Incident created.";
        return await OnGetAsync();
    }

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

        var incident = await _database.Incidents.FindAsync(UpdateDtoModel.IncidentId);
        if (incident != null)
        {
            incident.Status = UpdateDtoModel.Status;
            incident.UpdatedAt = DateTime.UtcNow;
            if (UpdateDtoModel.Status == IncidentStatus.Resolved)
            {
                incident.ResolvedAt = DateTime.UtcNow;
            }

            _database.IncidentUpdates.Add(new IncidentUpdate
            {
                IncidentId = incident.Id,
                Message = UpdateDtoModel.Message,
                Status = UpdateDtoModel.Status
            });
            await _database.SaveChangesAsync();
        }

        Message = "Update posted.";
        return await OnGetAsync();
    }

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

        var incident = await _database.Incidents.FindAsync(id);
        if (incident != null)
        {
            incident.Status = IncidentStatus.Resolved;
            incident.ResolvedAt = DateTime.UtcNow;
            incident.UpdatedAt = DateTime.UtcNow;
            _database.IncidentUpdates.Add(new IncidentUpdate
            {
                IncidentId = id,
                Message = "Incident resolved.",
                Status = IncidentStatus.Resolved
            });
            await _database.SaveChangesAsync();
        }

        Message = "Incident resolved.";
        return await OnGetAsync();
    }

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

        var incident = await _database.Incidents.FindAsync(id);
        if (incident != null)
        {
            _database.Incidents.Remove(incident);
            await _database.SaveChangesAsync();
        }

        Message = "Incident deleted.";
        return await OnGetAsync();
    }
}
