using Microsoft.AspNetCore.Mvc;
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.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 MonitorsModel : PageModel
{
    private readonly DatabaseContext _db;
    private readonly MonitoringService _monSvc;
    public MonitorsModel(DatabaseContext db, MonitoringService monSvc) { _db = db; _monSvc = monSvc; }

    public List<Monitor> Monitors { get; set; } = new();

    [BindProperty] public Monitor EditMonitor { get; set; } = new();
    public string? Message { get; set; }

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

        Monitors = await _db.Monitors.OrderBy(m => m.GroupName).ThenBy(m => m.Name).ToListAsync();
        Message = msg;
        return Page();
    }

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

        // If no host, extract from URL
        if (string.IsNullOrWhiteSpace(EditMonitor.Host) && !string.IsNullOrEmpty(EditMonitor.Url))
        {
            try
            {
                var uri = new Uri(EditMonitor.Url);
                EditMonitor.Host = uri.Host;
                if (EditMonitor.Port == null || EditMonitor.Port == 0)
                {
                    EditMonitor.Port = uri.Port;
                }
            }
            catch { }
        }

        if (EditMonitor.Id == 0)
        {
            _db.Monitors.Add(EditMonitor);
        }
        else
        {
            var existing = await _db.Monitors.FindAsync(EditMonitor.Id);
            if (existing == null)
            {
                return RedirectToPage(new { msg = "Monitor not found." });
            }

            existing.Name = EditMonitor.Name;
            existing.Description = EditMonitor.Description;
            existing.Type = EditMonitor.Type;
            existing.Host = EditMonitor.Host;
            existing.Port = EditMonitor.Port;
            existing.Url = EditMonitor.Url;
            existing.ProcessName = EditMonitor.ProcessName;
            existing.IntervalSeconds = EditMonitor.IntervalSeconds;
            existing.TimeoutMs = EditMonitor.TimeoutMs;
            existing.IsActive = EditMonitor.IsActive;
            existing.IsPublic = EditMonitor.IsPublic;
            existing.Tags = EditMonitor.Tags;
            existing.GroupName = EditMonitor.GroupName;
            // new fields
            existing.FailureThreshold = Math.Max(1, EditMonitor.FailureThreshold);
            existing.ExpectedKeyword = EditMonitor.ExpectedKeyword;
            existing.ExpectedStatusCode = EditMonitor.ExpectedStatusCode;
        }

        await _db.SaveChangesAsync();
        return RedirectToPage(new { msg = "Monitor saved." });
    }

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

        var m = await _db.Monitors.FindAsync(id);
        if (m != null) { _db.Monitors.Remove(m); await _db.SaveChangesAsync(); }
        return RedirectToPage(new { msg = "Monitor deleted." });
    }

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

        var m = await _db.Monitors.FindAsync(id);
        if (m != null)
        {
            await _monSvc.CheckMonitorAsync(m);
        }

        return RedirectToPage(new { msg = "Check completed." });
    }
}
