package parking

import (
	"fmt"
	"sync"
	"time"
	"wails-app/internal/dao"
	"wails-app/internal/global"
	common "wails-app/internal/model/common"
	"wails-app/internal/model/vehicle/request"
	"wails-app/internal/service/vehicle"
)

// GateOpener 道闸控制函数（由 UHF 模块在初始化时注入，避免循环依赖）
var GateOpener func(deviceCode string, validTime byte) error

// PassageService 统一的进出场服务（所有触发方式共用：RFID、摄像头、手动录入）
type PassageService struct{}

// ===================== 防抖与状态 =====================
var (
	passageLastTime    = make(map[string]int64)
	passageStatus      = make(map[string]bool) // true=在场内
	passageMutex       sync.Mutex
	passageDebounceSec = int64(3) // 3秒防抖
)

// getIdentifier 从请求中提取唯一标识（优先 RFID，其次车牌）
func getIdentifier(req common.PassageRequest) string {
	if req.RFIDTag != "" {
		return req.RFIDTag
	}
	return req.PlateNumber
}

// HandlePassage 统一的进出场处理入口
// 调用方只需传入车辆标识 + 设备编码，其余逻辑全部在此处理：
//
//	查询设备/通道 → 查询车辆 → 黑名单检查 → 临时车规则 → 进场/出场 → 开闸
func (s *PassageService) HandlePassage(req common.PassageRequest) (*common.PassageResult, error) {
	identifier := getIdentifier(req)
	if identifier == "" {
		return nil, fmt.Errorf("缺少车辆标识（RFIDTag 或 PlateNumber）")
	}

	// ===================== 1. 防抖 =====================
	passageMutex.Lock()
	if last, ok := passageLastTime[identifier]; ok && time.Now().Unix()-last < passageDebounceSec {
		passageMutex.Unlock()
		return nil, fmt.Errorf("防抖中: %s", identifier)
	}
	passageLastTime[identifier] = time.Now().Unix()
	passageMutex.Unlock()

	// ===================== 2. 查询设备 + 通道 =====================
	var device dao.UHFReader
	if err := global.GVA_DB.Preload("Channel").First(&device, "device_code = ?", req.DeviceCode).Error; err != nil {
		return nil, fmt.Errorf("设备不存在: %s", req.DeviceCode)
	}
	channel := device.Channel
	direction := channel.Direction
	allowTemporary := channel.AllowTemporary

	// ===================== 3. 查询车辆 =====================
	vehicleSvc := &vehicle.VehicleService{}
	shortlistSvc := &vehicle.ShortlistService{}

	v, err := vehicleSvc.GetVehicleByPlateNumber(req.PlateNumber, req.RFIDTag)
	isTempVehicle := false
	if err != nil || v.ID == 0 {
		isTempVehicle = true
	} else if v.VehicleType != nil {
		isTempVehicle = v.VehicleType.IsSystem
	} else {
		isTempVehicle = true
	}

	// ===================== 4. 黑名单检查 =====================
	isBlack, _ := shortlistSvc.CheckVehicleShortlist(req.PlateNumber, req.RFIDTag)
	if isBlack {
		fmt.Printf("🚫 禁止通行 | 车辆在黑名单中 | 设备:%s 车牌:%s RFID:%s\n", req.DeviceCode, req.PlateNumber, req.RFIDTag)
		return nil, fmt.Errorf("车辆在黑名单中")
	}

	// ===================== 5. 临时车规则 =====================
	if isTempVehicle && !allowTemporary {
		fmt.Printf("🚫 禁止通行 | 临时车不允许此通道 | 设备:%s 车牌:%s RFID:%s\n", req.DeviceCode, req.PlateNumber, req.RFIDTag)
		return nil, fmt.Errorf("临时车不允许此通道")
	}

	// ===================== 6. 根据方向处理 =====================
	switch direction {
	case "in":
		return s.handleEntry(req, identifier, channel.ParkingLotID)
	case "out":
		return s.handleExit(req, identifier)
	default:
		return nil, fmt.Errorf("未知通道方向: %s", direction)
	}
}

// handleEntry 处理入场
func (s *PassageService) handleEntry(req common.PassageRequest, identifier string, parkingLotID uint) (*common.PassageResult, error) {
	passageMutex.Lock()
	canIn := !passageStatus[identifier]
	passageMutex.Unlock()

	if !canIn {
		return nil, fmt.Errorf("车辆已在场内: %s", identifier)
	}

	fmt.Printf("🟢 入口开闸 | 设备:%s 车牌:%s RFID:%s\n", req.DeviceCode, req.PlateNumber, req.RFIDTag)

	// 开闸
	if GateOpener != nil {
		if err := GateOpener(req.DeviceCode, 2); err != nil {
			fmt.Printf("⚠️ 开闸失败: %v\n", err)
		}
	}

	// 执行入场
	vehicleSvc := &vehicle.VehicleService{}
	resp, err := vehicleSvc.VehicleEntry(request.VehicleEntry{
		PlateNumber:  req.PlateNumber,
		RFIDTag:      req.RFIDTag,
		ParkingLotID: parkingLotID,
		EntryImage:   req.Image,
	})
	if err != nil {
		return nil, err
	}

	passageMutex.Lock()
	passageStatus[identifier] = true
	passageMutex.Unlock()

	return &common.PassageResult{
		Success:     true,
		Message:     "入场成功",
		Direction:   "in",
		PlateNumber: resp.Data.PlateNumber,
		RFIDTag:     req.RFIDTag,
		EntryTime:   resp.Data.EntryTime,
	}, nil
}

// handleExit 处理出场（使用新的收费流程 ExitConfirm）
func (s *PassageService) handleExit(req common.PassageRequest, identifier string) (*common.PassageResult, error) {
	fmt.Printf("🔴 出口开闸 | 设备:%s 车牌:%s RFID:%s\n", req.DeviceCode, req.PlateNumber, req.RFIDTag)

	// 开闸
	if GateOpener != nil {
		if err := GateOpener(req.DeviceCode, 2); err != nil {
			fmt.Printf("⚠️ 开闸失败: %v\n", err)
		}
	}

	// 执行出场（RFID自动出场统一走免密，无人工收费）
	vehicleSvc := &vehicle.VehicleService{}
	confirmReq := request.ExitConfirmRequest{
		PlateNumber:   req.PlateNumber,
		RFIDTag:       req.RFIDTag,
		PaymentMethod: "free",
		PaidAmount:    0,
	}
	resp, err := vehicleSvc.ExitConfirm(confirmReq, 0)
	if err != nil {
		return nil, err
	}

	passageMutex.Lock()
	passageStatus[identifier] = false
	passageMutex.Unlock()

	return &common.PassageResult{
		Success:     true,
		Message:     "出场成功",
		Direction:   "out",
		PlateNumber: req.PlateNumber,
		RFIDTag:     req.RFIDTag,
		Fee:         resp.Fee,
		StayTime:    resp.StayTime,
		EntryTime:   resp.EntryTime,
		ExitTime:    resp.ExitTime,
	}, nil
}

// SetEpcExit 手动重置离场状态
func SetEpcExit(identifier string) {
	passageMutex.Lock()
	defer passageMutex.Unlock()
	passageStatus[identifier] = false
	fmt.Printf("🚙 手动重置离场 | 标识: %s\n", identifier)
}
