package cn.reghao.tnb.user.app.rpc;

import cn.reghao.jutil.jdk.web.result.Result;
import cn.reghao.jutil.jdk.string.SnowFlake;
import cn.reghao.tnb.common.auth.UserContext;
import cn.reghao.tnb.common.util.ConstantId;
import cn.reghao.tnb.message.api.constant.MsgType;
import cn.reghao.tnb.user.api.dto.ChargeReq;
import cn.reghao.tnb.message.api.dto.UserMessageDto;
import cn.reghao.tnb.user.api.dto.WalletChargeDto;
import cn.reghao.tnb.user.api.iface.UserService;
import cn.reghao.tnb.user.api.iface.UserWalletService;
import cn.reghao.tnb.user.app.db.mapper.WalletBillMapper;
import cn.reghao.tnb.user.app.db.mapper.WalletChargeMapper;
import cn.reghao.tnb.user.app.model.constant.BillType;
import cn.reghao.tnb.user.app.model.po.WalletBill;
import cn.reghao.tnb.user.app.model.po.WalletCharge;
import cn.reghao.tnb.user.app.service.WalletService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @author reghao
 * @date 2024-07-06 00:22:33
 */
@Slf4j
@DubboService
@Service
public class UserWalletServiceImpl implements UserWalletService {
    @DubboReference(check = false)
    private UserService userService;

    private final SnowFlake idGenerator;
    private final WalletChargeMapper walletChargeMapper;
    private final WalletBillMapper walletBillMapper;
    private WalletService walletService;

    public UserWalletServiceImpl(WalletChargeMapper walletChargeMapper, WalletBillMapper walletBillMapper,
                                 WalletService walletService) {
        this.idGenerator = new SnowFlake(1L, 1L);
        this.walletChargeMapper = walletChargeMapper;
        this.walletBillMapper = walletBillMapper;
        this.walletService = walletService;
    }

    @Override
    public void charge(ChargeReq chargeReq) {
        long chargeId = idGenerator.nextId();
        WalletCharge walletCharge = new WalletCharge(chargeId, chargeReq);
        walletChargeMapper.save(walletCharge);

        long loginUser = UserContext.getUserId();
        int msgType = MsgType.chargeMsg.getValue();
        String title = "充值消息";
        String content = String.format("来自 %s 的充值请求", loginUser);
        UserMessageDto userMessageDto = new UserMessageDto(msgType, title, content, ConstantId.ANONYMOUS_USER_ID);
        //userService.sendUserMessage(userMessageDto);
    }

    @Override
    public List<WalletChargeDto> getChargeReqs() {
        int status = 1;
        return walletChargeMapper.findByStatus(status);
    }

    @Override
    public void approveCharge(long chargeId) {
        WalletCharge walletCharge = walletChargeMapper.findByChargeId(chargeId);
        if (walletCharge == null) {
            return;
        }

        int status = 2;
        walletChargeMapper.updateStatus(chargeId, status);
        double quantity = walletCharge.getQuantity();
        long owner = walletCharge.getOwner();
        WalletBill walletBill = new WalletBill(BillType.InCome.getCode(), quantity, owner);
        walletBillMapper.save(walletBill);

        long receiver = walletCharge.getOwner();
        int msgType = MsgType.chargeMsg.getValue();
        String title = "充值成功";
        String content = String.format("系统同意了您的充值请求");
        UserMessageDto userMessageDto = new UserMessageDto(msgType, title, content, receiver);
        //userMessageService.addMessage(userMessageDto);
    }

    @Override
    public void approveAllCharges() {
        int status = 1;
        walletChargeMapper.findByStatus(status).forEach(walletChargeDto -> {
            long chargeId = walletChargeDto.getChargeId();
            approveCharge(chargeId);
        });
    }

    @Override
    public void declineCharge(long chargeId) {
        WalletCharge walletCharge = walletChargeMapper.findByChargeId(chargeId);
        if (walletCharge == null) {
            return;
        }
        int status = 3;
        walletChargeMapper.updateStatus(chargeId, status);

        long receiver = walletCharge.getOwner();
        int msgType = MsgType.chargeMsg.getValue();
        String title = "充值失败";
        String content = String.format("系统拒绝了您的充值请求");
        UserMessageDto userMessageDto = new UserMessageDto(msgType, title, content, receiver);
        //userMessageService.addMessage(userMessageDto);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result pay(long fromUserId, double amount, long toUserId) {
        double balance = walletService.getBalance(fromUserId);
        if (balance < amount) {
            return Result.fail("余额不足");
        }

        WalletBill walletBill1 = new WalletBill(BillType.Expenditure.getCode(), amount, fromUserId);
        WalletBill walletBill2 = new WalletBill(BillType.InCome.getCode(), amount, toUserId);
        walletBillMapper.saveAll(List.of(walletBill1, walletBill2));
        return Result.success();
    }
}
