package com.red.circle.other.infra.database.rds.service.user.user.impl;

import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.framework.core.response.CommonErrorCode;
import com.red.circle.framework.dto.PageResult;
import com.red.circle.framework.mybatis.constant.PageConstant;
import com.red.circle.framework.mybatis.service.impl.BaseServiceImpl;
import com.red.circle.tool.core.date.TimestampUtils;
import com.red.circle.tool.core.text.StringUtils;
import com.red.circle.other.infra.database.rds.dao.user.user.InviteTargetTransitBalanceDAO;
import com.red.circle.other.infra.database.rds.entity.user.user.InviteTargetTransitBalance;
import com.red.circle.other.infra.database.rds.service.user.user.InviteTargetTransitBalanceService;
import com.red.circle.other.inner.model.cmd.user.invite.InviteBalancePageQryCmd;
import com.red.circle.other.inner.model.cmd.user.invite.InviteTargetTransitBalanceCmd;
import com.red.circle.wallet.inner.error.WalletErrorCode;
import java.math.BigDecimal;
import java.util.Objects;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;

/**
 * <p>
 * 邀请新用户-目标中转账户 服务实现类.
 * </p>
 *
 * @author pengshigang on 2023-12-05 18:10
 */
@AllArgsConstructor
@Service
public class InviteTargetTransitBalanceServiceImpl extends
    BaseServiceImpl<InviteTargetTransitBalanceDAO, InviteTargetTransitBalance> implements
    InviteTargetTransitBalanceService {

  @Override
  public boolean decr(Long id, String sysOrigin, BigDecimal expenditure) {

    if (Objects.isNull(getById(id))) {
      add(id, sysOrigin);
    }

    return update().setSql("expenditure_balance=expenditure_balance+" + expenditure)
        .eq(InviteTargetTransitBalance::getId, id)
        .apply("income_amount>=expenditure_balance+" + expenditure)
        .last(PageConstant.LIMIT_ONE)
        .execute();
  }

  @Override
  public boolean incr(Long id, String sysOrigin, BigDecimal income) {

    if (Objects.isNull(getById(id))) {
      add(id, sysOrigin);
    }

    return update().setSql("income_amount=income_amount+" + income)
        .eq(InviteTargetTransitBalance::getId, id)
        .last(PageConstant.LIMIT_ONE)
        .execute();
  }

  @Override
  public PageResult<InviteTargetTransitBalance> pageTargetTransitBalance(
      InviteBalancePageQryCmd cmd) {

    return query()
        .eq(Objects.nonNull(cmd.getUserId()), InviteTargetTransitBalance::getId,
            cmd.getUserId())
        .eq(StringUtils.isNotBlank(cmd.getSysOrigin()),
            InviteTargetTransitBalance::getSysOrigin,
            cmd.getSysOrigin())
        .orderByDesc(InviteTargetTransitBalance::getCreateTime)
        .page(cmd.getPageQuery());
  }

  @Override
  public void reduceTarget(InviteTargetTransitBalanceCmd cmd) {

    InviteTargetTransitBalance balance = getById(cmd.getId());
    ResponseAssert.notNull(CommonErrorCode.NOT_FOUND_RECORD_INFO, balance);

    ResponseAssert.isTrue(WalletErrorCode.INSUFFICIENT_BALANCE, balance.getIncomeAmount()
        .compareTo(balance.getExpenditureBalance().add(BigDecimal.valueOf(cmd.getTarget())))
        >= 0);

    update()
        .setSql("expenditure_balance=expenditure_balance+" + BigDecimal.valueOf(cmd.getTarget()))
        .set(InviteTargetTransitBalance::getUpdateUser, cmd.getUpdateUser())
        .set(InviteTargetTransitBalance::getUpdateTime, TimestampUtils.now())
        .eq(InviteTargetTransitBalance::getId, cmd.getId())
        .last(PageConstant.LIMIT_ONE)
        .execute();

  }

  private void add(Long id, String sysOrigin) {
    InviteTargetTransitBalance balance = new InviteTargetTransitBalance();
    balance.setId(id);
    balance.setExpenditureBalance(BigDecimal.ZERO);
    balance.setIncomeAmount(BigDecimal.ZERO);
    balance.setSysOrigin(sysOrigin);
    balance.setCreateUser(id);
    balance.setCreateTime(TimestampUtils.now());
    super.save(balance);
  }


}
