package com.ga.api.service.commission;

import com.ga.common.exception.BizException;
import com.ga.common.exception.ErrorCode;
import com.ga.common.model.PageResponse;
import com.ga.core.mapper.commission.ReinstatementCommissionLedgerMapper;
import com.ga.core.mapper.commission.ReinstatementCommissionRuleMapper;
import com.ga.core.vo.commission.*;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;

@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class ReinstatementCommissionService {

    private final ReinstatementCommissionRuleMapper ruleMapper;
    private final ReinstatementCommissionLedgerMapper ledgerMapper;

    // ── Rule ──────────────────────────────────────────────────────────────────

    public PageResponse<ReinstatementCommissionRuleResp> listRules(ReinstatementCommissionRuleSearchParam param) {
        param.startPage();
        return PageResponse.of(ruleMapper.selectList(param));
    }

    public ReinstatementCommissionRuleResp detailRule(Long ruleId) {
        ReinstatementCommissionRuleResp resp = ruleMapper.selectById(ruleId);
        if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
        return resp;
    }

    @Transactional
    public Long createRule(ReinstatementCommissionRuleSaveReq req) {
        ReinstatementCommissionRuleVO vo = new ReinstatementCommissionRuleVO();
        vo.setProductId(req.getProductId());
        vo.setPayType(req.getPayType());
        vo.setRateValue(req.getRateValue());
        vo.setFixedAmount(req.getFixedAmount());
        vo.setChargebackReversalRate(req.getChargebackReversalRate());
        vo.setEffectiveFrom(req.getEffectiveFrom());
        vo.setEffectiveTo(req.getEffectiveTo());
        ruleMapper.insert(vo);
        return vo.getRuleId();
    }

    @Transactional
    public void updateRule(Long ruleId, ReinstatementCommissionRuleSaveReq req) {
        ReinstatementCommissionRuleResp resp = ruleMapper.selectById(ruleId);
        if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
        ReinstatementCommissionRuleVO vo = new ReinstatementCommissionRuleVO();
        vo.setRuleId(ruleId);
        vo.setProductId(req.getProductId());
        vo.setPayType(req.getPayType());
        vo.setRateValue(req.getRateValue());
        vo.setFixedAmount(req.getFixedAmount());
        vo.setChargebackReversalRate(req.getChargebackReversalRate());
        vo.setEffectiveFrom(req.getEffectiveFrom());
        vo.setEffectiveTo(req.getEffectiveTo());
        ruleMapper.update(vo);
    }

    @Transactional
    public void deleteRule(Long ruleId) {
        ReinstatementCommissionRuleResp resp = ruleMapper.selectById(ruleId);
        if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
        ruleMapper.delete(ruleId);
    }

    // ── Ledger ────────────────────────────────────────────────────────────────

    public PageResponse<ReinstatementCommissionLedgerResp> listLedgers(ReinstatementCommissionLedgerSearchParam param) {
        param.startPage();
        return PageResponse.of(ledgerMapper.selectList(param));
    }

    public ReinstatementCommissionLedgerResp detailLedger(Long ledgerId) {
        ReinstatementCommissionLedgerResp resp = ledgerMapper.selectById(ledgerId);
        if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
        return resp;
    }

    /**
     * 수동 등록 — chargebackReversal 은 요청값 그대로.
     * netCommission = commissionAmount + chargebackReversal 로 자동 계산.
     */
    @Transactional
    public Long createLedger(ReinstatementCommissionLedgerSaveReq req) {
        ReinstatementCommissionLedgerVO vo = new ReinstatementCommissionLedgerVO();
        vo.setContractId(req.getContractId());
        vo.setAgentId(req.getAgentId());
        vo.setRuleId(req.getRuleId());
        vo.setSettleMonth(req.getSettleMonth());
        vo.setReinstatementDate(req.getReinstatementDate());
        vo.setReinstatementPremium(req.getReinstatementPremium());
        vo.setCommissionAmount(req.getCommissionAmount());
        BigDecimal reversal = req.getChargebackReversal() != null ? req.getChargebackReversal() : BigDecimal.ZERO;
        vo.setChargebackReversal(reversal);
        vo.setNetCommission(req.getCommissionAmount().add(reversal));
        vo.setPayType(req.getPayType());
        vo.setStatus("CALCULATED");
        ledgerMapper.insert(vo);
        return vo.getLedgerId();
    }
}
