package com.ga.api.service.installment;

import com.ga.core.mapper.installment.InstallmentRatioMapper;
import com.ga.core.vo.installment.InstallmentPlanVO;
import com.ga.core.vo.installment.InstallmentRatioVO;
import com.ga.core.vo.installment.InstallmentStatus;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

@Component
@RequiredArgsConstructor
public class InstallmentPlanGenerator {

    private static final DateTimeFormatter DATE_FMT = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    private static final DateTimeFormatter MONTH_FMT = DateTimeFormatter.ofPattern("yyyyMM");

    private final InstallmentRatioMapper ratioMapper;

    /**
     * 계약 체결일 기준 1~7차년 분급 계획 생성.
     * ratioPercent 합이 100%가 안 되는 경우 각 연차별 비율만큼 지급.
     */
    public List<InstallmentPlanVO> generate(Long contractId, BigDecimal totalCommission,
                                            LocalDate contractDate, String productCategory) {
        String baseDate = contractDate.format(DATE_FMT);
        List<InstallmentRatioVO> ratios = ratioMapper.selectAllActiveRatios(productCategory, baseDate);

        List<InstallmentPlanVO> plans = new ArrayList<>();
        for (InstallmentRatioVO ratio : ratios) {
            // 마스터의 plan_month 가 NULL 이면 연 단위(첫 달 지급), NOT NULL 이면 그 회차(월) 그대로 사용.
            int planMonth = ratio.getPlanMonth() != null ? ratio.getPlanMonth() : 1;

            InstallmentPlanVO plan = new InstallmentPlanVO();
            plan.setContractId(contractId);
            plan.setPlanYear(ratio.getPlanYear());
            plan.setPlanMonth(planMonth);
            plan.setSettleMonth(
                    contractDate.plusYears(ratio.getPlanYear()).plusMonths(planMonth - 1L).format(MONTH_FMT)
            );
            plan.setExpectedAmount(
                    totalCommission.multiply(ratio.getRatioPercent())
                                   .divide(BigDecimal.valueOf(100), 0, RoundingMode.HALF_UP)
            );
            plan.setStatus(InstallmentStatus.SCHEDULED.code());
            plans.add(plan);
        }
        return plans;
    }
}
