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.conditions.update.LambdaUpdateWrapper;
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.OrderStatusConstant;
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.courseOrder.CourseOrderAddRequest;
import com.greenorange.promotion.model.dto.courseOrder.CourseOrderQueryRequest;
import com.greenorange.promotion.model.dto.courseOrder.CourseOrderUpdateRequest;
import com.greenorange.promotion.model.entity.Course;
import com.greenorange.promotion.model.entity.CourseOrder;
import com.greenorange.promotion.model.vo.course.CourseCardVO;
import com.greenorange.promotion.model.vo.courseOrder.CourseOrderCardVO;
import com.greenorange.promotion.model.vo.courseOrder.CourseOrderVO;
import com.greenorange.promotion.service.common.CommonService;
import com.greenorange.promotion.service.course.CourseOrderService;
import com.greenorange.promotion.service.course.CourseService;
import com.greenorange.promotion.utils.OrderNumberUtils;
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.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.util.Collections;
import java.util.List;


/**
 * 课程订单 控制器
 */
@RestController
@RequestMapping("courseOrder")
@Slf4j
@Tag(name = "课程订单模块")
public class CourseOrderController {

    @Resource
    private CourseService courseService;

    @Resource
    private CourseOrderService courseOrderService;

    @Resource
    private CommonService commonService;

    /**
     * 小程序端用户生成课程订单
     * @param courseOrderAddRequest 课程id
     * @return 是否添加成功
     */
    @PostMapping("add")
    @Operation(summary = "小程序端用户生成课程订单", description = "参数：课程id，权限：管理员，方法名：addCourseOrder")
    @RequiresPermission(mustRole = UserConstant.DEFAULT_ROLE)
    @SysLog(title = "课程订单管理", content = "小程序端用户生成课程订单")
    public BaseResponse<Long> addCourseOrder(@Valid @RequestBody CourseOrderAddRequest courseOrderAddRequest, HttpServletRequest request) {
        Long userId = (Long) request.getAttribute("userId");
        Long courseId = courseOrderAddRequest.getCourseId();
        Course course = courseService.getById(courseId);
        ThrowUtils.throwIf(course == null, ErrorCode.OPERATION_ERROR, "该课程不存在");
        CourseOrder courseOrder = commonService.copyProperties(course, CourseOrder.class);
        courseOrder.setOrderNumber(OrderNumberUtils.generateOrderId());
        courseOrder.setTotalAmount(course.getDiscountPrice());
        courseOrder.setUserId(userId);
        courseOrderService.save(courseOrder);
        return ResultUtils.success(courseOrder.getId());
    }


    /**
     * 小程序端用户取消课程订单
     * @param courseOrderAddRequest 课程id
     * @return 是否添加成功
     */
    @PostMapping("cancel")
    @Operation(summary = "小程序端用户取消课程订单", description = "参数：订单id，权限：管理员，方法名：cancelCourseOrder")
    @RequiresPermission(mustRole = UserConstant.DEFAULT_ROLE)
    @SysLog(title = "课程订单管理", content = "小程序端用户取消课程订单")
    public BaseResponse<Long> cancelCourseOrder(@Valid @RequestBody CourseOrderAddRequest courseOrderAddRequest) {
        Long courseId = courseOrderAddRequest.getCourseId();
        CourseOrder courseOrder = courseOrderService.getById(courseId);
        ThrowUtils.throwIf(courseOrder == null || !courseOrder.getOrderStatus().equals(OrderStatusConstant.PENDING),
                ErrorCode.OPERATION_ERROR, "该订单不存在或者订单状态错误");
        LambdaUpdateWrapper<CourseOrder> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(CourseOrder::getId, courseId).set(CourseOrder::getOrderStatus, OrderStatusConstant.CLOSED);
        courseOrderService.update(updateWrapper);
        return ResultUtils.success(courseOrder.getId());
    }


    /**
     * 小程序端用户查询课程订单列表
     * @return 课程订单列表
     */
    @PostMapping("query/list")
    @Operation(summary = "小程序端用户查询课程订单列表", description = "参数：无，权限：管理员，方法名:queryCourseOrderList")
    @RequiresPermission(mustRole = UserConstant.DEFAULT_ROLE)
    @SysLog(title = "课程订单管理", content = "小程序端用户查询课程订单列表")
    public BaseResponse<List<CourseOrderCardVO>> queryCourseOrderList(HttpServletRequest request) {
        Long userId = (Long) request.getAttribute("userId");
        List<CourseOrder> courseOrderList = commonService.findByFieldEqTargetField(CourseOrder::getUserId, userId, courseOrderService);
        List<CourseOrderCardVO> courseOrderCardVOS = commonService.convertList(courseOrderList, CourseOrderCardVO.class);
        Collections.reverse(courseOrderCardVOS);
        return ResultUtils.success(courseOrderCardVOS);
    }


    /**
     * 小程序端用户根据id查询订单详情
     * @return 课程订单列表
     */
    @PostMapping("query/detail")
    @Operation(summary = "小程序端用户根据id查询订单详情", description = "参数：订单id，权限：管理员，方法名:queryCourseOrderDetailById")
    @RequiresPermission(mustRole = UserConstant.DEFAULT_ROLE)
    @SysLog(title = "课程订单管理", content = "小程序端用户根据id查询订单详情")
    public BaseResponse<CourseOrderVO> queryCourseOrderDetailById(@RequestBody CommonRequest commonRequest) {
        Long id = commonRequest.getId();
        CourseOrder courseOrder = courseOrderService.getById(id);
        CourseOrderVO courseOrderVO = commonService.copyProperties(courseOrder, CourseOrderVO.class);
        return ResultUtils.success(courseOrderVO);
    }






    /**
     * web端管理员根据id删除课程订单
     * @param commonRequest 课程订单删除请求体
     * @return 是否删除成功
     */
    @PostMapping("delete")
    @Operation(summary = "web端管理员根据id删除课程订单", description = "参数：课程订单删除请求体，权限：管理员，方法名：delCourseOrder")
    @RequiresPermission(mustRole = UserConstant.ADMIN_ROLE)
    @SysLog(title = "课程订单管理", content = "web端管理员根据id删除课程订单")
    public BaseResponse<Boolean> delCourseOrder(@Valid @RequestBody CommonRequest commonRequest) {
        Long id = commonRequest.getId();
        CourseOrder courseOrder = courseOrderService.getById(id);
        ThrowUtils.throwIf(courseOrder == null || !courseOrder.getOrderStatus().equals(OrderStatusConstant.CLOSED),
                ErrorCode.OPERATION_ERROR, "该课程订单不存在或订单状态错误");
        courseOrderService.removeById(id);
        return ResultUtils.success(true);
    }

    /**
     * web端管理员批量删除课程订单
     * @param commonBatchRequest 课程订单批量删除请求体
     * @return 是否删除成功
     */
    @PostMapping("delBatch")
    @Operation(summary = "web端管理员批量删除课程订单", description = "参数：课程订单批量删除请求体，权限：管理员，方法名：delBatchCourseOrder")
    @RequiresPermission(mustRole = UserConstant.ADMIN_ROLE)
    @SysLog(title = "课程订单管理", content = "web端管理员批量删除课程订单")
    public BaseResponse<Boolean> delBatchCourseOrder(@Valid @RequestBody CommonBatchRequest commonBatchRequest) {
        List<Long> ids = commonBatchRequest.getIds();
        LambdaQueryWrapper<CourseOrder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.ne(CourseOrder::getOrderStatus, OrderStatusConstant.CLOSED);
        long count = courseOrderService.count(queryWrapper);
        ThrowUtils.throwIf(count > 0, ErrorCode.OPERATION_ERROR, "存在未关闭的课程订单");
        courseOrderService.removeByIds(ids);
        return ResultUtils.success(true);
    }

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

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