package main

import (
	"encoding/json"
	"fmt"
	"log"
	"math"
	"math/rand"
	"net/http"
	"os"
	"path/filepath"
	"strings"
	"sync"
	"sync/atomic"
	"time"

	mqtt "github.com/eclipse/paho.mqtt.golang"
)

// 定义路线名称常量
const (
	Route1Name = "route1" // G7
	Route2Name = "route2" // 短倒/支线
)

//[MQTT-alarm] keys => [pos time title type vin 位置 司机 状态 订单 车牌 车辆状态 运单 速度 里程]
//[MQTT-data] keys => [alarm_level charging_state coal_pickup_order cumulative_mileage data_time driver_status driver_status_original general_alarm highest_temperature highest_voltage_battery latitude longitude lowest_temperature lowest_voltage_battery operation_mode order_id phonenumber soc speed subsystem_number total_current total_voltage vehicle_id vehicle_state vehicle_type vin waybill ]

// 定义运输方式常量
const (
	TransportModeTrunk      = "干线"
	TransportModeShortHaul  = "短倒"
	TransportModeBranchLine = "支线"
	TransportModeUnknown    = "未知"
)

var startingPoint = RoutePoint{
	Longitude: 89.172811,
	Latitude:  44.859511,
	Attribute: 1,
}

// 定义运输方式映射
var transportModeMap = map[string]struct {
	MainMode   string
	BranchMode string
}{
	Route1Name: {
		MainMode:   TransportModeTrunk,
		BranchMode: "",
	},
	Route2Name: {
		MainMode:   TransportModeShortHaul,
		BranchMode: TransportModeBranchLine,
	},
}

// RoutePoint 表示路线中的一个坐标点
type RoutePoint struct {
	Longitude float64 `json:"longitude"`
	Latitude  float64 `json:"latitude"`
	Attribute int     `json:"attribute"`
}

// SimulationParams 包含模拟的参数
type SimulationParams struct {
	MainOrderNumber string  `json:"main_order_number"` // 主订单号字段
	StartDateTime   string  `json:"start_date_time"`
	EndDateTime     string  `json:"end_date_time"`
	Frequency       float64 `json:"frequency"`
	LoadWeight      float64 `json:"load_weight"`
	TruckCount      int     `json:"truck_count"`
	CoalPickupOrder string  `json:"coal_pickup_order"` // 固定提煤单
}

// Truck 表示一辆卡车
type Truck struct {
	ID              int
	VIN             string
	OrderID         string
	CoalPickupOrder string
	Waybill         string
	Route           []RoutePoint
	MQTTClient      mqtt.Client
	LoadWeight      float64
	RouteName       string

	DriverName    string  // 司机姓名
	PhoneNumber   string  // 司机电话号码
	CarPlate      string  // 新增字段
	Mileage       float64 // 新增字段
	Speed         float64 // 新增字段
	Location      string  // 新增字段
	VehicleStatus string  // 新增字段

	targetPointReachedCount int32
	eventMutex              sync.Mutex
	eventsSent              map[int]bool
	currentEventIndex       int
}

// DriverStatus 表示司机在特定位置的状态
type DriverStatus struct {
	Status    string
	Longitude float64
	Latitude  float64
}

var driverStatuses = []DriverStatus{
	{Status: "离线", Longitude: 89.153942, Latitude: 44.757513},
	{Status: "犯困", Longitude: 89.174784, Latitude: 44.78754},
	{Status: "车道偏离", Longitude: 89.316852, Latitude: 44.762968},
	{Status: "停车", Longitude: 90.40854, Latitude: 43.868251},
	{Status: "抽烟", Longitude: 89.365738, Latitude: 44.768674},
}

var targetPoint = RoutePoint{
	Longitude: 90.535948,
	Latitude:  43.835969,
	Attribute: 2,
}

var additionalPoints = []RoutePoint{
	{Longitude: 90.625132, Latitude: 43.802499, Attribute: 4},
}

// MQTT相关和全局变量
var (
	mqttBroker     = "tcp://192.168.3.110:1883"
	mqttTopic      = "vehicle/sim/data"
	eventMQTTTopic = "vehicle/sim/event"
	alarmMQTTTopic = "vehicle/sim/alarm"
	clientID       = "SimTruckService"
	username       = "emqx_test"
	password       = "emqx_test"

	routeFile1 string
	routeFile2 string

	simMutex           sync.Mutex
	simulationStopChan chan struct{}
	//全局停止通道，用来通知所有运行中的卡车停止模拟
	simulationWaitGroup sync.WaitGroup
	//等待所有卡车模拟goroutine结束

	truckIDMutex   sync.Mutex
	currentTruckID int

	closeOnce sync.Once

	maxConcurrentTrucks = 118
	//同时最大并发卡车数量
	concurrentSemaphore chan struct{}
	//控制并发度的带缓冲通道

	totalVehiclesStartedRoute1 int
	totalVehiclesStartedRoute2 int
	//统计两条路线各自已经发车的车辆数
	totalVehiclesMutex sync.Mutex

	maxTotalTrucks = 118

	isRunning         int32 = 0
	activeTrucks      int
	activeTrucksMutex sync.Mutex

	route1StartChan chan struct{}
	//当电车（route2）触发特定事件后，用此通道通知发车氢车（route1）

	speedMultiplier float64 = 1.0
	//倍速功能
	speedMultiplierMutex sync.RWMutex

	totalCoalAtPoint1 float64 = 2000000.0
	totalCoalAtPoint2 float64 = 0.0
	//两个地点的煤炭库存量
	coalMutex sync.Mutex

	// 全局计数器
	waybillCounter int64 = 1
	vinCounter     int64 = 1
	//运单号和VIN生成唯一编号的计数器

	// 定义字段顺序
	dataFieldOrder = []string{
		"alarm_level",
		"charging_state",
		"coal_pickup_order",
		"cumulative_mileage",
		"data_time",
		"driver_status",
		"driver_status_original",
		"general_alarm",
		"highest_temperature",
		"highest_voltage_battery",
		"latitude",
		"longitude",
		"lowest_temperature",
		"lowest_voltage_battery",
		"operation_mode",
		"order_id",
		"phonenumber",
		"soc",
		"speed",
		"subsystem_number",
		"total_current",
		"total_voltage",
		"vehicle_id",
		"vehicle_state",
		"vehicle_type",
		"vin",
		"waybill",
	}

	// allEventsRoute1 存储 route1 的所有事件定义，键为事件类型，如 "0", "1", ...
	allEventsRoute1 map[string][]map[string]interface{}
	// allEventsRoute2 存储 route2 的所有事件定义，键为事件类型，如 "0", "1", ...
	allEventsRoute2 map[string][]map[string]interface{}
)

// loadAllEvents 从指定的 JSON 文件加载所有事件
func loadAllEvents(filename string) (map[string][]map[string]interface{}, error) {
	absPath, err := filepath.Abs(filename)
	if err != nil {
		return nil, fmt.Errorf("无法获取文件绝对路径: %v", err)
	}
	log.Printf("加载事件文件: %s", absPath)

	data, err := os.ReadFile(absPath)
	if err != nil {
		return nil, fmt.Errorf("无法读取文件 %s: %v", absPath, err)
	}

	var events map[string][]map[string]interface{}
	err = json.Unmarshal(data, &events)
	if err != nil {
		return nil, fmt.Errorf("无法解析事件 JSON 数据: %v", err)
	}
	log.Printf("成功加载事件数据，包含 %d 类事件", len(events))

	return events, nil
}

// init 初始化函数
var allEventsAlarm map[string][]map[string]interface{}

func init() {
	rand.Seed(time.Now().UnixNano())
	concurrentSemaphore = make(chan struct{}, maxConcurrentTrucks)

	// 设置路线文件路径
	routeFile1 = `C:\Users\29620\tms-simulate\routes\routeG7干线.json`
	routeFile2 = `C:\Users\29620\tms-simulate\routes\route煤矿到陆港3.json`

	// 检查路线文件是否存在
	if _, err := os.Stat(routeFile1); os.IsNotExist(err) {
		log.Fatalf("路线文件不存在: %s", routeFile1)
	}
	if _, err := os.Stat(routeFile2); os.IsNotExist(err) {
		log.Fatalf("路线文件不存在: %s", routeFile2)
	}

	route1StartChan = make(chan struct{})

	// 加载所有事件
	eventsFilePathRoute1 := `D:\worker\tms-simulate\tmsTemplateroute1.json` // 请根据实际路径调整
	loadedEventsRoute1, err := loadAllEvents(eventsFilePathRoute1)
	if err != nil {
		log.Fatalf("加载 route1 事件失败: %v", err)
	}
	allEventsRoute1 = loadedEventsRoute1
	log.Printf("Route1 事件类型数量: %d", len(allEventsRoute1))

	eventsFilePathRoute2 := `D:\worker\tms-simulate\tmsTemplateroute2.json` // 请根据实际路径调整
	loadedEventsRoute2, err := loadAllEvents(eventsFilePathRoute2)
	if err != nil {
		log.Fatalf("加载 route2 事件失败: %v", err)
	}
	allEventsRoute2 = loadedEventsRoute2
	log.Printf("Route2 事件类型数量: %d", len(allEventsRoute2))

	// 加载报警事件
	eventsFilePathAlarm := `D:\worker\tms-simulate\tmsTemplateAlarm.json` // 请根据实际路径调整
	allEventsAlarm, err = loadAllEvents(eventsFilePathAlarm)
	if err != nil {
		log.Fatalf("加载报警事件失败: %v", err)
	}
	log.Printf("Alarm 事件类型数量: %d", len(allEventsAlarm))

	// 检查报警事件类型 "12" 是否存在
	if _, exists := allEventsAlarm["12"]; !exists {
		log.Fatalf("报警事件文件中未找到事件类型 '12'")
	}
}

// reverseRoute 反转路线 用于车辆往返时使用同一路线反向行驶
func reverseRoute(route []RoutePoint) []RoutePoint {
	reversed := make([]RoutePoint, len(route))
	for i := range route {
		reversed[i] = route[len(route)-1-i]
	}
	return reversed
}

// roundTo 将一个 float64 数字四舍五入到指定的小数位数
func roundTo(val float64, places int) float64 {
	factor := math.Pow(10, float64(places))
	return math.Round(val*factor) / factor
}

// interpolate 两点间插值
// 给定两个点 p1, p2 和一个步数 steps，生成介于两点之间的若干中间点 ，以提高轨迹的平滑度
// 在计算插值时，将经度和纬度四舍五入到6位小数
func interpolate(p1, p2 RoutePoint, steps int) []RoutePoint {
	var interpolated []RoutePoint
	deltaLon := (p2.Longitude - p1.Longitude) / float64(steps)
	deltaLat := (p2.Latitude - p1.Latitude) / float64(steps)

	for i := 1; i <= steps; i++ {
		interpolatedPoint := RoutePoint{
			Longitude: roundTo(p1.Longitude+deltaLon*float64(i), 6),
			Latitude:  roundTo(p1.Latitude+deltaLat*float64(i), 6),
			Attribute: p1.Attribute, // 保持属性不变
		}
		interpolated = append(interpolated, interpolatedPoint)
	}
	return interpolated
}

// loadRouteFromFile 加载路线
func loadRouteFromFile(filename string) ([]RoutePoint, error) {
	absPath, err := filepath.Abs(filename)
	if err != nil {
		return nil, fmt.Errorf("无法获取文件绝对路径: %v", err)
	}
	log.Printf("加载路线文件: %s", absPath)

	data, err := os.ReadFile(absPath)
	if err != nil {
		return nil, fmt.Errorf("无法读取文件 %s: %v", absPath, err)
	}

	var rawRoute [][]float64
	err = json.Unmarshal(data, &rawRoute)
	if err != nil {
		return nil, fmt.Errorf("无法解析 JSON 数据: %v", err)
	}
	log.Printf("成功解析 JSON 路线数据，包含 %d 个点", len(rawRoute))

	route := make([]RoutePoint, 0, len(rawRoute))
	for idx, point := range rawRoute {
		if len(point) < 2 {
			log.Printf("跳过第 %d 个点，因为数据不足: %v", idx, point)
			continue
		}
		rp := RoutePoint{
			Longitude: point[0],
			Latitude:  point[1],
		}
		if len(point) >= 3 {
			rp.Attribute = int(point[2])
		}
		route = append(route, rp)
	}
	log.Printf("转换后的 RoutePoint 数量: %d", len(route))
	return route, nil
}

// createMQTTClient 创建MQTT客户端
func createMQTTClient() (mqtt.Client, error) {
	opts := mqtt.NewClientOptions()
	opts.AddBroker(mqttBroker)
	opts.SetUsername(username)
	opts.SetPassword(password)
	opts.SetClientID(fmt.Sprintf("%s_%d", clientID, rand.Intn(100000)))

	opts.AutoReconnect = true
	opts.MaxReconnectInterval = 30 * time.Second

	opts.OnConnectionLost = func(client mqtt.Client, err error) {
		log.Printf("MQTT连接丢失: %v", err)
	}

	opts.OnConnect = func(c mqtt.Client) {
		log.Println("成功连接到MQTT Broker")
	}

	client := mqtt.NewClient(opts)
	token := client.Connect()
	token.Wait()
	if token.Error() != nil {
		return nil, fmt.Errorf("无法连接MQTT: %v", token.Error())
	}
	return client, nil
}

// getNextTruckID 获取下一个卡车ID 每启动一辆卡车时分配唯一ID
func getNextTruckID() int {
	truckIDMutex.Lock()
	defer truckIDMutex.Unlock()
	currentTruckID++
	return currentTruckID
}

// getDriverStatusAtPoint 获取司机状态
func getDriverStatusAtPoint(current RoutePoint) (string, bool) {
	const tolerance = 0.0001
	for _, ds := range driverStatuses {
		if math.Abs(current.Longitude-ds.Longitude) <= tolerance &&
			math.Abs(current.Latitude-ds.Latitude) <= tolerance {
			return ds.Status, true
		}
	}
	return "", false
}

// checkTargetPointAtPoint 检查目标点 若卡车到达特定状态点，则返回对应的司机状态
func checkTargetPointAtPoint(current RoutePoint) bool {
	const tolerance = 0.0001
	return math.Abs(current.Longitude-targetPoint.Longitude) <= tolerance &&
		math.Abs(current.Latitude-targetPoint.Latitude) <= tolerance &&
		current.Attribute == targetPoint.Attribute
}

// generateWaybill 生成运单号 示例格式：PAC000000001
func generateWaybill(mainOrder string) string {
	current := atomic.AddInt64(&waybillCounter, 1)
	return fmt.Sprintf("PAC%09d", current)
}

// generateFixedVIN 生成固定的 VIN 码 示例格式：LHGCM82633A004501
func generateFixedVIN() string {
	current := atomic.AddInt64(&vinCounter, 1)
	// 假设前缀固定，后面6位数字
	return fmt.Sprintf("LHGCM82633A%06d", current)
}

// mapDriverStatusToCategory 状态匹配 实际司机状态匹配到run/stop/alarm/danger/offline等分类
func mapDriverStatusToCategory(status string) string {
	switch status {
	case "正常":
		return "run"
	case "停车":
		return "stop"
	case "犯困":
		return "alarm"
	case "车道偏离", "抽烟":
		return "danger"
	case "离线":
		return "offline"
	default:
		return "run"
	}
}

// cloneEvent 深拷贝事件 避免并发修改问题，对事件map进行深拷贝
func cloneEvent(event map[string]interface{}) map[string]interface{} {
	// Marshal and unmarshal to achieve deep copy
	data, err := json.Marshal(event)
	if err != nil {
		log.Printf("Error cloning event: %v", err)
		return nil
	}
	var cloned map[string]interface{}
	if err := json.Unmarshal(data, &cloned); err != nil {
		log.Printf("Error unmarshaling cloned event: %v", err)
		return nil
	}
	// 获取当前真实时间
	now := time.Now()

	// 设置 starttime 为当前时间
	startTime := now.Format("2006-01-02 15:04:05")

	// 设置 endtime 为 starttime 后 24 小时
	endTime := now.Add(24 * time.Hour).Format("2006-01-02 15:04:05")

	// 强制覆盖时间字段
	cloned["starttime"] = startTime
	cloned["endtime"] = endTime
	cloned["time"] = now.Format("2006-01-02 15:04:05")
	return cloned
}

// getRouteEvents 根据 RouteName 和事件类型获取相应的事件
func getRouteEvents(routeName, eventType string) []map[string]interface{} {
	switch routeName {
	case Route1Name:
		return allEventsRoute1[eventType]
	case Route2Name:
		return allEventsRoute2[eventType]
	case "alarm": // 新增处理报警事件
		return allEventsAlarm[eventType]
	default:
		return nil
	}
}

// sendEvent 发送单个事件到 MQTT，动态处理字段
func sendEvent(mqttClient mqtt.Client, event map[string]interface{}) {
	go func() {
		// 添加基本延迟
		delay := 2*time.Second + time.Duration(rand.Intn(3))*time.Second
		time.Sleep(delay)

		// 更新时间戳
		event["time"] = time.Now().Format("2006-01-02 15:04:05")

		// 处理特殊字段
		if msg, exists := event["msg"].(string); exists {
			// 替换消息中的占位符
			msg = strings.ReplaceAll(msg, "蒙K123ER", event["车牌"].(string))
			event["msg"] = msg
		}

		// JSON 编码
		jsonData, err := json.Marshal(event)
		if err != nil {
			log.Printf("事件 VIN %v JSON 编码错误: %v", event["vin"], err)
			return
		}

		// 发布到 MQTT
		token := mqttClient.Publish(eventMQTTTopic, 0, false, jsonData)
		token.Wait()
		if token.Error() != nil {
			log.Printf("事件 VIN %v 发布 MQTT 消息失败: %v", event["vin"], token.Error())
		} else {
			log.Printf("事件 VIN %v 发布成功: %s", event["vin"], string(jsonData))
		}
	}()
}

// sendInitialEvent 发送初始事件，根据 RouteName 选择事件类型 "0_route1" 或 "0_route2"
func (t *Truck) sendInitialEvent(coalPickupOrder string) {
	var initialEvents []map[string]interface{}
	var key string

	switch t.RouteName {
	case Route1Name:
		key = "0"
		initialEvents = getRouteEvents(Route1Name, key)
	case Route2Name:
		key = "0"
		initialEvents = getRouteEvents(Route2Name, key)
	default:
		log.Printf("未知的 RouteName: %s", t.RouteName)
		return
	}

	if len(initialEvents) == 0 {
		log.Printf("事件类型 %s 不存在或为空", key)
		return
	}

	initialEvent := cloneEvent(initialEvents[0])

	// 获取当前真实时间
	now := time.Now()

	// 设置 starttime 为当前时间
	startTime := now.Format("2006-01-02 15:04:05")

	// 设置 endtime 为 starttime 后 24 小时
	endTime := now.Add(24 * time.Hour).Format("2006-01-02 15:04:05")

	// 动态设置字段
	initialEvent["车牌"] = t.CarPlate
	initialEvent["司机"] = t.DriverName
	initialEvent["司机电话"] = t.PhoneNumber
	initialEvent["vin"] = t.VIN
	initialEvent["订单"] = t.OrderID
	initialEvent["运单"] = t.Waybill
	initialEvent["货箱编号"] = "TRA1205B" // 固定值
	initialEvent["净重吨数"] = fmt.Sprintf("%.2f", t.LoadWeight)
	initialEvent["starttime"] = startTime
	initialEvent["endtime"] = endTime
	initialEvent["status"] = "已接单"

	// 根据 RouteName 设置不同的字段
	if t.RouteName == Route1Name {
		initialEvent["线路类型"] = "干线"
	} else if t.RouteName == Route2Name {
		initialEvent["线路类型"] = "短倒"
	}

	initialEvent["车辆类型"] = "E"
	initialEvent["线路"] = "G7线"
	initialEvent["from"] = "色连一矿"
	initialEvent["to"] = "河西电厂"
	initialEvent["时长"] = "00:00:36" // 示例时长，可根据需要动态调整

	// 验证数据完整性
	if initialEvent["车牌"] == "" || initialEvent["司机"] == "" {
		log.Printf("卡车 %d 创建运单事件数据不完整", t.ID)
		return
	}

	sendEvent(t.MQTTClient, initialEvent)
}

// sendAbnormalEvents 发送50条异常状态事件到报警主题
func (t *Truck) sendAbnormalEvents() {
	log.Printf("卡车 %d 开始发送50条异常状态事件", t.ID)
	for i := 0; i < 50; i++ {
		// 随机选择一个异常状态
		status := driverStatuses[rand.Intn(len(driverStatuses))].Status
		log.Printf("卡车 %d 第 %d 条异常状态: %s", t.ID, i+1, status)

		// 获取对应的事件类型 "12" 从报警事件
		driverStatusEvents := getRouteEvents("alarm", "12")
		if len(driverStatusEvents) == 0 {
			log.Printf("卡车 %d 没有定义事件类型 '12' 对应的司机状态事件", t.ID)
			continue
		}

		var selectedEvent map[string]interface{}
		// 查找与当前状态匹配的事件定义
		for _, evt := range driverStatusEvents {
			if evt["状态"] == status {
				selectedEvent = evt
				break
			}
		}

		if selectedEvent == nil {
			log.Printf("卡车 %d 未找到与状态 '%s' 匹配的事件定义", t.ID, status)
			continue
		}

		// 深拷贝事件
		event := cloneEvent(selectedEvent)
		if event == nil {
			log.Printf("卡车 %d 无法克隆事件，状态: %s", t.ID, status)
			continue
		}

		// 动态填充字段
		event["司机"] = t.DriverName
		event["车牌"] = t.CarPlate // 假设 "车牌" 对应 CarPlate
		event["time"] = time.Now().Format("2006-01-02 15:04:05")
		event["vin"] = t.VIN
		event["订单"] = t.OrderID
		event["运单"] = t.Waybill
		event["里程"] = t.Mileage
		event["速度"] = t.Speed
		event["位置"] = t.Location
		event["车辆状态"] = t.VehicleStatus

		log.Printf("卡车 %d 正在发送异常状态事件 %d: %v", t.ID, i+1, event)
		sendAlarmEvent(t.MQTTClient, event) // 使用新的发送函数

		// 可选：添加短暂延迟，避免事件发送过快
		time.Sleep(500 * time.Millisecond)
	}
	log.Printf("卡车 %d 完成发送50条异常状态事件", t.ID)
}

// sendAlarmEvent 发送单个报警事件到 MQTT
func sendAlarmEvent(mqttClient mqtt.Client, event map[string]interface{}) {
	go func() {
		//logKeysSorted("alarm", event)

		// JSON 编码
		jsonData, err := json.Marshal(event)
		if err != nil {
			log.Printf("报警事件 VIN %v JSON 编码错误: %v", event["vin"], err)
			return
		}

		// 发布到 MQTT 的 alarm 主题
		token := mqttClient.Publish(alarmMQTTTopic, 0, false, jsonData)
		token.Wait()
		if token.Error() != nil {
			log.Printf("报警事件 VIN %v 发布 MQTT 消息失败: %v", event["vin"], token.Error())
		} else {
			log.Printf("报警事件 VIN %v 发布成功: %s", event["vin"], string(jsonData))
		}
	}()
}

// runSimulation 执行卡车的模拟
func (t *Truck) runSimulation(stopChan chan struct{}, mainOrderNumber string, coalPickupOrder string) {
	defer simulationWaitGroup.Done()

	concurrentSemaphore <- struct{}{}
	defer func() { <-concurrentSemaphore }()

	activeTrucksMutex.Lock()
	activeTrucks++
	if activeTrucks == 1 {
		atomic.StoreInt32(&isRunning, 1)
		log.Println("模拟开始，有车辆正在运行")
	}
	activeTrucksMutex.Unlock()

	defer func() {
		activeTrucksMutex.Lock()
		activeTrucks--
		if activeTrucks == 0 {
			atomic.StoreInt32(&isRunning, 0)
			log.Println("所有车辆已停止运行")
		}
		activeTrucksMutex.Unlock()
	}()

	// 使用传入的主订单号作为 OrderID
	t.OrderID = mainOrderNumber
	log.Printf("卡车 %d 订单号: %s", t.ID, t.OrderID)

	// 设置固定的提煤单
	t.CoalPickupOrder = coalPickupOrder
	log.Printf("卡车 %d 提煤单: %s", t.ID, t.CoalPickupOrder)

	// 生成运单
	t.Waybill = generateWaybill(mainOrderNumber)
	log.Printf("卡车 %d 生成运单: %s", t.ID, t.Waybill)

	// 生成固定的 VIN 码
	t.VIN = generateFixedVIN()
	log.Printf("卡车 %d 生成 VIN: %s", t.ID, t.VIN)

	// 发送所有事件（包括创建运单事件和后续事件）
	log.Printf("卡车 %d 开始发送所有事件", t.ID)
	t.sendAllEvents()

	// 添加日志，确认即将发送异常状态事件
	log.Printf("卡车 %d 即将发送50条异常状态事件", t.ID)

	// 发送50条异常状态事件
	t.sendAbnormalEvents()

	// 设置初始事件索引
	t.currentEventIndex = 0

	// 等待10秒后开始执行事件
	log.Printf("卡车 %d 等待10秒后开始执行行驶模拟", t.ID)
	select {
	case <-time.After(10 * time.Second):
	case <-stopChan:
		return
	}

	// 往返循环开始行驶模拟...
	for {
		select {
		case <-stopChan:
			log.Printf("卡车 %d 模拟被停止", t.ID)
			return
		default:
			// 更新煤炭库存
			coalMutex.Lock()
			totalCoalAtPoint1 -= t.LoadWeight
			coalMutex.Unlock()

			if !t.runRouteSegment(stopChan, t.Route) {
				return
			}

			coalMutex.Lock()
			totalCoalAtPoint2 += t.LoadWeight
			coalMutex.Unlock()

			coalMutex.Lock()
			totalCoalAtPoint2 -= t.LoadWeight
			coalMutex.Unlock()

			reverseRoute := reverseRoute(t.Route)

			if !t.runRouteSegment(stopChan, reverseRoute) {
				return
			}

			coalMutex.Lock()
			totalCoalAtPoint1 += t.LoadWeight
			coalMutex.Unlock()
		}
	}
}

// sendAllEvents 按顺序发送所有事件
func (t *Truck) sendAllEvents() {
	// 事件类型按顺序存储在一个切片中
	eventTypes := []string{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"}

	for _, eventType := range eventTypes {
		// 获取当前事件类型的所有事件
		events := getRouteEvents(t.RouteName, eventType)
		if len(events) == 0 {
			log.Printf("卡车 %d 没有事件类型 %s 的事件定义", t.ID, eventType)
			continue
		}

		// 遍历该类型的所有事件并发送
		for _, event := range events {
			// 深拷贝事件
			eventCopy := cloneEvent(event)
			if eventCopy == nil {
				continue
			}

			// 更新事件的动态字段
			eventCopy["车牌"] = t.CarPlate
			eventCopy["司机"] = t.DriverName
			eventCopy["vin"] = t.VIN
			eventCopy["订单"] = t.OrderID
			eventCopy["运单"] = t.Waybill
			eventCopy["time"] = time.Now().Format("2006-01-02 15:04:05")

			// 如果有货箱编号字段，设置它
			if _, exists := eventCopy["货箱编号"]; exists {
				eventCopy["货箱编号"] = "TRA1205B"
			}

			// 如果有净重字段，设置它
			if _, exists := eventCopy["净重吨数"]; exists {
				eventCopy["净重吨数"] = t.LoadWeight
			}

			if _, exists := eventCopy["提煤单"]; exists {
				eventCopy["提煤单"] = t.CoalPickupOrder
			}

			if pos, exists := eventCopy["pos"].([]interface{}); exists {
				// 使用当前位置更新pos字段
				currentPoint := t.Route[0] // 使用路线的第一个点作为初始位置
				pos[0] = currentPoint.Longitude
				pos[1] = currentPoint.Latitude
				eventCopy["pos"] = pos
			}

			// 发送事件
			sendEvent(t.MQTTClient, eventCopy)

			// 在事件之间添加延迟，让事件按序发生
			time.Sleep(5 * time.Second)
		}
	}
}

// runRouteSegment 执行路线段的模拟（已移除基于位置的事件触发逻辑）
func (t *Truck) runRouteSegment(stopChan chan struct{}, routeSegment []RoutePoint) bool {
	stepsBetweenPoints := 10
	for i := 0; i < len(routeSegment)-1; i++ {
		select {
		case <-stopChan:
			log.Printf("卡车 %d 模拟被停止", t.ID)
			return false
		default:
			p1 := routeSegment[i]
			p2 := routeSegment[i+1]
			interpolatedPoints := interpolate(p1, p2, stepsBetweenPoints)

			for _, pt := range interpolatedPoints {
				select {
				case <-stopChan:
					log.Printf("卡车 %d 模拟被停止", t.ID)
					return false
				default:
					// 移除基于位置的事件触发逻辑

					// 构建位置数据的 payload
					speed := math.Round((20+80*rand.Float64())*10) / 10 // 定义 speed 变量
					vehicleType := "hydrogen"
					if t.RouteName == Route2Name {
						vehicleType = "electric"
					}

					payload := map[string]interface{}{
						"alarm_level":             0,
						"charging_state":          0,
						"coal_pickup_order":       t.CoalPickupOrder,
						"cumulative_mileage":      15003.7, // 这里可以根据需求动态计算
						"data_time":               time.Now().Format("2006-01-02 15:04:05"),
						"driver_status":           "run",
						"driver_status_original":  "正常",
						"general_alarm":           0,
						"highest_temperature":     43,
						"highest_voltage_battery": 3.65,
						"latitude":                pt.Latitude,  // 动态设置纬度
						"longitude":               pt.Longitude, // 动态设置经度
						"lowest_temperature":      22,
						"lowest_voltage_battery":  3.29,
						"operation_mode":          0,
						"order_id":                t.OrderID,     // 动态设置订单号
						"phonenumber":             t.PhoneNumber, // 动态设置电话号码
						"soc":                     82,
						"speed":                   speed, // 使用 speed 变量
						"subsystem_number":        1,
						"total_current":           13.4,
						"total_voltage":           351.2,
						"vehicle_id":              fmt.Sprintf("Truck-%d", t.ID), // 动态设置车辆ID
						"vehicle_state":           0,
						"vehicle_type":            vehicleType,
						"vin":                     t.VIN,     // 动态设置VIN
						"waybill":                 t.Waybill, // 动态设置运单号
					}

					// 根据状态设置 driver_status 和 driver_status_original
					// 由于已移除基于位置的事件触发，这里可以简化
					// 如果需要，可以根据其他条件调整

					// 创建一个仅包含值的数组，按照固定顺序
					//logKeysSorted("data", payload)
					values := make([]interface{}, 0, len(dataFieldOrder))
					for _, key := range dataFieldOrder {
						if val, exists := payload[key]; exists {
							values = append(values, val)
						} else {
							// 如果某个字段缺失，根据需求填充默认值
							values = append(values, nil)
						}
					}

					// JSON 编码数组
					jsonData, err := json.Marshal(values)
					if err != nil {
						log.Printf("卡车 %d JSON 编码错误: %v", t.ID, err)
						continue
					}

					// 发布到 MQTT 的 data 主题
					token := t.MQTTClient.Publish(mqttTopic, 0, false, jsonData)
					token.Wait()
					if token.Error() != nil {
						log.Printf("卡车 %d 发布 MQTT 数据消息失败: %v", t.ID, token.Error())
					} else {
						log.Printf("卡车 %d (%s) 发布数据: %s", t.ID, t.RouteName, string(jsonData))
					}

					// 控制速度
					speedMultiplierMutex.RLock()
					currentMultiplier := speedMultiplier
					speedMultiplierMutex.RUnlock()

					baseSleepDuration := 500 * time.Millisecond
					adjustedSleepDuration := time.Duration(float64(baseSleepDuration) / currentMultiplier)
					time.Sleep(adjustedSleepDuration)
				}
			}
		}
	}
	return true
}

// stopSimulation 停止模拟
func stopSimulation() {
	simMutex.Lock()
	defer simMutex.Unlock()

	if simulationStopChan == nil {
		log.Println("模拟未在运行中")
		return
	}

	closeOnce.Do(func() {
		close(simulationStopChan)
		simulationStopChan = nil
	})

	simulationWaitGroup.Wait()

	totalVehiclesMutex.Lock()
	totalVehiclesStartedRoute1 = 0
	totalVehiclesStartedRoute2 = 0
	totalVehiclesMutex.Unlock()

	activeTrucksMutex.Lock()
	activeTrucks = 0
	atomic.StoreInt32(&isRunning, 0)
	activeTrucksMutex.Unlock()

	log.Println("所有车辆模拟已停止")
}

// closeSimulation 关闭模拟
func closeSimulation() {
	simMutex.Lock()
	defer simMutex.Unlock()

	if simulationStopChan != nil {
		close(simulationStopChan)
		simulationStopChan = nil
	}
	simulationWaitGroup.Wait()

	totalVehiclesMutex.Lock()
	totalVehiclesStartedRoute1 = 0
	totalVehiclesStartedRoute2 = 0
	totalVehiclesMutex.Unlock()

	activeTrucksMutex.Lock()
	activeTrucks = 0
	atomic.StoreInt32(&isRunning, 0)
	activeTrucksMutex.Unlock()

	log.Println("所有车辆模拟已停止")
}

// setSpeedHandler 设置速度倍数
func setSpeedHandler(w http.ResponseWriter, r *http.Request) {
	log.Println("收到 /setSpeed 请求")
	if r.Method != http.MethodPost {
		http.Error(w, "仅支持 POST 方法", http.StatusMethodNotAllowed)
		return
	}

	var payload struct {
		Multiplier float64 `json:"multiplier"`
	}
	if err := json.NewDecoder(r.Body).Decode(&payload); err != nil {
		log.Printf("参数解析错误: %v\n", err)
		http.Error(w, "参数解析错误", http.StatusBadRequest)
		return
	}

	if payload.Multiplier <= 0 {
		http.Error(w, "multiplier 必须大于0", http.StatusBadRequest)
		return
	}

	speedMultiplierMutex.Lock()
	speedMultiplier = payload.Multiplier
	speedMultiplierMutex.Unlock()

	log.Printf("速度倍数已设置为 %.2f\n", payload.Multiplier)
	w.WriteHeader(http.StatusOK)
	w.Write([]byte(fmt.Sprintf("速度倍数已设置为 %.2f", payload.Multiplier)))
}

// allStatusHandler 返回所有状态信息
func allStatusHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodGet {
		http.Error(w, "仅支持GET方法", http.StatusMethodNotAllowed)
		return
	}

	running := atomic.LoadInt32(&isRunning) == 1

	speedMultiplierMutex.RLock()
	currentMultiplier := speedMultiplier
	speedMultiplierMutex.RUnlock()

	coalMutex.Lock()
	p1 := totalCoalAtPoint1
	p2 := totalCoalAtPoint2
	coalMutex.Unlock()

	resp := map[string]interface{}{
		"is_running":        running,
		"speed_multiplier":  currentMultiplier,
		"point1_total_coal": p1,
		"point2_total_coal": p2,
	}

	jsonData, err := json.Marshal(resp)
	if err != nil {
		http.Error(w, "状态获取失败", http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(http.StatusOK)
	w.Write(jsonData)
}

// startRoute 开始一条路线的模拟
func startRoute(stopChan chan struct{}, mqttClient mqtt.Client, route []RoutePoint, loadWeight float64, truckCount int, routeName string, frequency float64, mainOrderNumber string, coalPickupOrder string) {
	// 司机姓名列表
	var driverNames = []string{
		"张三丰",
		"李四",
		"王五",
		"赵六",
		"孙七",
	}

	for i := 0; i < truckCount; i++ {
		select {
		case <-stopChan:
			return
		default:
			truckID := getNextTruckID()
			driverName := driverNames[rand.Intn(len(driverNames))] // 随机分配司机
			truck := &Truck{
				ID:              truckID,
				Route:           route,
				MQTTClient:      mqttClient,
				LoadWeight:      loadWeight,
				RouteName:       routeName,
				CoalPickupOrder: coalPickupOrder, // 固定提煤单
				Waybill:         "",              // 将在 runSimulation 中生成
				DriverName:      driverName,      // 分配司机姓名
				PhoneNumber:     "18940028888",   // 分配固定电话号码
				CarPlate:        "蒙K123ER",       // 新增字段，固定或动态分配
				Mileage:         100.0,           // 新增字段，示例值，实际应动态获取
				Speed:           60.0,            // 新增字段，示例值，实际应动态获取
				Location:        "北京",            // 新增字段，示例值，实际应动态获取
				VehicleStatus:   "ACC正常",         // 新增字段，示例值，实际应动态获取
				eventsSent:      make(map[int]bool),
			}
			simulationWaitGroup.Add(1)
			go truck.runSimulation(stopChan, mainOrderNumber, coalPickupOrder)

			if i < truckCount-1 {
				speedMultiplierMutex.RLock()
				currentMultiplier := speedMultiplier
				speedMultiplierMutex.RUnlock()

				baseInterval := time.Duration(frequency * float64(time.Minute))
				adjustedInterval := time.Duration(float64(baseInterval) / currentMultiplier)

				select {
				case <-time.After(adjustedInterval):
				case <-stopChan:
					return
				}
			}
		}
	}
}

// startSimulation 启动模拟
func startSimulation(params SimulationParams) error {
	simMutex.Lock()
	defer simMutex.Unlock()

	if simulationStopChan != nil {
		return fmt.Errorf("模拟已经在运行中")
	}

	simulationStopChan = make(chan struct{})

	const customFormat = "2006-01-02 15:04:05" // 修改时间格式，去掉时区

	startTime, err := time.ParseInLocation(customFormat, params.StartDateTime, time.Local)
	if err != nil {
		return fmt.Errorf("开始时间格式错误: %v", err)
	}
	endTime, err := time.ParseInLocation(customFormat, params.EndDateTime, time.Local)
	if err != nil {
		return fmt.Errorf("结束时间格式错误: %v", err)
	}

	routeG7, err := loadRouteFromFile(routeFile1)
	if err != nil {
		return err
	}
	routeMine, err := loadRouteFromFile(routeFile2)
	if err != nil {
		return err
	}

	routeMine = reverseRoute(routeMine)

	mqttClient, err := createMQTTClient()
	if err != nil {
		return err
	}

	currentTime := time.Now()
	speedMultiplierMutex.RLock()
	currentMultiplier := speedMultiplier
	speedMultiplierMutex.RUnlock()

	if currentTime.Before(startTime) {
		waitDuration := startTime.Sub(currentTime)
		adjustedWaitDuration := time.Duration(float64(waitDuration) / currentMultiplier)
		log.Printf("等待 %v 后开始模拟", adjustedWaitDuration)
		select {
		case <-time.After(adjustedWaitDuration):
		case <-simulationStopChan:
			return nil
		}
	} else {
		log.Println("开始时间已过去，立即开始模拟")
	}

	totalDuration := endTime.Sub(startTime)
	adjustedTotalDuration := time.Duration(float64(totalDuration) / currentMultiplier)

	if adjustedTotalDuration <= 0 {
		log.Println("结束时间早于或等于开始时间，停止模拟")
		closeSimulation()
		return nil
	}

	simulationEndTimer := time.NewTimer(adjustedTotalDuration)
	go func() {
		select {
		case <-simulationEndTimer.C:
			log.Println("达到结束时间，停止模拟")
			stopSimulation()
		case <-simulationStopChan:
			log.Println("收到停止信号，停止模拟")
		}
	}()

	toStart := params.TruckCount
	totalVehiclesMutex.Lock()
	totalStartedNow := totalVehiclesStartedRoute1 + totalVehiclesStartedRoute2
	remainingVehicles := maxTotalTrucks - totalStartedNow
	totalVehiclesMutex.Unlock()

	if toStart > remainingVehicles {
		toStart = remainingVehicles
	}
	if toStart <= 0 {
		msg := "无法发车，达到最大总车辆数限制"
		log.Println(msg)
		return fmt.Errorf(msg)
	}

	availableSlots := maxConcurrentTrucks - len(concurrentSemaphore)
	if toStart > availableSlots {
		toStart = availableSlots
		log.Printf("限制发车数量为 %d 辆车，因达到最大并发限制", toStart)
	}
	if toStart <= 0 {
		msg := "无法发车，达到最大并发限制"
		log.Println(msg)
		return fmt.Errorf(msg)
	}

	// 先发route2
	totalVehiclesMutex.Lock()
	totalVehiclesStartedRoute2 += toStart
	totalVehiclesMutex.Unlock()

	log.Printf("开始煤矿到陆港2路线(电车)，共发车 %d 辆车，每 %.2f 分钟发一辆车", toStart, params.Frequency)
	go startRoute(simulationStopChan, mqttClient, routeMine, params.LoadWeight, toStart, "route2", params.Frequency, params.MainOrderNumber, params.CoalPickupOrder)

	go func() {
		for {
			select {
			case <-route1StartChan:
				log.Println("检测到 route2 路线有车第二次到达目标点，开始发车G7干线路线(氢车)")
				simMutex.Lock()
				defer simMutex.Unlock()

				toStartG7 := params.TruckCount
				totalVehiclesMutex.Lock()
				totalStartedNow2 := totalVehiclesStartedRoute1 + totalVehiclesStartedRoute2
				remainingVehicles2 := maxTotalTrucks - totalStartedNow2
				totalVehiclesMutex.Unlock()

				if toStartG7 > remainingVehicles2 {
					toStartG7 = remainingVehicles2
				}
				if toStartG7 <= 0 {
					log.Println("无法发车G7干线(氢车)，已达最大车辆总数限制")
					return
				}

				availableSlots2 := maxConcurrentTrucks - len(concurrentSemaphore)
				if toStartG7 > availableSlots2 {
					toStartG7 = availableSlots2
					log.Printf("限制G7干线发车数量为 %d 辆车，因达到最大并发限制", toStartG7)
				}
				if toStartG7 <= 0 {
					log.Println("无法发车G7干线(氢车)，已达最大并发限制")
					return
				}

				totalVehiclesMutex.Lock()
				totalVehiclesStartedRoute1 += toStartG7
				totalVehiclesMutex.Unlock()

				log.Printf("开始G7干线路线(氢车)，共发车 %d 辆车，每 %.2f 分钟发一辆车", toStartG7, params.Frequency)
				startRoute(simulationStopChan, mqttClient, routeG7, params.LoadWeight, toStartG7, "route1", params.Frequency, params.MainOrderNumber, params.CoalPickupOrder)

			case <-simulationStopChan:
				return
			}
		}
	}()

	return nil
}

// startHandler 处理启动模拟的请求
func startHandler(w http.ResponseWriter, r *http.Request) {
	log.Println("收到 /start 请求")
	if r.Method != http.MethodPost {
		log.Printf("无效的方法: %s\n", r.Method)
		http.Error(w, "仅支持 POST 方法", http.StatusMethodNotAllowed)
		return
	}

	var params SimulationParams
	if err := json.NewDecoder(r.Body).Decode(&params); err != nil {
		log.Printf("参数解析错误: %v\n", err)
		http.Error(w, "参数解析错误", http.StatusBadRequest)
		return
	}

	// 验证必填字段
	if params.MainOrderNumber == "" {
		http.Error(w, "main_order_number 是必填字段", http.StatusBadRequest)
		return
	}

	if params.StartDateTime == "" || params.EndDateTime == "" {
		http.Error(w, "start_date_time 和 end_date_time 为必填字段", http.StatusBadRequest)
		return
	}
	if params.TruckCount <= 0 || params.TruckCount > maxTotalTrucks {
		http.Error(w, fmt.Sprintf("truck_count 必须在 1 到 %d 之间", maxTotalTrucks), http.StatusBadRequest)
		return
	}

	if params.Frequency <= 0 {
		http.Error(w, "frequency 必须大于0", http.StatusBadRequest)
		return
	}

	if params.CoalPickupOrder == "" {
		http.Error(w, "coal_pickup_order 是必填字段", http.StatusBadRequest)
		return
	}

	err := startSimulation(params)
	if err != nil {
		log.Printf("启动模拟失败: %v\n", err)
		http.Error(w, err.Error(), http.StatusForbidden)
		return
	}

	log.Println("模拟已启动")
	w.WriteHeader(http.StatusOK)
	w.Write([]byte("模拟已启动"))
}

// stopHandler 处理停止模拟的请求
func stopHandler(w http.ResponseWriter, r *http.Request) {
	log.Println("收到 /stop 请求")
	if r.Method != http.MethodPost {
		http.Error(w, "仅支持 POST 方法", http.StatusMethodNotAllowed)
		return
	}

	stopSimulation()

	log.Println("模拟已停止")
	w.WriteHeader(http.StatusOK)
	w.Write([]byte("模拟已停止"))
}

func main() {
	http.HandleFunc("/start", startHandler)
	http.HandleFunc("/stop", stopHandler)
	http.HandleFunc("/allStatus", allStatusHandler) // 新增整合接口
	http.HandleFunc("/setSpeed", setSpeedHandler)

	fmt.Println("服务正在监听端口 :8201")
	log.Fatal(http.ListenAndServe(":8201", nil))
}
