package co.yixiang.yshop.module.distributor.service.distributororder;

import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.mock.mockito.MockBean;

import javax.annotation.Resource;

import co.yixiang.yshop.framework.test.core.ut.BaseDbUnitTest;

import co.yixiang.yshop.module.distributor.controller.admin.distributororder.vo.*;
import co.yixiang.yshop.module.distributor.dal.dataobject.distributororder.DistributorOrderDO;
import co.yixiang.yshop.module.distributor.dal.mysql.distributororder.DistributorOrderMapper;
import co.yixiang.yshop.framework.common.pojo.PageResult;

import javax.annotation.Resource;

import org.springframework.context.annotation.Import;

import java.util.*;
import java.time.LocalDateTime;

import static cn.hutool.core.util.RandomUtil.*;
import static co.yixiang.yshop.module.distributor.enums.ErrorCodeConstants.*;
import static co.yixiang.yshop.framework.test.core.util.AssertUtils.*;
import static co.yixiang.yshop.framework.test.core.util.RandomUtils.*;
import static co.yixiang.yshop.framework.common.util.date.LocalDateTimeUtils.*;
import static co.yixiang.yshop.framework.common.util.object.ObjectUtils.*;
import static co.yixiang.yshop.framework.common.util.date.DateUtils.*;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;

/**
 * {@link DistributorOrderServiceImpl} 的单元测试类
 *
 * @author admin
 */
@Import(DistributorOrderServiceImpl.class)
public class DistributorOrderServiceImplTest extends BaseDbUnitTest {

    @Resource
    private DistributorOrderServiceImpl orderService;

    @Resource
    private DistributorOrderMapper orderMapper;

    @Test
    public void testCreateOrder_success() {
        // 准备参数
        DistributorOrderCreateReqVO reqVO = randomPojo(DistributorOrderCreateReqVO.class);

        // 调用
        Long orderId = orderService.createOrder(reqVO);
        // 断言
        assertNotNull(orderId);
        // 校验记录的属性是否正确
        DistributorOrderDO order = orderMapper.selectById(orderId);
        assertPojoEquals(reqVO, order);
    }

    @Test
    public void testUpdateOrder_success() {
        // mock 数据
        DistributorOrderDO dbOrder = randomPojo(DistributorOrderDO.class);
        orderMapper.insert(dbOrder);// @Sql: 先插入出一条存在的数据
        // 准备参数
        DistributorOrderUpdateReqVO reqVO = randomPojo(DistributorOrderUpdateReqVO.class, o -> {
            o.setId(dbOrder.getId()); // 设置更新的 ID
        });

        // 调用
        orderService.updateOrder(reqVO);
        // 校验是否更新正确
        DistributorOrderDO order = orderMapper.selectById(reqVO.getId()); // 获取最新的
        assertPojoEquals(reqVO, order);
    }

    @Test
    public void testUpdateOrder_notExists() {
        // 准备参数
        DistributorOrderUpdateReqVO reqVO = randomPojo(DistributorOrderUpdateReqVO.class);

        // 调用, 并断言异常
        assertServiceException(() -> orderService.updateOrder(reqVO), ORDER_NOT_EXISTS);
    }

    @Test
    public void testDeleteOrder_success() {
        // mock 数据
        DistributorOrderDO dbOrder = randomPojo(DistributorOrderDO.class);
        orderMapper.insert(dbOrder);// @Sql: 先插入出一条存在的数据
        // 准备参数
        Long id = dbOrder.getId();

        // 调用
        orderService.deleteOrder(id);
        // 校验数据不存在了
        assertNull(orderMapper.selectById(id));
    }

    @Test
    public void testDeleteOrder_notExists() {
        // 准备参数
        Long id = randomLongId();

        // 调用, 并断言异常
        assertServiceException(() -> orderService.deleteOrder(id), ORDER_NOT_EXISTS);
    }

    @Test
    @Disabled  // TODO 请修改 null 为需要的值，然后删除 @Disabled 注解
    public void testGetOrderPage() {
        // mock 数据
        DistributorOrderDO dbOrder = randomPojo(DistributorOrderDO.class, o -> { // 等会查询到
            o.setCreateTime(null);
            o.setSettlementTime(null);
            o.setOid(null);
            o.setOrderId(null);
            o.setStatus(null);
            o.setDistributionRule(null);
            o.setDistributionPurchase(null);
            o.setDistributionProductSettlement(null);
            o.setDistributionWagesSettlement(null);
            o.setUserId(null);
            o.setUserName(null);
            o.setProductId(null);
            o.setProductAttrValueId(null);
            o.setProductName(null);
            o.setProductPrice(null);
            o.setDetailId(null);
            o.setSuperiorIdP1(null);
            o.setSuperiorNameP1(null);
            o.setSuperiorIdP2(null);
            o.setSuperiorNameP2(null);
            o.setFirstWages(null);
            o.setSecondWages(null);
            o.setFirstAmount(null);
            o.setSecondAmount(null);
        });
        orderMapper.insert(dbOrder);
        // 测试 createTime 不匹配
        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setCreateTime(null)));
        // 测试 settlementTime 不匹配
        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setSettlementTime(null)));
        // 测试 oid 不匹配
        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setOid(null)));
        // 测试 orderId 不匹配
        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setOrderId(null)));
        // 测试 status 不匹配
        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setStatus(null)));
        // 测试 distributionRule 不匹配
        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setDistributionRule(null)));
        // 测试 distributionPurchase 不匹配
        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setDistributionPurchase(null)));
        // 测试 distributionProductSettlement 不匹配
        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setDistributionProductSettlement(null)));
        // 测试 distributionWagesSettlement 不匹配
        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setDistributionWagesSettlement(null)));
        // 测试 userId 不匹配
        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setUserId(null)));
        // 测试 userName 不匹配
        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setUserName(null)));
        // 测试 productId 不匹配
        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setProductId(null)));
        // 测试 productAttrValueId 不匹配
        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setProductAttrValueId(null)));
        // 测试 productName 不匹配
        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setProductName(null)));
        // 测试 productPrice 不匹配
        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setProductPrice(null)));
        // 测试 detailId 不匹配
        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setDetailId(null)));
        // 测试 superiorIdP1 不匹配
        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setSuperiorIdP1(null)));
        // 测试 superiorNameP1 不匹配
        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setSuperiorNameP1(null)));
        // 测试 superiorIdP2 不匹配
        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setSuperiorIdP2(null)));
        // 测试 superiorNameP2 不匹配
        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setSuperiorNameP2(null)));
        // 测试 firstWages 不匹配
        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setFirstWages(null)));
        // 测试 secondWages 不匹配
        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setSecondWages(null)));
        // 测试 firstAmount 不匹配
        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setFirstAmount(null)));
        // 测试 secondAmount 不匹配
        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setSecondAmount(null)));
        // 准备参数
        DistributorOrderPageReqVO reqVO = new DistributorOrderPageReqVO();
        reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
        reqVO.setSettlementTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
        reqVO.setOid(null);
        reqVO.setOrderId(null);
        reqVO.setStatus(null);
        reqVO.setDistributionRule(null);
        reqVO.setDistributionPurchase(null);
        reqVO.setDistributionProductSettlement(null);
        reqVO.setDistributionWagesSettlement(null);
        reqVO.setUserId(null);
        reqVO.setUserName(null);
        reqVO.setProductId(null);
        reqVO.setProductAttrValueId(null);
        reqVO.setProductName(null);
        reqVO.setProductPrice(null);
        reqVO.setDetailId(null);
        reqVO.setSuperiorIdP1(null);
        reqVO.setSuperiorNameP1(null);
        reqVO.setSuperiorIdP2(null);
        reqVO.setSuperiorNameP2(null);
        reqVO.setFirstWages(null);
        reqVO.setSecondWages(null);
        reqVO.setFirstAmount(null);
        reqVO.setSecondAmount(null);

        // 调用
        PageResult<DistributorOrderDO> pageResult = orderService.getOrderPage(reqVO);
        // 断言
        assertEquals(1, pageResult.getTotal());
        assertEquals(1, pageResult.getList().size());
        assertPojoEquals(dbOrder, pageResult.getList().get(0));
    }

    @Test
    @Disabled  // TODO 请修改 null 为需要的值，然后删除 @Disabled 注解
    public void testGetOrderList() {
        // mock 数据
        DistributorOrderDO dbOrder = randomPojo(DistributorOrderDO.class, o -> { // 等会查询到
            o.setCreateTime(null);
            o.setSettlementTime(null);
            o.setOid(null);
            o.setOrderId(null);
            o.setStatus(null);
            o.setDistributionRule(null);
            o.setDistributionPurchase(null);
            o.setDistributionProductSettlement(null);
            o.setDistributionWagesSettlement(null);
            o.setUserId(null);
            o.setUserName(null);
            o.setProductId(null);
            o.setProductAttrValueId(null);
            o.setProductName(null);
            o.setProductPrice(null);
            o.setDetailId(null);
            o.setSuperiorIdP1(null);
            o.setSuperiorNameP1(null);
            o.setSuperiorIdP2(null);
            o.setSuperiorNameP2(null);
            o.setFirstWages(null);
            o.setSecondWages(null);
            o.setFirstAmount(null);
            o.setSecondAmount(null);
        });
        orderMapper.insert(dbOrder);
        // 测试 createTime 不匹配
        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setCreateTime(null)));
        // 测试 settlementTime 不匹配
        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setSettlementTime(null)));
        // 测试 oid 不匹配
        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setOid(null)));
        // 测试 orderId 不匹配
        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setOrderId(null)));
        // 测试 status 不匹配
        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setStatus(null)));
        // 测试 distributionRule 不匹配
        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setDistributionRule(null)));
        // 测试 distributionPurchase 不匹配
        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setDistributionPurchase(null)));
        // 测试 distributionProductSettlement 不匹配
        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setDistributionProductSettlement(null)));
        // 测试 distributionWagesSettlement 不匹配
        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setDistributionWagesSettlement(null)));
        // 测试 userId 不匹配
        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setUserId(null)));
        // 测试 userName 不匹配
        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setUserName(null)));
        // 测试 productId 不匹配
        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setProductId(null)));
        // 测试 productAttrValueId 不匹配
        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setProductAttrValueId(null)));
        // 测试 productName 不匹配
        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setProductName(null)));
        // 测试 productPrice 不匹配
        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setProductPrice(null)));
        // 测试 detailId 不匹配
        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setDetailId(null)));
        // 测试 superiorIdP1 不匹配
        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setSuperiorIdP1(null)));
        // 测试 superiorNameP1 不匹配
        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setSuperiorNameP1(null)));
        // 测试 superiorIdP2 不匹配
        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setSuperiorIdP2(null)));
        // 测试 superiorNameP2 不匹配
        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setSuperiorNameP2(null)));
        // 测试 firstWages 不匹配
        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setFirstWages(null)));
        // 测试 secondWages 不匹配
        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setSecondWages(null)));
        // 测试 firstAmount 不匹配
        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setFirstAmount(null)));
        // 测试 secondAmount 不匹配
        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setSecondAmount(null)));
        // 准备参数
        DistributorOrderExportReqVO reqVO = new DistributorOrderExportReqVO();
        reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
        reqVO.setSettlementTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
        reqVO.setOid(null);
        reqVO.setOrderId(null);
        reqVO.setStatus(null);
        reqVO.setDistributionRule(null);
        reqVO.setDistributionPurchase(null);
        reqVO.setDistributionProductSettlement(null);
        reqVO.setDistributionWagesSettlement(null);
        reqVO.setUserId(null);
        reqVO.setUserName(null);
        reqVO.setProductId(null);
        reqVO.setProductAttrValueId(null);
        reqVO.setProductName(null);
        reqVO.setProductPrice(null);
        reqVO.setDetailId(null);
        reqVO.setSuperiorIdP1(null);
        reqVO.setSuperiorNameP1(null);
        reqVO.setSuperiorIdP2(null);
        reqVO.setSuperiorNameP2(null);
        reqVO.setFirstWages(null);
        reqVO.setSecondWages(null);
        reqVO.setFirstAmount(null);
        reqVO.setSecondAmount(null);

        // 调用
        List<DistributorOrderDO> list = orderService.getOrderList(reqVO);
        // 断言
        assertEquals(1, list.size());
        assertPojoEquals(dbOrder, list.get(0));
    }

}
