package com.ga.api.service.settle;

import com.ga.common.exception.BizException;
import com.ga.common.exception.ErrorCode;
import com.ga.common.model.PageResponse;
import com.ga.common.util.SecurityUtil;
import com.ga.core.mapper.settle.CommissionDisputeMapper;
import com.ga.core.vo.settle.CommissionDisputeResp;
import com.ga.core.vo.settle.CommissionDisputeSaveReq;
import com.ga.core.vo.settle.CommissionDisputeSearchParam;
import com.ga.core.vo.settle.CommissionDisputeVO;
import com.ga.core.vo.settle.DisputeStatus;
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 CommissionDisputeService {

    private final CommissionDisputeMapper disputeMapper;

    public PageResponse<CommissionDisputeResp> list(CommissionDisputeSearchParam param) {
        param.startPage();
        return PageResponse.of(disputeMapper.selectList(param));
    }

    public CommissionDisputeResp detail(Long disputeId) {
        CommissionDisputeResp resp = disputeMapper.selectById(disputeId);
        if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
        return resp;
    }

    @Transactional
    public Long create(CommissionDisputeSaveReq req) {
        CommissionDisputeVO vo = new CommissionDisputeVO();
        vo.setAgentId(req.getAgentId());
        vo.setSettleMonth(req.getSettleMonth());
        vo.setSettleId(req.getSettleId());
        vo.setDisputedAmount(req.getDisputedAmount());
        vo.setClaimAmount(req.getClaimAmount());
        vo.setReason(req.getReason());
        vo.setEvidenceUrl(req.getEvidenceUrl());
        vo.setStatus(DisputeStatus.OPEN.name());
        disputeMapper.insert(vo);
        return vo.getDisputeId();
    }

    @Transactional
    public void approve(Long disputeId, String resolution, BigDecimal adjustmentAmount, Long correctionId) {
        CommissionDisputeVO vo = disputeMapper.selectVoById(disputeId);
        if (vo == null) throw new BizException(ErrorCode.NOT_FOUND);
        if (!DisputeStatus.IN_REVIEW.name().equals(vo.getStatus())) {
            throw new BizException(ErrorCode.INVALID_STATUS, "검토 중 상태만 승인 가능합니다");
        }
        disputeMapper.resolve(disputeId, DisputeStatus.APPROVED.name(),
                resolution, adjustmentAmount, correctionId, SecurityUtil.getCurrentUserId());
    }

    @Transactional
    public void reject(Long disputeId, String resolution) {
        CommissionDisputeVO vo = disputeMapper.selectVoById(disputeId);
        if (vo == null) throw new BizException(ErrorCode.NOT_FOUND);
        if (!DisputeStatus.IN_REVIEW.name().equals(vo.getStatus())) {
            throw new BizException(ErrorCode.INVALID_STATUS, "검토 중 상태만 기각 가능합니다");
        }
        disputeMapper.resolve(disputeId, DisputeStatus.REJECTED.name(),
                resolution, null, null, SecurityUtil.getCurrentUserId());
    }

    @Transactional
    public void startReview(Long disputeId) {
        CommissionDisputeVO vo = disputeMapper.selectVoById(disputeId);
        if (vo == null) throw new BizException(ErrorCode.NOT_FOUND);
        if (!DisputeStatus.OPEN.name().equals(vo.getStatus())) {
            throw new BizException(ErrorCode.INVALID_STATUS, "OPEN 상태만 검토 시작 가능합니다");
        }
        disputeMapper.startReview(disputeId, SecurityUtil.getCurrentUserId());
    }
}
