using System.Data;
using System.Threading.Tasks;
using System;
using JiaZhiQuan.Common.Config;
using Wicture.DbRESTFul;
using Wicture.DbRESTFul.Infrastructure.Repository;

namespace JiaZhiQuan.Common
{
    public static partial class RepositoryExtension
    {
        /// <summary>
        /// C2C确认收货，不包含分账
        /// </summary>
        /// <param name="orderId">订单号</param>
        /// <param name="userId">买家编号，如果为0，表示系统自动确认收货</param>
        /// <returns>是否执行成功</returns>
        public static async Task<bool> MallOrderConfirmReceipt(this DbRESTFulRepository repository, ConfigFromDb config, long orderId, long userId)
        {
            var count = 0;
            var ratingExpireAt = DateTime.Now.AddHours(config.MallOrderRatingTimeoutHours);
            using (var conn = repository.ConnectionManager.GetConnection(false))
            {
                conn.Open();
                var trans = conn.BeginTransaction();
                try
                {
                    count = await repository.QuerySingleOrDefaultAsync<int>(@$"update mall_order set
                        orderState={(int)MallOrderState.交易成功},
                        userRatingState={(int)MallOrderRatingState.待评}, sellerRatingState={(int)MallOrderRatingState.待评},
                        userRatingExpireAt='{ratingExpireAt:yyyy-MM-dd HH:mm:ss}', sellerRatingExpireAt='{ratingExpireAt:yyyy-MM-dd HH:mm:ss}'
                        where orderId={orderId} and orderState={(int)MallOrderState.待收货};
                        select row_count() as count;", null, conn, trans);
                    if (count > 0)
                    {
                        await repository.QueryAsync<dynamic>(
                            $@"insert into mall_order_change_events(orderId, eventName, eventDesc, operatorId, operatorType, createAt) values (
                            @orderId, @eventName, @eventDesc, {userId}, @operatorType, now())",
                            new
                            {
                                orderId,
                                eventName = userId > 0 ? "【交易成功】买家主动确认收货" : "【交易成功】买家超时未确认收货，系统自动确认收货",
                                eventDesc = "",
                                operatorType = (int)(userId > 0 ? MallOrderChangeOperatorType.买家 : MallOrderChangeOperatorType.平台)
                            }, conn, trans);
                    }
                    trans.Commit();
                }
                catch
                {
                    trans.Rollback();
                    throw;
                }
            }

            return count > 0;
        }

        /// <summary>
        /// 卖家分账
        /// </summary>
        /// <param name="orderId">订单号</param>
        /// <param name="billId">流水编号（提前生成）</param>
        /// <param name="cashoutTaskId">打款任务编号（提前生成）</param>
        /// <returns>商家到手金额（分）</returns>
        public static async Task<int> MallOrderSellerSettlement(this DbRESTFulRepository repository, long orderId, long billId, long cashoutTaskId)
        {
            // 确认分账信息，卖家所得 = （订单金额-订单退款金额）— [（服务费 / 订单金额）* （订单金额-订单退款金额）]
            using (var conn = repository.ConnectionManager.GetConnection(false))
            {
                conn.Open();
                var totalAfterAmount = await repository.QuerySingleOrDefaultAsync<int?>(
                                           $"select sum(refundOrderAmount - lossAmount) as amount from mall_after_sale where orderId={orderId} and state=5",
                                           null, conn) ??
                                       0;
                var orderInfo =
                    await repository.QuerySingleOrDefaultAsync<dynamic>(
                        $"select orderAmount, serviceAmount, sellerId from mall_order where orderId={orderId}", null, conn);
                var orderDetailInfo = await repository.QuerySingleOrDefaultAsync<dynamic>(
                    $"select goodsName, goodsDesc from mall_order_detail where orderId={orderId} limit 1", null, conn);
                var title = string.IsNullOrEmpty(orderDetailInfo.goodsName)
                    ? (string)orderDetailInfo.goodsDesc
                    : (string)orderDetailInfo.goodsName;
                if (title.Length > 100) title = title.Substring(0, 97) + "...";
                var sellerId = (long)orderInfo.sellerId;
                var orderAmount = (int)orderInfo.orderAmount;
                var serviceAmount = (int)Math.Floor((orderAmount - totalAfterAmount) * ((int)orderInfo.serviceAmount * 1d /
                    orderAmount));
                var sellerFinalAmount = orderAmount - totalAfterAmount - serviceAmount;
                // 如果最终分账金额小于0.1，则不收取服务费
                if (sellerFinalAmount < 10)
                {
                    serviceAmount = 0;
                    sellerFinalAmount = orderAmount - totalAfterAmount;
                }
                // 记录流水并添加卖家打款任务
                var trans = conn.BeginTransaction();
                try
                {
                    // 如果存在，则忽略
                    var existBillId = await repository.QuerySingleOrDefaultAsync<long>(
                        $"select billId from mall_bill_record where orderId={orderId} and billType={(int)MallBillRecordBillType.分账流水}",
                        null, conn, trans);
                    if (existBillId == 0)
                    {
                        var cashoutAccount = await repository.QuerySingleOrDefaultAsync<dynamic>(
                            $"select uName, loginName, platform from n_balance_cashout_user_platform where userId={sellerId} and platform='ALIPAY'",
                            null, conn, trans);

                        if (sellerFinalAmount > 0)
                        {
                            // 同一订单，只会生成一条分账打款记录
                            var existId = await repository.QuerySingleOrDefaultAsync<long>(
                                $"select id from n_balance_cashout_tasks where sourceId={orderId} and sourceType={(int)BalanceCashoutTaskSourceType.C2C订单分账打款}",
                                null, conn, trans);
                            if (existId == 0)
                            {
                                await repository.QueryAsync<dynamic>(@"insert into n_balance_cashout_tasks(
                                    id, userId, sourceId, sourceType, amount, transAmount, title, uName, platform, loginName, taxRate, feeRate, feeMinAmount, status, createAt) values (
                                    @id, @userId, @sourceId, @sourceType, @amount, @transAmount, @title, @uName, @platform, @loginName, @taxRate, @feeRate, @feeMinAmount, @status, @createAt)",
                                    new
                                    {
                                        id = cashoutTaskId,
                                        userId = sellerId,
                                        sourceId = orderId,
                                        sourceType = (int)BalanceCashoutTaskSourceType.C2C订单分账打款,
                                        amount = sellerFinalAmount,
                                        transAmount = sellerFinalAmount,
                                        title,
                                        uName = cashoutAccount?.uName ?? string.Empty,
                                        platform = cashoutAccount?.platform ?? string.Empty,
                                        loginName = cashoutAccount?.loginName ?? string.Empty,
                                        taxRate = 0,
                                        feeRate = 0,
                                        feeMinAmount = 0,
                                        status = 0,
                                        createAt = DateTime.Now
                                    }, conn, trans);
                            }
                        }

                        await repository.QuerySingleOrDefaultAsync<dynamic>(@"insert into mall_bill_record(
                            billId, orderId, userId, afterSaleId, billType, taskOrderId, realAmount, refundAmount, billPoints, pointsDeductionAmount, serviceAmount, billAmount, billState, payPlatform, platformBillNo, createAt) values (
                            @billId, @orderId, @userId, @afterSaleId, @billType, @taskOrderId, @realAmount, @refundAmount, @billPoints, @pointsDeductionAmount, @serviceAmount, @billAmount, @billState, @payPlatform, @platformBillNo, @createAt)",
                            new
                            {
                                billId,
                                orderId,
                                userId = sellerId,
                                afterSaleId = 0,
                                billType = (int)MallBillRecordBillType.分账流水,
                                taskOrderId = cashoutTaskId.ToString(),
                                realAmount = sellerFinalAmount,
                                refundAmount = totalAfterAmount,
                                billPoints = 0,
                                pointsDeductionAmount = 0,
                                serviceAmount,
                                billAmount = sellerFinalAmount,
                                billState = (int)MallBillRecordBillState.待支付,
                                payPlatform = 1,
                                platformBillNo = string.Empty,
                                createAt = DateTime.Now
                            }, conn, trans);
                    }
                    trans.Commit();
                    return sellerFinalAmount;
                }
                catch
                {
                    trans.Rollback();
                    throw;
                }
            }
        }
    }
}
