package com.ruoyi.web.modules.trading.service.impl;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.util.Collections;
import org.junit.jupiter.api.BeforeEach;
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 org.mockito.junit.jupiter.MockitoSettings;
import org.mockito.quality.Strictness;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.web.modules.trading.TradeOrderTestSamples;
import com.ruoyi.web.modules.trading.domain.BizSupplierSettlement;
import com.ruoyi.web.modules.trading.domain.BizTradeOrder;
import com.ruoyi.web.modules.trading.mapper.BizMarketEntryEarTagMapper;
import com.ruoyi.web.modules.trading.mapper.BizTradeOrderLineMapper;
import com.ruoyi.web.modules.trading.mapper.BizTradeOrderMapper;
import com.ruoyi.web.modules.trading.support.SettlementOnPayService;
import com.ruoyi.web.modules.trading.support.TradeOrderNoGenerator;
import com.ruoyi.web.modules.trading.support.TradeOrderRules;
import com.ruoyi.web.modules.trading.support.TradeOrderValidation;

@ExtendWith(MockitoExtension.class)
@MockitoSettings(strictness = Strictness.LENIENT)
@DisplayName("BizTradeOrderServiceImpl")
class BizTradeOrderServiceImplTest
{
    @Mock
    private BizTradeOrderMapper bizTradeOrderMapper;

    @Mock
    private BizTradeOrderLineMapper bizTradeOrderLineMapper;

    @Mock
    private BizMarketEntryEarTagMapper bizMarketEntryEarTagMapper;

    @Mock
    private TradeOrderValidation tradeOrderValidation;

    @Mock
    private TradeOrderNoGenerator tradeOrderNoGenerator;

    @Mock
    private SettlementOnPayService settlementOnPayService;

    @InjectMocks
    private BizTradeOrderServiceImpl service;

    @BeforeEach
    void stubValidation()
    {
        doAnswer(inv -> {
            BizTradeOrder row = inv.getArgument(0);
            if (row.getLineList() != null)
            {
                row.setTotalHeads(row.getLineList().size());
            }
            return null;
        }).when(tradeOrderValidation).prepareAndValidateForSave(any());
        when(tradeOrderNoGenerator.allocateNextOrderNo()).thenReturn(TradeOrderTestSamples.ORDER_NO);
    }

    @Test
    @DisplayName("ZCZX-JYDDGL-UT-025 新增主从表")
    void ut025_insert()
    {
        BizTradeOrder row = TradeOrderTestSamples.normalSaveRow();
        when(bizTradeOrderMapper.insertBizTradeOrder(any())).thenAnswer(inv -> {
            BizTradeOrder r = inv.getArgument(0);
            r.setId(TradeOrderTestSamples.ORDER_ID);
            return 1;
        });
        service.insertBizTradeOrder(row);
        ArgumentCaptor<BizTradeOrder> captor = ArgumentCaptor.forClass(BizTradeOrder.class);
        verify(bizTradeOrderMapper).insertBizTradeOrder(captor.capture());
        verify(bizTradeOrderLineMapper).batchInsertLine(any());
        assertEquals(TradeOrderRules.ORDER_STATUS_PENDING, captor.getValue().getOrderStatus());
    }

    @Test
    @DisplayName("ZCZX-JYDDGL-UT-028 已完成禁删")
    void ut028_deleteCompleted()
    {
        BizTradeOrder done = TradeOrderTestSamples.pendingRow();
        done.setOrderStatus(TradeOrderRules.ORDER_STATUS_COMPLETED);
        when(bizTradeOrderMapper.selectBizTradeOrderByIdAny(TradeOrderTestSamples.ORDER_ID))
                .thenReturn(done);
        assertThrows(ServiceException.class,
                () -> service.deleteBizTradeOrderByIds(new Long[] { TradeOrderTestSamples.ORDER_ID }, "tester"));
    }

    @Test
    @DisplayName("ZCZX-JYDDGL-UT-021 完成支付写结算")
    void ut021_completePay()
    {
        BizTradeOrder pending = TradeOrderTestSamples.pendingRow();
        when(bizTradeOrderMapper.selectBizTradeOrderById(TradeOrderTestSamples.ORDER_ID)).thenReturn(pending);
        when(bizTradeOrderLineMapper.selectLineListByOrderId(TradeOrderTestSamples.ORDER_ID))
                .thenReturn(pending.getLineList());
        when(bizTradeOrderMapper.updateOrderCompletePay(any())).thenReturn(1);
        when(tradeOrderValidation.assertSupplierFeeConfigured(any()))
                .thenReturn(TradeOrderTestSamples.supplierPerHead());
        BizSupplierSettlement settlement = new BizSupplierSettlement();
        settlement.setId(3001L);
        settlement.setSettlementNo("JSD20260520001");
        when(settlementOnPayService.createFromOrder(any(), any(), any())).thenReturn(settlement);

        BizTradeOrder result = service.completePay(TradeOrderTestSamples.payRequest(), "tester");
        assertEquals(TradeOrderRules.ORDER_STATUS_COMPLETED, result.getOrderStatus());
        assertEquals("JSD20260520001", result.getSettlementNo());
        verify(bizMarketEntryEarTagMapper).deleteBySupplierIdAndEarTag(
                eq(TradeOrderTestSamples.SUPPLIER_ID_1), eq("E101"));
    }
}
