package com.qaup.collision.rule.event;

import com.fasterxml.jackson.annotation.JsonFormat;
import jakarta.persistence.*;
import org.locationtech.jts.geom.Point;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import com.qaup.collision.rule.model.enums.RuleAlertLevel;

import java.time.LocalDateTime;
import java.util.Objects;

/**
 * 无人车违规事件实体类
 * 专门针对机场无人车冲突检测场景设计的简化模型
 * 
 * @author AI Assistant
 * @version 5.0 - 无人车专用简化版本
 * @since 2025-01-17
 */
@Entity
@Table(name = "uv_violation_events", indexes = {
    @Index(name = "idx_uv_violations_vehicle", columnList = "vehicle_id"),
    @Index(name = "idx_uv_violations_rule", columnList = "rule_name"),
    @Index(name = "idx_uv_violations_time", columnList = "violation_time"),
    @Index(name = "idx_uv_violations_alert_level", columnList = "alert_level")
})
@EntityListeners(AuditingEntityListener.class)
public class RuleViolationEvent {

    /**
     * 主键ID
     */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    /**
     * 车辆ID（关联sys_vehicle_info.vehicle_id）
     * 内部逻辑处理完全基于此字段
     */
    @Column(name = "vehicle_id", nullable = false)
    private Long vehicleId;

    /**
     * 违规规则名称（简化，直接存储规则名称）
     */
    @Column(name = "rule_name", nullable = false, length = 100)
    private String ruleName;

    /**
     * 违规类型（SPEED-超速, ACCESS-未授权进入, HEIGHT-超高, WEIGHT-超重）
     */
    @Column(name = "violation_type", nullable = false, length = 10)
    private String violationType;

    /**
     * 告警级别（INFO-信息, WARNING-警告, CRITICAL-严重, EMERGENCY-紧急）
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "alert_level", nullable = false, length = 20)
    private RuleAlertLevel alertLevel;

    /**
     * 违规描述
     */
    @Column(name = "description", length = 150)
    private String description;

    /**
     * 违规位置
     */
    @Column(name = "location", columnDefinition = "geometry(Point,4326)")
    private Point location;

    /**
     * 实际值（如实际速度：19.8）
     */
    @Column(name = "actual_value")
    private Double actualValue;

    /**
     * 限制值（如限速：5.0）
     */
    @Column(name = "limit_value")
    private Double limitValue;

    /**
     * 违规发生时间
     */
    @Column(name = "violation_time", nullable = false)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime violationTime;

    /**
     * 记录创建时间
     */
    @CreatedDate
    @Column(name = "created_at", nullable = false, updatable = false)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createdAt;

    // 构造函数
    public RuleViolationEvent() {
        this.violationTime = LocalDateTime.now();
        this.createdAt = LocalDateTime.now();  // 手动设置创建时间，避免审计功能依赖
    }

    public RuleViolationEvent(Long vehicleId, String ruleName, String violationType, 
                              RuleAlertLevel alertLevel, String description) {
        this();
        this.vehicleId = vehicleId;
        this.ruleName = ruleName;
        this.violationType = violationType;
        this.description = description;
        this.alertLevel = alertLevel;
    }

    // 业务方法
    public boolean isSpeedViolation() {
        return "SPEED".equals(violationType);
    }

    public boolean isAccessViolation() {
        return "ACCESS".equals(violationType);
    }

    public boolean isHeightViolation() {
        return "HEIGHT".equals(violationType);
    }

    public boolean isWeightViolation() {
        return "WEIGHT".equals(violationType);
    }

    public boolean isOtherViolation() {
        return "OTHER".equals(violationType);
    }

    public String getViolationSummary() {
        return String.format("车辆ID[%d]在[%s]违反了[%s]规则", 
                           vehicleId, violationTime.toString(), ruleName);
    }

    // Getters and Setters
    public Long getId() { return id; }
    public void setId(Long id) { this.id = id; }

    public Long getVehicleId() { return vehicleId; }
    public void setVehicleId(Long vehicleId) { this.vehicleId = vehicleId; }

    public String getRuleName() { return ruleName; }
    public void setRuleName(String ruleName) { this.ruleName = ruleName; }

    public String getViolationType() { return violationType; }
    public void setViolationType(String violationType) { this.violationType = violationType; }

    public RuleAlertLevel getAlertLevel() { return alertLevel; }
    public void setAlertLevel(RuleAlertLevel alertLevel) { this.alertLevel = alertLevel; }

    public String getDescription() { return description; }
    public void setDescription(String description) { this.description = description; }

    public Point getLocation() { return location; }
    public void setLocation(Point location) { this.location = location; }

    public Double getActualValue() { return actualValue; }
    public void setActualValue(Double actualValue) { this.actualValue = actualValue; }

    public Double getLimitValue() { return limitValue; }
    public void setLimitValue(Double limitValue) { this.limitValue = limitValue; }

    public LocalDateTime getViolationTime() { return violationTime; }
    public void setViolationTime(LocalDateTime violationTime) { this.violationTime = violationTime; }

    public LocalDateTime getCreatedAt() { return createdAt; }
    public void setCreatedAt(LocalDateTime createdAt) { this.createdAt = createdAt; }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        RuleViolationEvent that = (RuleViolationEvent) o;
        return Objects.equals(id, that.id);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id);
    }

    @Override
    public String toString() {
        return "RuleViolationEvent{" +
                "id=" + id +
                ", vehicleId=" + vehicleId +
                ", ruleName='" + ruleName + '\'' +
                ", violationType='" + violationType + '\'' +
                ", description='" + description + '\'' +
                ", actualValue=" + actualValue +
                ", limitValue=" + limitValue +
                ", violationTime=" + violationTime +
                '}';
    }
} 