
package com.clx.performance.service.impl;

import com.clx.performance.dao.OrderChildDao;
import com.clx.performance.dao.OrderGoodsDao;
import com.clx.performance.dto.gd.GdRouteDTO;
import com.clx.performance.enums.EnabledStatusEnum;
import com.clx.performance.enums.OrderChildEnum;
import com.clx.performance.enums.PerformanceResultEnum;
import com.clx.performance.model.OrderChild;
import com.clx.performance.model.OrderGoods;
import com.clx.performance.param.app.OrderChildLoadRangeCheckParam;
import com.clx.performance.service.OrderChildOperateLimitConfigService;
import com.clx.performance.utils.gd.GdService;
import com.clx.performance.vo.app.OrderChildLoadRangeCheckResultVO;
import com.clx.performance.vo.pc.OrderChildOperateLimitConfigVO;
import com.msl.common.base.Optional;
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 org.mockito.junit.jupiter.MockitoSettings;
import org.mockito.quality.Strictness;

import java.math.BigDecimal;
import java.util.Collections;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.*;

@ExtendWith(MockitoExtension.class)
@MockitoSettings(strictness = Strictness.LENIENT)
class OrderChildServiceImpl3Test {

    @Mock
    private OrderGoodsDao orderGoodsDao;

    @Mock
    private OrderChildDao orderChildDao;

    @Mock
    private GdService gdService;

    @Mock
    private OrderChildOperateLimitConfigService orderChildOperateLimitConfigService;

    @InjectMocks
    private OrderChildServiceImpl orderChildService;

    private OrderChildLoadRangeCheckParam param;

    @BeforeEach
    void setUp() {
        param = new OrderChildLoadRangeCheckParam();
        param.setChildNo("testChildNo");
        param.setLatitude(BigDecimal.TEN);
        param.setLongitude(BigDecimal.TEN);
    }

    /**
     * 无配置情况
     */
    @Test
    void loadRangeCheck_whenConfigIsNull_shouldReturnError() {
        when(orderChildDao.getByChildNo(param.getChildNo())).thenReturn(Optional.of(new OrderChild()));
        when(orderGoodsDao.getByOrderGoodsNo(anyString())).thenReturn(Optional.of(new OrderGoods()));

        OrderChildLoadRangeCheckResultVO result = orderChildService.loadRangeCheck(param);

        assertEquals(PerformanceResultEnum.ORDER_CHILD_LOAD_LIMIT_CONFIG_ERROR.getCode(), result.getCode());
    }

    @Test
    void loadRangeCheck_whenConfigIsDisabled_shouldReturnDisabled() {
        OrderChildOperateLimitConfigVO config = new OrderChildOperateLimitConfigVO();
        config.setStatus(EnabledStatusEnum.DISABLE.getCode());
        // 限制装车距离为1.5
        config.setAllowUploadDistance(new BigDecimal("1.5"));


        OrderChild orderChild = new OrderChild();
        orderChild.setOrderGoodsNo("ordergoodsno");
        orderChild.setOrderNo("orderno");
        orderChild.setChildNo("orderno");
        orderChild.setStatus(OrderChildEnum.Status.GO_TO_SEND.getCode());
        OrderGoods orderGoods = new OrderGoods();
        when(orderChildOperateLimitConfigService.listConfig()).thenReturn(config);
        when(orderChildDao.getByChildNo(param.getChildNo())).thenReturn(Optional.of(orderChild));
        when(orderGoodsDao.getByOrderGoodsNo(anyString())).thenReturn(Optional.of(orderGoods));
        GdRouteDTO route = new GdRouteDTO();
        route.setDistance(2000);
        when(gdService.getRoute(any(), any(), any(), any())).thenReturn(Collections.singletonList(route));
        OrderChildLoadRangeCheckResultVO result = orderChildService.loadRangeCheck(param);
        assertEquals(PerformanceResultEnum.ORDER_CHILD_LOAD_LIMIT_CONFIG_DISABLED.getCode(), result.getCode());
    }

    /**
     * 在装车范围内，不进行提示
     */
    @Test
    void loadRangeCheck_ok() {
        OrderChildOperateLimitConfigVO config = new OrderChildOperateLimitConfigVO();
        config.setStatus(EnabledStatusEnum.ENABLE.getCode());
        // 限制装车距离为1.5
        config.setAllowUploadDistance(new BigDecimal("1.5"));

        OrderChild orderChild = new OrderChild();
        orderChild.setOrderGoodsNo("ordergoodsno");
        orderChild.setOrderNo("orderno");
        orderChild.setChildNo("orderno");
        orderChild.setStatus(OrderChildEnum.Status.GO_TO_SEND.getCode());
        OrderGoods orderGoods = new OrderGoods();
        when(orderChildOperateLimitConfigService.listConfig()).thenReturn(config);
        when(orderChildDao.getByChildNo(param.getChildNo())).thenReturn(Optional.of(orderChild));
        when(orderGoodsDao.getByOrderGoodsNo(anyString())).thenReturn(Optional.of(orderGoods));
        GdRouteDTO route = new GdRouteDTO();
        //距离装车距离为1000
        route.setDistance(1000);
        when(gdService.getRoute(any(), any(), any(), any())).thenReturn(Collections.singletonList(route));
        OrderChildLoadRangeCheckResultVO result = orderChildService.loadRangeCheck(param);
        assertEquals(OrderChildEnum.NeedAlertEnum.OK.getCode(), result.getCode());
    }

    /**
     * 运单不存在
     */
    @Test
    void loadRangeCheck_whenOrderChildNotFound_shouldReturnNotFound() {
        OrderChildOperateLimitConfigVO config = new OrderChildOperateLimitConfigVO();
        config.setStatus(EnabledStatusEnum.ENABLE.getCode());
        // 限制装车距离为1.5
        config.setAllowUploadDistance(new BigDecimal("1.5"));

        when(orderChildOperateLimitConfigService.listConfig()).thenReturn(config);
        when(orderChildDao.getByChildNo(param.getChildNo())).thenReturn(new Optional<>());
        OrderChildLoadRangeCheckResultVO result = orderChildService.loadRangeCheck(param);
        assertEquals(PerformanceResultEnum.ORDER_CHILD_NO_FOUND.getCode(), result.getCode());
        assertEquals(OrderChildEnum.NeedAlertEnum.FAIL.getCode(), result.getNeedAlert());
    }

}
