using Alipay.EasySDK.Factory;

using CloudGaming.Code.Aliyun;
using CloudGaming.Code.Contract;
using CloudGaming.Code.WeChat;
using CloudGaming.DtoModel.Mall;
using CloudGaming.DtoModel.Payment;

using SKIT.FlurlHttpClient.Wechat.TenpayV3;
using SKIT.FlurlHttpClient.Wechat.TenpayV3.Settings;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CloudGaming.Code.Payment;

/// <summary>
/// 
/// </summary>
public static class PaymentExtend
{
    private static WechatTenpayClientOptions wechatTenpayClientOptions { get; set; } = new WechatTenpayClientOptions();
    private static WeChatConfig weChatConfig { get; set; }
    private static WechatTenpayClient wxClient { get; set; }
    /// <summary>
    /// 支付
    /// </su0mmary>
    /// <param name="builder"></param>
    /// <returns></returns>
    public static IHostApplicationBuilder AddPayment(this IHostApplicationBuilder builder)
    {

        AddAlipay(builder.Configuration);
        AddWeChat(builder.Configuration);
        return builder;
    }

    /// <summary>
    /// 加载微信支付
    /// </summary>
    /// <param name="configuration"></param>
    public static void AddWeChat(IConfiguration configuration)
    {
        var _weChatConfig = configuration.GetSection("Payment:WeChatConfig").Get<WeChatConfig>();
        if (_weChatConfig == null)
        {
            Console.WriteLine("微信支付失败");
            //throw new Exception("微信支付失败");
            return;
        }
        weChatConfig = _weChatConfig;
        var manager = new InMemoryCertificateManager();
        /* 仅列出必须配置项。也包含一些诸如超时时间、UserAgent 等的配置项 */
        wechatTenpayClientOptions = new WechatTenpayClientOptions()
        {

            MerchantId = weChatConfig.MchId,
            MerchantV3Secret = weChatConfig.Key,
            MerchantCertificateSerialNumber = weChatConfig.MerchantCertificateSerialNumber,
            MerchantCertificatePrivateKey = weChatConfig.MerchantCertificatePrivateKey,
            PlatformCertificateManager = manager
        };
        wxClient = new WechatTenpayClient(wechatTenpayClientOptions);
    }

    /// <summary>
    /// 
    /// </summary>
    public static Alipay.EasySDK.Kernel.Config AlipayConfig { get; set; }
    /// <summary>
    /// 支付
    /// </summary>
    /// <param name="configuration"></param>
    public static void AddAlipay(IConfiguration configuration)
    {
        var _config = configuration.GetSection("Payment:AlipayConfig").Get<Alipay.EasySDK.Kernel.Config>();

        if (_config == null)
        {
            Console.WriteLine("接入支付失败");
            return;
        }
        var config = new Alipay.EasySDK.Kernel.Config()
        {
            Protocol = "https",
            GatewayHost = "openapi.alipay.com",
            SignType = "RSA2",
            AppId = _config.AppId,
            // 为避免私钥随源码泄露，推荐从文件中读取私钥字符串而不是写入源码中
            MerchantPrivateKey = _config.MerchantPrivateKey,
            // 如果采用非证书模式，则无需赋值上面的三个证书路径，改为赋值如下的支付宝公钥字符串即可
            AlipayPublicKey = _config.AlipayPublicKey,
            //可设置异步通知接收服务地址（可选）
            NotifyUrl = _config.NotifyUrl,
        };
        AlipayConfig = config;
        Factory.SetOptions(config);
    }

    /// <summary>
    ///获取支付方式
    /// </summary>
    /// <param name="payment"></param>
    /// <returns></returns>
    public static IPayment GetPayment(string payment, CloudGamingBase cloudGamingBase)
    {
        //miaoYuBase.AppConfig.Payment
        if (payment == "zfb")
        {
            return new AlipayPayment(cloudGamingBase.AppConfig, cloudGamingBase._UserId);
        }

        if (cloudGamingBase.AppConfig != null)
        {
            if (cloudGamingBase.AppConfig.Payment == null)
            {
                cloudGamingBase.AppConfig.Payment = new PaymentModel()
                {
                    WeChatConfig = weChatConfig
                };
            }
            if (cloudGamingBase.AppConfig.Payment.WeChatConfig == null)
            {
                cloudGamingBase.AppConfig.Payment.WeChatConfig = weChatConfig;
            }
        }

        var _weChatConfig = cloudGamingBase.AppConfig.Payment.WeChatConfig ?? weChatConfig;
        var _wxClient = cloudGamingBase.AppConfig.Payment.WxClientContext ?? wxClient;
        if (payment == "xcx")
        {
            if (cloudGamingBase._UserId == 0)
            {
                throw new Exception("请先登录");
            }
            var userAccount = cloudGamingBase.Dao.DaoUser.Context.T_User_MiniProgram_Account.FirstOrDefault(it => it.UserId == cloudGamingBase._UserId);
            if (userAccount == null)
            {
                throw new Exception("未找到人员数据，请先登录");
            }

            //return new WeChatMiniProgram(_wxClient, _weChatConfig, miaoYuBase.TenantInfo, miaoYuBase._UserId, userAccount.OpenId);
        }
        return new WeChatPayment(_wxClient, _weChatConfig, cloudGamingBase.AppConfig, cloudGamingBase._UserId);
    }


    /// <summary>
    /// 获取支付包支付接口
    /// </summary>
    /// <param name="payment"></param>
    /// <returns></returns>
    public static Alipay.EasySDK.Payment.App.Client App(this PaymentModel payment)
    {
        return new Alipay.EasySDK.Payment.App.Client(new Alipay.EasySDK.Kernel.Client(payment.AliPayContext));
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="productCache"></param>
    /// <param name="payment"></param>
    /// <param name="orderId"></param>
    /// <param name="channel"></param>
    /// <returns></returns>
    public static T_User_IntentOrder ToIntentOrder(this ProductCache productCache, string payment, string orderId, string channel)
    {

        T_User_IntentOrder t_User_IntentOrder = new T_User_IntentOrder()
        {
            Price = productCache.Price,
            CreatedAt = DateTime.Now,
            CreatedDay = int.Parse(DateTime.Now.ToString("yyyyMMdd")),
            Method = payment,
            Notes = "",
            ProductId = productCache.ProductId,
            Quantity = 1,
            Status = (int)OrderState.已下单,
            UpdatedAt = DateTime.Now,
            OrderId = orderId,
            Channel = channel
        };
        return t_User_IntentOrder;
    }

    /// <summary>
    /// 生成订单编号
    /// </summary>
    /// <param name="identifier"></param>
    /// <param name="userId"></param>
    /// <param name="machineCode"></param>
    /// <returns></returns>
    /// <exception cref="ArgumentException"></exception>
    public static string GenerateCustomString(string identifier, int userId, int producId, string machineCode)
    {
        // 确保标识符为3位，不足补0
        string identifierPadded = identifier.PadRight(3, '0');

        // 获取当前时间戳
        long timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds();

        // 将用户ID补足6位，不足补0
        string userIdPadded = userId.ToString().PadLeft(6, '0');
        // 产品id补足3位
        string producIdPadded = producId.ToString().PadLeft(3, '0');
        // 确保机器码为3位，不足补0
        string machineCodePadded = machineCode.PadLeft(3, '0');

        // 计算随机字符串应占用的位数
        int randomStringLength = 32 - (identifierPadded.Length + 1 + 10 + 1 + userIdPadded.Length + 1 + machineCodePadded.Length + 1 + producIdPadded.Length + 1);

        // 生成指定长度的随机字符串（字母和数字混合）
        string randomPadded = GenerateRandomString(randomStringLength);

        // 使用 StringBuilder 拼接成最终字符串
        var sb = new StringBuilder(32);
        sb.Append(identifierPadded)
          .Append('T').Append(timestamp)
          .Append('U').Append(userIdPadded)
          .Append('P').Append(producIdPadded)
          .Append('M').Append(machineCodePadded)
          .Append('R').Append(randomPadded);

        return sb.ToString();
    }

    private static string GenerateRandomString(int length)
    {
        const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        var random = new Random();
        var result = new char[length];
        for (int i = 0; i < length; i++)
        {
            result[i] = chars[random.Next(chars.Length)];
        }
        return new string(result);
    }
    /// <summary>
    /// 解析订单号
    /// </summary>
    /// <param name="customString"></param>
    /// <returns></returns>
    /// <exception cref="ArgumentException"></exception>
    public static (string Identifier, long Timestamp, int UserId, int ProductId, string MachineCode, string RandomString) ParseCustomString(string customString)
    {
        if (customString.Length != 32)
        {
            throw new ArgumentException("Custom string must be exactly 32 characters long.");
        }

        // 通过索引位置缓存各个部分的起始位置
        int tIndex = customString.IndexOf('T');

        int uIndex = customString.IndexOf('U');
        int pIndex = customString.IndexOf('P');
        int mIndex = customString.IndexOf('M');
        int rIndex = customString.IndexOf('R');

        // 提取并去掉标识符的末尾零
        string identifier = customString.Substring(0, tIndex).TrimEnd('0');

        // 提取时间戳
        long timestamp = long.Parse(customString.Substring(tIndex + 1, uIndex - tIndex - 1));

        // 提取用户ID
        int userId = int.Parse(customString.Substring(uIndex + 1, pIndex - uIndex - 1));

        // 提取产品ID
        int productId = int.Parse(customString.Substring(pIndex + 1, mIndex - pIndex - 1));

        // 提取机器码
        string machineCode = customString.Substring(mIndex + 1, rIndex - mIndex - 1);

        // 提取随机字符串
        string randomString = customString.Substring(rIndex + 1);

        return (identifier, timestamp, userId, productId, machineCode, randomString);
    }
}
