package com.cico.nest.lcdp.boot.core.qxsd.infrastructure.gatewayimpl.ws.xlw.dto;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONArray;
import com.cico.nest.lcdp.boot.core.qxsd.adapter.config.runner.WsApplicationRunner;
import com.cico.nest.lcdp.boot.core.qxsd.domain.event.EventTypeAllEnum;
import com.cico.nest.lcdp.boot.core.qxsd.infrastructure.common.constatnt.XlwConstants;
import com.cico.nest.lcdp.boot.core.qxsd.infrastructure.gatewayimpl.database.dataobject.EventDetailDO;
import lombok.Data;
import org.springframework.boot.ApplicationRunner;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

import static com.cico.nest.lcdp.boot.core.qxsd.domain.event.EventStatus.disposing_await;
import static com.cico.nest.lcdp.boot.core.qxsd.domain.event.EventType.*;
import static com.cico.nest.lcdp.boot.core.qxsd.domain.vehicle.VehicleType.*;

/**
 * 实时事件
 * @author zws
 * @date 2024/8/14
 */

@Data
public class XlwRealTimeEventDTO {

    /**
     * 事件唯一id
     */
    private String guid;

    /**
     * 确认时间,格式：时间戳
     */
    private Long ackTime;

    /**
     * 确认人
     */
    private String ackUser;

    /**
     * 事件发生持续时长，单位：毫秒
     */
    private Integer duration;

    /**
     * 事件结束时间
     */
    private Long endTime;

    /**
     * 车牌颜色
     */
    private Integer entityColor;

    /**
     * 实体id，实体为车辆时对应车辆唯一id，实体为断面事件时为设备SN
     */
    private String entityId;

    /**
     * 实体为车辆时对应车牌号码，实体为断面事件时为设备SN
     */
    private String entityName;

    /**
     * 车型、参照交通部的收费车型（1~4 客1~客4 、11~16 货1~货6、专项车21~26 专项1~专项6）
     */
    private Integer entityType;

    /**
     * 事件等级，枚举：0低、1中、2高
     */
    private Integer eventLevel;

    /**
     * 事件备注信息
     */
    private String eventRemark;

    /**
     * 事件状态，枚举：0结束、1预警、2处理中
     */
    private Integer eventStatus;

    /**
     * 事件类型
     */
    private Integer eventType;

    /**
     * 车道号
     */
    private Integer eventRoadNo;

    /**
     * 车辆时速，单位：km/h
     */
    private Float speed;

    /**
     * 车辆扩展信息
     */
    private String extendInfo;

    /**
     * 事件开始时间，格式：时间戳
     */
    private Long startTime;

    /**
     * 开始预警时间，格式：时间戳
     */
    private Long startWarningTime;

    /**
     * 隧道id
     */
    private String tunnelId;

    /**
     * 设备SN
     */
    private String deviceSn;

    /**
     * 设备名称
     */
    private String deviceName;

    /**
     * 纬度
     */
    private Float latitude;

    /**
     * 经度
     */
    private Float longitude;

    /**
     * 桩号
     */
    private String milestone;

    /**
     * 方向。上行/下行
     */
    private String direction;

    /**
     * 方向名称
     */
    private String directionName;

    /**
     * 事件图片数组
     */
    private List<EventImage> imageList;
    /**
     * 轨迹ID
     */
    private String trackId;

    @Data
    public static class EventImage{

        /**
         * 设备名称
         */
        private String deviceName;

        /**
         * 设备SN
         */
        private String deviceSn;

        /**
         * 位置标识。入；经；出。为空时取车尾图
         */
        private String positionMark;

        /**
         * 设备顺序
         */
        private Integer deviceOrder;

        /**
         * 抓拍时间,格式：时间戳
         */
        private Long captureTime;

        /**
         * 车头图。positionMark为“入”或“出”时有效。可能为空
         */
        private String headImage;

        /**
         * 车尾图。positionMark为 “出”时为空
         */
        private String tailImage;
    }


    public static EventDetailDO convert2DO(XlwRealTimeEventDTO dto){
        EventDetailDO eventDO = new EventDetailDO();
        eventDO.setEventSource(XlwConstants.EVENT_SOURCE_XLW);
        eventDO.setDeviceCode(dto.getDeviceSn());
        eventDO.setThirdPartyId(dto.getGuid());
        eventDO.setTrackId(dto.getTrackId());
        eventDO.setDirection(dto.getDirection());
        eventDO.setDirectionName(dto.getDirectionName());
        if(Objects.nonNull(dto.getEventRoadNo())){
            eventDO.setEventRoadNo(String.valueOf(dto.getEventRoadNo() + 1));
        }
        eventDO.setEventStartTime(new Date(dto.getStartTime()));
        if(Objects.nonNull(dto.getEndTime())){
            eventDO.setEventEndTime(new Date(dto.getEndTime()));
        }
        //eventDO.setEventType(XlwRealTimeEventDTO.convertDOEventType(dto.getEventType()));
        EventTypeAllEnum eventTypeEnum = EventTypeAllEnum.getByXlwCode(String.valueOf(dto.getEventType()));
        eventDO.setEventType(eventTypeEnum.getCode());
        eventDO.setEventStatus(disposing_await.type);
        //车牌号码
        List<String> eventCarPlate = new ArrayList<>();
        eventCarPlate.add(dto.getEntityName());
        eventDO.setEventCarPlate(eventCarPlate);
        //车辆信息
        EventDetailDO.EventCarInfo eventCarInfo = new EventDetailDO.EventCarInfo();
        eventCarInfo.setCarId(dto.getEntityId());
        eventCarInfo.setCarPlateColor(dto.getEntityColor());
        eventCarInfo.setSpeed(dto.getSpeed());
        eventCarInfo.setVehicleType(XlwRealTimeEventDTO.carModelConvertVehicleType(dto.getEntityType()));
        eventCarInfo.setCarPlate(dto.getEntityName());
        List<EventDetailDO.EventCarInfo> carInfoList = new ArrayList<>();
        carInfoList.add(eventCarInfo);
        eventDO.setCarInfoList(JSONArray.from(carInfoList));
        //车辆图片
        if(Objects.nonNull(dto.getImageList())){
            List<String> imagePathList = new ArrayList<>();
            dto.getImageList().forEach(eventImage->{
                if(StrUtil.isNotBlank(eventImage.getHeadImage())){
                    imagePathList.add(eventImage.getHeadImage());
                }

                if(StrUtil.isNotBlank(eventImage.getTailImage())){
                    imagePathList.add(eventImage.getTailImage());
                }
            });
            eventDO.setEventImagesPath(imagePathList);
        }
        String milestone = dto.getMilestone();
        //事件桩号
        if(StrUtil.isNotBlank(milestone)){
            eventDO.setMilestone(convertMilestoneStr(milestone));
            eventDO.setDeviceMilestone(convertMilestoneStr(milestone));
        }
        //设备桩号
        if(StrUtil.isNotBlank(dto.getDeviceSn())){
            String deviceMilestone = WsApplicationRunner.deviceMap.get(dto.getDeviceSn());
            if(Objects.nonNull(deviceMilestone)){
                eventDO.setDeviceMilestone(convertMilestoneStr(deviceMilestone));
            }
        }
        eventDO.setCreateTime(new Date());
        return eventDO;
    }

    public static String convertMilestoneStr(String milestone){
        try{
            if(milestone.contains("-")){
                String[] milestoneArray = milestone.split("-");
                int milestoneInt = Integer.parseInt(milestoneArray[0]) * 1000;
                if(milestoneArray.length > 1){
                    milestoneInt = milestoneInt + Integer.parseInt(milestoneArray[1]);
                }
                return milestoneInt+"";
            }else if(milestone.contains("+")){
                String[] milestoneArray = milestone.split("\\+");
                String startSplit = milestoneArray[0].substring(1);
                int milestoneInt = Integer.parseInt(startSplit) * 1000;
                if(milestoneArray.length > 1){
                    milestoneInt = milestoneInt + Integer.parseInt(milestoneArray[1]);
                }
                return milestoneInt+"";
            }
            return milestone;
        }catch (Exception e){
            return milestone;
        }
    }

    /**
     * 第一版 卫首2024年8月写的信路威事件类型映射关系
     * 信路威 -> 全息隧道
     * 0拥挤,1堵塞 -> 5拥堵
     * 201车辆违停 -> 8停车
     * 105实线变道 -> 2实线变道
     * 111急加速 -> 0急加速
     * 112急减速 -> 1急减速
     * 113蛇形驾驶 -> 3蛇形驾驶
     * @param dtoEventType
     * @return
     */
    public static Integer convertDOEventType(Integer dtoEventType){
        return switch (dtoEventType) {
            case 0, 1 -> congestion.type;
            case 201 -> parking.type;
            case 105 -> implement_lane_changes.type;
            case 111 -> hasten.type;
            case 112 -> deceleration.type;
            case 113 -> serpentine_driving.type;
            default -> other.type;
        };
    }


    public static Integer carModelConvertVehicleType(Integer carModel){
        if(Objects.isNull(carModel)){
            return other_car.type;
        }
        return switch (carModel) {
            case 1, 2,3,4 -> passenger.type;
            case 11,12,13,14,15,16 -> truck.type;
            default -> other_car.type;
        };
    }

}
