using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Volo.Abp.Application.Services;
using Yi.Framework.AiHub.Domain.Alipay;
using Yi.Framework.AiHub.Domain.Managers;
using Yi.Framework.AiHub.Application.Contracts.Dtos.Pay;
using Yi.Framework.AiHub.Domain.Shared.Enums;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Yi.Framework.AiHub.Application.Contracts.IServices;
using Volo.Abp;
using Yi.Framework.AiHub.Domain.Entities.Pay;
using Yi.Framework.SqlSugarCore.Abstractions;
using System.ComponentModel;
using System.Reflection;
using Volo.Abp.Users;
using Yi.Framework.AiHub.Application.Contracts.Dtos.Recharge;

namespace Yi.Framework.AiHub.Application.Services;

/// <summary>
/// 支付服务
/// </summary>
public class PayService : ApplicationService, IPayService
{
    private readonly AlipayManager _alipayManager;
    private readonly PayManager _payManager;
    private readonly ILogger<PayService> _logger;
    private readonly ISqlSugarRepository<PayOrderAggregateRoot, Guid> _payOrderRepository;
    private readonly IRechargeService _rechargeService;
    private readonly PremiumPackageManager _premiumPackageManager;

    public PayService(
        AlipayManager alipayManager,
        PayManager payManager,
        ILogger<PayService> logger,
        ISqlSugarRepository<PayOrderAggregateRoot, Guid> payOrderRepository,
        IRechargeService rechargeService,
        PremiumPackageManager premiumPackageManager)
    {
        _alipayManager = alipayManager;
        _payManager = payManager;
        _logger = logger;
        _payOrderRepository = payOrderRepository;
        _rechargeService = rechargeService;
        _premiumPackageManager = premiumPackageManager;
    }

    /// <summary>
    /// 创建订单并发起支付
    /// </summary>
    /// <param name="input">创建订单输入</param>
    /// <returns>订单创建结果</returns>
    [Authorize]
    [HttpPost("pay/Order")]
    public async Task<CreateOrderOutput> CreateOrderAsync(CreateOrderInput input)
    {
        // 1. 通过PayManager创建订单（内部会验证VIP资格）
        var order = await _payManager.CreateOrderAsync(input.GoodsType);

        // 2. 通过AlipayManager发起页面支付
        var paymentPageHtml = await _alipayManager.PaymentPageAsync(
            order.GoodsName,
            order.OutTradeNo,
            order.TotalAmount,
            input.ReturnUrl);

        // 3. 返回结果
        return new CreateOrderOutput
        {
            OrderId = order.Id,
            OutTradeNo = order.OutTradeNo,
            PaymentPageHtml = paymentPageHtml.Body
        };
    }

    /// <summary>
    /// 支付宝异步通知处理
    /// </summary>
    /// <param name="form">表单数据</param>
    /// <returns></returns>
    [HttpPost("pay/AlipayNotify")]
    [AllowAnonymous]
    public async Task<string> AlipayNotifyAsync([FromForm] IFormCollection form)
    {
        // 1. 将表单数据转换为字典，保持原始顺序
        var notifyData = new Dictionary<string, string>();
        foreach (var item in form)
        {
            notifyData[item.Key] = item.Value.ToString();
        }

        var signStr = string.Join("&", notifyData.Select(kv => $"{kv.Key}={kv.Value}"));
        _logger.LogInformation($"收到支付宝回调通知：{signStr}");

        // 2. 验证签名
        await _alipayManager.VerifyNotifyAsync(notifyData);

        // 3. 记录支付通知
        await _payManager.RecordPayNoticeAsync(notifyData, signStr);

        // 4. 更新订单状态
        var outTradeNo = notifyData.GetValueOrDefault("out_trade_no", string.Empty);
        var tradeStatus = notifyData.GetValueOrDefault("trade_status", string.Empty);
        var tradeNo = notifyData.GetValueOrDefault("trade_no", string.Empty);

        if (!string.IsNullOrEmpty(outTradeNo) && !string.IsNullOrEmpty(tradeStatus))
        {
            var status = ParseTradeStatus(tradeStatus);
            var order = await _payManager.UpdateOrderStatusAsync(outTradeNo, status, tradeNo);

            _logger.LogInformation("订单状态更新成功，订单号：{OutTradeNo}，状态：{TradeStatus}", outTradeNo, tradeStatus);

            // 验证交易状态，只有交易成功才执行充值逻辑
            if (status != TradeStatusEnum.TRADE_SUCCESS)
            {
                _logger.LogError($"订单 {outTradeNo} 状态为 {tradeStatus}，不执行充值逻辑");
                return "success";
            }

            // 5. 根据商品类型进行不同的处理
            if (order.GoodsType.IsPremiumPackage())
            {
                var tokenAmount = order.GoodsType.GetTokenAmount();
                var packageName = order.GoodsType.GetDisplayName();
                // 处理尊享包商品：创建尊享包记录
                await _premiumPackageManager.CreatePremiumPackageAsync(
                    order.UserId,
                    tokenAmount,
                    packageName,
                    order.TotalAmount,
                    "自助充值",
                    expireMonths: null // 尊享包不设置过期时间，或者可以根据需求设置
                );

                _logger.LogInformation(
                    $"用户 {order.UserId} 购买尊享包成功，订单号：{outTradeNo}，商品：{order.GoodsName}");
            }
            else if (order.GoodsType.IsVipService())
            {
                // 处理VIP服务商品：充值VIP
                await _rechargeService.RechargeVipAsync(new RechargeCreateInput
                {
                    UserId = order.UserId,
                    RechargeAmount = order.TotalAmount,
                    Content = order.GoodsName,
                    Months = order.GoodsType.GetValidMonths(),
                    Remark = "自助充值",
                    ContactInfo = null
                });

                _logger.LogInformation(
                    $"用户 {order.UserId} 充值VIP成功，订单号：{outTradeNo}，月数：{order.GoodsType.GetValidMonths()}");
            }
            else
            {
                _logger.LogWarning($"未知的商品类型：{order.GoodsType}，订单号：{outTradeNo}");
            }
        }
        else
        {
            throw new AlipayException($"回调格式错误");
        }

        return "success";
    }

    /// <summary>
    /// 查询订单状态
    /// </summary>
    /// <param name="input">查询订单状态输入</param>
    /// <returns>订单状态信息</returns>
    [HttpGet("pay/OrderStatus")]
    [Authorize]
    public async Task<QueryOrderStatusOutput> QueryOrderStatusAsync([FromQuery] QueryOrderStatusInput input)
    {
        // 通过PayManager查询订单
        var order = await _payOrderRepository.GetFirstAsync(x => x.OutTradeNo == input.OutTradeNo);
        if (order == null)
        {
            throw new UserFriendlyException($"订单不存在：{input.OutTradeNo}");
        }

        return new QueryOrderStatusOutput
        {
            OrderId = order.Id,
            OutTradeNo = order.OutTradeNo,
            TradeNo = order.TradeNo,
            TradeStatus = order.TradeStatus,
            TradeStatusDescription = GetTradeStatusDescription(order.TradeStatus),
            TotalAmount = order.TotalAmount,
            GoodsName = order.GoodsName,
            GoodsType = order.GoodsType,
            CreationTime = order.CreationTime,
            LastModificationTime = order.LastModificationTime
        };
    }

    /// <summary>
    /// 获取商品列表
    /// </summary>
    /// <param name="input">获取商品列表输入</param>
    /// <returns>商品列表</returns>
    [HttpGet("pay/GoodsList")]
    public async Task<List<GoodsListOutput>> GetGoodsListAsync([FromQuery] GetGoodsListInput input)
    {
        var goodsList = new List<GoodsListOutput>();

        // 获取当前用户的累加充值金额（仅已登录用户）
        decimal totalRechargeAmount = 0m;
        if (CurrentUser.IsAuthenticated)
        {
            totalRechargeAmount = await _payManager.GetUserTotalRechargeAmountAsync(CurrentUser.GetId());
        }

        // 遍历所有商品枚举
        foreach (GoodsTypeEnum goodsType in Enum.GetValues(typeof(GoodsTypeEnum)))
        {
            // 如果指定了商品类别，则过滤
            if (input.GoodsCategoryType.HasValue)
            {
                var goodsCategory = goodsType.GetGoodsCategory();
                if (goodsCategory != input.GoodsCategoryType.Value)
                {
                    continue; // 跳过不匹配的商品
                }
            }

            var originalPrice = goodsType.GetTotalAmount();
            decimal actualPrice = originalPrice;
            decimal? discountAmount = null;
            string? discountDescription = null;

            // 如果是尊享包商品，计算折扣
            if (goodsType.IsPremiumPackage())
            {

                
                if (CurrentUser.IsAuthenticated)
                {
                    discountAmount = goodsType.CalculateDiscount(totalRechargeAmount);
                    actualPrice = goodsType.GetDiscountedPrice(totalRechargeAmount);
                    if (discountAmount > 0)
                    {
                        discountDescription = $"根据累积充值已优惠 ¥{discountAmount:F2}";
                    }
                    else
                    {
                        discountDescription = $"累积充值过低，暂无优惠";
                    }
                }
                else
                {
                    discountDescription = $"登录后查看优惠";
                }
            }

            var goodsItem = new GoodsListOutput
            {
                GoodsName = goodsType.GetChineseName(),
                OriginalPrice = originalPrice,
                ReferencePrice = goodsType.GetReferencePrice(),
                GoodsPrice = actualPrice,
                GoodsCategory = goodsType.GetGoodsCategory().ToString(),
                Remark = goodsType.GetRemark(),
                DiscountAmount = discountAmount,
                DiscountDescription = discountDescription,
                GoodsType = goodsType
            };

            goodsList.Add(goodsItem);
        }

        return goodsList;
    }


    /// <summary>
    /// 获取交易状态描述
    /// </summary>
    /// <param name="tradeStatus">交易状态</param>
    /// <returns>状态描述</returns>
    private string GetTradeStatusDescription(TradeStatusEnum tradeStatus)
    {
        var fieldInfo = tradeStatus.GetType().GetField(tradeStatus.ToString());
        var descriptionAttribute = fieldInfo?.GetCustomAttribute<DescriptionAttribute>();
        return descriptionAttribute?.Description ?? "未知状态";
    }

    /// <summary>
    /// 解析交易状态
    /// </summary>
    /// <param name="tradeStatus">状态字符串</param>
    /// <returns></returns>
    private TradeStatusEnum ParseTradeStatus(string tradeStatus)
    {
        if (Enum.TryParse<TradeStatusEnum>(tradeStatus, out var result))
        {
            return result;
        }

        return TradeStatusEnum.WAIT_TRADE;
    }
}