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

namespace Admin.Pages.Forum.Posts.List
{
    public class WriteModel(IMediator mediator) : PageModel
    {
        public string? ReturnUrl { get; set; }
        public List<SelectListItem> BoardList { get; set; } = [];

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

        public sealed class InputModel
        {
            [DisplayName("게시판")]
            [Required(ErrorMessage = "{0}은 필수입니다.")]
            public int BoardID { get; set; }

            [DisplayName("말머리")]
            public int? BoardPrefixID { get; set; }

            [DisplayName("제목")]
            [Required(ErrorMessage = "{0}은 필수입니다.")]
            [StringLength(255, ErrorMessage = "{0}은 {1}자 이내로 입력하세요.")]
            public string Subject { get; set; } = null!;

            [DisplayName("내용")]
            public string? Content { get; set; }

            [DisplayName("대표 이미지")]
            public IFormFile? ThumbnailFile { get; set; }

            [DisplayName("첨부파일")]
            public List<IFormFile>? Files { get; set; }

            [DisplayName("태그")]
            public string? TagsInput { get; set; }

            [DisplayName("공지")]
            public bool IsNotice { get; set; } = false;

            [DisplayName("비밀")]
            public bool IsSecret { get; set; } = false;

            [DisplayName("익명")]
            public bool IsAnonymous { get; set; } = false;

            public string? ReturnUrl { get; set; }
        }

        public async Task OnGetAsync(CancellationToken ct)
        {
            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}"
            })];

            ReturnUrl = Request.Headers.Referer.ToString();
        }

        public async Task<IActionResult> OnGetPrefixesAsync(int boardID, CancellationToken ct)
        {
            var result = await mediator.Send(new GetBoardPrefixes.Query(boardID), ct);
            var items = result.List.Where(c => c.IsActive).Select(c => new { id = c.ID, name = c.Name });

            var meta = await mediator.Send(new GetBoardMeta.Query(boardID), ct);
            var isQnA = meta.List.Layout == BoardLayout.QnA;

            return new JsonResult(new { items, isQnA });
        }

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

                var tags = string.IsNullOrWhiteSpace(Input.TagsInput)
                    ? null
                    : Input.TagsInput.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries).ToList();

                await mediator.Send(new CreatePost.Command(
                    Input.BoardID,
                    Input.BoardPrefixID,
                    Input.Subject,
                    Input.Content,
                    Input.ThumbnailFile,
                    Input.Files,
                    tags,
                    Input.IsNotice,
                    Input.IsSecret,
                    Input.IsAnonymous
                ), ct);

                TempData["SuccessMessage"] = "게시글이 등록되었습니다.";

                return RedirectToPage("/Forum/Posts/List/Index");
            }
            catch (Exception e)
            {
                TempData["ErrorMessages"] = e.Message;

                return RedirectToPage("/Forum/Posts/List/Write");
            }
        }
    }
}
