
package com.tmerclub.cloud.order.service.impl;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.tmerclub.cloud.api.delivery.constant.DistanceUtil;
import com.tmerclub.cloud.api.delivery.vo.StationVO;
import com.tmerclub.cloud.api.feign.SearchOrderFeignClient;
import com.tmerclub.cloud.api.order.constant.OrderStatus;
import com.tmerclub.cloud.common.constant.Constant;
import com.tmerclub.cloud.common.database.dto.PageDTO;
import com.tmerclub.cloud.common.database.util.PageUtil;
import com.tmerclub.cloud.common.database.vo.PageVO;
import com.tmerclub.cloud.common.exception.LuckException;
import com.tmerclub.cloud.common.order.constant.OrderActivityType;
import com.tmerclub.cloud.common.order.constant.RefundStatusEnum;
import com.tmerclub.cloud.common.order.dto.OrderSearchDTO;
import com.tmerclub.cloud.common.order.vo.*;
import com.tmerclub.cloud.common.util.BeanUtil;
import com.tmerclub.cloud.delivery.manager.DeliveryManager;
import com.tmerclub.cloud.order.mapper.OrderSelfStationMapper;
import com.tmerclub.cloud.order.model.OrderSelfStation;
import com.tmerclub.cloud.order.service.OrderSelfStationService;
import com.tmerclub.cloud.order.service.OrderVirtualInfoService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 自提订单自提点信息
 *
 * @author tmerclub
 * @date 2020-12-05 14:13:50
 */
@Service
public class OrderSelfStationServiceImpl implements OrderSelfStationService {

    @Autowired
    private OrderSelfStationMapper orderSelfStationMapper;

    @Autowired
    private DeliveryManager deliveryManager;
    @DubboReference
    private SearchOrderFeignClient searchOrderFeignClient;
    @Autowired
    private OrderVirtualInfoService orderVirtualInfoService;

    /**
     * 默认地球半径
     * //赤道半径(单位m)
     */
    private static final double EARTH_RADIUS = 6371000;

    @Override
    public PageVO<OrderSelfStationVO> page(PageDTO pageDTO) {
        return PageUtil.doPage(pageDTO, () -> orderSelfStationMapper.list());
    }

    @Override
    public OrderSelfStationVO getById(Long id) {
        return orderSelfStationMapper.getById(id);
    }

    @Override
    public void save(OrderSelfStation orderSelfStation) {
        orderSelfStationMapper.save(orderSelfStation);
    }

    @Override
    public void saveBatch(List<OrderSelfStation> orderSelfStations) {
        orderSelfStationMapper.saveBatch(orderSelfStations);
    }

    @Override
    public void update(OrderSelfStation orderSelfStation) {
        orderSelfStationMapper.update(orderSelfStation);
    }

    @Override
    public void deleteById(Long id) {
        orderSelfStationMapper.deleteById(id);
    }

    @Override
    public List<OrderSelfStation> getStationUserInfo(Long userId) {
        return orderSelfStationMapper.getStationUserInfo(userId);
    }

    @Override
    public OrderVO getOrderByStationCode(Long stationId, String code) {
        StationVO stationVO = deliveryManager.getStation(stationId);
        OrderSearchDTO orderSearchDTO = new OrderSearchDTO();
        orderSearchDTO.setPageSize(1);
        orderSearchDTO.setPageNum(1);
        orderSearchDTO.setStatus(OrderStatus.PAYED.value());
        orderSearchDTO.setStationCode(code);
        orderSearchDTO.setStationId(stationId);
        orderSearchDTO.setShopId(stationVO.getShopId());
        List<EsOrderVO> orderList = searchOrderFeignClient.listEsOrder(orderSearchDTO).getData();
        if (Objects.isNull(orderList) || orderList.size() == 0) {
            orderSearchDTO = new OrderSearchDTO();
            orderSearchDTO.setPageSize(1);
            orderSearchDTO.setPageNum(1);
            orderSearchDTO.setStatusList(Arrays.asList(
                    OrderStatus.CONSIGNMENT.value(),
                    OrderStatus.SUCCESS.value())
            );
            orderSearchDTO.setWriteOffStatus(0);
            orderSearchDTO.setOrderMold(1);
            orderSearchDTO.setWriteOffCode(code);
            orderSearchDTO.setShopId(stationVO.getShopId());
            // 如果查询不到，就去查询虚拟商品的券码信息
            orderList = searchOrderFeignClient.listEsOrder(orderSearchDTO).getData();
            if (Objects.isNull(orderList) || orderList.size() == 0) {
                throw new LuckException("该提货码，没有对应的订单");
            } else {
                List<OrderVirtualInfoVO> orderVirtualInfoVOList = orderVirtualInfoService.getByOrderIdAndCode(orderList.get(0).getOrderId(), code);
                if (Objects.nonNull(orderVirtualInfoVOList)) {
                    List<OrderVirtualInfoVO> infoList = orderVirtualInfoVOList.stream().filter(infoVO -> infoVO.getIsWriteOff() == 0).collect(Collectors.toList());
                    if (infoList.size() == 0) {
                        throw new LuckException("该提货码，没有对应的订单");
                    }
                    orderList.get(0).setOrderVirtualInfoList(infoList);
                }
            }
        } else if (Objects.equals(orderList.get(0).getRefundStatus(), RefundStatusEnum.SUCCEED.value())) {
            // 该提货码，没有对应的订单
            throw new LuckException("该提货码，没有对应的订单");
        }
        OrderVO orderByStationCode = BeanUtil.map(orderList.get(0), OrderVO.class);
        if (Objects.isNull(stationId)) {
            return orderByStationCode;
        }
        if (StrUtil.isBlank(orderByStationCode.getShopName())) {
            orderByStationCode.setShopName(Constant.PLATFORM_SHOP_NAME);
        }
        orderByStationCode.setOrderSelfStationVO(orderSelfStationMapper.getStationByOrderId(orderByStationCode.getOrderId()));
        Map<Long, List<OrderItemVO>> giveawayMap = orderByStationCode.getOrderItems().stream().filter(orderItemVO -> Objects.equals(orderItemVO.getActivityType(), OrderActivityType.GIVEAWAY.value()))
                .collect(Collectors.groupingBy(OrderItemVO::getActivityId));
        Map<Long, List<OrderItemVO>> comboMap = orderByStationCode.getOrderItems().stream().filter(orderItemVO -> Objects.equals(orderItemVO.getActivityType(), OrderActivityType.COMBO_PROD.value()))
                .collect(Collectors.groupingBy(OrderItemVO::getActivityId));
        if (MapUtil.isEmpty(giveawayMap) && MapUtil.isEmpty(comboMap)) {
            return orderByStationCode;
        }
        Iterator<OrderItemVO> iterator = orderByStationCode.getOrderItems().iterator();
        while (iterator.hasNext()) {
            OrderItemVO orderItem = iterator.next();
            if (Objects.equals(orderItem.getActivityType(), OrderActivityType.GIVEAWAY.value()) || Objects.equals(orderItem.getActivityType(), OrderActivityType.COMBO_PROD.value())) {
                iterator.remove();
            }
            orderItem.setGiveawayList(giveawayMap.get(orderItem.getOrderItemId()));
            orderItem.setComboItemList(comboMap.get(orderItem.getOrderItemId()));
        }
        return orderByStationCode;
    }

    @Override
    public OrderSelfStationVO getStationByOrderId(OrderSelfStationVO orderSelfStation, Long orderId) {
        OrderSelfStationVO stationByOrderId;
        if(Objects.nonNull(orderSelfStation)){
            stationByOrderId = orderSelfStation;
        }else {
            stationByOrderId = orderSelfStationMapper.getStationByOrderId(orderId);
        }
        if (Objects.isNull(stationByOrderId)) {
            throw new LuckException("订单不存在");
        }
        StationVO stationVO = deliveryManager.getStation(stationByOrderId.getStationId());
        String addr = stationByOrderId.getStationAddress();
        if(StrUtil.isBlank(addr)){
            addr = stationVO.getProvince() + stationVO.getCity() + stationVO.getArea() + stationVO.getAddr();
        }
        stationByOrderId.setStationName(stationVO.getStationName());
        stationByOrderId.setLat(stationVO.getLat());
        stationByOrderId.setLng(stationVO.getLng());
        stationByOrderId.setTimeInfo(stationVO.getTimeInfo());
        stationByOrderId.setStationStatus(stationVO.getStatus());
        stationByOrderId.setStationImgUrl(stationVO.getImgUrl());
        stationByOrderId.setStationAddress(addr);
        // 自提点营业时间(不包含月和日)
        return stationByOrderId;
    }

    @Override
    public Double setStationDistance(Long stationId, Double lat, Double lng) {
        StationVO stationVO = deliveryManager.getStation(stationId);
        return DistanceUtil.getDistance(lng, lat, stationVO.getLng(), stationVO.getLat());
    }

    @Override
    public List<OrderSelfStationVO> getUserStation(Long userId) {
        return orderSelfStationMapper.getUserStation(userId);
    }

    @Override
    public List<OrderSelfStationVO> listSelfStationByOrderIds(List<Long> orderIds) {
        if (CollectionUtils.isEmpty(orderIds)) {
            return new ArrayList<>(0);
        }
        return orderSelfStationMapper.listSelfStationByOrderIds(orderIds);
    }

    @Override
    public List<OrderSelfStationVO> getOrderSelfStationByStationIdOrShopId(Long userId, Long stationId, Long shopId) {
        return orderSelfStationMapper.getOrderSelfStationByStationIdOrShopId(userId, stationId, shopId);
    }
}
