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

import java.math.BigDecimal;
import java.text.ParseException;
import java.util.Collections;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.web.modules.circulation.domain.BizTradeMarket;
import com.ruoyi.web.modules.circulation.mapper.BizTradeMarketMapper;
import com.ruoyi.web.modules.circulation.support.TradeMarketRules;
import com.ruoyi.web.modules.trading.MarketDailyQuoteTestSamples;
import com.ruoyi.web.modules.trading.domain.BizMarketDailyQuote;
import com.ruoyi.web.modules.trading.mapper.BizMarketDailyQuoteMapper;
import com.ruoyi.web.modules.trading.support.MarketDailyQuoteReferenceChecker;
import com.ruoyi.web.modules.trading.support.MarketDailyQuoteRules;
import com.ruoyi.web.modules.trading.support.MarketDailyQuoteValidation;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
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;

@ExtendWith(MockitoExtension.class)
@MockitoSettings(strictness = Strictness.LENIENT)
@DisplayName("BizMarketDailyQuoteServiceImpl")
class BizMarketDailyQuoteServiceImplTest
{
    @Mock
    private BizMarketDailyQuoteMapper quoteMapper;

    @Mock
    private BizTradeMarketMapper tradeMarketMapper;

    @Mock
    private MarketDailyQuoteValidation validation;

    @Mock
    private MarketDailyQuoteReferenceChecker referenceChecker;

    @InjectMocks
    private BizMarketDailyQuoteServiceImpl service;

    @Test
    @DisplayName("新增落库均价")
    void insert() throws ParseException
    {
        doAnswer(inv -> {
            BizMarketDailyQuote row = inv.getArgument(0);
            row.setAvgPrice(new BigDecimal("12.00"));
            return null;
        }).when(validation).prepareAndValidateForSave(any(), eq(null));
        when(quoteMapper.insertBizMarketDailyQuote(any())).thenReturn(1);
        BizMarketDailyQuote row = MarketDailyQuoteTestSamples.validSaveRow();
        assertEquals(1, service.insertBizMarketDailyQuote(row));
        verify(quoteMapper).insertBizMarketDailyQuote(argThat(r ->
                MarketDailyQuoteRules.DEL_FLAG_NORMAL.equals(r.getDelFlag())
                        && new BigDecimal("12.00").compareTo(r.getAvgPrice()) == 0));
    }

    @Test
    @DisplayName("逻辑删除")
    void remove()
    {
        BizMarketDailyQuote db = new BizMarketDailyQuote();
        db.setId(5L);
        db.setDelFlag(MarketDailyQuoteRules.DEL_FLAG_NORMAL);
        when(quoteMapper.selectBizMarketDailyQuoteByIdAny(5L)).thenReturn(db);
        when(referenceChecker.hasReference(5L)).thenReturn(false);
        when(quoteMapper.logicDeleteBizMarketDailyQuoteByIds(any(), eq("tester"))).thenReturn(1);
        assertEquals(1, service.deleteBizMarketDailyQuoteByIds(new Long[] { 5L }, "tester"));
    }

    @Test
    @DisplayName("删除有关联")
    void removeBlocked()
    {
        BizMarketDailyQuote db = new BizMarketDailyQuote();
        db.setId(8L);
        db.setDelFlag(MarketDailyQuoteRules.DEL_FLAG_NORMAL);
        when(quoteMapper.selectBizMarketDailyQuoteByIdAny(8L)).thenReturn(db);
        when(referenceChecker.hasReference(8L)).thenReturn(true);
        assertThrows(ServiceException.class,
                () -> service.deleteBizMarketDailyQuoteByIds(new Long[] { 8L }, "tester"));
        verify(quoteMapper, never()).logicDeleteBizMarketDailyQuoteByIds(any(), any());
    }

    @Test
    @DisplayName("渠道下拉仅正常市场")
    void tradeMarketOptions()
    {
        BizTradeMarket m = MarketDailyQuoteTestSamples.activeTradeMarket();
        when(tradeMarketMapper.selectBizTradeMarketList(any())).thenReturn(Collections.singletonList(m));
        assertEquals(1, service.selectTradeMarketOptions().size());
        verify(tradeMarketMapper).selectBizTradeMarketList(argThat(q ->
                TradeMarketRules.OPERATE_STATUS_NORMAL == q.getOperateStatus()));
    }
}
