package com.ningdatech.carapi.alarm;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ningdatech.carapi.AppTests;
import com.ningdatech.carapi.car.monitor.entity.DataAccessAlarmWarn;
import com.ningdatech.carapi.car.monitor.entity.DataAccessAlarmWarnFile;
import com.ningdatech.carapi.car.monitor.entity.VehicleSecurityMonitor;
import com.ningdatech.carapi.car.monitor.service.IDataAccessAlarmWarnFileService;
import com.ningdatech.carapi.car.monitor.service.IDataAccessAlarmWarnService;
import com.ningdatech.carapi.car.monitor.service.IVehicleSecurityMonitorService;
import com.ningdatech.carapi.car.vehicle.model.NdVehicleBaseInfo;
import com.ningdatech.carapi.common.constant.BgTypeEnum;
import com.ningdatech.carapi.common.constant.DeletedEnum;
import com.ningdatech.carapi.common.constant.VehicleTypeEnum;
import com.ningdatech.carapi.common.util.CodeUtil;
import com.ningdatech.carapi.driver.constant.DriverAbnormalBehaviorAppendixTypeEnum;
import com.ningdatech.carapi.scheduler.contants.TaskConstant;
import com.ningdatech.carapi.sys.helper.VehiclesCacheHelper;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.StopWatch;
import lombok.extern.slf4j.Slf4j;

/**
 * @author PoffyZhang
 * @Classname AlarmTest
 * @Description
 * @Date 2022/12/15 18:11
 */
@Slf4j
public class AlarmTest extends AppTests {

    @Resource
    private IDataAccessAlarmWarnService dataAccessAlarmWarnService;

    @Resource
    private IDataAccessAlarmWarnFileService dataAccessAlarmWarnFileService;

    @Resource
    private VehiclesCacheHelper vehiclesCacheHelper;
    @Autowired
    private RedisTemplate<String,Object> redisTemplate;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private IVehicleSecurityMonitorService vehicleSecurityMonitorService;

    @Test
    public void test1(){
        Map<Object, Object> online_index = stringRedisTemplate.opsForHash().entries("online_index");
        System.out.println(online_index);
    }

    @Test
    public void test(){
        log.info("========== 更新车辆安全监控数据 ==========任务开始");
        StopWatch stopWatch = StopWatch.create(StringUtils.EMPTY);
        stopWatch.start();

        List<DataAccessAlarmWarn> alarms = dataAccessAlarmWarnService.list(Wrappers.lambdaQuery(DataAccessAlarmWarn.class)
                .eq(DataAccessAlarmWarn::getId,16078)
                .isNotNull(DataAccessAlarmWarn::getBgType)
                .orderBy(Boolean.TRUE,Boolean.TRUE,DataAccessAlarmWarn::getId));

        if(CollUtil.isEmpty(alarms)){
            log.info("this time vehicle alarm size is empty");
            return;
        }

        log.info("this time vehicle alarm size :{}",alarms.size());

        //获取异常行为列表的所有报警唯一序号
        List<Long> alarmMsgSnList = alarms.stream().map(DataAccessAlarmWarn::getAlarmMsgSn).collect(Collectors.toList());
        List<DataAccessAlarmWarnFile> files = dataAccessAlarmWarnFileService.list(Wrappers.lambdaQuery(DataAccessAlarmWarnFile.class)
                .in(DataAccessAlarmWarnFile::getAlarmMsgSn,alarmMsgSnList));
        for (DataAccessAlarmWarn alarm : alarms) {
            NdVehicleBaseInfo car = vehiclesCacheHelper.getByCarPlate(alarm.getVehicleNo());
            if(Objects.isNull(car)){
                log.info("此条异常行为数据 系统里没有这辆车 {}", JSON.toJSONString(alarm));
                continue;
            }

            VehicleSecurityMonitor monitor = new VehicleSecurityMonitor();
            List<DataAccessAlarmWarnFile> matchFiles = files.stream()
                    .filter(d -> Objects.nonNull(d.getAlarmMsgSn())
                            && d.getAlarmMsgSn().equals(alarm.getAlarmMsgSn())
                            && Objects.nonNull(d.getGnssCenterId())
                            && d.getGnssCenterId().equals(alarm.getGnssCenterId()))
                    .collect(Collectors.toList());
            for (DataAccessAlarmWarnFile file : matchFiles) {
                if (DriverAbnormalBehaviorAppendixTypeEnum.PICTURE.getCode().equals(file.getFileType())){
                    monitor.setPictureUrl(StringUtils.isNotBlank(file.getFilePath()) ? file.getFilePath() : file.getSrcPath());
                } else if (DriverAbnormalBehaviorAppendixTypeEnum.VIDEO.getCode().equals(file.getFileType())){
                    monitor.setVideoUrl(StringUtils.isNotBlank(file.getFilePath()) ? file.getFilePath() : file.getSrcPath());
                }
            }

            String content = alarm.getContent();
            if(Objects.isNull(content) || !CodeUtil.getJSONType(content)){
                log.info("此条异常行为数据content内容有误 {}",JSON.toJSONString(alarm));
                continue;
            }

            JSONObject jsonContent = JSON.parseObject(content);
            JSONObject gpsJson = jsonContent.getJSONObject(TaskConstant.DataField.GPS);

            if(Objects.isNull(gpsJson)){
                log.info("此条异常行为数据 GPS 内容有误 {}",JSON.toJSONString(alarm));
                continue;
            }

            monitor.setLongitude(Optional.of(gpsJson.getBigDecimal(TaskConstant.DataField.LONGITUDE))
                    .map(c -> c.divide(TaskConstant.Math.LONGITUDE_UNITS, BigDecimal.ROUND_HALF_EVEN,BigDecimal.ROUND_HALF_UP)).get());
            monitor.setLatitude(Optional.of(gpsJson.getBigDecimal(TaskConstant.DataField.LATITUDE))
                    .map(c -> c.divide(TaskConstant.Math.LONGITUDE_UNITS,BigDecimal.ROUND_HALF_EVEN,BigDecimal.ROUND_HALF_UP)).get());

            // 装配告警信息
            monitor.setCompanyId(car.getCompanyId());
            monitor.setRegionId(car.getRegionId());
            CodeUtil.searchCompanyNameAndRegionName(monitor);
            monitor.setAlarmAddress(alarm.getAddress());
            monitor.setAlarmId(alarm.getAlarmMsgSn());
            monitor.setAlarmType(alarm.getBgType());
            monitor.setAlarmTypeName(BgTypeEnum.getDescByCode(alarm.getBgType()));
            monitor.setCarPlate(alarm.getVehicleNo());
            monitor.setVehicleType(car.getVehicleType());
            monitor.setVehicleTypeName(VehicleTypeEnum.getDescByCode(car.getVehicleType()));
            monitor.setAlarmTime(alarm.getStartTime());
            monitor.setAlarmLevel(alarm.getGrade());
            monitor.setOperatorId(alarm.getGnssCenterId());

            VehicleSecurityMonitor one = vehicleSecurityMonitorService.getOne(Wrappers.lambdaQuery(VehicleSecurityMonitor.class)
                    .eq(VehicleSecurityMonitor::getDeleted, DeletedEnum.NO_DELETED)
                    .eq(VehicleSecurityMonitor::getAlarmId, alarm.getAlarmMsgSn())
                    .eq(VehicleSecurityMonitor::getOperatorId,alarm.getGnssCenterId()));
            if(Objects.nonNull(one)){
                monitor.setId(one.getId());
            }

            vehicleSecurityMonitorService.saveOrUpdate(monitor);
        }
        stopWatch.stop();
        log.info(stopWatch.getTotalTimeSeconds() + ":::");
    }


}
