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.PeriodCloseMapper;
import com.ga.core.vo.settle.PeriodCloseResp;
import com.ga.core.vo.settle.PeriodCloseSaveReq;
import com.ga.core.vo.settle.PeriodCloseSearchParam;
import com.ga.core.vo.settle.PeriodCloseVO;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

    private final PeriodCloseMapper periodCloseMapper;

    public PageResponse<PeriodCloseResp> list(PeriodCloseSearchParam param) {
        param.startPage();
        return PageResponse.of(periodCloseMapper.selectList(param));
    }

    public PeriodCloseResp detail(Long closeId) {
        PeriodCloseResp resp = periodCloseMapper.selectById(closeId);
        if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
        return resp;
    }

    @Transactional
    public void close(PeriodCloseSaveReq req) {
        // 이미 마감된 월인지 확인
        if (periodCloseMapper.isClosedMonth(req.getCloseMonth())) {
            throw new BizException(ErrorCode.DUPLICATE_DATA, "이미 마감된 정산월입니다: " + req.getCloseMonth());
        }
        PeriodCloseVO vo = new PeriodCloseVO();
        vo.setCloseMonth(req.getCloseMonth());
        vo.setNote(req.getNote());
        vo.setClosedBy(SecurityUtil.getCurrentUserId());
        periodCloseMapper.insert(vo);
    }

    @Transactional
    public void reopen(Long closeId, String reopenReason) {
        PeriodCloseResp resp = periodCloseMapper.selectById(closeId);
        if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
        periodCloseMapper.reopen(closeId, SecurityUtil.getCurrentUserId(), reopenReason);
    }

    /**
     * 마감 가드: 해당 정산월이 마감 상태이면 예외 발생.
     * settle_correction, payment 등 변경 서비스에서 호출.
     */
    public void assertNotClosed(String settleMonth) {
        if (periodCloseMapper.isClosedMonth(settleMonth)) {
            throw new BizException(ErrorCode.NOT_PERMITTED, "마감된 기간입니다: " + settleMonth);
        }
    }
}
