package com.yupi.project.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
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.DeleteRequest;
import com.yupi.project.common.ErrorCode;
import com.yupi.project.common.ResultUtils;
import com.yupi.project.constant.UserConstant;
import com.yupi.project.exception.BusinessException;
import com.yupi.project.exception.ThrowUtils;
import com.yupi.project.model.dto.parking_spot.ParkingSpotAddRequest;
import com.yupi.project.model.dto.parking_spot.ParkingSpotQueryRequest;
import com.yupi.project.model.dto.parking_spot.ParkingSpotUpdateRequest;
import com.yupi.project.model.entity.ParkingSpot;
import com.yupi.project.model.enums.ParkingSpotStatusEnum;
import com.yupi.project.service.ParkingSpotService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.web.bind.annotation.*;

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

/**
 * 车位管理接口 (管理员权限)
 */
@RestController
@RequestMapping("/admin/spot")
@Slf4j
@Api(tags = "车位管理接口 (管理员)")
public class ParkingSpotAdminController {

    @Resource
    private ParkingSpotService parkingSpotService;

    @ApiOperation("添加车位")
    @PostMapping("/add")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Long> addParkingSpot(@RequestBody ParkingSpotAddRequest addRequest, HttpServletRequest request) {
        if (addRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        if (StringUtils.isBlank(addRequest.getSpotUid())) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "车位UID不能为空");
        }
        // robotAssignable 默认为true，如果 DTO 中是 Boolean，则 null 会被处理

        ParkingSpot spot;
        try {
            spot = parkingSpotService.addParkingSpot(
                    addRequest.getSpotUid(),
                    addRequest.getLocationDescription(),
                    addRequest.getRobotAssignable() == null ? true : addRequest.getRobotAssignable()
            );
        } catch (DuplicateKeyException e) {
            //捕获由数据库唯一约束抛出的 DuplicateKeyException
            log.warn("添加车位失败，车位UID已存在 (数据库约束冲突): {}", addRequest.getSpotUid(), e);
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "车位UID '" + addRequest.getSpotUid() + "' 已存在。");
        }
        // BusinessException (如 "车位UID已存在") 会由 Service 层直接抛出，这里无需再次捕获

        if (spot == null || spot.getId() == null) {
            // 这种情况理论上应该被Service层的异常覆盖，或者save失败时抛出异常
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "添加车位失败，未知原因。");
        }
        return ResultUtils.success(spot.getId());
    }

    @ApiOperation("删除车位")
    @PostMapping("/delete")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Boolean> deleteParkingSpot(@RequestBody DeleteRequest deleteRequest, HttpServletRequest request) {
        if (deleteRequest == null || deleteRequest.getId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        // 检查车位是否正在使用等逻辑可以在Service层实现，这里直接删除
        boolean b = parkingSpotService.removeById(deleteRequest.getId());
        return ResultUtils.success(b);
    }

    @ApiOperation("更新车位信息")
    @PostMapping("/update")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Boolean> updateParkingSpot(@RequestBody ParkingSpotUpdateRequest updateRequest, HttpServletRequest request) {
        if (updateRequest == null || updateRequest.getId() == null || updateRequest.getId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        ParkingSpot parkingSpot = new ParkingSpot();
        BeanUtils.copyProperties(updateRequest, parkingSpot);

        if (StringUtils.isNotBlank(updateRequest.getStatus()) && ParkingSpotStatusEnum.getEnumByValue(updateRequest.getStatus()) == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "无效的车位状态值");
        }

        boolean result = parkingSpotService.updateById(parkingSpot);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
        return ResultUtils.success(true);
    }

    @ApiOperation("根据ID获取车位信息")
    @GetMapping("/get")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<ParkingSpot> getParkingSpotById(long id, HttpServletRequest request) {
        if (id <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        ParkingSpot parkingSpot = parkingSpotService.getById(id);
        ThrowUtils.throwIf(parkingSpot == null, ErrorCode.NOT_FOUND_ERROR);
        return ResultUtils.success(parkingSpot);
    }

    @ApiOperation("分页获取车位列表")
    @PostMapping("/list/page")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Page<ParkingSpot>> listParkingSpotsByPage(@RequestBody ParkingSpotQueryRequest queryRequest, HttpServletRequest request) {
        if (queryRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        long current = queryRequest.getCurrent();
        long size = queryRequest.getPageSize();
        Page<ParkingSpot> page = new Page<>(current, size);
        QueryWrapper<ParkingSpot> queryWrapper = new QueryWrapper<>();

        if (StringUtils.isNotBlank(queryRequest.getSpotUid())) {
            queryWrapper.like("spot_uid", queryRequest.getSpotUid());
        }
        if (StringUtils.isNotBlank(queryRequest.getStatus())) {
            queryWrapper.eq("status", queryRequest.getStatus());
        }
        if (queryRequest.getRobotAssignable() != null) {
            queryWrapper.eq("robot_assignable", queryRequest.getRobotAssignable());
        }
        if (StringUtils.isNotBlank(queryRequest.getSortField())) {
            // 确保 queryRequest.getSortOrder() 不为 null，并转换为 boolean
            boolean isAsc = "asc".equalsIgnoreCase(queryRequest.getSortOrder()) || "ascend".equalsIgnoreCase(queryRequest.getSortOrder());
            queryWrapper.orderBy(true, isAsc, queryRequest.getSortField());
        }

        parkingSpotService.page(page, queryWrapper);
        return ResultUtils.success(page);
    }

    @ApiOperation("获取所有车位状态类型")
    @GetMapping("/status/types")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<List<String>> getParkingSpotStatusTypes() {
        List<String> statusTypes = Arrays.stream(ParkingSpotStatusEnum.values())
                .map(ParkingSpotStatusEnum::getValue)
                .collect(Collectors.toList());
        return ResultUtils.success(statusTypes);
    }
} 