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.LapsedReinstatementRecoveryMapper;
import com.ga.core.vo.commission.*;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

    private final LapsedReinstatementRecoveryMapper mapper;

    public PageResponse<LapsedReinstatementRecoveryResp> list(LapsedReinstatementRecoverySearchParam param) {
        param.startPage();
        return PageResponse.of(mapper.selectList(param));
    }

    public LapsedReinstatementRecoveryResp detail(Long recoveryId) {
        LapsedReinstatementRecoveryResp resp = mapper.selectById(recoveryId);
        if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
        return resp;
    }

    /**
     * 부활 등록 — withheld_amount 입력, status = PENDING.
     */
    @Transactional
    public Long create(LapsedReinstatementRecoverySaveReq req) {
        LapsedReinstatementRecoveryVO vo = new LapsedReinstatementRecoveryVO();
        vo.setContractId(req.getContractId());
        vo.setAgentId(req.getAgentId());
        vo.setLapsedMonth(req.getLapsedMonth());
        vo.setReinstatedMonth(req.getReinstatedMonth());
        vo.setWithheldAmount(req.getWithheldAmount());
        vo.setRepaidAmount(java.math.BigDecimal.ZERO);
        vo.setStatus("PENDING");
        mapper.insert(vo);
        return vo.getRecoveryId();
    }

    /**
     * 재지급 처리 — status = REPAID, repaid_amount = withheld_amount.
     */
    @Transactional
    public void repay(Long recoveryId) {
        LapsedReinstatementRecoveryResp resp = mapper.selectById(recoveryId);
        if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
        if (!"PENDING".equals(resp.getStatus())) throw new BizException(ErrorCode.INVALID_PARAMETER);
        mapper.updateStatus(recoveryId, "REPAID", resp.getWithheldAmount());
    }

    /**
     * 취소 — status = CANCELLED.
     */
    @Transactional
    public void cancel(Long recoveryId) {
        LapsedReinstatementRecoveryResp resp = mapper.selectById(recoveryId);
        if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
        if ("REPAID".equals(resp.getStatus()) || "CANCELLED".equals(resp.getStatus())) {
            throw new BizException(ErrorCode.INVALID_PARAMETER);
        }
        mapper.updateStatus(recoveryId, "CANCELLED", java.math.BigDecimal.ZERO);
    }
}
