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

namespace Admin.Pages.Forum.Board;

public class PrefixModel(IMediator mediator) : PageModel
{
    public int BoardID { get; set; }
    public List<(int ID, string Name)> BoardList { get; set; } = [];
    public string? QueryString { get; set; }
    public int Total { get; set; }

    public List<(
        int ID,
        string Name,
        string? Color,
        short Order,
        int Posts,
        bool IsActive,
        string? UpdatedAt,
        string CreatedAt
    )> Data { get; set; } = [];

    [BindProperty]
    public InputModel Input { get; set; } = new();

    public sealed class InputModel
    {
        public string? Name { get; set; }
        public string? Color { get; set; }
        public short Order { get; set; }
    }

    [BindProperty]
    public List<UpdateItemModel> UpdateItems { get; set; } = [];

    public sealed class UpdateItemModel
    {
        [Required]
        [DisplayName("ID")]
        public int ID { get; set; }

        [Required]
        [MaxLength(50)]
        [DisplayName("말머리")]
        public string Name { get; set; } = default!;

        [Required]
        [DisplayName("색상")]
        public string? Color { get; set; }

        [Required]
        [Range(-9999, 9999)]
        [DisplayName("순서")]
        public short Order { get; set; }

        [DisplayName("사용 여부")]
        public bool IsActive { get; set; }
    }

    [BindProperty]
    public int DeleteID { get; set; }

    public async Task OnGetAsync(int id, CancellationToken ct)
    {
        BoardID = id;
        QueryString = Request.QueryString.ToString();

        var boards = await mediator.Send(new SearchBoards.Query(null, null, 1, 100), ct);
        BoardList = [..boards.List.Select(c => (c.ID, c.Name))];

        var result = await mediator.Send(new GetBoardPrefixes.Query(id), ct);
        Total = result.Total;
        Data = [..result.List.Select(c => (
            c.ID,
            c.Name,
            c.Color,
            c.Order,
            c.Posts,
            c.IsActive,
            c.UpdatedAt,
            c.CreatedAt
        ))];
    }

    public async Task<IActionResult> OnPostCreateAsync(int id, CancellationToken ct)
    {
        try
        {
            if (string.IsNullOrWhiteSpace(Input.Name))
                throw new Exception("말머리 이름을 입력하세요.");

            await mediator.Send(new SaveBoardPrefixes.Command(
                id,
                new SaveBoardPrefixes.Command.Create(
                    Input.Name,
                    Input.Color,
                    Input.Order
                ),
                null,
                null
            ), ct);

            TempData["SuccessMessage"] = "말머리가 추가되었습니다.";
        }
        catch (Exception e)
        {
            TempData["ErrorMessages"] = e.Message;
        }

        return Redirect($"/Forum/Board/Prefix/{id}{Request.QueryString}");
    }

    public async Task<IActionResult> OnPostSaveAsync(int id, CancellationToken ct)
    {
        try
        {
            foreach (var key in ModelState.Keys.Where(k => k.StartsWith("Input.")).ToList())
            {
                ModelState.Remove(key);
            }

            if (!ModelState.IsValid)
            {
                throw new Exception(ModelState.GetErrorMessages());
            }

            var updates = UpdateItems.Select(x => new SaveBoardPrefixes.Command.Update(
                x.ID,
                x.Name,
                x.Color,
                x.Order,
                x.IsActive
            )).ToList();

            await mediator.Send(new SaveBoardPrefixes.Command(
                id,
                null,
                updates,
                null
            ), ct);

            TempData["SuccessMessage"] = "말머리 목록이 저장되었습니다.";
        }
        catch (Exception e)
        {
            TempData["ErrorMessages"] = e.Message;
        }

        return Redirect($"/Forum/Board/Prefix/{id}{Request.QueryString}");
    }

    public async Task<IActionResult> OnPostDeleteAsync(int id, CancellationToken ct)
    {
        try
        {
            ModelState.Clear();

            await mediator.Send(new SaveBoardPrefixes.Command(
                id,
                null,
                null,
                [DeleteID]
            ), ct);

            TempData["SuccessMessage"] = "말머리가 삭제되었습니다.";
        }
        catch (Exception e)
        {
            TempData["ErrorMessages"] = e.Message;
        }

        return Redirect($"/Forum/Board/Prefix/{id}{Request.QueryString}");
    }
}