package com.gxwebsoft.shop;

import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.shop.dto.OrderCreateRequest;
import com.gxwebsoft.shop.entity.ShopGoods;
import com.gxwebsoft.shop.entity.ShopOrder;
import com.gxwebsoft.shop.entity.ShopOrderGoods;
import com.gxwebsoft.shop.service.OrderBusinessService;
import com.gxwebsoft.shop.service.ShopGoodsService;
import com.gxwebsoft.shop.service.ShopOrderGoodsService;
import com.gxwebsoft.shop.service.ShopOrderService;
import org.junit.jupiter.api.BeforeEach;
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 java.math.BigDecimal;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;

/**
 * 订单业务服务测试类
 *
 * @author 科技小王子
 * @since 2025-01-26
 */
@ExtendWith(MockitoExtension.class)
public class OrderBusinessServiceTest {

    @Mock
    private ShopOrderService shopOrderService;

    @Mock
    private ShopOrderGoodsService shopOrderGoodsService;

    @Mock
    private ShopGoodsService shopGoodsService;

    @InjectMocks
    private OrderBusinessService orderBusinessService;

    private User testUser;
    private OrderCreateRequest testRequest;
    private ShopGoods testGoods;

    @BeforeEach
    void setUp() {
        // 准备测试用户
        testUser = new User();
        testUser.setUserId(1);
        testUser.setOpenid("test_openid");
        testUser.setPhone("13800138000");

        // 准备测试商品
        testGoods = new ShopGoods();
        testGoods.setGoodsId(10018);
        testGoods.setName("科技小王子大米年卡套餐2.5kg");
        testGoods.setPrice(new BigDecimal("99.00"));
        testGoods.setImage("test_image.jpg");

        // 准备测试订单请求
        testRequest = new OrderCreateRequest();
        testRequest.setType(0);
        testRequest.setTotalPrice(new BigDecimal("99.00"));
        testRequest.setPayPrice(new BigDecimal("99.00"));
        testRequest.setTotalNum(1);
        testRequest.setPayType(1);
        testRequest.setTenantId(1);
        testRequest.setAddressId(10832);
        testRequest.setComments("科技小王子大米年卡套餐2.5kg");
        testRequest.setDeliveryType(0);

        // 准备商品项列表
        OrderCreateRequest.OrderGoodsItem goodsItem = new OrderCreateRequest.OrderGoodsItem();
        goodsItem.setGoodsId(10018);
        goodsItem.setQuantity(1);
        goodsItem.setPayType(1);

        testRequest.setGoodsItems(Arrays.asList(goodsItem));
    }

    @Test
    void testCreateOrderWithGoods() {
        // Mock 商品查询
        when(shopGoodsService.getById(10018)).thenReturn(testGoods);

        // Mock 订单保存
        when(shopOrderService.save(any(ShopOrder.class))).thenAnswer(invocation -> {
            ShopOrder order = invocation.getArgument(0);
            order.setOrderId(1); // 模拟数据库生成的ID
            return true;
        });

        // Mock 订单商品批量保存
        when(shopOrderGoodsService.saveBatch(anyList())).thenReturn(true);

        // Mock 微信支付订单创建
        HashMap<String, String> wxOrderInfo = new HashMap<>();
        wxOrderInfo.put("prepay_id", "test_prepay_id");
        when(shopOrderService.createWxOrder(any(ShopOrder.class))).thenReturn(wxOrderInfo);

        // 执行测试
        Map<String, String> result = orderBusinessService.createOrder(testRequest, testUser);

        // 验证结果
        assert result != null;
        assert result.containsKey("prepay_id");

        // 验证方法调用
        verify(shopGoodsService, times(1)).getById(10018);
        verify(shopOrderService, times(1)).save(any(ShopOrder.class));
        verify(shopOrderGoodsService, times(1)).saveBatch(anyList());
        verify(shopOrderService, times(1)).createWxOrder(any(ShopOrder.class));
    }

    @Test
    void testCreateOrderWithMultipleGoods() {
        // 准备多个商品项
        OrderCreateRequest.OrderGoodsItem goodsItem1 = new OrderCreateRequest.OrderGoodsItem();
        goodsItem1.setGoodsId(10018);
        goodsItem1.setQuantity(1);
        goodsItem1.setPayType(1);

        OrderCreateRequest.OrderGoodsItem goodsItem2 = new OrderCreateRequest.OrderGoodsItem();
        goodsItem2.setGoodsId(10019);
        goodsItem2.setQuantity(2);
        goodsItem2.setPayType(1);

        testRequest.setGoodsItems(Arrays.asList(goodsItem1, goodsItem2));
        testRequest.setTotalPrice(new BigDecimal("297.00")); // 99 + 99*2

        // Mock 商品查询
        when(shopGoodsService.getById(10018)).thenReturn(testGoods);

        ShopGoods testGoods2 = new ShopGoods();
        testGoods2.setGoodsId(10019);
        testGoods2.setName("测试商品2");
        testGoods2.setPrice(new BigDecimal("99.00"));
        testGoods2.setImage("test_image2.jpg");
        when(shopGoodsService.getById(10019)).thenReturn(testGoods2);

        // Mock 其他服务
        when(shopOrderService.save(any(ShopOrder.class))).thenAnswer(invocation -> {
            ShopOrder order = invocation.getArgument(0);
            order.setOrderId(1);
            return true;
        });
        when(shopOrderGoodsService.saveBatch(anyList())).thenReturn(true);
        when(shopOrderService.createWxOrder(any(ShopOrder.class))).thenReturn(new HashMap<>());

        // 执行测试
        orderBusinessService.createOrder(testRequest, testUser);

        // 验证商品查询次数
        verify(shopGoodsService, times(1)).getById(10018);
        verify(shopGoodsService, times(1)).getById(10019);

        // 验证保存的商品项数量
        verify(shopOrderGoodsService, times(1)).saveBatch(argThat(list ->
            ((List<ShopOrderGoods>) list).size() == 2
        ));
    }
}
