package com.ga.batch.settlement.domain;

import com.ga.core.mapper.installment.InstallmentRatioMapper;
import com.ga.core.vo.installment.InstallmentPlanVO;
import com.ga.core.vo.installment.InstallmentRatioVO;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.when;

/**
 * 분급 계획 생성기 — plan_month 반영 검증 (API InstallmentPlanGenerator와 동일 출력).
 */
@ExtendWith(MockitoExtension.class)
class BatchInstallmentPlanGeneratorTest {

    @Mock InstallmentRatioMapper ratioMapper;
    @InjectMocks BatchInstallmentPlanGenerator generator;

    static final LocalDate CONTRACT_DATE = LocalDate.of(2024, 1, 15);

    private InstallmentRatioVO ratio(int year, Integer month, String pct) {
        InstallmentRatioVO r = new InstallmentRatioVO();
        r.setPlanYear(year);
        r.setPlanMonth(month);
        r.setRatioPercent(new BigDecimal(pct));
        return r;
    }

    @Test
    @DisplayName("plan_month 가 설정되면 settleMonth = 계약일 +N년 +(plan_month-1)월")
    void usesPlanMonthInSettleMonth() {
        // 1차년 4월차 100% (단일 회차)
        when(ratioMapper.selectAllActiveRatios(anyString(), anyString()))
                .thenReturn(List.of(ratio(1, 4, "100")));

        List<InstallmentPlanVO> plans = generator.generate(
                100L, new BigDecimal("700000"), CONTRACT_DATE, "WHOLE_LIFE");

        assertThat(plans).hasSize(1);
        InstallmentPlanVO p = plans.get(0);
        assertThat(p.getPlanMonth()).isEqualTo(4);
        // 2024-01 +1년 +3개월 = 2025-04
        assertThat(p.getSettleMonth()).isEqualTo("202504");
        assertThat(p.getExpectedAmount()).isEqualByComparingTo("700000");
    }

    @Test
    @DisplayName("plan_month 가 NULL 이면 연 단위(첫 달) — settleMonth = 계약일 +N년")
    void nullPlanMonthDefaultsToYearStart() {
        when(ratioMapper.selectAllActiveRatios(any(), anyString()))
                .thenReturn(List.of(ratio(2, null, "100")));

        List<InstallmentPlanVO> plans = generator.generate(
                100L, new BigDecimal("500000"), CONTRACT_DATE, null);

        InstallmentPlanVO p = plans.get(0);
        assertThat(p.getPlanMonth()).isEqualTo(1);
        // 2024-01 +2년 +0개월 = 2026-01
        assertThat(p.getSettleMonth()).isEqualTo("202601");
    }
}
