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.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import java.text.ParseException;
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.MarketEntryTestSamples;
import com.ruoyi.web.modules.trading.domain.BizMarketEntry;
import com.ruoyi.web.modules.trading.mapper.BizMarketEntryEarTagMapper;
import com.ruoyi.web.modules.trading.mapper.BizMarketEntryMapper;
import com.ruoyi.web.modules.trading.support.MarketEntryReferenceChecker;
import com.ruoyi.web.modules.trading.support.MarketEntryRules;
import com.ruoyi.web.modules.trading.support.MarketEntryValidation;

@ExtendWith(MockitoExtension.class)
@MockitoSettings(strictness = Strictness.LENIENT)
@DisplayName("BizMarketEntryServiceImpl")
class BizMarketEntryServiceImplTest
{
    @Mock
    private BizMarketEntryMapper bizMarketEntryMapper;

    @Mock
    private BizMarketEntryEarTagMapper bizMarketEntryEarTagMapper;

    @Mock
    private MarketEntryValidation marketEntryValidation;

    @Mock
    private MarketEntryReferenceChecker referenceChecker;

    @InjectMocks
    private BizMarketEntryServiceImpl service;

    @BeforeEach
    void stubValidation()
    {
        doAnswer(invocation -> {
            BizMarketEntry row = invocation.getArgument(0);
            row.setStallCode("01");
            if (row.getEarTagList() != null)
            {
                row.setQuantity(row.getEarTagList().size());
                row.setEarTags(String.join(",", row.getEarTagList()));
            }
            return null;
        }).when(marketEntryValidation).prepareAndValidateForSave(any());
    }

    @Test
    @DisplayName("ZCZX-SCJLDJ-UT-017 新增写入 stall_code")
    void ut017_insertStallCode() throws ParseException
    {
        BizMarketEntry row = MarketEntryTestSamples.normalSaveRow();
        when(bizMarketEntryMapper.insertBizMarketEntry(any())).thenAnswer(inv -> {
            BizMarketEntry r = inv.getArgument(0);
            r.setId(MarketEntryTestSamples.ENTRY_ID);
            return 1;
        });
        service.insertBizMarketEntry(row);
        ArgumentCaptor<BizMarketEntry> captor = ArgumentCaptor.forClass(BizMarketEntry.class);
        verify(bizMarketEntryMapper).insertBizMarketEntry(captor.capture());
        verify(bizMarketEntryEarTagMapper).batchInsertEarTag(any());
        assertEquals("01", captor.getValue().getStallCode());
        assertEquals(MarketEntryRules.DEL_FLAG_NORMAL, captor.getValue().getDelFlag());
    }

    @Test
    @DisplayName("ZCZX-SCJLDJ-UT-018 逻辑删除")
    void ut018_delete()
    {
        BizMarketEntry db = new BizMarketEntry();
        db.setId(MarketEntryTestSamples.ENTRY_ID);
        db.setDelFlag(MarketEntryRules.DEL_FLAG_NORMAL);
        when(bizMarketEntryMapper.selectBizMarketEntryByIdAny(MarketEntryTestSamples.ENTRY_ID)).thenReturn(db);
        when(bizMarketEntryMapper.logicDeleteBizMarketEntryByIds(any(), eq("tester"))).thenReturn(1);
        service.deleteBizMarketEntryByIds(new Long[] { MarketEntryTestSamples.ENTRY_ID }, "tester");
        verify(bizMarketEntryMapper).logicDeleteBizMarketEntryByIds(
                new Long[] { MarketEntryTestSamples.ENTRY_ID }, "tester");
    }

    @Test
    @DisplayName("ZCZX-SCJLDJ-UT-019 删除有关联禁止")
    void ut019_deleteReferenced()
    {
        BizMarketEntry db = new BizMarketEntry();
        db.setId(MarketEntryTestSamples.ENTRY_ID);
        db.setDelFlag(MarketEntryRules.DEL_FLAG_NORMAL);
        when(bizMarketEntryMapper.selectBizMarketEntryByIdAny(MarketEntryTestSamples.ENTRY_ID)).thenReturn(db);
        when(referenceChecker.hasReference(MarketEntryTestSamples.ENTRY_ID)).thenReturn(true);
        assertThrows(ServiceException.class,
                () -> service.deleteBizMarketEntryByIds(new Long[] { MarketEntryTestSamples.ENTRY_ID }, "tester"));
    }

    @Test
    @DisplayName("详情解析耳标列表")
    void detailEarTagList() throws ParseException
    {
        BizMarketEntry row = MarketEntryTestSamples.persistedRow();
        row.setEarTags("E103,E104");
        when(bizMarketEntryMapper.selectBizMarketEntryById(MarketEntryTestSamples.ENTRY_ID)).thenReturn(row);
        BizMarketEntry result = service.selectBizMarketEntryById(MarketEntryTestSamples.ENTRY_ID);
        assertEquals(2, result.getEarTagList().size());
    }
}
