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

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;
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 com.ruoyi.web.modules.trading.domain.AppYakMarketQuoteRow;
import com.ruoyi.web.modules.trading.domain.vo.AppYakMarketDailyListVo;
import com.ruoyi.web.modules.trading.domain.vo.AppYakMarketForecastVo;
import com.ruoyi.web.modules.trading.domain.vo.AppYakMarketStats7Vo;
import com.ruoyi.web.modules.trading.domain.vo.AppYakMarketTrendPointVo;
import com.ruoyi.web.modules.trading.domain.vo.AppYakMarketYesterdayVo;
import com.ruoyi.web.modules.trading.mapper.AppYakMarketQuoteMapper;
import com.ruoyi.web.modules.trading.support.MarketDailyQuoteRules;

@ExtendWith(MockitoExtension.class)
@DisplayName("牦牛行情服务")
class AppYakMarketServiceImplTest
{
    @Mock
    private AppYakMarketQuoteMapper appYakMarketQuoteMapper;

    @InjectMocks
    private AppYakMarketServiceImpl service;

    @Test
    @DisplayName("昨日行情有数据")
    void yesterdayFound() throws ParseException
    {
        AppYakMarketQuoteRow row = sampleRow("2026-05-19", "18.68");
        when(appYakMarketQuoteMapper.selectByQuoteDate(any(Date.class))).thenReturn(row);

        AppYakMarketYesterdayVo vo = service.selectYesterdayQuote();
        assertNotNull(vo);
        assertEquals(new BigDecimal("18.68"), vo.getAvgPrice());
        assertEquals("元/斤", vo.getPriceUnitName());
    }

    @Test
    @DisplayName("昨日行情无数据")
    void yesterdayEmpty()
    {
        when(appYakMarketQuoteMapper.selectByQuoteDate(any(Date.class))).thenReturn(null);
        assertNull(service.selectYesterdayQuote());
    }

    @Test
    @DisplayName("7日统计")
    void stats7() throws ParseException
    {
        when(appYakMarketQuoteMapper.selectByQuoteDateRange(any(Date.class), any(Date.class)))
                .thenReturn(Arrays.asList(
                        sampleRow("2026-05-17", "17.53"),
                        sampleRow("2026-05-19", "18.68")));

        AppYakMarketStats7Vo vo = service.selectStats7();
        assertEquals(new BigDecimal("18.11"), vo.getAvgPrice7());
        assertEquals(new BigDecimal("17.53"), vo.getMinPrice7());
        assertEquals(new BigDecimal("18.68"), vo.getMaxPrice7());
    }

    @Test
    @DisplayName("走势 7 日")
    void trend7() throws ParseException
    {
        when(appYakMarketQuoteMapper.selectByQuoteDateRange(any(Date.class), any(Date.class)))
                .thenReturn(Collections.singletonList(sampleRow("2026-05-19", "18.68")));

        List<AppYakMarketTrendPointVo> list = service.selectTrend(7);
        assertEquals(1, list.size());
        assertEquals(new BigDecimal("18.68"), list.get(0).getAvgPrice());
    }

    @Test
    @DisplayName("价格预测")
    void forecast() throws ParseException
    {
        AppYakMarketQuoteRow row = sampleRow("2026-05-19", "18.68");
        row.setProbRise(new BigDecimal("35"));
        row.setProbFlat(new BigDecimal("40"));
        row.setProbFall(new BigDecimal("25"));
        when(appYakMarketQuoteMapper.selectByQuoteDate(any(Date.class))).thenReturn(row);

        AppYakMarketForecastVo vo = service.selectForecast();
        assertEquals(new BigDecimal("40"), vo.getProbFlat());
    }

    @Test
    @DisplayName("每日行情列表映射")
    void dailyList() throws ParseException
    {
        AppYakMarketQuoteRow row = sampleRow("2026-05-19", "18.68");
        row.setId(1L);
        row.setPriceMin(new BigDecimal("16"));
        row.setPriceMax(new BigDecimal("18"));
        row.setSupplyStatus(1);
        row.setChangeFactors("1,5");
        row.setProbRise(new BigDecimal("60"));
        row.setProbFlat(new BigDecimal("25"));
        row.setProbFall(new BigDecimal("15"));
        row.setOutboundAdvice("鼓励上市");
        row.setTradeMarketName("巴青牦牛交易市场");
        row.setCountyName("巴青县");
        when(appYakMarketQuoteMapper.selectDailyList()).thenReturn(Collections.singletonList(row));

        List<AppYakMarketDailyListVo> list = service.selectDailyList();
        assertEquals(1, list.size());
        assertEquals("看涨", list.get(0).getTrendPrediction());
        assertEquals("鼓励上市", list.get(0).getOutboundAdvice());
    }

    private static AppYakMarketQuoteRow sampleRow(String date, String avg) throws ParseException
    {
        AppYakMarketQuoteRow row = new AppYakMarketQuoteRow();
        row.setQuoteDate(new SimpleDateFormat("yyyy-MM-dd").parse(date));
        row.setAvgPrice(new BigDecimal(avg));
        row.setPriceUnit(MarketDailyQuoteRules.PRICE_UNIT_PER_JIN);
        row.setCreateTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2026-05-19 10:00:00"));
        return row;
    }
}
