package com.greenorange.promotion.controller.course;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.greenorange.promotion.annotation.RequiresPermission;
import com.greenorange.promotion.annotation.SysLog;
import com.greenorange.promotion.common.BaseResponse;
import com.greenorange.promotion.common.ErrorCode;
import com.greenorange.promotion.common.ResultUtils;
import com.greenorange.promotion.constant.UserConstant;
import com.greenorange.promotion.exception.ThrowUtils;
import com.greenorange.promotion.model.dto.CommonBatchRequest;
import com.greenorange.promotion.model.dto.CommonRequest;
import com.greenorange.promotion.model.dto.CommonStringRequest;
import com.greenorange.promotion.model.dto.course.CourseAddRequest;
import com.greenorange.promotion.model.dto.course.CourseQueryRequest;
import com.greenorange.promotion.model.dto.course.CourseUpdateRequest;
import com.greenorange.promotion.model.entity.Course;
import com.greenorange.promotion.model.vo.course.CourseCardVO;
import com.greenorange.promotion.model.vo.course.CourseDetailVO;
import com.greenorange.promotion.model.vo.course.CourseVO;
import com.greenorange.promotion.service.common.CommonService;
import com.greenorange.promotion.service.course.CourseService;
import com.greenorange.promotion.service.wechat.WechatGetQrcodeService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * 课程 控制器
 */
@RestController
@RequestMapping("course")
@Slf4j
@Tag(name = "课程模块")
@Transactional
public class CourseController {

    @Resource
    private CourseService courseService;

    @Resource
    private CommonService commonService;


    /**
     * 小程序端用户查看热门课程列表
     * @return 课程信息列表
     */
    @PostMapping("query/hot")
    @Operation(summary = "小程序端用户查看热门课程列表", description = "参数：无，权限：管理员，方法名：miniQueryHotCourseList")
    @RequiresPermission(mustRole = UserConstant.DEFAULT_ROLE)
//    @SysLog(title = "课程管理", content = "小程序端用户查看热门课程列表")
    public BaseResponse<List<CourseCardVO>> miniQueryHotCourseList() {
        List<Course> courseList = commonService.findByFieldEqTargetField(Course::getIsShelves, true, courseService);
        // 降序排序并取前四个元素
        courseList = courseList.stream()
                .sorted((course1, course2) -> Integer.compare(course2.getOrderCount(), course1.getOrderCount())) // 降序排序
                .limit(6)  // 取前六个元素
                .collect(Collectors.toList());
        List<CourseCardVO> courseCardVOS = commonService.convertList(courseList, CourseCardVO.class);
        return ResultUtils.success(courseCardVOS);
    }


    /**
     * 小程序端用户根据类别查看课程列表
     * @param commonStringRequest 课程类别
     * @return 课程信息列表
     */
    @PostMapping("query/type")
    @Operation(summary = "小程序端用户根据类别查看课程列表", description = "参数：课程添加请求体，权限：管理员，方法名：miniQueryCourseByType")
    @RequiresPermission(mustRole = UserConstant.DEFAULT_ROLE)
//    @SysLog(title = "课程管理", content = "小程序端用户根据类别查看课程列表")
    public BaseResponse<List<CourseCardVO>> miniQueryCourseByType(@Valid @RequestBody CommonStringRequest commonStringRequest) {
        String courseType = commonStringRequest.getTemplateString();
        Map<SFunction<Course, ?>, Object> fieldConditions = Map.of(Course::getType, courseType, Course::getIsShelves, true);
        List<Course> courseList = commonService.findByFieldEqTargetFields(fieldConditions, courseService);
        List<CourseCardVO> courseCardVOS = commonService.convertList(courseList, CourseCardVO.class);
        return ResultUtils.success(courseCardVOS);
    }


    /**
     * 小程序端用户根据名称搜索课程
     * @param commonStringRequest 搜索关键词
     * @return 课程信息列表
     */
    @PostMapping("query/keyword")
    @Operation(summary = "小程序端用户根据类别查看课程列表", description = "参数：搜索关键词，权限：管理员，方法名：miniQueryCourseByKeyword")
    @RequiresPermission(mustRole = UserConstant.DEFAULT_ROLE)
//    @SysLog(title = "课程管理", content = "小程序端用户根据名称搜索课程")
    public BaseResponse<List<CourseCardVO>> miniQueryCourseByKeyword(@Valid @RequestBody CommonStringRequest commonStringRequest) {
        String keyword = commonStringRequest.getTemplateString();
        LambdaQueryWrapper<Course> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Course::getIsShelves, 1);
        lambdaQueryWrapper.like(Course::getName, keyword);
        List<Course> courseList = courseService.list(lambdaQueryWrapper);
        List<CourseCardVO> courseCardVOS = commonService.convertList(courseList, CourseCardVO.class);
        return ResultUtils.success(courseCardVOS);
    }


    /**
     * 小程序端用户根据id查询课程详情
     * @param commonRequest 课程id
     * @return 课程信息列表
     */
    @PostMapping("query/id")
    @Operation(summary = "小程序端用户根据id查询课程详情", description = "参数：课程id，权限：管理员，方法名：miniQueryCourseById")
//    @SysLog(title = "课程管理", content = "小程序端用户根据id查询课程详情")
    public BaseResponse<CourseDetailVO> miniQueryCourseById(@Valid @RequestBody CommonRequest commonRequest) {
        Long id = commonRequest.getId();
        Course course = courseService.getById(id);
        CourseDetailVO courseDetailVO = commonService.copyProperties(course, CourseDetailVO.class);
        return ResultUtils.success(courseDetailVO);
    }



    /**
     * 小程序端用户根据id查看课程基本信息
     * @param commonRequest 课程id
     * @return 课程基本信息
     */
    @PostMapping("detail/id")
    @Operation(summary = "小程序端用户根据id查看课程基本信息", description = "参数：课程id，权限：管理员，方法名：miniQueryCourseBaseInfo")
    @RequiresPermission(mustRole = UserConstant.DEFAULT_ROLE)
//    @SysLog(title = "课程管理", content = "小程序端用户根据id查看课程基本信息")
    public BaseResponse<CourseCardVO> miniQueryCourseBaseInfo(@Valid @RequestBody CommonRequest commonRequest) {
        Long id = commonRequest.getId();
        Course course = courseService.getById(id);
        CourseCardVO courseCardVO = commonService.copyProperties(course, CourseCardVO.class);
        return ResultUtils.success(courseCardVO);
    }









    /**
     * web端管理员添加课程
     * @param courseAddRequest 课程添加请求体
     * @return 是否添加成功
     */
    @PostMapping("add")
    @Operation(summary = "web端管理员添加课程", description = "参数：课程添加请求体，权限：管理员，方法名：addCourse")
    @RequiresPermission(mustRole = UserConstant.ADMIN_ROLE)
//    @SysLog(title = "课程管理", content = "web端管理员添加课程")
    public BaseResponse<Long> addCourse(@Valid @RequestBody CourseAddRequest courseAddRequest) {
        Course course = commonService.copyProperties(courseAddRequest, Course.class);
        courseService.save(course);
        return ResultUtils.success(course.getId());
    }

    /**
     * web端管理员根据id修改课程信息
     * @param courseUpdateRequest 课程更新请求体
     * @return 是否更新成功
     */
    @PostMapping("update")
    @Operation(summary = "web端管理员根据id修改课程信息", description = "参数：课程更新请求体，权限：管理员，方法名：updateCourse")
    @RequiresPermission(mustRole = UserConstant.ADMIN_ROLE)
//    @SysLog(title = "课程管理", content = "web端管理员根据id修改课程信息")
    public BaseResponse<Boolean> updateCourse(@Valid @RequestBody CourseUpdateRequest courseUpdateRequest) {
        Course course = commonService.copyProperties(courseUpdateRequest, Course.class);
        courseService.updateById(course);
        return ResultUtils.success(true);
    }

    /**
     * web端管理员根据id删除课程
     * @param commonRequest 课程删除请求体
     * @return 是否删除成功
     */
    @PostMapping("delete")
    @Operation(summary = "web端管理员根据id删除课程", description = "参数：课程删除请求体，权限：管理员，方法名：delCourse")
    @RequiresPermission(mustRole = UserConstant.ADMIN_ROLE)
//    @SysLog(title = "课程管理", content = "web端管理员根据id删除课程")
    public BaseResponse<Boolean> delCourse(@Valid @RequestBody CommonRequest commonRequest) {
        Long id = commonRequest.getId();
        courseService.removeById(id);
        return ResultUtils.success(true);
    }

    /**
     * web端管理员批量删除课程
     * @param commonBatchRequest 课程批量删除请求体
     * @return 是否删除成功
     */
    @PostMapping("delBatch")
    @Operation(summary = "web端管理员批量删除课程", description = "参数：课程批量删除请求体，权限：管理员，方法名：delBatchCourse")
    @RequiresPermission(mustRole = UserConstant.ADMIN_ROLE)
//    @SysLog(title = "课程管理", content = "web端管理员批量删除课程")
    public BaseResponse<Boolean> delBatchCourse(@Valid @RequestBody CommonBatchRequest commonBatchRequest) {
        List<Long> ids = commonBatchRequest.getIds();
        courseService.removeByIds(ids);
        return ResultUtils.success(true);
    }

    /**
     * web端管理员根据id查询课程
     * @param commonRequest 课程查询请求体
     * @return 课程信息
     */
    @PostMapping("queryById")
    @Operation(summary = "web端管理员根据id查询课程", description = "参数：课程查询请求体，权限：管理员，方法名：queryCourseById")
    @RequiresPermission(mustRole = UserConstant.ADMIN_ROLE)
//    @SysLog(title = "课程管理", content = "web端管理员根据id查询课程")
    public BaseResponse<CourseVO> queryCourseById(@Valid @RequestBody CommonRequest commonRequest) {
        Long id = commonRequest.getId();
        Course course = courseService.getById(id);
        CourseVO courseVO = commonService.copyProperties(course, CourseVO.class);
        return ResultUtils.success(courseVO);
    }


    /**
     * web端管理员上（下）架课程
     * @param commonRequest 课程id
     * @return 课程信息
     */
    @PostMapping("isShelves")
    @Operation(summary = "web端管理员上（下）架课程", description = "参数：课程查询请求体，权限：管理员，方法名：updateCourseShelvesStatus")
    @RequiresPermission(mustRole = UserConstant.ADMIN_ROLE)
//    @SysLog(title = "课程管理", content = "web端管理员上（下）架课程")
    public BaseResponse<Boolean> updateCourseShelvesStatus(@Valid @RequestBody CommonRequest commonRequest) {
        Long id = commonRequest.getId();
        Course course = courseService.getById(id);
        course.setIsShelves(!course.getIsShelves());
        courseService.updateById(course);
        return ResultUtils.success(true);
    }


    /**
     * Web端管理员分页查询课程
     * @param courseQueryRequest 课程查询请求体
     * @return 课程列表
     */
    @PostMapping("page")
    @Operation(summary = "Web端管理员分页查询课程", description = "参数：课程查询请求体，权限：管理员，方法名：listCourseByPage")
    @RequiresPermission(mustRole = UserConstant.ADMIN_ROLE)
//    @SysLog(title = "课程管理", content = "Web端管理员分页查询课程")
    public BaseResponse<Page<CourseVO>> listCourseByPage(@Valid @RequestBody CourseQueryRequest courseQueryRequest) {
        long current = courseQueryRequest.getCurrent();
        long pageSize = courseQueryRequest.getPageSize();
        QueryWrapper<Course> queryWrapper = courseService.getQueryWrapper(courseQueryRequest);
        Page<Course> page = courseService.page(new Page<>(current, pageSize), queryWrapper);
        List<Course> courseList = page.getRecords();
        List<CourseVO> courseVOList = commonService.convertList(courseList, CourseVO.class);
        Page<CourseVO> voPage = new Page<>(current, pageSize);
        voPage.setRecords(courseVOList);
        voPage.setPages(page.getPages());
        voPage.setTotal(page.getTotal());
        return ResultUtils.success(voPage);
    }
}