using SharedKernel.Helpers;
using SharedKernel.Extensions;
using MediatR;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;

namespace Admin.Pages.Director.AccessLog;

public class IndexModel(IMediator mediator) : PageModel
{
    [BindProperty(SupportsGet = true)]
    public QueryParams Query { get; set; } = new();

    public sealed class QueryParams
    {
        [Range(1, int.MaxValue)]
        [DisplayName("페이지 번호")]
        public int PageNum { get; set; } = 1;

        [Range(1, 100)]
        [DisplayName("페이지 목록 수")]
        public ushort PerPage { get; set; } = 20;

        [DisplayName("검색 조건")]
        [Range(1, 4, ErrorMessage = "{0}이(가) 올바르지 않습니다.")]
        public int? Search { get; set; }

        [DisplayName("검색어")]
        [MaxLength(255, ErrorMessage = "{0}은(는) {1}자 이하로 입력하세요.")]
        public string? Keyword { get; set; }

        [DisplayName("Method")]
        public string? Method { get; set; }

        [DisplayName("시작일")]
        public string? StartAt { get; set; }

        [DisplayName("종료일")]
        public string? EndAt { get; set; }
    }

    public int Total { get; set; } = 0;

    public List<(
        int Num,
        long ID,
        string UserID,
        string? UserName,
        string Method,
        string Path,
        string? QueryString,
        int StatusCode,
        long ElapsedMs,
        string? MenuName,
        string? IpAddress,
        string CreatedAt
    )> List { get; set; } = [];

    public Pagination? Pagination { get; set; }

    public async Task OnGetAsync(CancellationToken ct)
    {
        if (!ModelState.IsValid)
        {
            return;
        }

        var result = await mediator.Send(new SearchAdminAccessLogs.Query(
            Query.PageNum,
            Query.PerPage,
            Query.Search,
            Query.Keyword,
            Query.Method,
            Query.StartAt,
            Query.EndAt
        ), ct);

        Total = result.Total;
        List = [..result.List.Select(c => (
            c.Num,
            c.ID,
            c.UserID,
            c.UserName,
            c.Method,
            c.Path,
            c.QueryString,
            c.StatusCode,
            c.ElapsedMs,
            c.MenuName,
            c.IpAddress,
            c.CreatedAt.GetDateAt()
        ))];

        Pagination = new Pagination(result.Total, Query.PageNum, Query.PerPage);
    }

    public async Task<IActionResult> OnPostDeleteAsync(long[] ids, CancellationToken ct)
    {
        try
        {
            if (ids.Length == 0)
            {
                throw new Exception("삭제할 항목을 선택해주세요.");
            }

            await mediator.Send(new DeleteAdminAccessLog.Command(ids), ct);

            TempData["SuccessMessage"] = $"{ids.Length}건이 삭제되었습니다.";
        }
        catch (Exception e)
        {
            TempData["ErrorMessages"] = e.Message;
        }

        return RedirectToPage(Query);
    }
}