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.SettleMasterMapper;
import com.ga.core.vo.settle.SettleMasterResp;
import com.ga.core.vo.settle.SettleMasterVO;
import com.ga.core.vo.settle.SettleSearchParam;
import com.ga.core.vo.settle.SettleStatus;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;

@Service
@RequiredArgsConstructor
public class SettleService {

    private final SettleMasterMapper masterMapper;

    @Transactional(readOnly = true)
    public PageResponse<SettleMasterResp> list(SettleSearchParam param) {
        param.startPage();
        return PageResponse.of(masterMapper.selectList(param));
    }

    @Transactional(readOnly = true)
    public SettleMasterResp detail(Long agentId, String settleMonth) {
        SettleMasterResp r = masterMapper.selectDetail(agentId, settleMonth);
        if (r == null) throw new BizException(ErrorCode.NOT_FOUND);
        return r;
    }

    @Transactional(readOnly = true)
    public Map<String, Object> summary(String settleMonth) {
        return masterMapper.selectMonthSummary(settleMonth);
    }

    @Transactional(readOnly = true)
    public List<Map<String, Object>> orgSummary(String settleMonth) {
        return masterMapper.selectOrgSummary(settleMonth);
    }

    @Transactional
    public void confirm(Long settleId) {
        SettleMasterVO vo = masterMapper.selectById(settleId);
        if (vo == null) throw new BizException(ErrorCode.NOT_FOUND);
        if (SettleStatus.CONFIRMED.name().equals(vo.getStatus()) || SettleStatus.PAID.name().equals(vo.getStatus())) {
            throw new BizException(ErrorCode.ALREADY_CONFIRMED);
        }
        masterMapper.updateStatus(settleId, SettleStatus.CONFIRMED.name(), SecurityUtil.getCurrentUserId());
    }

    @Transactional
    public void hold(Long settleId, String reason, String reasonCode) {
        SettleMasterVO vo = masterMapper.selectById(settleId);
        if (vo == null) throw new BizException(ErrorCode.NOT_FOUND);
        if (SettleStatus.PAID.name().equals(vo.getStatus())) {
            throw new BizException(ErrorCode.NOT_PERMITTED, "지급완료된 정산은 보류할 수 없습니다");
        }
        masterMapper.updateHold(settleId, reason, reasonCode);
    }

    @Transactional
    public void release(Long settleId) {
        SettleMasterVO vo = masterMapper.selectById(settleId);
        if (vo == null) throw new BizException(ErrorCode.NOT_FOUND);
        if (!SettleStatus.HOLD.name().equals(vo.getStatus())) {
            throw new BizException(ErrorCode.INVALID_STATUS, "보류 상태가 아닙니다");
        }
        masterMapper.updateStatus(settleId, SettleStatus.CALCULATED.name(), SecurityUtil.getCurrentUserId());
    }
}
