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.IncentiveProgramMapper;
import com.ga.core.vo.settle.IncentiveProgramResp;
import com.ga.core.vo.settle.IncentiveProgramSaveReq;
import com.ga.core.vo.settle.IncentiveProgramSearchParam;
import com.ga.core.vo.settle.IncentiveProgramVO;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

    private final IncentiveProgramMapper programMapper;

    public PageResponse<IncentiveProgramResp> list(IncentiveProgramSearchParam param) {
        param.startPage();
        return PageResponse.of(programMapper.selectList(param));
    }

    public IncentiveProgramResp detail(Long programId) {
        IncentiveProgramResp resp = programMapper.selectById(programId);
        if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
        return resp;
    }

    @Transactional
    public Long create(IncentiveProgramSaveReq req) {
        IncentiveProgramVO vo = new IncentiveProgramVO();
        vo.setProgramName(req.getProgramName());
        vo.setProgramType(req.getProgramType());
        vo.setTargetType(req.getTargetType());
        vo.setTargetGradeId(req.getTargetGradeId());
        vo.setTargetOrgId(req.getTargetOrgId());
        vo.setProductCategory(req.getProductCategory());
        vo.setStartMonth(req.getStartMonth());
        vo.setEndMonth(req.getEndMonth());
        vo.setConditionDesc(req.getConditionDesc());
        vo.setPayRate(req.getPayRate());
        vo.setPayAmountFixed(req.getPayAmountFixed());
        vo.setPayType(req.getPayType());
        vo.setBudgetAmount(req.getBudgetAmount());
        vo.setIsActive(true);
        vo.setCreatedBy(SecurityUtil.getCurrentUserId());
        programMapper.insert(vo);
        return vo.getProgramId();
    }

    @Transactional
    public void update(Long programId, IncentiveProgramSaveReq req) {
        IncentiveProgramVO existing = programMapper.selectVoById(programId);
        if (existing == null) throw new BizException(ErrorCode.NOT_FOUND);

        existing.setProgramName(req.getProgramName());
        existing.setProgramType(req.getProgramType());
        existing.setTargetType(req.getTargetType());
        existing.setTargetGradeId(req.getTargetGradeId());
        existing.setTargetOrgId(req.getTargetOrgId());
        existing.setProductCategory(req.getProductCategory());
        existing.setStartMonth(req.getStartMonth());
        existing.setEndMonth(req.getEndMonth());
        existing.setConditionDesc(req.getConditionDesc());
        existing.setPayRate(req.getPayRate());
        existing.setPayAmountFixed(req.getPayAmountFixed());
        existing.setPayType(req.getPayType());
        existing.setBudgetAmount(req.getBudgetAmount());
        existing.setUpdatedBy(SecurityUtil.getCurrentUserId());
        programMapper.update(existing);
    }

    @Transactional
    public void toggleActive(Long programId, boolean isActive) {
        IncentiveProgramVO existing = programMapper.selectVoById(programId);
        if (existing == null) throw new BizException(ErrorCode.NOT_FOUND);
        programMapper.updateActive(programId, isActive, SecurityUtil.getCurrentUserId());
    }
}
