package com.yupi.project.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yupi.project.annotation.AuthCheck;
import com.yupi.project.common.BaseResponse;
import com.yupi.project.common.ErrorCode;
import com.yupi.project.common.ResultUtils;
import com.yupi.project.exception.BusinessException;
import com.yupi.project.exception.ThrowUtils;
import com.yupi.project.model.dto.charging_session.ChargingRequest;
import com.yupi.project.model.dto.charging_session.ChargingSessionQueryRequest;
import com.yupi.project.model.dto.charging_session.PaymentRequest;
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.vo.ChargingSessionVO;
import com.yupi.project.service.ChargingSessionService;
import com.yupi.project.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 充电会话接口 (用户权限)
 */
@RestController
@RequestMapping("/session")
@Slf4j
@Api(tags = "充电会话接口 (用户)")
public class ChargingSessionController {

    @Resource
    private ChargingSessionService chargingSessionService;

    @Resource
    private UserService userService;

    @ApiOperation("用户请求充电")
    @PostMapping("/request")
    @AuthCheck // 需要登录
    public BaseResponse<Long> requestCharging(@RequestBody ChargingRequest chargingRequest, HttpServletRequest request) {
        if (chargingRequest == null || chargingRequest.getSpotId() == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "请求参数错误，必须指定车位ID");
        }
        User loginUser = userService.getCurrentUser(request);
        ChargingSession session = chargingSessionService.requestCharging(loginUser, chargingRequest);
        return ResultUtils.success(session.getId());
    }

    @ApiOperation("用户获取自己的充电会话列表 (分页)")
    @PostMapping("/my/list/page")
    @AuthCheck // 需要登录
    public BaseResponse<Page<ChargingSessionVO>> listMyChargingSessionsByPage(@RequestBody ChargingSessionQueryRequest queryRequest, HttpServletRequest request) {
        if (queryRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        User loginUser = userService.getCurrentUser(request);
        queryRequest.setUserId(loginUser.getId()); // 强制查询当前用户的

        long current = queryRequest.getCurrent();
        long size = queryRequest.getPageSize();

        // 限制爬虫
        ThrowUtils.throwIf(size > 20, ErrorCode.PARAMS_ERROR);
        Page<ChargingSession> sessionPage = chargingSessionService.page(new Page<>(current, size),
                chargingSessionService.getQueryWrapper(queryRequest));
        
        Page<ChargingSessionVO> sessionVOPage = new Page<>(sessionPage.getCurrent(), sessionPage.getSize(), sessionPage.getTotal());
        List<ChargingSessionVO> voList = sessionPage.getRecords().stream().map(ChargingSessionVO::objToVo).collect(Collectors.toList());
        sessionVOPage.setRecords(voList);

        return ResultUtils.success(sessionVOPage);
    }
    
    @ApiOperation("用户获取当前激活的充电会话")
    @GetMapping("/my/active")
    @AuthCheck // 需要登录
    public BaseResponse<ChargingSessionVO> getMyActiveChargingSession(HttpServletRequest request) {
        User loginUser = userService.getCurrentUser(request);
        ChargingSession activeSession = chargingSessionService.getActiveSessionByUserId(loginUser.getId());
        if (activeSession == null) {
            return ResultUtils.success(null); // 没有激活的会话
        }
        return ResultUtils.success(ChargingSessionVO.objToVo(activeSession));
    }

    @ApiOperation("用户获取单个充电会话详情")
    @GetMapping("/get")
    @AuthCheck
    public BaseResponse<ChargingSessionVO> getChargingSessionById(long id, HttpServletRequest request) {
        if (id <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        User loginUser = userService.getCurrentUser(request);
        ChargingSession session = chargingSessionService.getById(id);
        if (session == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
        }
        // 权限校验，只能看自己的
        if (!session.getUserId().equals(loginUser.getId())) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
        }
        return ResultUtils.success(ChargingSessionVO.objToVo(session));
    }

    @ApiOperation("用户取消充电会话")
    @PostMapping("/cancel")
    @AuthCheck
    public BaseResponse<Boolean> cancelChargingSession(@RequestBody PaymentRequest cancelRequest, HttpServletRequest request) { // 复用PaymentRequest只取sessionId
        if (cancelRequest == null || cancelRequest.getSessionId() == null || cancelRequest.getSessionId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        User loginUser = userService.getCurrentUser(request);
        boolean result = chargingSessionService.cancelChargingSession(cancelRequest.getSessionId(), loginUser.getId(), "用户主动取消", ChargingSessionStatusEnum.CANCELLED_BY_USER);
        return ResultUtils.success(result);
    }

    @ApiOperation("用户请求停止当前充电")
    @PostMapping("/stop")
    @AuthCheck
    public BaseResponse<Boolean> stopCharging(@RequestBody PaymentRequest stopRequest, HttpServletRequest request) { // 复用PaymentRequest只取sessionId
        if (stopRequest == null || stopRequest.getSessionId() == null || stopRequest.getSessionId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        User loginUser = userService.getCurrentUser(request);
        boolean result = chargingSessionService.stopChargingByUser(stopRequest.getSessionId(), loginUser.getId());
        return ResultUtils.success(result);
    }

    @ApiOperation("用户支付充电费用")
    @PostMapping("/pay")
    @AuthCheck
    public BaseResponse<Boolean> payChargingSession(@RequestBody PaymentRequest paymentRequest, HttpServletRequest request) {
        if (paymentRequest == null || paymentRequest.getSessionId() == null || paymentRequest.getSessionId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        User loginUser = userService.getCurrentUser(request);
        boolean result = chargingSessionService.processPayment(paymentRequest.getSessionId(), loginUser.getId());
        return ResultUtils.success(result);
    }
} 