package com.yupi.project.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.yupi.project.model.entity.ParkingSpot;
import com.yupi.project.model.enums.ParkingSpotStatusEnum;

import java.util.List;

/**
* @author Yupi
* @description 针对表【parking_spot(车位表)】的数据库操作Service
* @createDate 2023-12-03 10:00:00
*/
public interface ParkingSpotService extends IService<ParkingSpot> {

    /**
     * 添加新的车位信息
     *
     * @param spotUid 车位唯一ID
     * @param locationDescription 位置描述
     * @param robotAssignable 是否可指派机器人
     * @return 创建的车位实体
     */
    ParkingSpot addParkingSpot(String spotUid, String locationDescription, boolean robotAssignable);

    /**
     * 根据车位UID查找车位
     *
     * @param spotUid 车位唯一ID
     * @return 车位实体，未找到则返回null
     */
    ParkingSpot findBySpotUid(String spotUid);

    /**
     * 更新车位状态
     *
     * @param spotId 车位DB主键ID
     * @param newStatus 新状态
     * @param currentSessionId (可选) 当前关联的充电会话ID
     * @return 是否更新成功
     */
    boolean updateParkingSpotStatus(Long spotId, ParkingSpotStatusEnum newStatus, Long currentSessionId);

    /**
     * 查找所有可用的、可指派机器人的车位
     *
     * @return 可用车位列表
     */
    List<ParkingSpot> findAvailableAndAssignableSpots();

    /**
     * 占用一个车位（例如，用户预订或开始充电会话时）
     *
     * @param spotId 车位ID
     * @param sessionId 关联的充电会话ID
     * @param targetStatus 目标状态 (如 OCCUPIED_BY_CAR, RESERVED, CHARGING)
     * @return 操作是否成功
     */
    boolean occupySpot(Long spotId, Long sessionId, ParkingSpotStatusEnum targetStatus);

    /**
     * 释放一个车位 (例如，充电结束或取消预订)
     *
     * @param spotId 车位ID
     * @return 操作是否成功
     */
    boolean releaseSpot(Long spotId);

    /**
     * 更新车位状态及当前关联的充电会话ID。
     *
     * @param spotUID          车位唯一标识符
     * @param newStatus        新的车位状态
     * @param currentSessionId 当前占用此车位的充电会话ID (如果车位变为空闲，则应传入 null)
     * @return 更新是否成功
     */
    boolean updateSpotStatus(String spotUID, ParkingSpotStatusEnum newStatus, Long currentSessionId);

    /**
     * 获取可用车位数量 (状态为 available)
     *
     * @return 可用车位数量
     */
    long countAvailableSpots();

} 