using Infrastructure.Persistence.Identity;
using Application.Abstractions.Messaging;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;

namespace Admin.Pages.Member.Wallet.List;

public class ViewModel(IMediator mediator, UserManager<ApplicationUser> userManager) : PageModel
{
    public WalletInfo Wallet { get; set; } = new();
    public MemberInfo Member { get; set; } = new();

    [BindProperty]
    [Required(ErrorMessage = "충전 금액을 입력해주세요.")]
    [Range(-99999999, 99999999, ErrorMessage = "금액은 -99,999,999 ~ 99,999,999 범위입니다.")]
    [DisplayName("충전 금액")]
    public long Amount { get; set; }

    [BindProperty]
    [Required(ErrorMessage = "비밀번호를 입력해주세요.")]
    [DisplayName("비밀번호")]
    public string Password { get; set; } = default!;

    [BindProperty]
    [MaxLength(1000, ErrorMessage = "메모는 {1}자 이하로 입력하세요.")]
    [DisplayName("메모")]
    public string? Memo { get; set; }

    public sealed class WalletInfo
    {
        public int ID { get; set; }
        public string Balance { get; set; } = "0";
    }

    public sealed class MemberInfo
    {
        public int ID { get; set; }
        public string Email { get; set; } = default!;
        public string? GradeName { get; set; }
    }

    public async Task<IActionResult> OnGetAsync(int id, CancellationToken ct)
    {
        try
        {
            var result = await mediator.Send(new GetWallet.Query(id), ct);

            Wallet = new WalletInfo
            {
                ID = result.WalletID,
                Balance = result.Balance.ToString("N0")
            };

            Member = new MemberInfo
            {
                ID = result.MemberID,
                Email = result.MemberEmail,
                GradeName = result.GradeName
            };
        }
        catch (Exception e)
        {
            TempData["ErrorMessages"] = e.Message;
            return RedirectToPage("Index");
        }

        return Page();
    }

    public async Task<IActionResult> OnPostChargeAsync(int id, CancellationToken ct)
    {
        try
        {
            if (Amount == 0)
            {
                throw new ArgumentException("충전 금액을 입력해주세요.");
            }

            var admin = await userManager.GetUserAsync(User);
            if (admin is null || !await userManager.CheckPasswordAsync(admin, Password))
            {
                throw new UnauthorizedAccessException("비밀번호가 올바르지 않습니다.");
            }

            await mediator.Send(new ChargeWallet.Command(
                id,
                Amount,
                Memo
            ), ct);

            TempData["SuccessMessage"] = Amount > 0
                ? $"{Amount:N0}P 충전되었습니다."
                : $"{Math.Abs(Amount):N0}P 차감되었습니다.";
        }
        catch (Exception e)
        {
            TempData["ErrorMessages"] = e.Message;
        }

        return RedirectToPage("View", new { id });
    }
}