package com.red.circle.other.app.command.user;

import com.red.circle.common.business.core.enums.SysOriginPlatformEnum;
import com.red.circle.component.redis.service.RedisService;
import com.red.circle.external.inner.endpoint.binance.BinanceClient;
import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.framework.core.response.CommonErrorCode;
import com.red.circle.order.inner.endpoint.UserFreightRechargeRecordClient;
import com.red.circle.other.app.dto.cmd.user.user.FreightRechargeCmd;
import com.red.circle.other.app.scheduler.MyAmazingBot;
import com.red.circle.other.domain.gateway.user.UserProfileGateway;
import com.red.circle.other.domain.model.user.UserProfile;
import com.red.circle.other.inner.asserts.ImErrorCode;
import com.red.circle.other.inner.asserts.user.UserErrorCode;
import com.red.circle.other.inner.endpoint.material.props.BadgeBackpackClient;
import com.red.circle.other.inner.endpoint.material.props.BadgeSourceClient;
import com.red.circle.other.inner.enums.freight.FreightPolicyEnum;
import com.red.circle.tool.core.num.ArithmeticUtils;
import com.red.circle.wallet.inner.endpoint.freight.FreightGoldClient;
import com.red.circle.wallet.inner.error.FreightErrorCode;
import com.red.circle.wallet.inner.model.cmd.AddFreightBalanceRunningWaterCmd;
import com.red.circle.wallet.inner.model.cmd.FreightAgentReviewCmd;
import com.red.circle.wallet.inner.model.dto.UserFreightBalanceDTO;
import com.red.circle.wallet.inner.model.enums.FreightBalanceOrigin;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Objects;
import java.util.Optional;

/**
 * @author longli on  2024/3/22
 */

@Component
@RequiredArgsConstructor
public class FreightRechargeCmdExe {

    private final BadgeBackpackClient badgeBackpackClient;
    private final RedisService redisService;
    private final UserProfileGateway userProfileGateway;
    private final BinanceClient binanceClient;
    private final FreightGoldClient freightGoldClient;
    private final UserFreightRechargeRecordClient userFreightRechargeRecordClient;
    private final BadgeSourceClient badgeSourceClient;

    public void recharge(FreightRechargeCmd cmd) {
        UserProfile userProfile = userProfileGateway.getByUserId(cmd.getReqUserId());
        ResponseAssert.notNull(ImErrorCode.NOT_FOUND_USER_INFO, userProfile);
        ResponseAssert.isTrue(UserErrorCode.USER_INFO_NOT_FOUND,
                Objects.equals(userProfile.getOriginSys(), cmd.requireReqSysOrigin()));

        ResponseAssert.isFalse(FreightErrorCode.THE_GOLD_COINS_HAVE_ARRIVED, freightGoldClient.existsRecord(cmd.getTxId()).getBody());

        String lockKey = "back_send_freight_ship:" + cmd.getTxId();
        try {
            // 操作冲突
            ResponseAssert.isTrue(CommonErrorCode.OPERATION_CONFLICT, redisService.lock(lockKey, 60));

            String dollar = "";
            if (cmd.getTxId().length() == 18) {
                dollar = binanceClient.transactions(cmd.getTxId()).getBody();
            } else {
                dollar = binanceClient.depositHistory(cmd.getTxId()).getBody();
            }
            ResponseAssert.isTrue(FreightErrorCode.INCORRECT_ORDER_NUMBER, StringUtils.isNotBlank(dollar));

            BigDecimal bigDecimal = new BigDecimal(dollar);

            BigDecimal earnPoints = FreightPolicyEnum.earnPoints(bigDecimal);

            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append("Likei 币商充值").append("\n")
                    .append("用户ID:").append(userProfile.getAccount()).append("\n")
                    .append("充值金额: ").append(bigDecimal).append("\n")
                    .append("自动到账金币: ").append(earnPoints).append("\n")
                    .append("订单号: ").append(cmd.getTxId());
            sendTelegram(stringBuilder);

            // 插入流水
            if (ArithmeticUtils.gte(earnPoints, BigDecimal.ONE)) {

                BigDecimal balance = getAvailableBalance(cmd.getReqUserId());

                freightGoldClient.addRunningWater(new AddFreightBalanceRunningWaterCmd()

                        .setSysOrigin(cmd.requireReqSysOrigin())
                        .setUserId(cmd.getReqUserId())
                        .setAcceptUserId(cmd.getReqUserId())
                        .setType(0)
                        .setQuantity(earnPoints)
                        .setUsdQuantity(BigDecimal.ZERO)
                        .setBalance(balance)
                        .setRechargeType("USDT-进货")
                        .setAmount(bigDecimal)
                        .setOrigin(FreightBalanceOrigin.PURCHASE.name())
                        .setRemark(cmd.getTxId())
                        .setCreateUser(cmd.getReqUserId())
                        .setUpdateUser(cmd.getReqUserId()));
            }
        } catch (UnsupportedEncodingException | NoSuchAlgorithmException | InvalidKeyException e) {
            throw new RuntimeException(e);
        } finally {
            redisService.unlock(lockKey);
        }

    }

    private void sendTelegram(StringBuilder stringBuilder) {
        //机器人来咯
        MyAmazingBot myAmazingBot = new MyAmazingBot();
        myAmazingBot.sendMsg("机器人群组", stringBuilder.toString());
    }

    private BigDecimal getAvailableBalance(Long userId) {
        return Optional.ofNullable(
                        ResponseAssert.requiredSuccess(freightGoldClient.getFreightBalance(userId)))
                .map(balance -> balance.getEarnPoints()
                        .subtract(balance.getConsumptionPoints())
                        .setScale(2, RoundingMode.DOWN))
                .orElse(BigDecimal.ZERO);
    }

}
