package com.cico.nest.lcdp.boot.core.qxsd.infrastructure.gatewayimpl.database.dataobject;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.fastjson2.JSONArray;
import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import com.cico.nest.lcdp.boot.core.qxsd.adapter.web.vo.event.EventDetailRespVO;
import com.cico.nest.lcdp.boot.core.qxsd.application.service.TunnelDetailService;
import com.cico.nest.lcdp.boot.core.qxsd.domain.event.EventType;
import com.cico.nest.lcdp.boot.core.qxsd.infrastructure.common.utils.EventUtil;
import com.cico.nest.lcdp.framework.common.util.date.DateUtils;
import com.cico.nest.lcdp.framework.mybatis.core.type.StringListTypeHandler;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.*;
import org.springframework.format.annotation.DateTimeFormat;

import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 事件详情 DO
 *
 * @author 管理员
 */
@TableName(value = "qxsd_event_detail",autoResultMap = true)
@KeySequence("qxsd_event_detail_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库，可不写。
@Data
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class EventDetailDO {

    /**
     * 主键
     */
    @TableId(type = IdType.ASSIGN_UUID)
    private String id;
    /**
     * 三方系统id
     */
    private String thirdPartyId;
    /**
     * 隧道id-(目前保存的是隧道信息的id)
     */
    private String tunnelId;
    /**
     * xlw隧道id
     */
    private String xlwTunnelId;
    /**
     * 所属隧道id
     */
    private String baseTunnelId;
    /**
     * 所属隧道code
     */
    private String baseTunnelCode;
    /**
     * 所属洞id
     */
    private String holeId;
    /**
     * 方向   上行/下行
     */
    private String direction;
    /**
     * 方向名称
     */
    private String directionName;
    /**
     * 桩号
     */
    private String milestone;
    /**
     * 车道号
     */
    private String eventRoadNo;
    /**
     * 事件开始时间
     */
    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date eventStartTime;
    /**
     * 0急加速1急减速2实现变道3蛇形驾驶4逆行5拥堵6可疑事件7追尾8停车
     */
    private Integer eventType;
    /**
     * 事件状态 0待处置1处置中2已处置3待处置-已读
     */
    private Integer eventStatus;
    /**
     * 事件处置状态 1确认， 2无需处置，3误报，4挂起，5结束
     */
    private Integer eventProcessStatus;

    /**
     * 第三方事件状态事件状态  0结束、1预警、2处理中
     */
    private Integer thirdEventStatus;

    //设备桩米号
    private String deviceMilestone;

    /**
     * 事件结束时间
     */
    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date eventEndTime;
    /**
     * 现场情况
     */
    private String sceneSituation;
    /**
     * 事件备注
     */
    private String eventRemark;

    /**
     * 车牌
     */
    @TableField(typeHandler = StringListTypeHandler.class)
    private List<String> eventCarPlate;

    /**
     * 时间图片路径
     */
    @TableField(typeHandler = StringListTypeHandler.class)
    private List<String> eventImagesPath;

    /**
     * 车辆信息
     */
    @TableField(typeHandler = JacksonTypeHandler.class)
    private JSONArray carInfoList;

    /**
     * 消除原因
     */
    private String dispelCause;
    /**
     * 事件来源：1信路威，2隧道管控
     */
    private Integer eventSource;
    /**
     * 事是否是重复事件：0不是，1是
     */
    private Integer isRepeat;
    /**
     * 隧道管控-事件告警id
     */
    private String alarmId;
    /**
     * 监测到事件的设备编号
     */
    private String deviceCode;
    /**
     * 创建人
     */
    private String createBy;
    /**
     * 更新人
     */
    private String updateBy;
    /**
     * 上报时间
     */
    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private java.util.Date reportTime;
    /**
     * 处置方式(1:上报事件;2:消除事件;)
     */
    private Integer processingType;
    /**
     * 处置操作人姓名
     */
    private String processingOperationsName;
    /**
     * 处置时间
     */
    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date processingTime;
    /**
     * 创建时间
     */
    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private java.util.Date createTime;

    /**
     * 更新时间
     */
    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private java.util.Date updateTime;

    /**
     * 轨迹ID
     */
    private String trackId;

    @Data
    public static class EventCarInfo{
        /**
         * 进隧道时间
         */
        private Long inTunnelTime;

        /**
         * 车辆id
         */
        private String carId;

        /**
         * 车辆颜色
         */
        private Integer carPlateColor;

        /**
         * 车辆时速
         */
        private Float speed;

        /**
         * 车辆类型
         */
        private Integer vehicleType;

        /**
         * 车牌号码
         */
        private String carPlate;

        /**
         * 车头图片
         */
        private String headImageUrl;

        /**
         * 车牌图片
         */
        private String plateImageUrl;

        /**
         * 危是否化品车辆，枚举：0否、1是
         */
        private Boolean isDangerous = false;

        //是否重点标记
        private Boolean isFocusMark = false;

        //留存时间（分钟）
        private Integer retainedMinutesTime = 0;

        //是否驶出隧道
        private Boolean isDriveTunnel = false;

        /**
         * 进隧道时间
         */
        private String inTunnelTimeStr;

        /**
         * 车辆图片
         */
        private String carImageUrl;
    }


    public static EventDetailRespVO convert2VO(EventDetailDO eventDetail,String xlwImagePath) {
        if (eventDetail == null) {
            return null;
        }
        EventDetailRespVO eventDetailRespVO = new EventDetailRespVO();
        org.springframework.beans.BeanUtils.copyProperties(eventDetail, eventDetailRespVO);
        //车牌号码
        List<String> carPlateList = eventDetail.getEventCarPlate();
        carPlateList = carPlateList.stream().filter(carPlate -> !EventUtil.CAR_PLATE_ERROR_LIST.contains(carPlate)).toList();
        eventDetailRespVO.setEventCarPlate(carPlateList);

        if (Objects.nonNull(eventDetail.getCarInfoList())) {
            eventDetailRespVO.setCarInfoList(JSONArray.parseArray(eventDetail.getCarInfoList().toJSONString(), EventCarInfo.class));
        }
        Date endTime = Objects.isNull(eventDetail.getEventEndTime()) ? new Date() : eventDetail.getEventEndTime();
        long diffSecond = DateUtils.diff(endTime, eventDetail.getEventStartTime()) / 1000;
        int second = (int) diffSecond % 60;
        int minute = (int) diffSecond / 60;
        eventDetailRespVO.setRetainedTime(minute + "分" + second + "秒");
        if (minute > 60) {
            int hour = minute / 60;
            minute = minute % 60;
            eventDetailRespVO.setRetainedTime(hour + "小时" + minute + "分");
            if (hour > 24) {
                int day = hour / 24;
                hour = hour % 24;
                eventDetailRespVO.setRetainedTime(day + "天" + hour + "小时");
            }
        }
        String singMultiCar = "";
        if (eventDetail.getCarInfoList() != null) {
            if (eventDetail.getCarInfoList().size() > 1) {
                singMultiCar = "多车";
                eventDetailRespVO.setSingleMultiCar("多车");
            } else {
                eventDetailRespVO.setSingleMultiCar("单车");
                singMultiCar = "单车";
            }
        }
        String eventSituation = "";
        TunnelDetailService tunnelDetailService = SpringUtil.getBean(TunnelDetailService.class);
        TunnelDetailDO tunnelDetailDO = tunnelDetailService.getTunnelDetail(eventDetail.getTunnelId());
        if (Objects.nonNull(tunnelDetailDO)) {
            eventSituation = eventSituation.concat(tunnelDetailDO.getTunnelName())
                    .concat(tunnelDetailDO.getDirectionName());
        }
        EventType eventType = EventType.findByType(eventDetail.getEventType());
        String milestone = EventDetailDO.convertMilestoneStr(eventDetail.getMilestone());

        if (Objects.nonNull(milestone)) {
            eventSituation = eventSituation.concat(milestone)
                    .concat(", ");
        }
        if (Objects.nonNull(eventDetail.getEventRoadNo())) {
            eventSituation = eventSituation.concat("第").concat(eventDetail.getEventRoadNo()).concat("车道");
        }
        boolean isNonVehicle = EventUtil.isNonVehicle(eventDetail.getEventType());
        eventSituation = eventSituation.concat("发现").concat(eventType.desc);
        //位置方向
        String directionalPosition = tunnelDetailDO.getDirectionName();
        if (Objects.nonNull(milestone)) {
            directionalPosition = directionalPosition.concat(milestone);
        }
        if (Objects.nonNull(eventDetail.getEventRoadNo())) {
            directionalPosition = directionalPosition.concat("第").concat(eventDetail.getEventRoadNo()).concat("车道");
        }
        //现场情况
        String situationSpot = "";
        if (Objects.nonNull(eventDetail.getEventRoadNo())) {
            situationSpot = situationSpot.concat("第").concat(eventDetail.getEventRoadNo()).concat("车道");
        }
        situationSpot = situationSpot.concat("发现").concat(eventType.desc);
        //非车辆事件不显示单车多车标识
        if(isNonVehicle){
            eventSituation.concat("(").concat(singMultiCar).concat(")");
            situationSpot.concat("(").concat(singMultiCar).concat(")");
        }
        //事件图片
        List<String> eventImagesPath = eventDetail.getEventImagesPath();
        if (CollUtil.isNotEmpty(eventImagesPath)) {
            eventDetailRespVO.setEventImagesPath(eventImagesPath.stream().filter(e -> e.startsWith("/")).map(xlwImagePath::concat).toList());
        }
        //事件开始时间格式化
        if (Objects.nonNull(eventDetail.getEventStartTime())) {
            eventDetailRespVO.setEventStartTimeFormat(eventDetail.getEventStartTime());
        }
        eventDetailRespVO.setEventSituation(eventSituation);
        eventDetailRespVO.setMilestoneStr(milestone);
        eventDetailRespVO.setDirectionalPosition(directionalPosition);
        eventDetailRespVO.setSituationSpot(situationSpot);
        return eventDetailRespVO;
    }

    public static List<EventDetailRespVO> convert2VO(List<EventDetailDO> eventDetailList,String xlwImagePath){
        return eventDetailList.stream().map(e->EventDetailDO.convert2VO(e,xlwImagePath)).collect(Collectors.toList());
    }


    public static String convertMilestoneStr(String milestone){
        try{
            int milestoneInt = Integer.parseInt(milestone);
            int k = milestoneInt / 1000;
            int m = milestoneInt % 1000;
            return "k" + k + "+" + m;
        }catch (Exception e){
            return milestone;
        }
    }

}
