package com.cico.nest.lcdp.boot.core.qxsd.application.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONObject;
import com.cico.nest.lcdp.boot.core.qxsd.adapter.web.request.LocusDataRequest;
import com.cico.nest.lcdp.boot.core.qxsd.adapter.web.request.PassingProfileRequest;
import com.cico.nest.lcdp.boot.core.qxsd.adapter.web.request.RealTimeVehicleQueryRequest;
import com.cico.nest.lcdp.boot.core.qxsd.adapter.web.vo.PassProfileImageVO;
import com.cico.nest.lcdp.boot.core.qxsd.adapter.web.vo.PassingProfileVO;
import com.cico.nest.lcdp.boot.core.qxsd.application.service.TunnelDetailService;
import com.cico.nest.lcdp.boot.core.qxsd.application.service.VehicleService;
import com.cico.nest.lcdp.boot.core.qxsd.domain.gateway.VehicleGateway;
import com.cico.nest.lcdp.boot.core.qxsd.domain.vehicle.HistoryTunnelVehicle;
import com.cico.nest.lcdp.boot.core.qxsd.domain.vehicle.TunnelRealTimeVehicle;
import com.cico.nest.lcdp.boot.core.qxsd.domain.vehicle.VehicleInfo;
import com.cico.nest.lcdp.boot.core.qxsd.domain.vehicle.VehicleType;
import com.cico.nest.lcdp.boot.core.qxsd.infrastructure.common.constatnt.RedisConstants;
import com.cico.nest.lcdp.boot.core.qxsd.infrastructure.common.constatnt.XlwConstants;
import com.cico.nest.lcdp.boot.core.qxsd.infrastructure.gatewayimpl.VehicleGatewayImpl;
import com.cico.nest.lcdp.boot.core.qxsd.infrastructure.gatewayimpl.database.dataobject.TunnelDetailDO;
import com.cico.nest.lcdp.framework.common.pojo.PageResult;
import jakarta.annotation.Resource;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

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

/**
 * @author zws
 * @date 2024/8/8
 */

@Service
public class VehicleServiceImpl implements VehicleService {
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private TunnelDetailService tunnelDetailService;

    @Resource
    private VehicleGateway vehicleGateway;

    @Override
    public TunnelRealTimeVehicle realTimeVehicleList(RealTimeVehicleQueryRequest request) {
        List<TunnelRealTimeVehicle> allVehicleList = new ArrayList<>();
        List<String> tunnelIds = request.getTunnelIds();
        if(CollUtil.isEmpty(tunnelIds)){
            Set<String> keys = stringRedisTemplate.keys(RedisConstants.REDIS_REAL_TIME_VEHICLE_KEY.concat("*"));
            if(CollUtil.isNotEmpty(keys)){
                keys.forEach( key->{
                    String vehicleJson = stringRedisTemplate.opsForValue().get(key);
                    TunnelRealTimeVehicle vehicle = JSONObject.parseObject(vehicleJson,TunnelRealTimeVehicle.class);
                    allVehicleList.add(vehicle);
                });
            }
        }else{
            tunnelIds.forEach(tunnelId->{
                String redisKey = RedisConstants.REDIS_REAL_TIME_VEHICLE_KEY + tunnelId;
                String vehicleJson = stringRedisTemplate.opsForValue().get(redisKey);
                if(StrUtil.isNotEmpty(vehicleJson)){
                    TunnelRealTimeVehicle vehicle = JSONObject.parseObject(vehicleJson,TunnelRealTimeVehicle.class);
                    allVehicleList.add(vehicle);
                }
            });
        }

        if(allVehicleList.isEmpty()){
            return new TunnelRealTimeVehicle();
        }

        TunnelRealTimeVehicle countVehicle = allVehicleList.get(0);
        if(allVehicleList.size() > 1){
            for(int i = 1;i<allVehicleList.size();i++){
                countVehicle = countVehicle.add(allVehicleList.get(i));
            }
        }

        List<VehicleInfo> filterVehicleList = countVehicle.getVehicleInfoList().stream().filter(vehicle -> {
            boolean isDangerous = true;
            boolean vehicleType = true;
            boolean carPlate = true;
            boolean retainedMinutesTime = true;
            boolean direction = true;


            if(request.getIsDangerous() && vehicle.getIsDangerous() == 0){
                isDangerous = false;
            }
            if(request.getVehicleType() != null && !Objects.equals(vehicle.getVehicleType(), request.getVehicleType())){
                vehicleType = false;
            }
            if(StrUtil.isNotEmpty(request.getCarPlate()) && !vehicle.getCarPlate().contains(request.getCarPlate())){
                carPlate = false;
            }
            if(request.getRetainedMinutesTime() != null && vehicle.getRetainedMinutesTime() > request.getRetainedMinutesTime()){
                retainedMinutesTime = false;
            }
            if(StrUtil.isNotEmpty(request.getDirection()) && !Objects.equals(vehicle.getDirection(), request.getDirection())){
                direction = false;
            }
            return isDangerous && vehicleType && carPlate && retainedMinutesTime && direction;
        }).toList();
        filterVehicleList = filterVehicleList.stream()
                .sorted(Comparator.comparing(VehicleInfo::getInTunnelTime).reversed())
                .collect(Collectors.toList());
        countVehicle.setVehicleInfoList(filterVehicleList);

        //重新计算
        /*if(filterVehicleList.size() != countVehicle.getVehicleInfoList().size()){
            countVehicle = countVehicle.calculateMetrics(filterVehicleList);
        }*/
        return countVehicle;
    }

    @Override
    public VehicleInfo vehicleInfoByCarId(String carId) {
        List<TunnelRealTimeVehicle> allVehicleList = new ArrayList<>();
        Set<String> keys = stringRedisTemplate.keys(RedisConstants.REDIS_REAL_TIME_VEHICLE_KEY.concat("*"));
        if(CollUtil.isNotEmpty(keys)){
            keys.forEach( key->{
                String vehicleJson = stringRedisTemplate.opsForValue().get(key);
                TunnelRealTimeVehicle vehicle = JSONObject.parseObject(vehicleJson,TunnelRealTimeVehicle.class);
                allVehicleList.add(vehicle);
            });
        }

        if(CollUtil.isNotEmpty(allVehicleList)){
            TunnelRealTimeVehicle countVehicle = allVehicleList.get(0);
            if(allVehicleList.size() > 1){
                for(int i = 1;i<allVehicleList.size();i++){
                    countVehicle = countVehicle.add(allVehicleList.get(i));
                }
            }
            for(VehicleInfo vehicleInfo : countVehicle.getVehicleInfoList()){
                if(Objects.equals(vehicleInfo.getCarId(), carId)){
                    TunnelDetailDO tunnelDetailDO = tunnelDetailService.getTunnelDetail(vehicleInfo.getTunnelId());
                    VehicleType vehicleType = VehicleType.findByType(vehicleInfo.getVehicleType());
                    String eventSituation = vehicleType.desc.concat("(").concat(vehicleInfo.getCarPlate()).concat(")")
                            .concat(vehicleInfo.getInTunnelTime())
                            .concat("驶入")
                            .concat(tunnelDetailDO.getTunnelName())
                            .concat(tunnelDetailDO.getDirectionName());
                    vehicleInfo.setEventSituation(eventSituation);
                    return vehicleInfo;
                }
            }
        }
        return new VehicleInfo();
    }

    @Override
    public void focusVehiclesMark(String carId) {
        String redisKey = RedisConstants.REDIS_FOCUS_VEHICLE_MARK_KEY + carId;
        stringRedisTemplate.opsForValue().set(redisKey,carId);
    }

    @Override
    public void focusVehiclesUnMark(String carId) {
        String redisKey = RedisConstants.REDIS_FOCUS_VEHICLE_MARK_KEY + carId;
        stringRedisTemplate.delete(redisKey);
    }

    @Override
    public PageResult<PassingProfileVO> passingProfileList(PassingProfileRequest passingProfileRequest) {
        return vehicleGateway.passingProfileList(passingProfileRequest);
    }

    @Override
    public PassProfileImageVO passProfileImage(String passProfileId) {
        return vehicleGateway.passProfileImage(passProfileId);
    }

    @Override
    public Map<String,PassProfileImageVO> passProfileImages(List<String> passProfileIds) {
        return vehicleGateway.passProfileImageList(passProfileIds);
    }


    @Override
    public List<HistoryTunnelVehicle> getCarLocusData(LocusDataRequest request) {
        return vehicleGateway.getCarLocusData(request);
    }
}
