package com.qxgmat.controller.api;


import com.github.pagehelper.Page;
import com.nuliji.tools.*;
import com.qxgmat.data.constants.enums.ExperienceDayRange;
import com.qxgmat.data.constants.enums.ExperienceScoreRange;
import com.qxgmat.data.constants.enums.module.CourseModule;
import com.qxgmat.data.constants.enums.module.ProductType;
import com.qxgmat.data.constants.enums.status.DirectionStatus;
import com.qxgmat.data.constants.enums.user.DataType;
import com.qxgmat.data.dao.entity.*;
import com.qxgmat.data.relation.entity.UserPreviewPaperRelation;
import com.qxgmat.dto.extend.CourseExtendDto;
import com.qxgmat.dto.extend.UserPreviewPaperExtendDto;
import com.qxgmat.dto.response.*;
import com.qxgmat.help.ShiroHelp;
import com.qxgmat.service.extend.PreviewService;
import com.qxgmat.service.inline.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpSession;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/api/course")
@Api(tags = "课程", description = "课程接口")
public class CourseController {

    @Autowired
    private ShiroHelp shiroHelp;

    @Autowired
    private CourseService courseService;

    @Autowired
    private CourseDataService courseDataService;

    @Autowired
    private CoursePackageService coursePackageService;

    @Autowired
    private CourseTeacherService courseTeacherService;

    @Autowired
    private CourseExperienceService courseExperienceService;

    @Autowired
    private PreviewService previewService;

    @Autowired
    private PreviewPaperService previewPaperService;

    @Autowired
    private QuestionNoService questionNoService;

    @Autowired
    private QuestionService questionService;

    @Autowired
    private UserCourseService userCourseService;

    @Autowired
    private UserOrderRecordService userOrderRecordService;


    @RequestMapping(value = "/vs", method = RequestMethod.GET)
    @ApiOperation(value = "获取1v1课程信息", notes = "获取1v1课程信息", httpMethod = "GET")
    public Response<List<CourseListDto>> vs()  {
        List<Course> p = courseService.all(CourseModule.VS);
        List<CourseListDto> pr = Transform.convert(p, CourseListDto.class);
        return ResponseHelp.success(pr);
    }

    @RequestMapping(value = "/video/list", method = RequestMethod.GET)
    @ApiOperation(value = "在线课程列表", httpMethod = "GET")
    public Response<PageMessage<CourseListDto>> listVideo(
            @RequestParam(required = false, defaultValue = "1") int page,
            @RequestParam(required = false, defaultValue = "100") int size,
            @RequestParam(required = false) Integer structId,
            @RequestParam(required = false, defaultValue = "id") String order,
            @RequestParam(required = false, defaultValue = "desc") String direction,
            HttpSession session) {

        Page<Course> p = courseService.list(page, size, CourseModule.VIDEO, structId, order, DirectionStatus.ValueOf(direction));

        List<CourseListDto> pr = Transform.convert(p, CourseListDto.class);
        return ResponseHelp.success(pr, page, size, p.getTotal());
    }

    @RequestMapping(value = "/detail", method = RequestMethod.GET)
    @ApiOperation(value = "课程详情", httpMethod = "GET")
    public Response<Course> detail(
            @RequestParam(required = true) Integer courseId
    ) {
        User user = (User) shiroHelp.getLoginUser();

        Course course = courseService.get(courseId);

        return ResponseHelp.success(course);
    }

    @RequestMapping(value = "/package/list", method = RequestMethod.GET)
    @ApiOperation(value = "套餐列表", httpMethod = "GET")
    public Response<PageMessage<CoursePackageListDto>> listPackage(
            @RequestParam(required = false, defaultValue = "1") int page,
            @RequestParam(required = false, defaultValue = "100") int size,
            @RequestParam(required = false) Integer structId,
            @RequestParam(required = false, defaultValue = "id") String order,
            @RequestParam(required = false, defaultValue = "desc") String direction,
            HttpSession session) {

        Page<CoursePackage> p = coursePackageService.list(page, size, structId, order, DirectionStatus.ValueOf(direction));

        List<CoursePackageListDto> pr = Transform.convert(p, CoursePackageListDto.class);

        Map<Integer, Integer[]> courseIdsMap = new HashMap<>();
        for(CoursePackage cp : p){
            courseIdsMap.put(cp.getId(), cp.getCourseIds());
        }
        Map courseMap = courseService.groupByMap(courseIdsMap);
        Transform.combine(pr, courseMap, CoursePackageListDto.class, "id", "courses", CourseExtendDto.class);

        return ResponseHelp.success(pr, page, size, p.getTotal());
    }

    @RequestMapping(value = "/package/detail", method = RequestMethod.GET)
    @ApiOperation(value = "套餐详情", httpMethod = "GET")
    public Response<CoursePackageDetailDto> detailPackage(
            @RequestParam(required = true) Integer packageId
    ) {
        User user = (User) shiroHelp.getLoginUser();

        CoursePackage coursePackage = coursePackageService.get(packageId);
        CoursePackageDetailDto dto = Transform.convert(coursePackage, CoursePackageDetailDto.class);

        List<Course> courseList = courseService.select(coursePackage.getCourseIds());

        dto.setCourses(Transform.convert(courseList, CourseExtendDto.class));

        return ResponseHelp.success(dto);
    }

    @RequestMapping(value = "/data/list", method = RequestMethod.GET)
    @ApiOperation(value = "资料列表", httpMethod = "GET")
    public Response<PageMessage<CourseDataListDto>> listData(
            @RequestParam(required = false, defaultValue = "1") int page,
            @RequestParam(required = false, defaultValue = "100") int size,
            @RequestParam(required = false) Integer structId,
            @RequestParam(required = false) String dataType,
            @RequestParam(required = false) Boolean isNovice,
            @RequestParam(required = false) Boolean isOriginal,
            @RequestParam(required = false, defaultValue = "id") String order,
            @RequestParam(required = false, defaultValue = "desc") String direction,
            HttpSession session) {

        Page<CourseData> p = courseDataService.list(page, size, structId, DataType.ValueOf(dataType), isNovice, isOriginal, order, DirectionStatus.ValueOf(direction));
        List<CourseDataListDto> pr = Transform.convert(p, CourseDataListDto.class);

        return ResponseHelp.success(pr, page, size, p.getTotal());
    }

    @RequestMapping(value = "/data/detail", method = RequestMethod.GET)
    @ApiOperation(value = "资料详情", httpMethod = "GET")
    public Response<CourseData> detailData(
            @RequestParam(required = true) Integer dataId
    ) {
        User user = (User) shiroHelp.getLoginUser();

        CourseData courseData = courseDataService.get(dataId);

        return ResponseHelp.success(courseData);
    }

    @RequestMapping(value = "/teacher/list", method = RequestMethod.GET)
    @ApiOperation(value = "资料列表", httpMethod = "GET")
    public Response<List<CourseTeacher>> listTeacher(
            @RequestParam(required = false) Integer courseId,
            HttpSession session) {

        List<CourseTeacher> p = courseTeacherService.allByCourse(courseId);

        return ResponseHelp.success(p);
    }

    @RequestMapping(value = "/experience/list", method = RequestMethod.GET)
    @ApiOperation(value = "心经列表", httpMethod = "GET")
    public Response<PageMessage<CourseExperience>> listExperience(
            @RequestParam(required = false, defaultValue = "1") int page,
            @RequestParam(required = false, defaultValue = "100") int size,
            @RequestParam(required = false) String prepareStatus,
            @RequestParam(required = false) String experienceDay,
            @RequestParam(required = false) String experienceScore,
            @RequestParam(required = false) String experiencePercent,
            @RequestParam(required = false, defaultValue = "id") String order,
            @RequestParam(required = false, defaultValue = "desc") String direction,
            HttpSession session) {

        Page<CourseExperience> p = courseExperienceService.list(page, size, prepareStatus, ExperienceScoreRange.ValueOf(experienceScore), ExperienceDayRange.ValueOf(experienceDay), experiencePercent, order, DirectionStatus.ValueOf(direction));

        return ResponseHelp.success(p, page, size, p.getTotal());
    }

    @RequestMapping(value = "/progress", method = RequestMethod.GET)
    @ApiOperation(value = "获取课程进度", notes = "获取所有课程及状态进度", httpMethod = "GET")
    public Response<List<UserCourseDetailDto>> progress()  {
        User user = (User) shiroHelp.getLoginUser();
        List<UserCourse> userCourseList = userOrderRecordService.getByUser(user.getId());
        List<UserCourseDetailDto> dtos = Transform.convert(userCourseList, UserCourseDetailDto.class);

        // 获取每个科目的最后2次作业
        Map<Object, Collection<UserPreviewPaperRelation>> previewMap = previewService.groupByCategory(user.getId(), 3);
        Transform.combine(dtos, previewMap, UserCourseDetailDto.class, "courseId", "previews", UserPreviewPaperExtendDto.class);

        // 获取课程状态:已购买未开通
        List<UserOrderRecord> records = userOrderRecordService.listUnUse(user.getId(), ProductType.COURSE);
        Collection ids = Transform.getIds(userCourseList, UserCourse.class, "courseId");
        for(UserOrderRecord record : records){
            Integer courseId = record.getProductId();
            if (!ids.contains(courseId)){
                UserCourseDetailDto dto = new UserCourseDetailDto();
                dto.setCourseId(courseId);
                dto.setPayed(true);
                dtos.add(dto);
            }
        }
        // todo 区分完成状态

        return ResponseHelp.success(dtos);
    }

    @RequestMapping(value = "/preview/list", method = RequestMethod.GET)
    @ApiOperation(value = "获取预习作业列表", notes = "获取预习作业列表", httpMethod = "GET")
    public Response<PageMessage<UserPreviewPaperExtendDto>> listPreview(
            @RequestParam(required = false, defaultValue = "1") int page,
            @RequestParam(required = false, defaultValue = "100") int size,
            @RequestParam(required = false) Number category,
            @RequestParam(required = false) String endTime,
            @RequestParam(required = false) Boolean finish
    )  {
        User user = (User) shiroHelp.getLoginUser();
        PageResult<UserPreviewPaperRelation> p = previewService.list(page, size, category, user.getId(), endTime, finish);

        List<UserPreviewPaperExtendDto> pr = Transform.convert(p, UserPreviewPaperExtendDto.class);

        // 获取试卷统计信息
        Map map = Transform.getMap(p, UserPreviewPaperRelation.class, "id", "paper");
        Map<Integer, Integer[]> questionNoIdsMap = new HashMap<>();
        for(Object value : map.keySet()){
            Integer key = (Integer) value;
            PreviewPaper preview = (PreviewPaper) map.get(key);
            questionNoIdsMap.put(key, preview.getQuestionNoIds());
        }
        Map statMap = questionNoService.statPaperMap(questionNoIdsMap);
        Transform.combine(pr, statMap, UserPreviewPaperExtendDto.class, "id", "stat");

        return ResponseHelp.success(pr, page, size, p.getTotal());
    }

    @RequestMapping(value = "/preview/paper", method = RequestMethod.GET)
    @ApiOperation(value = "获取预习作业", notes = "获取预习作业", httpMethod = "GET")
    public Response<PaperBaseDto> detailPreview(
            @RequestParam(required = true, name="id") Integer paperId
    )  {
        User user = (User) shiroHelp.getLoginUser();
        PreviewPaper preview = previewPaperService.get(paperId);
        PaperBaseDto paperDto = Transform.convert(preview, PaperBaseDto.class);

        return ResponseHelp.success(paperDto);
    }
}