package com.clx.performance.service.impl;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.clx.order.feign.AddressFeign;
import com.clx.order.feign.OrderFeign;
import com.clx.order.vo.feign.FeignAddressVO;
import com.clx.order.vo.feign.FeignOrderInfoVO;
import com.clx.order.vo.feign.SystemAddressVO;
import com.clx.performance.dao.OrderChildDao;
import com.clx.performance.dto.zjxl.TruckTraceDTO;
import com.clx.performance.enums.PerformanceResultEnum;
import com.clx.performance.model.MongoLargeScreenAddressRoute;
import com.clx.performance.model.OrderChild;
import com.clx.performance.service.LargeScreenService;
import com.clx.performance.utils.zjxl.ZjxlGpsService;
import com.clx.user.feign.DriverFeign;
import com.msl.common.base.Optional;
import com.msl.common.enums.ResultEnum;
import com.msl.common.result.Result;
import com.msl.common.utils.DateUtils;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.geo.GeoJsonLineString;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;

@Service
@Slf4j
@AllArgsConstructor
public class LargeScreenServiceImpl implements LargeScreenService {


    private final ZjxlGpsService zjxlGpsService;

    private final DriverFeign driverFeign;

    private final AddressFeign addressFeign;

    private final OrderChildDao orderChildDao;

    private final OrderFeign orderFeign;

    private final MongoTemplate mongoTemplate;

    @Override
    public List<JSONObject> emptyCarList() {
        List<String> data = driverFeign.driverTruckList().getData();

        String now = DateUtils.formatDateTime(LocalDateTime.now(), "yyyy-MM-dd HH:mm:ss").get();
        List<OrderChild> orderChildList = orderChildDao.selectListWithEmptyCarList();
        if (CollectionUtils.isEmpty(orderChildList)) {
            return null;
        }
        List<String> list = orderChildList.stream().map(OrderChild::getTruckNo).collect(Collectors.toList());
        List<JSONObject> result = new LinkedList<>();
        int index = 0;
        String s = "<div><div><spanstyle='color:#999;display:inline-block;width:96px;text-align:right;'>车牌号：</span><spanstyle='color:#000;'>truckNo</span></div><div></div></div>";
        for (String truckNo : data) {
            if (list.contains(truckNo)) {
                continue;
            }

            List<TruckTraceDTO> truckTrace = zjxlGpsService.getTruckTrace(truckNo, now,
                    now);
            if (CollectionUtils.isNotEmpty(truckTrace)) {
                JSONObject jsonObject = new JSONObject();
                BigDecimal[] location = truckTrace.get(truckTrace.size() - 1).getLocation();
                BigDecimal longitude = location[0].setScale(4, BigDecimal.ROUND_DOWN);
                BigDecimal latitude = location[1].setScale(4, BigDecimal.ROUND_DOWN);
                jsonObject.set("id", ++index);
                jsonObject.set("lng", longitude);
                jsonObject.set("lat", latitude);
                jsonObject.set("info", s.replace("truckNo", truckNo));
                jsonObject.set("value", "");
                jsonObject.set("iconField", "ok");
                result.add(jsonObject);
            }

        }
        return result;

    }

    @Override
    public List<JSONObject> weightCarList() {
        List<String> data = driverFeign.driverTruckList().getData();

        String now = DateUtils.formatDateTime(LocalDateTime.now(), "yyyy-MM-dd HH:mm:ss").get();
        List<OrderChild> orderChildList = orderChildDao.selectListWithEmptyCarList();
        if (CollectionUtils.isEmpty(orderChildList)) {
            return null;
        }
        List<String> list = orderChildList.stream().map(OrderChild::getTruckNo).collect(Collectors.toList());
        List<JSONObject> result = new LinkedList<>();
        int index = 0;
        String s = "<div><div><spanstyle='color:#999;display:inline-block;width:96px;text-align:right;'>车牌号：</span><spanstyle='color:#000;'>truckNo</span></div><div></div></div>";

        for (String truckNo : data) {
            if (!list.contains(truckNo)) {
                continue;
            }

            List<TruckTraceDTO> truckTrace = zjxlGpsService.getTruckTrace(truckNo, now,
                    now);
            if (CollectionUtils.isNotEmpty(truckTrace)) {
                JSONObject jsonObject = new JSONObject();
                BigDecimal[] location = truckTrace.get(truckTrace.size() - 1).getLocation();
                BigDecimal longitude = location[0].setScale(4, BigDecimal.ROUND_DOWN);
                BigDecimal latitude = location[1].setScale(4, BigDecimal.ROUND_DOWN);
                jsonObject.set("id", ++index);
                jsonObject.set("lng", longitude);
                jsonObject.set("lat", latitude);
                jsonObject.set("info", s.replace("truckNo", truckNo));
                jsonObject.set("value", "");
                jsonObject.set("iconField", "ok");
                result.add(jsonObject);
            }

        }
        return result;
    }


    @Override
    public String receiveAddress(Integer addressId) {
        SystemAddressVO vo = Optional.of(addressFeign.getSystemReceiveAddress(addressId)).filter(Result::succeed)
                .map(Result::getData).orElseThrow(PerformanceResultEnum.HTTP_ERROR);
        JSONArray jsonArray = new JSONArray();
        String name = vo.getAddressShorter();
        String s = "<div style='max-width:180px;'><div style='display:flex;flex-direction:column;width:fit-content;margin:0auto;'><div style='text-align:center;'>name</div></div></div>";

        BigDecimal longitude = vo.getLongitude().setScale(4, RoundingMode.DOWN);
        BigDecimal latitude = vo.getLatitude().setScale(4, RoundingMode.DOWN);
        JSONObject jsonObject = new JSONObject();
        jsonObject.set("id", addressId);
        jsonObject.set("lng", longitude);
        jsonObject.set("lat", latitude);
        jsonObject.set("name", name);
        jsonObject.set("info", s.replace("name", name));
        jsonObject.set("iconField", "ok");
        jsonArray.add(jsonObject);
        return jsonArray.toString();
    }

    @Override
    public String sendAddress(Integer addressId) {
        List<SystemAddressVO> list = Optional.of(orderFeign.getOrderListByReceiveAddressId(addressId)).filter(Result::succeed)
                .map(Result::getData).orElseThrow(PerformanceResultEnum.DATA_NOT_FIND);
        JSONArray jsonArray = new JSONArray();
        String s = "<div style='max-width:180px;'><div style='display:flex;flex-direction:column;width:fit-content;margin:0auto;'><div style='text-align:center;'>name</div></div></div>";
        for (SystemAddressVO vo : list) {

            String name = vo.getAddressShorter();
            BigDecimal longitude = vo.getLongitude().setScale(4, RoundingMode.DOWN);
            BigDecimal latitude = vo.getLatitude().setScale(4, RoundingMode.DOWN);
            JSONObject jsonObject = new JSONObject();
            jsonObject.set("id", addressId);
            jsonObject.set("lng", longitude);
            jsonObject.set("lat", latitude);
            jsonObject.set("name", name);
            jsonObject.set("info", s.replace("name", name));
            jsonObject.set("iconField", "ok");
            jsonArray.add(jsonObject);
        }

        return jsonArray.toString();
    }

    @Override
    public String routeLine(Integer addressId) {
        List<SystemAddressVO> list = Optional.of(orderFeign.getOrderListByReceiveAddressId(addressId)).filter(Result::succeed)
                .map(Result::getData).orElseThrow(PerformanceResultEnum.DATA_NOT_FIND);
        List<Integer> addressIds = list.stream().map(SystemAddressVO::getId).collect(Collectors.toList());

        JSONArray jsonArray = new JSONArray();
        JSONObject jsonObject = new JSONObject();
        Query query = new Query();
        query.addCriteria(Criteria.where("sendSystemAddressId").in(addressIds));
        List<MongoLargeScreenAddressRoute> routes = mongoTemplate.find(query, MongoLargeScreenAddressRoute.class);
        if (CollectionUtils.isEmpty(routes)) {
            log.info("当前addressId查询mongodb轨迹数据为空,发货地集合为{}", JSONUtil.parse(addressIds));
            return null;
        }
        int randomNum = (int)(Math.random() * routes.size());

        MongoLargeScreenAddressRoute route = routes.get(randomNum);
        GeoJsonLineString geometry = route.getGeometry();
        jsonObject.set("id", "1");
        jsonObject.set("sendSystemAddressId", route.getSendSystemAddressId());
        jsonObject.set("receiveSystemAddressId", route.getReceiveSystemAddressId());
        jsonObject.set("name", route.getName());
        jsonObject.set("value", route.getValue());
        jsonObject.set("sizeField", "3");
        jsonObject.set("sizeField", "3");
        jsonObject.set("info", "info");
        jsonObject.set("geometry", JSONUtil.parse(geometry.getCoordinates()));
        jsonArray.add(jsonObject);
        return jsonArray.toString();
    }


}
