package com.yupi.project.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yupi.project.model.dto.charging_session.ChargingRequest;
import com.yupi.project.model.entity.ChargingSession;
import com.yupi.project.model.entity.User;
import com.yupi.project.model.enums.ChargingSessionStatusEnum;
import com.yupi.project.model.dto.charging_session.ChargingSessionQueryRequest;

import java.math.BigDecimal;
import java.util.List;

/**
* @author Yupi
* @description 针对表【charging_session(充电记录表)】的数据库操作Service
* @createDate 2023-12-03 10:00:00
*/
public interface ChargingSessionService extends IService<ChargingSession> {

    /**
     * 用户请求充电
     *
     * @param currentUser 当前登录用户
     * @param chargingRequest 充电请求参数 (如 车位ID等)
     * @return 创建的充电会话实体
     */
    ChargingSession requestCharging(User currentUser, ChargingRequest chargingRequest);

    /**
     * 系统处理充电请求，分配机器人
     * (通常在 requestCharging 内部被调用，或由异步任务触发)
     *
     * @param sessionId 充电会话ID
     * @return 更新后的充电会话实体，或null如果无法分配
     */
    ChargingSession assignRobotToSession(Long sessionId);

    /**
     * 更新充电会话状态 (机器人已到达)
     *
     * @param sessionId 充电会话ID
     * @param robotTaskId 关联的机器人任务ID (例如，机器人移动任务)
     * @return 是否成功
     */
    boolean handleRobotArrival(Long sessionId, Long robotTaskId);

    /**
     * 更新充电会话状态 (充电开始)
     *
     * @param sessionId 充电会话ID
     * @param robotTaskId 关联的机器人任务ID (例如，开始充电任务)
     * @return 是否成功
     */
    boolean handleChargingStart(Long sessionId, Long robotTaskId);

    /**
     * 更新充电会话状态 (充电结束)
     *
     * @param sessionId 充电会话ID
     * @param robotTaskId 关联的机器人任务ID (例如，结束充电任务)
     * @param energyConsumedKwh 消耗电量
     * @param durationSeconds 充电时长
     * @return 是否成功
     */
    boolean handleChargingEnd(Long sessionId, Long robotTaskId, BigDecimal energyConsumedKwh, int durationSeconds);

    /**
     * 计算费用并更新会话 (在充电结束后调用)
     *
     * @param sessionId 充电会话ID
     * @return 是否成功
     */
    boolean calculateCostAndFinalizeSession(Long sessionId);

    /**
     * 用户支付充电费用
     *
     * @param sessionId 充电会话ID
     * @param userId 用户ID (用于校验)
     * @return 是否成功
     */
    boolean processPayment(Long sessionId, Long userId);

    /**
     * 取消充电会话
     *
     * @param sessionId 充电会话ID
     * @param userId (可选) 如果是用户发起的取消，则为用户ID
     * @param reason 取消原因/发起方
     * @return 是否成功
     */
    boolean cancelChargingSession(Long sessionId, Long userId, String reason, ChargingSessionStatusEnum cancelStatus);

    /**
     * 根据用户ID查找其充电记录
     *
     * @param userId 用户ID
     * @return 充电会话列表
     */
    List<ChargingSession> findUserSessions(Long userId);

    /**
     * 根据机器人任务ID查找关联的充电会话
     * @param robotTaskId 机器人任务ID
     * @return 充电会话
     */
    ChargingSession findSessionByRobotTaskId(Long robotTaskId);

     /**
     * 处理充电会话相关的机器人任务超时
     * @param robotTaskId 超时的机器人任务ID
     */
    void handleSessionTaskTimeout(Long robotTaskId);

    /**
     * 用户请求停止当前正在进行的充电
     * (会向机器人发送停止指令，等待机器人确认后再完成计费)
     *
     * @param sessionId 充电会话ID
     * @param userId 用户ID (用于校验)
     * @return 是否成功发起停止请求 (不代表已完成)
     */
    boolean stopChargingByUser(Long sessionId, Long userId);

    /**
     * 获取查询包装类
     *
     * @param queryRequest
     * @return
     */
    QueryWrapper<ChargingSession> getQueryWrapper(ChargingSessionQueryRequest queryRequest);

    /**
     * 根据用户ID获取当前激活的充电会话
     *
     * @param userId 用户ID
     * @return ChargingSession 实体，如果没有激活的则返回 null
     */
    ChargingSession getActiveSessionByUserId(Long userId);

    /**
     * 获取今日的充电会话总数 (包括进行中和已完成)
     *
     * @return 今日充电会话总数
     */
    long countTodaySessions();

    /**
     * 获取今日的总收入 (基于已支付的会话)
     *
     * @return 今日总收入
     */
    BigDecimal sumTodayRevenue();

    long countActiveSessions();

    BigDecimal getTotalRevenue();

} 