package com.clx.performance.listener;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.clx.order.feign.AddressFeign;
import com.clx.order.vo.feign.FeignAddressVO;
import com.clx.order.vo.feign.FeignOrderVO;
import com.clx.order.vo.feign.ReceiveAndSendAddressVO;
import com.clx.performance.constant.RabbitKeyConstants;
import com.clx.performance.dao.LargeScreenAddressRouteDao;
import com.clx.performance.dto.gd.GdPosDTO;
import com.clx.performance.dto.gd.GdRouteDTO;
import com.clx.performance.enums.PerformanceResultEnum;
import com.clx.performance.model.Geometry;
import com.clx.performance.model.LargeScreenAddressRoute;
import com.clx.performance.model.MongoLargeScreenAddressRoute;
import com.clx.performance.utils.gd.GdService;
import com.msl.common.base.Optional;
import com.msl.common.result.Result;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.data.geo.Point;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.geo.GeoJsonLineString;
import org.springframework.data.mongodb.core.geo.GeoJsonPoint;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.LinkedList;
import java.util.List;

@Slf4j
@Component
@AllArgsConstructor
public class LargeScreenListener {

    private final LargeScreenAddressRouteDao largeScreenAddressRouteDao;

    private final GdService gdService;

    private final AddressFeign addressFeign;

    private final MongoTemplate mongoTemplate;

    @Transactional(rollbackFor = Exception.class)
    @RabbitListener(queues = RabbitKeyConstants.ORDER_LARGE_SCREEN_QUEUE)
    public void onMessage(String message) {
        try {
            FeignOrderVO orderVO = JSONUtil.toBean(message, FeignOrderVO.class);
            log.info("处理数据大屏标准地址路线监听器执行,订单Id为{},发货地标准地址ID为{},收货地标准地址ID为{}", orderVO.getOrderNo(), orderVO.getSendSystemAddressId(), orderVO.getReveiveSystemAddressId());

            if (ObjectUtil.isNull(orderVO.getSendSystemAddressId()) || ObjectUtil.isNull(orderVO.getReveiveSystemAddressId())) {
                log.info("当前订单标准地址相关为空,不予处理");
                return;
            }
            Integer receiveAddressId = orderVO.getReveiveSystemAddressId();
            Integer sendAddressId = orderVO.getSendSystemAddressId();
            String receiveName = orderVO.getReveiveAddressShorter();
            String sendName = orderVO.getSendAddressShorter();

            List<LargeScreenAddressRoute> list = largeScreenAddressRouteDao.getEntityByReceiveAddressIdAndSendAddressId(receiveAddressId, sendAddressId);
            if (CollectionUtil.isNotEmpty(list)) {
                log.info("当前地址已经记录receiveAddressId{}, sendAddressId{}", receiveAddressId, sendAddressId);
            } else {
                ReceiveAndSendAddressVO feignAddressVO = Optional.of(addressFeign.getSendAndReceiveSystemAddress(sendAddressId, receiveAddressId)).filter(Result::succeed)
                        .map(Result::getData).orElseThrow(PerformanceResultEnum.DATA_NOT_FIND);
                log.info("查询出标准地址相关坐标经纬度：{}", JSONUtil.parse(feignAddressVO));
                BigDecimal sendAddressLatitude = feignAddressVO.getSendAddressVo().getLatitude().setScale(4, RoundingMode.DOWN);
                BigDecimal sendAddressLongitude = feignAddressVO.getSendAddressVo().getLongitude().setScale(4, RoundingMode.DOWN);

                BigDecimal receiveAddressLatitude = feignAddressVO.getReceiveAddressVo().getLatitude().setScale(4, RoundingMode.DOWN);
                BigDecimal receiveAddressLongitude = feignAddressVO.getReceiveAddressVo().getLongitude().setScale(4, RoundingMode.DOWN);

                List<GdRouteDTO> route = gdService.getRoute(sendAddressLongitude, sendAddressLatitude, receiveAddressLongitude, receiveAddressLatitude);
                MongoLargeScreenAddressRoute mongoEntity = new MongoLargeScreenAddressRoute();

                mongoEntity.setName(sendName);
                mongoEntity.setReceiveSystemAddressId(receiveAddressId);
                mongoEntity.setSendSystemAddressId(sendAddressId);
                mongoEntity.setValue(sendName);
                mongoEntity.setColorField("3");
                mongoEntity.setSizeField("3");
                mongoEntity.setInfo(receiveName);
                List<Point> points = new LinkedList<>();
                List<GdPosDTO> posList = route.get(0).getPosList();
                for (GdPosDTO gdPosDTO : posList) {
                    GeoJsonPoint geoJsonPoint = new GeoJsonPoint(new Point(gdPosDTO.getLongitude().doubleValue(), gdPosDTO.getLatitude().doubleValue()));
                    points.add(geoJsonPoint);
                }
                mongoEntity.setGeometry(new GeoJsonLineString(points));
                mongoTemplate.insert(mongoEntity);
                LargeScreenAddressRoute build = LargeScreenAddressRoute.builder().
                        receiveSystemAddressId(receiveAddressId)
                        .sendSystemAddressId(sendAddressId)
                        .receiveName(receiveName)
                        .sendName(sendName)
                        .build();
                largeScreenAddressRouteDao.saveEntity(build);
            }

        } catch (Exception e) {
            log.info("数据大屏监控订单轨迹线路异常:{}", e.getMessage());
        }


    }


}
