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

import cn.reghao.jutil.jdk.converter.DateTimeConverter;
import cn.reghao.tnb.common.auth.UserContext;
import cn.reghao.tnb.user.app.db.mapper.WalletBillMapper;
import cn.reghao.tnb.user.app.model.constant.BillType;
import cn.reghao.tnb.user.app.model.vo.MyWallet;
import cn.reghao.tnb.user.app.model.po.WalletBill;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @author reghao
 * @date 2024-04-16 16:13:30
 */
@Service
public class WalletService {
    private final WalletBillMapper walletBillMapper;

    public WalletService(WalletBillMapper walletBillMapper) {
        this.walletBillMapper = walletBillMapper;
    }

    public synchronized void pay(double quantity, long owner) throws Exception {
        double balance = getBalance(owner);
        if (balance < quantity) {
            String errMsg = "余额不足";
            throw new Exception(errMsg);
        }

        WalletBill walletBill = new WalletBill(BillType.Expenditure.getCode(), quantity, owner);
        walletBillMapper.save(walletBill);
    }

    public MyWallet getMyWallet() {
        long loginUser = UserContext.getUserId();
        double balance = getBalance(loginUser);
        return new MyWallet(loginUser, balance);
    }

    public List<WalletBill> getWalletBillList(int pageNumber) {
        long owner = UserContext.getUserId();
        int pageSize = 10;
        List<WalletBill> list = walletBillMapper.findByOwner(pageSize, owner);
        list.forEach(walletBill -> {
            String typeStr = BillType.getDescByCode(walletBill.getType());
            walletBill.setTypeStr(typeStr);
            String createAtStr = DateTimeConverter.format(walletBill.getCreateAt());
            walletBill.setCreateAtStr(createAtStr);
        });
        return list;
    }

    public double getBalance(long owner) {
        double incomeSum = walletBillMapper.findSumByTypeAndOwner(BillType.InCome.getCode(), owner);
        double expenditureSum = walletBillMapper.findSumByTypeAndOwner(BillType.Expenditure.getCode(), owner);
        return incomeSum - expenditureSum;
    }
}
