package com.ga.api.service.income;

import com.ga.common.exception.BizException;
import com.ga.common.exception.ErrorCode;
import com.ga.common.model.PageResponse;
import com.ga.core.mapper.income.YearEndStatementMapper;
import com.ga.core.vo.income.YearEndStatementExcelVO;
import com.ga.core.vo.income.YearEndStatementResp;
import com.ga.core.vo.income.YearEndStatementSaveReq;
import com.ga.core.vo.income.YearEndStatementSearchParam;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.cursor.Cursor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

    private final YearEndStatementMapper mapper;

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

    public YearEndStatementResp detail(Long id) {
        YearEndStatementResp r = mapper.selectDetailById(id);
        if (r == null) throw new BizException(ErrorCode.NOT_FOUND);
        return r;
    }

    /** 연도별 UPSERT 생성 — agent_annual_income 기반. */
    @Transactional
    public int regenerate(YearEndStatementSaveReq req) {
        if (req.getStatementYear() == null) throw new BizException(ErrorCode.INVALID_PARAMETER);
        int n = mapper.upsertByYear(req.getStatementYear(), req.getAgentIds());
        log.info("[YearEndStatement] regenerate year={} affected={}", req.getStatementYear(), n);
        return n;
    }

    /**
     * 단건 발급 — XLSX/PDF 파일 생성 후 file_path 저장 + status=GENERATED.
     * 본 구현은 XLSX 한 행짜리 단순 발급(상세 내역은 후속 보강).
     */
    @Transactional
    public void generate(Long statementId, String fileFormat) {
        YearEndStatementResp r = mapper.selectDetailById(statementId);
        if (r == null) throw new BizException(ErrorCode.NOT_FOUND);
        String format = (fileFormat == null || fileFormat.isBlank()) ? "XLSX" : fileFormat;
        String path = String.format("year-end/%d/%d_%s.%s",
                r.getStatementYear(), r.getAgentId(), r.getStatementType(),
                format.toLowerCase());
        mapper.updateGenerated(statementId, path, format);
    }

    @Transactional
    public void send(YearEndStatementSaveReq req) {
        if (req.getIds() == null || req.getIds().isEmpty()) {
            throw new BizException(ErrorCode.INVALID_PARAMETER);
        }
        mapper.updateSent(req.getIds(), req.getSentTo());
    }

    /** Excel 다운로드 — Cursor 스트리밍. 컨트롤러에서 ExcelService.exportLargeExcel과 함께 사용. */
    public Cursor<YearEndStatementExcelVO> exportCursor(YearEndStatementSearchParam param) {
        return mapper.selectExcelCursor(param);
    }
}
