using Domain.Entities.Forum.Boards;
using SharedKernel.Extensions;
using MediatR;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace Admin.Pages.Forum.Board.Meta;

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

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

    public sealed class InputModel
    {
        public int ID { get; set; }
        public int BoardID { get; set; }
        public bool EnableExp { get; set; }
        public bool ShowExpGuide { get; set; }

        // 경험치 지급량
        public ushort PostWriteExp { get; set; }
        public ushort CommentWriteExp { get; set; }
        public ushort FileUploadExp { get; set; }
        public short FileDownloadExp { get; set; }
        public short OtherPostReadExp { get; set; }
        public ushort OtherPostLikeExp { get; set; }
        public ushort OtherPostDisLikeExp { get; set; }
        public ushort OtherCommentLikeExp { get; set; }
        public ushort OtherCommentDisLikeExp { get; set; }
        public ushort OwnPostReadExp { get; set; }
        public ushort OwnPostLikeExp { get; set; }
        public short OwnPostDisLikeExp { get; set; }
        public ushort OwnCommentLikeExp { get; set; }
        public short OwnCommentDisLikeExp { get; set; }

        // 경험치 회수량
        public ushort PostWriteUndoExp { get; set; }
        public ushort CommentWriteUndoExp { get; set; }
        public ushort FileUploadUndoExp { get; set; }
        public ushort OtherPostReadUndoExp { get; set; }
        public ushort OtherPostLikeUndoExp { get; set; }
        public ushort OtherPostDisLikeUndoExp { get; set; }
        public ushort OtherCommentLikeUndoExp { get; set; }
        public ushort OtherCommentDisLikeUndoExp { get; set; }
        public ushort OwnPostReadUndoExp { get; set; }
        public ushort OwnPostLikeUndoExp { get; set; }
        public ushort OwnPostDisLikeUndoExp { get; set; }
        public ushort OwnCommentLikeUndoExp { get; set; }
        public ushort OwnCommentDisLikeUndoExp { get; set; }

        // 경험치 지급 기한
        public ushort PostWriteExpWithinDays { get; set; }
        public ushort CommentWriteExpWithinDays { get; set; }
        public ushort FileUploadExpWithinDays { get; set; }
        public ushort OtherPostReadExpWithinDays { get; set; }
        public ushort OtherPostLikeExpWithinDays { get; set; }
        public ushort OtherPostDisLikeExpWithinDays { get; set; }
        public ushort OtherCommentLikeExpWithinDays { get; set; }
        public ushort OtherCommentDisLikeExpWithinDays { get; set; }
        public ushort OwnPostReadExpWithinDays { get; set; }
        public ushort OwnPostLikeExpWithinDays { get; set; }
        public ushort OwnPostDisLikeExpWithinDays { get; set; }
        public ushort OwnCommentLikeExpWithinDays { get; set; }
        public ushort OwnCommentDisLikeExpWithinDays { 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 meta = await mediator.Send(new GetBoardMeta.Query(id), ct);

        Input = new InputModel
        {
            ID = meta.ID,
            BoardID = meta.BoardID,
            EnableExp = meta.Exp.EnableExp,
            ShowExpGuide = meta.Exp.ShowExpGuide,
            PostWriteExp = meta.Exp.PostWriteExp,
            CommentWriteExp = meta.Exp.CommentWriteExp,
            FileUploadExp = meta.Exp.FileUploadExp,
            FileDownloadExp = meta.Exp.FileDownloadExp,
            OtherPostReadExp = meta.Exp.OtherPostReadExp,
            OtherPostLikeExp = meta.Exp.OtherPostLikeExp,
            OtherPostDisLikeExp = meta.Exp.OtherPostDisLikeExp,
            OtherCommentLikeExp = meta.Exp.OtherCommentLikeExp,
            OtherCommentDisLikeExp = meta.Exp.OtherCommentDisLikeExp,
            OwnPostReadExp = meta.Exp.OwnPostReadExp,
            OwnPostLikeExp = meta.Exp.OwnPostLikeExp,
            OwnPostDisLikeExp = meta.Exp.OwnPostDisLikeExp,
            OwnCommentLikeExp = meta.Exp.OwnCommentLikeExp,
            OwnCommentDisLikeExp = meta.Exp.OwnCommentDisLikeExp,
            PostWriteUndoExp = meta.Exp.PostWriteUndoExp,
            CommentWriteUndoExp = meta.Exp.CommentWriteUndoExp,
            FileUploadUndoExp = meta.Exp.FileUploadUndoExp,
            OtherPostReadUndoExp = meta.Exp.OtherPostReadUndoExp,
            OtherPostLikeUndoExp = meta.Exp.OtherPostLikeUndoExp,
            OtherPostDisLikeUndoExp = meta.Exp.OtherPostDisLikeUndoExp,
            OtherCommentLikeUndoExp = meta.Exp.OtherCommentLikeUndoExp,
            OtherCommentDisLikeUndoExp = meta.Exp.OtherCommentDisLikeUndoExp,
            OwnPostReadUndoExp = meta.Exp.OwnPostReadUndoExp,
            OwnPostLikeUndoExp = meta.Exp.OwnPostLikeUndoExp,
            OwnPostDisLikeUndoExp = meta.Exp.OwnPostDisLikeUndoExp,
            OwnCommentLikeUndoExp = meta.Exp.OwnCommentLikeUndoExp,
            OwnCommentDisLikeUndoExp = meta.Exp.OwnCommentDisLikeUndoExp,
            PostWriteExpWithinDays = meta.Exp.PostWriteExpWithinDays,
            CommentWriteExpWithinDays = meta.Exp.CommentWriteExpWithinDays,
            FileUploadExpWithinDays = meta.Exp.FileUploadExpWithinDays,
            OtherPostReadExpWithinDays = meta.Exp.OtherPostReadExpWithinDays,
            OtherPostLikeExpWithinDays = meta.Exp.OtherPostLikeExpWithinDays,
            OtherPostDisLikeExpWithinDays = meta.Exp.OtherPostDisLikeExpWithinDays,
            OtherCommentLikeExpWithinDays = meta.Exp.OtherCommentLikeExpWithinDays,
            OtherCommentDisLikeExpWithinDays = meta.Exp.OtherCommentDisLikeExpWithinDays,
            OwnPostReadExpWithinDays = meta.Exp.OwnPostReadExpWithinDays,
            OwnPostLikeExpWithinDays = meta.Exp.OwnPostLikeExpWithinDays,
            OwnPostDisLikeExpWithinDays = meta.Exp.OwnPostDisLikeExpWithinDays,
            OwnCommentLikeExpWithinDays = meta.Exp.OwnCommentLikeExpWithinDays,
            OwnCommentDisLikeExpWithinDays = meta.Exp.OwnCommentDisLikeExpWithinDays
        };
    }

    public async Task<IActionResult> OnPostAsync(CancellationToken ct)
    {
        try
        {
            if (!ModelState.IsValid)
            {
                throw new Exception(ModelState.GetErrorMessages());
            }

            await mediator.Send(new UpdateBoardMeta.Command(
                Input.ID,
                Input.BoardID,
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                new BoardMetaExp
                {
                    EnableExp = Input.EnableExp,
                    ShowExpGuide = Input.ShowExpGuide,
                    PostWriteExp = Input.PostWriteExp,
                    CommentWriteExp = Input.CommentWriteExp,
                    FileUploadExp = Input.FileUploadExp,
                    FileDownloadExp = Input.FileDownloadExp,
                    OtherPostReadExp = Input.OtherPostReadExp,
                    OtherPostLikeExp = Input.OtherPostLikeExp,
                    OtherPostDisLikeExp = Input.OtherPostDisLikeExp,
                    OtherCommentLikeExp = Input.OtherCommentLikeExp,
                    OtherCommentDisLikeExp = Input.OtherCommentDisLikeExp,
                    OwnPostReadExp = Input.OwnPostReadExp,
                    OwnPostLikeExp = Input.OwnPostLikeExp,
                    OwnPostDisLikeExp = Input.OwnPostDisLikeExp,
                    OwnCommentLikeExp = Input.OwnCommentLikeExp,
                    OwnCommentDisLikeExp = Input.OwnCommentDisLikeExp,
                    PostWriteUndoExp = Input.PostWriteUndoExp,
                    CommentWriteUndoExp = Input.CommentWriteUndoExp,
                    FileUploadUndoExp = Input.FileUploadUndoExp,
                    OtherPostReadUndoExp = Input.OtherPostReadUndoExp,
                    OtherPostLikeUndoExp = Input.OtherPostLikeUndoExp,
                    OtherPostDisLikeUndoExp = Input.OtherPostDisLikeUndoExp,
                    OtherCommentLikeUndoExp = Input.OtherCommentLikeUndoExp,
                    OtherCommentDisLikeUndoExp = Input.OtherCommentDisLikeUndoExp,
                    OwnPostReadUndoExp = Input.OwnPostReadUndoExp,
                    OwnPostLikeUndoExp = Input.OwnPostLikeUndoExp,
                    OwnPostDisLikeUndoExp = Input.OwnPostDisLikeUndoExp,
                    OwnCommentLikeUndoExp = Input.OwnCommentLikeUndoExp,
                    OwnCommentDisLikeUndoExp = Input.OwnCommentDisLikeUndoExp,
                    PostWriteExpWithinDays = Input.PostWriteExpWithinDays,
                    CommentWriteExpWithinDays = Input.CommentWriteExpWithinDays,
                    FileUploadExpWithinDays = Input.FileUploadExpWithinDays,
                    OtherPostReadExpWithinDays = Input.OtherPostReadExpWithinDays,
                    OtherPostLikeExpWithinDays = Input.OtherPostLikeExpWithinDays,
                    OtherPostDisLikeExpWithinDays = Input.OtherPostDisLikeExpWithinDays,
                    OtherCommentLikeExpWithinDays = Input.OtherCommentLikeExpWithinDays,
                    OtherCommentDisLikeExpWithinDays = Input.OtherCommentDisLikeExpWithinDays,
                    OwnPostReadExpWithinDays = Input.OwnPostReadExpWithinDays,
                    OwnPostLikeExpWithinDays = Input.OwnPostLikeExpWithinDays,
                    OwnPostDisLikeExpWithinDays = Input.OwnPostDisLikeExpWithinDays,
                    OwnCommentLikeExpWithinDays = Input.OwnCommentLikeExpWithinDays,
                    OwnCommentDisLikeExpWithinDays = Input.OwnCommentDisLikeExpWithinDays
                }), ct);

            TempData["SuccessMessage"] = "경험치 설정이 저장되었습니다.";
        }
        catch (Exception e)
        {
            TempData["ErrorMessages"] = e.Message;
        }

        return Redirect($"/Forum/Board/Meta/Exp/{Input.BoardID}{Request.QueryString}");
    }
}