package com.ruoyi.web.modules.stock.service;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.when;
import java.util.Collections;
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.common.exception.ServiceException;
import com.ruoyi.web.modules.goods.domain.BizGoods;
import com.ruoyi.web.modules.goods.mapper.BizGoodsMapper;
import com.ruoyi.web.modules.stock.constant.StockConstants;
import com.ruoyi.web.modules.stock.dto.StockQueryQuery;
import com.ruoyi.web.modules.stock.service.impl.StockQueryServiceImpl;
import com.ruoyi.web.modules.stock.support.StockSupport;
import com.ruoyi.web.modules.stock.vo.StockLogListRowVO;
import com.ruoyi.web.modules.stock.vo.StockQueryListRowVO;
import com.ruoyi.web.modules.stock.vo.StockQueryLogRowVO;

@ExtendWith(MockitoExtension.class)
class StockQueryServiceImplTest
{
    private static final Long SHOP_ID = 101L;

    private static final Long GOODS_ID = 1001L;

    @Mock
    private BizGoodsMapper goodsMapper;

    @Mock
    private IStockLogService stockLogService;

    @Mock
    private StockSupport stockSupport;

    @InjectMocks
    private StockQueryServiceImpl stockQueryService;

    @Test
    void selectList_enrichesSpecText()
    {
        StockQueryListRowVO row = new StockQueryListRowVO();
        row.setGoodsId(GOODS_ID);
        row.setGoodsName("测试商品");
        row.setStock(20);
        when(goodsMapper.selectStockQueryList(SHOP_ID, null)).thenReturn(Collections.singletonList(row));
        when(stockSupport.buildSpecText(GOODS_ID)).thenReturn("颜色:红");
        when(stockSupport.normalizeSpecText("颜色:红")).thenReturn("颜色:红");

        StockQueryListRowVO result = stockQueryService.selectList(SHOP_ID, new StockQueryQuery()).get(0);

        assertEquals("颜色:红", result.getSpecText());
        assertEquals(20, result.getStock());
    }

    @Test
    void listLogs_goodsNotFound_throws()
    {
        when(goodsMapper.selectByIdAndShop(GOODS_ID, SHOP_ID)).thenReturn(null);

        ServiceException ex = assertThrows(ServiceException.class,
                () -> stockQueryService.listLogs(SHOP_ID, GOODS_ID));
        assertEquals(StockConstants.MSG_INBOUND_GOODS_INVALID, ex.getMessage());
    }

    @Test
    void listLogs_signedQty()
    {
        BizGoods goods = new BizGoods();
        goods.setGoodsId(GOODS_ID);
        when(goodsMapper.selectByIdAndShop(GOODS_ID, SHOP_ID)).thenReturn(goods);

        StockLogListRowVO inbound = new StockLogListRowVO();
        inbound.setGoodsName("测试商品");
        inbound.setSpecText("—");
        inbound.setDirection(StockConstants.DIRECTION_IN);
        inbound.setChangeQty(5);
        inbound.setChangeReasonText("采购入库");

        StockLogListRowVO outbound = new StockLogListRowVO();
        outbound.setGoodsName("测试商品");
        outbound.setSpecText("—");
        outbound.setDirection(StockConstants.DIRECTION_OUT);
        outbound.setChangeQty(3);
        outbound.setChangeReasonText("下单扣减库存");

        StockLogListRowVO zero = new StockLogListRowVO();
        zero.setDirection(StockConstants.DIRECTION_OUT);
        zero.setChangeQty(0);
        zero.setChangeReasonText("删除产品规格");

        when(stockLogService.selectByGoodsId(SHOP_ID, GOODS_ID))
                .thenReturn(java.util.Arrays.asList(inbound, outbound, zero));

        java.util.List<StockQueryLogRowVO> rows = stockQueryService.listLogs(SHOP_ID, GOODS_ID);

        assertEquals(5, rows.get(0).getIoQty());
        assertEquals(-3, rows.get(1).getIoQty());
        assertEquals(0, rows.get(2).getIoQty());
    }
}
