using CloudGaming.Code.Account;
using CloudGaming.Code.AppExtend;
using CloudGaming.Code.DataAccess;
using CloudGaming.Code.Payment;
using CloudGaming.DtoModel.Account.User;
using CloudGaming.DtoModel.Payment;
using CloudGaming.Model.DbSqlServer.Db_User;

using HuanMeng.DotNetCore.MultiTenant.Contract;
using HuanMeng.DotNetCore.Redis;
using HuanMeng.DotNetCore.Utility;

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage;

using System.Text;

namespace CloudGaming.PayApi.Controllers
{
    /// <summary>
    /// 支付中心
    /// </summary>
    /// <param name="logger"></param>
    /// <param name="httpContextAccessor"></param>
    /// <param name="serviceProvider"></param>
    [Route("api/[controller]")]
    [ApiController]
    public class PayController(ILogger<PayController> logger, IHttpContextAccessor httpContextAccessor, IServiceProvider serviceProvider) : ControllerBase
    {

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        [HttpGet("{tenant?}/{pay?}/{orderId?}/{sign?}")]
        public async Task<string> Get(string? tenant, string? pay, string? orderId, string? sign)
        {
            return await PayCallback(logger, httpContextAccessor, serviceProvider, tenant, pay, orderId, sign);
        }

        /// <summary>
        /// 支付中心回调
        /// </summary>
        /// <param name="tenant"></param>
        /// <param name="pay"></param>
        /// <param name="orderId"></param>
        /// <param name="sign"></param>
        /// <returns></returns>
        [HttpPost("{tenant?}/{pay?}/{orderId?}/{sign?}")]
        public async Task<string> Post(string? tenant, string? pay, string? orderId, string? sign)
        {
            return await PayCallback(logger, httpContextAccessor, serviceProvider, tenant, pay, orderId, sign);

        }

        private static async Task<string> PayCallback(ILogger<PayController> logger, IHttpContextAccessor httpContextAccessor, IServiceProvider serviceProvider, string? tenant, string? pay, string? orderId, string? sign)
        {
            var context = httpContextAccessor.HttpContext;
            context.Request.EnableBuffering(); // Enable buffering to allow the body to be read multiple times
            using (var reader = new StreamReader(context.Request.Body, Encoding.UTF8, true, 1024, leaveOpen: true))
            {
                var bodyContent = await reader.ReadToEndAsync();
                logger.LogInformation($"请求支付回调接口，请求路径: {context.Request.Path}, 请求Body: {bodyContent}");
                context.Request.Body.Position = 0;
            }
            #region 验证签名

            var orderInfo = PaymentExtend.ParseCustomString(orderId);
            string newSign = $"{tenant}{orderId}{orderInfo.UserId}";
            newSign = MD5Encryption.ComputeMD5Hash(newSign);
            //签名不对
            if (newSign != sign)
            {
                logger.LogError($"{orderId}订单支付签名不对==>{newSign}==>{context.Request.Path}");
                return "error;签名不对";
            }
            #endregion
            var appConfig = AppConfigurationExtend.GetAppConfigIdentifier(tenant);
            if (appConfig == null)
            {
                return "error;租户不存在";
            }
            //重复请求锁
            var baseKey = $"pay:lock:{orderId}";

            var redis = appConfig.GetRedisDataBase();
            if (!redis.StringSetLock(baseKey, "", 10))
            {
                return "success";
            }
            DAO dao = new DAO(serviceProvider, appConfig);
            //查询意向订单
            var intentOrder = await dao.DaoUser.Context.T_User_IntentOrder.FirstOrDefaultAsync(it => it.OrderId == orderId);
            if (intentOrder == null)
            {
                redis.KeyDelete(baseKey);
                return "error;订单不存在";
            }
            if (intentOrder.Status != (int)OrderState.已下单)
            {
                redis.KeyDelete(baseKey);
                return $"success";
            }
            intentOrder.Status = (int)OrderState.正在发货;
            await dao.DaoUser.Context.SaveChangesAsync();

            var product = await dao.DaoPhone.Context.T_Products.Where(it => it.ProductId == intentOrder.ProductId).FirstOrDefaultAsync();
            if (product == null)
            {
                intentOrder.Status = (int)OrderState.发货失败;
                await dao.DaoUser.Context.SaveChangesAsync();
                return $"error;订单不存在";
            }
            var user = await dao.DaoUser.Context.T_User.FirstOrDefaultAsync(it => it.Id == intentOrder.UserId);
            if (user == null)
            {
                intentOrder.Status = (int)OrderState.发货失败;
                await dao.DaoUser.Context.SaveChangesAsync();
                return $"error;用户不存在";
            }
            using (IDbContextTransaction transaction = dao.DaoUser.Context.Database.BeginTransaction(System.Data.IsolationLevel.ReadUncommitted))
            {
                try
                {
                    T_User_OrderItems orderItems = new T_User_OrderItems();
                    orderItems.PayUrl = context.Request.Path;
                    //orderItems.
                    await product.OrderRewardsNoWorkAsync(user, pay, orderId, intentOrder.Price, intentOrder.Channel ?? "", intentOrder.CreatedAt, dao, orderItems);
                    //intentOrder = await dao.daoDbMiaoYu.context.T_User_IntentOrder.FirstOrDefaultAsync(it => it.OrderId == orderId);
                    intentOrder.Status = (int)OrderState.已完成;
                    await dao.DaoUser.Context.SaveChangesAsync();
                    await transaction.CommitAsync();
                }
                catch (Exception ex)
                {
                    logger.LogError($"请求支付回调接口，发货失败，请求路径: {context.Request.Path}", ex);
                    await transaction.RollbackAsync();
                    intentOrder.Status = (int)OrderState.发货失败;
                    await dao.DaoUser.Context.SaveChangesAsync();
                    redis.KeyDelete(baseKey);
                    return $"error;出现异常{ex.Message}";
                }
            }
            redis.KeyDelete(baseKey);
            var userDiamond = await dao.DaoUser.Context.T_User_Currency.Where(it => it.UserId == user.Id && it.CurrencyType == (int)UserCurrencyType.钻石).FirstOrDefaultAsync();
            //刷新钻石缓存
            await AccountExtend.RefreshUserInfo(user.Id, redis, (int)(userDiamond?.CurrencyMoney ?? 0), intentOrder.Price > 0 ? true : false);
            return "success";
        }
    }
}
