using SharedKernel.Extensions;
using SharedKernel.Helpers;
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.Crypto.List
{
    public class IndexModel(IMediator mediator) : PageModel
    {
        [BindProperty(SupportsGet = true)]
        public QueryParams Query { get; set; } = new();

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

        public sealed class QueryParams
        {
            [Range(1, int.MaxValue)]
            [DisplayName("페이지 번호")]
            public int PageNum { get; set; } = 1;

            [Range(1, 100)]
            [DisplayName("페이지 당 수")]
            public ushort PerPage { get; set; } = 20;

            [DisplayName("카테고리")]
            public int? CategoryID { get; set; }

            [DisplayName("검색어")]
            public string? Keyword { get; set; }

            [DisplayName("거래쌍 구분")]
            public ushort Tab { get; set; } = 0;

            public bool? IsActive { get; set; }
            public bool? IsWarning { get; set; }
            public bool? IsNew { get; set; }
            public bool? IsDelisted { get; set; }
        }

        public int Total { get; set; }

        public List<(
            int Num,
            int ID,
            string Market,
            string Symbol,
            string KorName,
            string EngName,
            string? LogoImage,
            IReadOnlyList<string> CategoryNames,
            char IsActive,
            char IsWarning,
            char IsNew,
            char IsDelisted,
            string? UpdatedAt,
            string CreatedAt,
            string EditURL
        )> List { get; set; } = [];

        public int AllCount { get; set; }
        public int KrwCount { get; set; }
        public int BtcCount { get; set; }
        public int UsdtCount { get; set; }

        public Pagination? Pagination { get; set; }

        public async Task OnGetAsync(CancellationToken ct)
        {
            if (!ModelState.IsValid)
            {
                return;
            }

            var categories = await mediator.Send(new GetCryptoCategories.Query(), ct);
            Categories = [..categories.List.Select(c => new SelectListItem(c.Name, c.ID.ToString()))];

            var result = await mediator.Send(new SearchCoins.Query(
                Query.CategoryID,
                Query.Keyword,
                Query.IsActive,
                Query.IsWarning,
                Query.IsNew,
                Query.IsDelisted,
                Query.PageNum,
                Query.PerPage,
                Query.Tab
            ), ct);

            Total = result.Total;
            AllCount = result.AllCount;
            KrwCount = result.KrwCount;
            BtcCount = result.BtcCount;
            UsdtCount = result.UsdtCount;

            List = [..result.List.Select(c => (
                c.Num,
                c.ID,
                string.Join(", ", c.CoinMarkets.Select(x => x.Market)),
                c.Symbol,
                c.KorName,
                c.EngName,
                c.LogoImage,
                c.CategoryNames,
                c.IsActive ? 'Y' : 'N',
                c.IsWarning ? 'Y' : 'N',
                c.IsNew ? 'Y' : 'N',
                c.IsDelisted ? 'Y' : 'N',
                c.UpdatedAt.GetDateAt() ?? "-",
                c.CreatedAt.GetDateAt(),
                EditURL: $"/Crypto/List/Edit/{c.ID}{Request.QueryString}"
            ))];

            Pagination = new Pagination(result.Total, Query.PageNum, Query.PerPage);
        }

        public async Task<IActionResult> OnPostDeleteAsync(int[] ids, CancellationToken ct)
        {
            try
            {
                await mediator.Send(new DeleteCoin.Command(ids), ct);

                TempData["SuccessMessage"] = $"{ids.Length}개 코인이 삭제되었습니다.";
            }
            catch (Exception e)
            {
                TempData["ErrorMessages"] = e.Message;
            }

            return RedirectToPage("/Crypto/List/Index", Query);
        }

        public async Task<IActionResult> OnPostSyncAsync(CancellationToken ct)
        {
            try
            {
                var result = await mediator.Send(new SyncCoins.Command(), ct);

                TempData["SuccessMessage"] = $"동기화 완료: 신규 {result.Created}개, 갱신 {result.Updated}개, 상폐 {result.Delisted}개";
            }
            catch (Exception e)
            {
                TempData["ErrorMessages"] = e.Message;
            }

            return RedirectToPage("/Crypto/List/Index", Query);
        }
    }
}