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.Popup;

public class EditModel(IMediator mediator) : PageModel
{
    [BindProperty]
    public string? QueryString { get; set; }

    public List<SelectListItem> Positions { get; private set; } = [];

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

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

        [DisplayName("위치")]
        [Required(ErrorMessage = "{0}은 필수입니다.")]
        public int PositionID { get; set; }

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

        [DisplayName("내용")]
        [DataType(DataType.Html)]
        [StringLength(4000, ErrorMessage = "{0}은 {1}자 이하로 입력하세요.")]
        public string? Content { get; set; }

        [DisplayName("주소")]
        [DataType(DataType.Url)]
        [StringLength(255, ErrorMessage = "{0}은 {1}자 이하로 입력하세요.")]
        public string? Link { get; set; }

        [DisplayName("시작 일시")]
        [DisplayFormat(DataFormatString = "{0:yyyy-MM-ddTHH:mm}", ApplyFormatInEditMode = true)]
        public DateTime? StartAt { get; set; }

        [DisplayName("종료 일시")]
        [DisplayFormat(DataFormatString = "{0:yyyy-MM-ddTHH:mm}", ApplyFormatInEditMode = true)]
        public DateTime? EndAt { get; set; }

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

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

        public string? UpdatedAt { get; set; }
        public string CreatedAt { get; set; } = default!;
    }

    public async Task OnGetAsync(int id, CancellationToken ct)
    {
        QueryString = HttpContext.Request.QueryString.HasValue ? HttpContext.Request.QueryString.Value!.TrimStart('?') : "";

        await LoadPositionsAsync(ct);

        var popup = await mediator.Send(new GetPopup.Query(id), ct);
        if (popup is null)
        {
            return;
        }

        Input.ID = popup.ID;
        Input.PositionID = popup.PositionID;
        Input.Subject = popup.Subject;
        Input.Content = popup.Content;
        Input.Link = popup.Link;
        Input.StartAt = popup.StartAt;
        Input.EndAt = popup.EndAt;
        Input.Order = popup.Order;
        Input.IsActive = popup.IsActive;
        Input.UpdatedAt = popup.UpdatedAt.GetDateAt();
        Input.CreatedAt = popup.CreatedAt.GetDateAt();
    }

    public async Task<IActionResult> OnPostAsync(CancellationToken ct)
    {
        try
        {
            if (!ModelState.IsValid)
            {
                await LoadPositionsAsync(ct);
                return Page();
            }

            var command = new UpdatePopup.Command(
                Input.ID,
                Input.PositionID,
                Input.Subject,
                Input.Content,
                Input.Link,
                Input.StartAt,
                Input.EndAt,
                Input.Order,
                Input.IsActive
            );

            await mediator.Send(command, ct);

            TempData["SuccessMessage"] = $"{Input.Subject} 팝업이 수정되었습니다.";
        }
        catch (Exception e)
        {
            TempData["ErrorMessages"] = e.Message;
        }

        return Redirect($"/Popup/Edit/{Input.ID}?{QueryString}");
    }

    private async Task LoadPositionsAsync(CancellationToken ct)
    {
        var result = await mediator.Send(new GetPopupPositions.Query(), ct);

        Positions = [..result.List.Select(x => new SelectListItem(
            x.Subject,
            x.ID.ToString())
        )];
    }
}