package com.red.circle.wallet.app.convertor;

import com.red.circle.common.business.core.enums.OpUserType;
import com.red.circle.common.business.core.enums.ReceiptType;
import com.red.circle.tool.core.sequence.IdWorkerUtils;
import com.red.circle.tool.core.tuple.PennyAmount;
import com.red.circle.wallet.app.dto.clientobject.SalaryAccountBalanceCO;
import com.red.circle.wallet.app.dto.clientobject.SalaryIssueResultCO;
import com.red.circle.wallet.app.dto.clientobject.SalaryRunningWaterCO;
import com.red.circle.wallet.app.dto.cmd.SalaryIssueCmd;
import com.red.circle.wallet.app.dto.cmd.SalaryWithdrawCmd;
import com.red.circle.wallet.inner.model.enums.SalaryEvent;
import com.red.circle.wallet.domain.salary.SalaryReceipt;
import com.red.circle.wallet.domain.salary.SalaryReceiptRes;
import com.red.circle.wallet.inner.model.enums.SalaryType;
import com.red.circle.wallet.infra.database.rds.entity.salary.SalaryAccountBalance;
import com.red.circle.wallet.infra.database.rds.entity.salary.SalaryAccountRunningWater;

import java.time.ZoneId;
import java.util.Objects;
import org.springframework.stereotype.Component;

/**
 * 工资账户转换器.
 */
@Component
public class SalaryAccountConvertor {

  public SalaryReceipt toSalaryReceipt(SalaryIssueCmd cmd) {
    return new SalaryReceipt()
        .setReceiptType(ReceiptType.INCOME)
        .setUserId(cmd.getUserId())
         .setAcceptUserId(cmd.getUserId())
        .setSysOrigin(cmd.getReqSysOrigin().getOrigin())
        .setSalaryType(SalaryType.of(cmd.getSalaryType()))
        .setSalaryEvent(SalaryEvent.of(cmd.getSalaryEvent()))
        .setAmount(PennyAmount.ofDollar(cmd.getAmount()))
        .setTrackId(cmd.getTrackId())
        .setBillBelong(cmd.getBillBelong())
        .setTeamId(cmd.getTeamId())
        .setBdId(cmd.getBdId())
        .setAgentId(cmd.getAgentId())
        .setEventDesc(cmd.getEventDesc())
        .setRemark(cmd.getRemark())
        .setOpUserType(OpUserType.APP)
        .setOpUserId(cmd.getReqUserId());
  }

  public SalaryReceipt toWithdrawRefundReceipt(SalaryWithdrawCmd cmd) {
    SalaryReceipt receipt = new SalaryReceipt()
        .setReceiptType(ReceiptType.INCOME)
        .setUserId(cmd.getReqUserId())
        .setAcceptUserId(cmd.getReqUserId())
        .setSysOrigin(cmd.getReqSysOrigin().getOrigin())
        .setSalaryType(SalaryType.of(cmd.getSalaryType()))
        .setSalaryEvent(SalaryEvent.WITHDRAW_REFUND)
        .setAmount(PennyAmount.ofDollar(cmd.getAmount()))
        .setTrackId(IdWorkerUtils.getIdStr())
        .setEventDesc("提现退回")
        .setRemark(cmd.getRemark())
        .setOpUserType(OpUserType.APP)
        .setOpUserId(cmd.getOpUserId());

//    if (Objects.nonNull(cmd.getServiceCharge()) && cmd.getServiceCharge() > 0) {
//      receipt.setServiceCharge(cmd.getServiceCharge());
//      BigDecimal chargeRate = new BigDecimal(cmd.getServiceCharge()).divide(new BigDecimal("1000"));
//      BigDecimal actualAmount = cmd.getAmount().multiply(BigDecimal.ONE.subtract(chargeRate));
//      receipt.setActualAmount(PennyAmount.ofDollar(actualAmount));
//    } else {
//      receipt.setActualAmount(PennyAmount.ofDollar(cmd.getAmount()));
//    }

    return receipt;
  }

    public SalaryReceipt toExchangeReceipt(SalaryWithdrawCmd cmd) {
        SalaryReceipt receipt = new SalaryReceipt()
                .setReceiptType(ReceiptType.EXPENDITURE)
                .setUserId(cmd.getReqUserId())
                .setAcceptUserId(cmd.getReqUserId())
                .setSysOrigin(cmd.getReqSysOrigin().getOrigin())
                .setSalaryType(SalaryType.of(cmd.getSalaryType()))
                .setSalaryEvent(SalaryEvent.SALARY_EXCHANGE)
                .setAmount(PennyAmount.ofDollar(cmd.getAmount()))
                .setTrackId(IdWorkerUtils.getIdStr())
                .setEventDesc(SalaryEvent.SALARY_EXCHANGE.getDesc())
                .setRemark(cmd.getRemark())
                .setOpUserType(OpUserType.APP)
                .setOpUserId(cmd.getReqUserId());
        return receipt;
    }

    public SalaryReceipt toTransferReceipt(SalaryWithdrawCmd cmd) {
        SalaryReceipt receipt = new SalaryReceipt()
                .setReceiptType(ReceiptType.EXPENDITURE)
                .setUserId(cmd.getReqUserId())
                .setAcceptUserId(cmd.getAcceptUserId())
                .setSysOrigin(cmd.getReqSysOrigin().getOrigin())
                .setSalaryType(SalaryType.of(cmd.getSalaryType()))
                .setSalaryEvent(SalaryEvent.SALARY_TRANSFER)
                .setAmount(PennyAmount.ofDollar(cmd.getAmount()))
                .setTrackId(cmd.getReqTraceId())
                .setEventDesc(SalaryEvent.SALARY_TRANSFER.getDesc())
                .setRemark(cmd.getRemark())
                .setOpUserType(OpUserType.APP)
                .setOpUserId(cmd.getReqUserId());
        return receipt;
    }

  public SalaryIssueResultCO toIssueResultCO(SalaryReceiptRes res) {
    SalaryIssueResultCO co = new SalaryIssueResultCO();
    co.setRecordId(res.getRecordId());
    co.setAmount(res.getAmount().getDollarAmount());
    co.setBalance(res.getBalance().getDollarAmount());
    co.setAvailableBalance(res.getAvailableBalance().getDollarAmount());
    return co;
  }

  public SalaryAccountBalanceCO toBalanceCO(SalaryAccountBalance entity) {
    if (Objects.isNull(entity)) {
      return null;
    }
    SalaryAccountBalanceCO co = new SalaryAccountBalanceCO();
    co.setUserId(entity.getUserId());
    co.setSalaryType(entity.getSalaryType());
    co.setEarnPoints(entity.getEarnPoints());
    co.setConsumptionPoints(entity.getConsumptionPoints());
    co.setBalance(entity.getBalance());
    co.setFrozenAmount(entity.getFrozenAmount());
    co.setAvailableBalance(entity.getAvailableBalance());
    return co;
  }

  public SalaryRunningWaterCO toRunningWaterCO(SalaryAccountRunningWater entity) {
    if (Objects.isNull(entity)) {
      return null;
    }
    SalaryRunningWaterCO co = new SalaryRunningWaterCO();
    co.setId(entity.getId());
    co.setUserId(entity.getUserId());
    co.setAcceptUserId(entity.getAcceptUserId());
    co.setType(entity.getType());
    co.setSalaryType(entity.getSalaryType());
    
    SalaryType salaryType = SalaryType.of(entity.getSalaryType());
    if (Objects.nonNull(salaryType)) {
      co.setSalaryTypeName(salaryType.getDesc());
    }
    
    co.setAmount(entity.getAmount());
    co.setBalance(entity.getBalance());
    co.setAvailableBalance(entity.getAvailableBalance());
    co.setSalaryEvent(entity.getSalaryEvent());
    co.setEventDesc(entity.getEventDesc());
    co.setTrackId(entity.getTrackId());
    co.setBillBelong(entity.getBillBelong());
    co.setTeamId(entity.getTeamId());
    co.setBdId(entity.getBdId());
    co.setAgentId(entity.getAgentId());
    co.setRemark(entity.getRemark());
    if (Objects.nonNull(entity.getCreateTime())) {
      co.setCreatedAt(entity.getCreateTime().toInstant()
          .atZone(ZoneId.systemDefault()).toLocalDateTime());
    }
    return co;
  }
}
