package com.ruoyi.course.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.course.common.R;
import com.ruoyi.course.domain.Classroom;
import com.ruoyi.course.domain.vo.ClassroomQueryVO;
import com.ruoyi.course.service.IClassroomService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 教室信息表 前端控制器
 * </p>
 *
 * @author xu
 * @since 2025-12-14
 */
@RestController
@RequestMapping("/course/classroom")
@Tag(name = "教室管理", description = "教室相关的CRUD操作和分配管理")
@Slf4j
public class ClassroomController extends BaseController {

    @Autowired
    private IClassroomService classroomService;

    @Operation(summary = "新增教室", description = "创建一个新的教室")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "新增成功"),
            @ApiResponse(responseCode = "500", description = "新增失败")
    })
    @PostMapping("/add")
    public R<Boolean> addClassroom(@RequestBody Classroom classroom) {
        // 设置创建时间和更新时间
        classroom.setCreateTime(LocalDateTime.now());
        classroom.setUpdateTime(LocalDateTime.now());

        boolean success = classroomService.save(classroom);
        return success ? R.ok(true, "新增成功") : R.error("新增失败");
    }

    @Operation(summary = "根据ID删除教室", description = "根据教室ID删除教室信息")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "删除成功"),
            @ApiResponse(responseCode = "404", description = "教室不存在"),
            @ApiResponse(responseCode = "500", description = "删除失败")
    })
    @DeleteMapping("/delete/{id}")
    public R<Boolean> deleteClassroom(
            @Parameter(description = "教室ID", required = true, example = "1")
            @PathVariable Long id) {
        boolean success = classroomService.removeById(id);
        return success ? R.ok(true, "删除成功") : R.error("删除失败");
    }

    @Operation(summary = "批量删除教室", description = "批量删除多个教室")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "批量删除成功"),
            @ApiResponse(responseCode = "400", description = "参数错误"),
            @ApiResponse(responseCode = "500", description = "批量删除失败")
    })
    @DeleteMapping("/batchDelete")
    public R<Boolean> batchDelete(@RequestBody List<Long> ids) {
        if (ids == null || ids.isEmpty()) {
            return R.paramError("请选择要删除的数据");
        }

        boolean success = classroomService.removeByIds(ids);
        return success ? R.ok(true, "批量删除成功") : R.error("批量删除失败");
    }

    @Operation(summary = "修改教室信息", description = "更新教室信息")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "修改成功"),
            @ApiResponse(responseCode = "400", description = "ID不能为空"),
            @ApiResponse(responseCode = "404", description = "教室不存在"),
            @ApiResponse(responseCode = "500", description = "修改失败")
    })
    @PutMapping("/update")
    public R<Boolean> updateClassroom(@RequestBody Classroom classroom) {
        if (classroom.getId() == null) {
            return R.paramError("ID不能为空");
        }

        // 设置更新时间
        classroom.setUpdateTime(LocalDateTime.now());

        boolean success = classroomService.updateById(classroom);
        return success ? R.ok(true, "修改成功") : R.error("修改失败");
    }

    @Operation(summary = "根据ID查询教室", description = "根据教室ID获取教室详细信息")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "查询成功"),
            @ApiResponse(responseCode = "404", description = "教室不存在")
    })
    @GetMapping("/get/{id}")
    public R<Classroom> getClassroomById(
            @Parameter(description = "教室ID", required = true, example = "1")
            @PathVariable Long id) {
        Classroom classroom = classroomService.getById(id);
        if (classroom == null) {
            return R.notFound("教室不存在");
        }
        return R.ok(classroom, "查询成功");
    }

    @Operation(summary = "查询所有教室", description = "获取所有教室列表")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "查询成功")
    })
    @GetMapping("/list")
    public TableDataInfo listTeachers() {
        startPage();
        List<Classroom> list = classroomService.list();
        return getDataTable(list);
    }

    @Operation(summary = "分页查询教室列表", description = "根据条件分页查询教室列表")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "查询成功")
    })
    @PostMapping("/page")
    public R<IPage<Classroom>> pageClassrooms(@RequestBody ClassroomQueryVO queryVO) {
        // 创建分页对象
        Page<Classroom> page = new Page<>(queryVO.getPageNum(), queryVO.getPageSize());

        // 创建查询条件
        LambdaQueryWrapper<Classroom> wrapper = new LambdaQueryWrapper<>();

        // 添加查询条件（非空判断）
        if (StringUtils.hasText(queryVO.getRoomNo())) {
            wrapper.like(Classroom::getRoomNo, queryVO.getRoomNo());
        }

        if (StringUtils.hasText(queryVO.getRoomName())) {
            wrapper.like(Classroom::getRoomName, queryVO.getRoomName());
        }

        if (StringUtils.hasText(queryVO.getRoomType())) {
            wrapper.eq(Classroom::getRoomType, queryVO.getRoomType());
        }

        if (queryVO.getMinCapacity() != null) {
            wrapper.ge(Classroom::getCapacity, queryVO.getMinCapacity());
        }

        if (queryVO.getMaxCapacity() != null) {
            wrapper.le(Classroom::getCapacity, queryVO.getMaxCapacity());
        }

        if (queryVO.getFloor() != null) {
            wrapper.eq(Classroom::getFloor, queryVO.getFloor());
        }

        if (StringUtils.hasText(queryVO.getBuilding())) {
            wrapper.eq(Classroom::getBuilding, queryVO.getBuilding());
        }

        if (queryVO.getIsAvailable() != null) {
            wrapper.eq(Classroom::getIsAvailable, queryVO.getIsAvailable());
        }

        // 按创建时间倒序
        wrapper.orderByDesc(Classroom::getCreateTime);

        // 执行分页查询
        IPage<Classroom> result = classroomService.page(page, wrapper);

        return R.ok(result, "查询成功");
    }

    @Operation(summary = "简单分页查询（无条件）", description = "无条件分页查询教室列表")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "查询成功")
    })
    @GetMapping("/page")
    public R<IPage<Classroom>> simplePage(
            @Parameter(description = "页码", required = false, example = "1")
            @RequestParam(defaultValue = "1") Integer pageNum,

            @Parameter(description = "每页条数", required = false, example = "10")
            @RequestParam(defaultValue = "10") Integer pageSize) {

        Page<Classroom> page = new Page<>(pageNum, pageSize);

        IPage<Classroom> result = classroomService.page(page);

        return R.ok(result, "查询成功");
    }











    @Operation(summary = "统计教室数量", description = "统计教室总数或根据条件统计")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "查询成功")
    })
    @GetMapping("/count")
    public R<Long> countClassrooms(
            @Parameter(description = "教室类型", required = false, example = "多媒体教室")
            @RequestParam(required = false) String roomType,
            @Parameter(description = "教学楼", required = false, example = "主教学楼")
            @RequestParam(required = false) String building,
            @Parameter(description = "楼层", required = false, example = "3")
            @RequestParam(required = false) Integer floor,
            @Parameter(description = "可用状态", required = false, example = "1")
            @RequestParam(required = false) Integer isAvailable) {

        LambdaQueryWrapper<Classroom> wrapper = new LambdaQueryWrapper<>();
        if (StringUtils.hasText(roomType)) {
            wrapper.eq(Classroom::getRoomType, roomType);
        }
        if (StringUtils.hasText(building)) {
            wrapper.eq(Classroom::getBuilding, building);
        }
        if (floor != null) {
            wrapper.eq(Classroom::getFloor, floor);
        }
        if (isAvailable != null) {
            wrapper.eq(Classroom::getIsAvailable, isAvailable);
        }

        Long count = classroomService.count(wrapper);
        return R.ok(count, "查询成功");
    }

    @Operation(summary = "根据容量范围查询教室", description = "根据容量范围查询符合条件的教室列表")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "查询成功")
    })
    @GetMapping("/listByCapacityRange")
    public R<List<Classroom>> listByCapacityRange(
            @Parameter(description = "最小容量", required = true, example = "30")
            @RequestParam Integer minCapacity,
            @Parameter(description = "最大容量", required = true, example = "100")
            @RequestParam Integer maxCapacity) {

        LambdaQueryWrapper<Classroom> wrapper = new LambdaQueryWrapper<>();
        wrapper.ge(Classroom::getCapacity, minCapacity);
        wrapper.le(Classroom::getCapacity, maxCapacity);
        wrapper.orderByDesc(Classroom::getCreateTime);

        List<Classroom> list = classroomService.list(wrapper);
        return R.ok(list, "查询成功");
    }

    @Operation(summary = "根据教学楼和楼层查询教室", description = "根据教学楼和楼层组合查询教室列表")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "查询成功")
    })
    @GetMapping("/listByBuildingAndFloor")
    public R<List<Classroom>> listByBuildingAndFloor(
            @Parameter(description = "教学楼名称", required = true, example = "主教学楼")
            @RequestParam String building,
            @Parameter(description = "楼层", required = true, example = "3")
            @RequestParam Integer floor) {

        LambdaQueryWrapper<Classroom> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Classroom::getBuilding, building);
        wrapper.eq(Classroom::getFloor, floor);
        wrapper.orderByDesc(Classroom::getCreateTime);

        List<Classroom> list = classroomService.list(wrapper);
        return R.ok(list, "查询成功");
    }



    @Operation(summary = "验证班级-教室绑定完整性", description = "验证班级与教室的绑定关系是否完整")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "验证成功")
    })
    @GetMapping("/validate-assignments")
    public Map<String, Object> validateAssignments() {
        log.info("调用班级-教室绑定验证接口");
        return classroomService.validateClassroomAssignments();
    }

    @Operation(summary = "自动分配教室给未分配的班级", description = "自动为未分配教室的班级分配教室")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "分配成功")
    })
    @PostMapping("/auto-assign")
    public Map<String, Object> autoAssignClassrooms(
            @Parameter(description = "年级", required = false, example = "2023级")
            @RequestParam(required = false) String grade) {
        log.info("调用自动分配教室接口，年级: {}", grade);
        return classroomService.autoAssignClassrooms(grade);
    }

    @Operation(summary = "手动为班级分配教室", description = "手动为指定班级分配教室")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "分配成功"),
            @ApiResponse(responseCode = "400", description = "分配失败")
    })
    @PostMapping("/assign")
    public Map<String, Object> assignClassroom(
            @Parameter(description = "班级ID", required = true, example = "1")
            @RequestParam Long classId,
            @Parameter(description = "教室ID", required = true, example = "1")
            @RequestParam Long classroomId) {
        log.info("调用手动分配教室接口，班级: {}, 教室: {}", classId, classroomId);

        Map<String, Object> result = new java.util.HashMap<>();
        try {
            boolean success = classroomService.assignClassroomToClass(classId, classroomId);
            result.put("success", success);
            result.put("message", success ? "分配成功" : "分配失败");
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", e.getMessage());
        }

        return result;
    }

    @Operation(summary = "移除班级的教室分配", description = "移除指定班级的教室分配")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "移除成功"),
            @ApiResponse(responseCode = "400", description = "移除失败")
    })
    @PostMapping("/remove-assignment")
    public Map<String, Object> removeClassroomAssignment(
            @Parameter(description = "班级ID", required = true, example = "1")
            @RequestParam Long classId) {
        log.info("调用移除教室分配接口，班级: {}", classId);

        Map<String, Object> result = new java.util.HashMap<>();
        boolean success = classroomService.removeClassroomFromClass(classId);
        result.put("success", success);
        result.put("message", success ? "移除成功" : "移除失败");

        return result;
    }

    @Operation(summary = "批量分配教室（按年级）", description = "按年级批量分配教室")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "分配成功")
    })
    @PostMapping("/batch-assign")
    public Map<String, Object> batchAssignClassrooms(
            @Parameter(description = "年级", required = true, example = "2023级")
            @RequestParam String grade,
            @Parameter(description = "教室类型", required = true, example = "普通教室")
            @RequestParam String roomType) {
        log.info("调用批量分配教室接口，年级: {}, 教室类型: {}", grade, roomType);
        return classroomService.batchAssignClassroomsByGrade(grade, roomType);
    }

    @Operation(summary = "获取教室使用统计", description = "获取教室使用情况统计信息")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "查询成功")
    })
    @GetMapping("/usage-statistics")
    public Map<String, Object> getUsageStatistics() {
        log.info("调用教室使用统计接口");
        return classroomService.getClassroomUsageStatistics();
    }
}