package com.ga.api.service.commission;

import com.ga.core.mapper.commission.IncomeCommissionLedgerMapper;
import com.ga.core.mapper.commission.MarginSummaryMapper;
import com.ga.core.vo.commission.IncomeCommissionLedgerSaveReq;
import com.ga.core.vo.commission.IncomeCommissionLedgerVO;
import com.ga.core.vo.commission.MarginSummaryVO;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import java.math.BigDecimal;

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

@ExtendWith(MockitoExtension.class)
class IncomeCommissionServiceTest {

    @Mock IncomeCommissionLedgerMapper ledgerMapper;
    @Mock MarginSummaryMapper marginMapper;

    @InjectMocks IncomeCommissionService service;

    @Test
    @DisplayName("createLedger: income_amount = premium × company_rate (1,000,000 × 0.6 = 600,000)")
    void createLedger_incomeAmount() {
        IncomeCommissionLedgerSaveReq req = new IncomeCommissionLedgerSaveReq();
        req.setContractId(1L);
        req.setCarrierId(10L);
        req.setSettleMonth("202506");
        req.setPremiumAmount(new BigDecimal("1000000"));
        req.setCompanyRate(new BigDecimal("0.6"));
        req.setCommissionType("RECRUIT");

        ArgumentCaptor<IncomeCommissionLedgerVO> captor = ArgumentCaptor.forClass(IncomeCommissionLedgerVO.class);
        when(ledgerMapper.insert(captor.capture())).thenReturn(1);

        service.createLedger(req);

        IncomeCommissionLedgerVO saved = captor.getValue();
        assertThat(saved.getIncomeAmount()).isEqualByComparingTo("600000.00");
        assertThat(saved.getStatus()).isEqualTo("CALCULATED");
    }

    @Test
    @DisplayName("recalcMargin: margin = income - payout, marginRate = margin / income")
    void recalcMargin_calculation() {
        when(marginMapper.sumIncomeByMonth("202506")).thenReturn(new BigDecimal("1000000"));
        when(marginMapper.sumPayoutByMonth("202506", null)).thenReturn(new BigDecimal("600000"));
        when(marginMapper.selectByMonthAndAgent("202506", null)).thenReturn(null);

        ArgumentCaptor<MarginSummaryVO> captor = ArgumentCaptor.forClass(MarginSummaryVO.class);
        when(marginMapper.insert(captor.capture())).thenReturn(1);

        service.recalcMargin("202506", null);

        MarginSummaryVO saved = captor.getValue();
        assertThat(saved.getMarginAmount()).isEqualByComparingTo("400000.00");
        assertThat(saved.getMarginRate()).isEqualByComparingTo("0.4000");
    }
}
