using Domain.Entities.Forum.ValueObject;
using SharedKernel.Helpers;
using SharedKernel.Extensions;
using Application.Abstractions.Messaging;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Mvc.Rendering;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;

namespace Admin.Pages.Forum.Reports.Comment
{
    public class IndexModel(IMediator mediator) : PageModel
    {
        [BindProperty(SupportsGet = true)]
        public QueryParams Query { get; set; } = new();

        public sealed class QueryParams
        {
            public int? BoardID { get; set; }
            public int? PostID { get; set; }
            public int? CommentID { get; set; }
            public int? Search { get; set; }
            public string? Keyword { get; set; }
            public string? StartAt { get; set; }
            public string? EndAt { get; set; }
            public byte? Status { get; set; }
            public byte? Type { get; set; }

            [Range(1, int.MaxValue)]
            [DisplayName("??? ??")]
            public int PageNum { get; set; } = 1;

            [Range(1, 100)]
            [DisplayName("??? ?? ?")]
            public ushort PerPage { get; set; } = 20;
        }

        public int Total { get; set; } = 0;
        public List<SelectListItem> BoardList { get; set; } = [];

        public List<(
            int Num,
            int ID,
            int BoardID,
            string BoardName,
            int PostID,
            string PostSubject,
            int CommentID,
            string Comment,
            int MemberID,
            string? MemberName,
            ReportType Type,
            string? Reason,
            ReportStatus Status,
            string? Memo,
            string? UpdatedAt,
            string CreatedAt
        )> List { get; set; } = [];

        public Pagination? Pagination { get; set; }

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

            var boards = await mediator.Send(new SearchBoards.Query(null, null, 1, 500), ct);
            BoardList = [..boards.List.Select(c => new SelectListItem
            {
                Value = c.ID.ToString(),
                Text = $"[{c.BoardGroupName}] {c.Name}"
            })];

            var result = await mediator.Send(new SearchCommentReports.Query(
                Query.BoardID,
                Query.PostID,
                Query.CommentID,
                Query.Search,
                Query.Keyword,
                Query.Status,
                Query.Type,
                Query.StartAt,
                Query.EndAt,
                Query.PageNum,
                Query.PerPage
            ), ct);

            Total = result.Total;
            List = [..result.List.Select(c => (
                c.Num,
                c.ID,
                c.BoardID,
                c.BoardName,
                c.PostID,
                c.PostSubject,
                c.CommentID,
                c.Comment,
                c.MemberID,
                c.MemberName ?? "-",
                c.Type,
                c.Reason ?? "-",
                c.Status,
                c.Memo ?? "-",
                c.UpdatedAt.GetDateAt() ?? "-",
                c.CreatedAt.GetDateAt()
            ))];

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

        public async Task<IActionResult> OnPostUpdateStatusAsync(int[] ids, byte status, string? memo, CancellationToken ct)
        {
            try
            {
                await mediator.Send(new UpdateCommentReportStatus.Command(ids, (ReportStatus)status, memo), ct);

                TempData["SuccessMessage"] = $"{ids.Length}?? ??? ???????.";
            }
            catch (Exception e)
            {
                TempData["ErrorMessages"] = e.Message;
            }

            return RedirectToPage("/Forum/Reports/Comment/Index", Query);
        }

        public async Task<IActionResult> OnPostDeleteAsync(int[] ids, CancellationToken ct)
        {
            try
            {
                await mediator.Send(new DeleteCommentReport.Command(ids), ct);

                TempData["SuccessMessage"] = $"{ids.Length}?? ???????.";
            }
            catch (Exception e)
            {
                TempData["ErrorMessages"] = e.Message;
            }

            return RedirectToPage("/Forum/Reports/Comment/Index", Query);
        }
    }
}