package com.ga.api.service.commission;

import com.ga.common.util.SecurityUtil;
import com.ga.core.mapper.commission.CommissionSimulationMapper;
import com.ga.core.vo.commission.CommissionSimulationResp;
import com.ga.core.vo.commission.CommissionSimulationSaveReq;
import com.ga.core.vo.commission.CommissionSimulationVO;
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.MockedStatic;
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.mockStatic;
import static org.mockito.Mockito.when;

@ExtendWith(MockitoExtension.class)
class CommissionSimulationServiceTest {

    @Mock CommissionSimulationMapper simulationMapper;

    @InjectMocks CommissionSimulationService service;

    /**
     * 1,000,000 × 0.6 = 600,000 (company_payment)
     * 600,000 × 0.75 = 450,000 (agent_commission)
     * 450,000 × 0.033 = 14,850 (withholding_tax)
     * 450,000 - 14,850 = 435,150 (net_amount)
     * 450,000 × 0.5 = 225,000 (expected_chargeback 자동 계산)
     */
    @Test
    @DisplayName("simulate: 수수료 공식 전체 검증 (1,000,000/0.6/0.75)")
    void simulate_fullFormula() {
        CommissionSimulationSaveReq req = new CommissionSimulationSaveReq();
        req.setSimName("테스트시뮬레이션");
        req.setPremiumAmount(new BigDecimal("1000000"));
        req.setCompanyRate(new BigDecimal("0.6"));
        req.setPayoutRate(new BigDecimal("0.75"));
        req.setCommissionYear(1);
        req.setExpectedChargeback(null); // 자동 계산

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

        CommissionSimulationResp mockResp = new CommissionSimulationResp();
        mockResp.setSimId(1L);
        when(simulationMapper.selectById(any())).thenReturn(mockResp);

        try (MockedStatic<SecurityUtil> staticMock = mockStatic(SecurityUtil.class)) {
            staticMock.when(SecurityUtil::getCurrentUserId).thenReturn(null);

            service.simulate(req);
        }

        CommissionSimulationVO saved = captor.getValue();
        assertThat(saved.getCompanyPayment()).isEqualByComparingTo("600000.00");
        assertThat(saved.getAgentCommission()).isEqualByComparingTo("450000.00");
        assertThat(saved.getWithholdingTax()).isEqualByComparingTo("14850.00");
        assertThat(saved.getNetAmount()).isEqualByComparingTo("435150.00");
        assertThat(saved.getExpectedChargeback()).isEqualByComparingTo("225000.00");
    }
}
