package com.ga.api.service.commission;

import com.ga.core.mapper.commission.SettlingSupportLedgerMapper;
import com.ga.core.mapper.commission.SettlingSupportRuleMapper;
import com.ga.core.vo.commission.SettlingSupportLedgerSaveReq;
import com.ga.core.vo.commission.SettlingSupportLedgerVO;
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 com.ga.common.exception.BizException;

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

@ExtendWith(MockitoExtension.class)
class SettlingSupportServiceTest {

    @Mock SettlingSupportRuleMapper ruleMapper;
    @Mock SettlingSupportLedgerMapper ledgerMapper;

    @InjectMocks SettlingSupportService service;

    @Test
    @DisplayName("createLedger: net_amount = support_amount - clawback_amount (500,000 - 50,000 = 450,000)")
    void createLedger_netAmount() {
        SettlingSupportLedgerSaveReq req = new SettlingSupportLedgerSaveReq();
        req.setAgentId(1L);
        req.setSettleMonth("202506");
        req.setSupportAmount(new BigDecimal("500000"));
        req.setClawbackAmount(new BigDecimal("50000"));

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

        service.createLedger(req);

        SettlingSupportLedgerVO saved = captor.getValue();
        assertThat(saved.getNetAmount()).isEqualByComparingTo("450000.00");
        assertThat(saved.getStatus()).isEqualTo("CALCULATED");
    }

    @Test
    @DisplayName("createLedger: clawback null이면 0으로 처리 → net = support_amount")
    void createLedger_noClawback() {
        SettlingSupportLedgerSaveReq req = new SettlingSupportLedgerSaveReq();
        req.setAgentId(1L);
        req.setSettleMonth("202506");
        req.setSupportAmount(new BigDecimal("300000"));
        req.setClawbackAmount(null);

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

        service.createLedger(req);

        SettlingSupportLedgerVO saved = captor.getValue();
        assertThat(saved.getNetAmount()).isEqualByComparingTo("300000.00");
        assertThat(saved.getClawbackAmount()).isEqualByComparingTo("0");
    }

    @Test
    @DisplayName("createLedger: 환수액이 지원금을 초과하면 거부(net 음수 방지) — 원장 미생성")
    void createLedger_clawbackExceedsSupport_rejected() {
        SettlingSupportLedgerSaveReq req = new SettlingSupportLedgerSaveReq();
        req.setAgentId(1L);
        req.setSettleMonth("202506");
        req.setSupportAmount(new BigDecimal("300000"));
        req.setClawbackAmount(new BigDecimal("400000")); // 지원금 초과

        assertThatThrownBy(() -> service.createLedger(req))
                .isInstanceOf(BizException.class);
        verify(ledgerMapper, never()).insert(any());
    }
}
