package parking

import (
	"errors"
	"wails-app/internal/dao"
	"wails-app/internal/global"
	"wails-app/internal/model/parking/request"
)

type parkingLotService struct{}

func NewParkingLotService() *parkingLotService {
	return &parkingLotService{}
}

// CreateParkingLot 创建停车区域
func (s *parkingLotService) CreateParkingLot(req request.ParkingLotCreate) error {
	// 检查区域编码是否已存在
	var existingLot dao.ParkingLot
	result := global.GVA_DB.Where("lot_code = ?", req.LotCode).First(&existingLot)
	if result.RowsAffected > 0 {
		return errors.New("区域编码已存在")
	}

	lot := dao.ParkingLot{
		LotCode:     req.LotCode,
		LotName:     req.LotName,
		Capacity:    req.Capacity,
		Available:   req.Capacity, // 初始可用车位等于总车位
		Description: req.Description,
	}

	return global.GVA_DB.Create(&lot).Error
}

// UpdateParkingLot 更新停车区域
func (s *parkingLotService) UpdateParkingLot(req request.ParkingLotUpdate) error {
	var lot dao.ParkingLot
	result := global.GVA_DB.First(&lot, req.ID)
	if result.RowsAffected == 0 {
		return errors.New("停车区域不存在")
	}

	// 检查区域编码是否被其他区域使用
	var existingLot dao.ParkingLot
	result = global.GVA_DB.Where("lot_code = ? AND id != ?", req.LotCode, req.ID).First(&existingLot)
	if result.RowsAffected > 0 {
		return errors.New("区域编码已被其他区域使用")
	}

	// 计算可用车位的变化
	capacityDiff := req.Capacity - lot.Capacity
	lot.LotCode = req.LotCode
	lot.LotName = req.LotName
	lot.Capacity = req.Capacity
	lot.Available += capacityDiff
	if lot.Available < 0 {
		lot.Available = 0
	}
	lot.Description = req.Description

	return global.GVA_DB.Save(&lot).Error
}

// GetParkingLotByID 根据ID获取停车区域
func (s *parkingLotService) GetParkingLotByID(id uint) (dao.ParkingLot, error) {
	var lot dao.ParkingLot
	result := global.GVA_DB.First(&lot, id)
	if result.RowsAffected == 0 {
		return dao.ParkingLot{}, errors.New("停车区域不存在")
	}
	return lot, nil
}

// GetParkingLotByCode 根据编码获取停车区域
func (s *parkingLotService) GetParkingLotByCode(code string) (dao.ParkingLot, error) {
	var lot dao.ParkingLot
	result := global.GVA_DB.Where("lot_code = ?", code).First(&lot)
	if result.RowsAffected == 0 {
		return dao.ParkingLot{}, errors.New("停车区域不存在")
	}
	return lot, nil
}

func (s *parkingLotService) QueryAllParkingLots() ([]dao.ParkingLot, error) {
	var parkingLots []dao.ParkingLot
	err := global.GVA_DB.Find(&parkingLots).Error

	if err != nil {
		return parkingLots, err
	}

	return parkingLots, nil
}

// ListParkingLots 获取停车区域列表
func (s *parkingLotService) ListParkingLots(req request.ParkingLotQuery) (int64, []dao.ParkingLot, error) {
	var lots []dao.ParkingLot
	var total int64

	query := global.GVA_DB.Model(&dao.ParkingLot{})

	if req.LotCode != "" {
		query = query.Where("lot_code LIKE ?", "%"+req.LotCode+"%")
	}

	if req.LotCode != "" {
		query = query.Where("id = ?", req.LotId)
	}

	if req.LotName != "" {
		query = query.Where("lot_name LIKE ?", "%"+req.LotName+"%")
	}

	// 计算总数
	query.Count(&total)

	// 分页查询
	offset := (req.Page - 1) * req.PageSize
	result := query.Offset(offset).Limit(req.PageSize).Preload("Booths").Preload("Channels").Preload("UHFReaders").Find(&lots)
	if result.Error != nil {
		return 0, nil, result.Error
	}

	return total, lots, nil
}

// DeleteParkingLot 删除停车区域
func (s *parkingLotService) DeleteParkingLot(id uint) error {
	result := global.GVA_DB.Delete(&dao.ParkingLot{}, id)
	if result.RowsAffected == 0 {
		return errors.New("停车区域不存在")
	}
	return result.Error
}

// UpdateParkingLotAvailability 更新停车区域可用车位
func (s *parkingLotService) UpdateParkingLotAvailability(lotID uint, delta int) error {
	var lot dao.ParkingLot
	result := global.GVA_DB.First(&lot, lotID)
	if result.RowsAffected == 0 {
		return errors.New("停车区域不存在")
	}

	lot.Available += delta
	if lot.Available < 0 {
		lot.Available = 0
	} else if lot.Available > lot.Capacity {
		lot.Available = lot.Capacity
	}

	return global.GVA_DB.Save(&lot).Error
}
