package com.zd.exam.controller;

import com.zd.common.core.domain.R;
import com.zd.common.core.utils.FileConfigUtils;
import com.zd.common.core.utils.SecurityUtils;
import com.zd.common.core.utils.UrlFormatUtils;
import com.zd.common.core.web.controller.BaseController;
import com.zd.common.core.web.page.TableDataInfo;
import com.zd.exam.domain.*;
import com.zd.exam.domain.vo.ElCourseVo;
import com.zd.exam.enums.ScopeType;
import com.zd.exam.service.*;
import com.zd.exam.service.convert.BonusPointsService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.io.File;
import java.util.*;

/**
 *  智能学习一体机Controller
 *
 */
@RestController
@RequestMapping("/api")
@Api(tags = {"智能学习一体机"})
public class ElAIOController extends BaseController {
    @Autowired
    private IElCategoryService elCategoryService;
    @Autowired
    private IElCourseService elCourseService;
    @Autowired
    private ElExamService elExamService;
    @Autowired
    private IElPaperService elPaperService;
    @Autowired
    private IElPaperQuService elPaperQuService;
    @Autowired
    private IElExamClassifyService elExamClassifyService;
    @Autowired
    private IElUserCertService userCertService;
    @Autowired
    private IElPractiseService elPractiseService;
    @Autowired
    private IElPractiseQuService practiseQuService;
    @Autowired
    private IElChapterLearnRecordService chapterLearnRecordService;
    @Autowired
    private FileConfigUtils fileConfigUtils;
    @Autowired
    private BonusPointsService bonusPointsService;

    /**-------------------------------安全学习------------------------------------*/
    /**
     * 获取学习分类树状结构
     * id 默认 0 查全部
     */
    @ApiOperation(value = "获取学习分类详细信息")
    @GetMapping(value = "/category/treeList/{id}")
    public R<List<ElCategory>> categoryTreeList(@PathVariable("id") Long id) {
        if(id == null){
            return R.fail("ID 不能为空！");
        }

        ElCategory elCategory = new ElCategory();
        elCategory.setType(2);
        elCategory.setParentId(id);

        return R.ok(elCategoryService.treeList(elCategory));
    }

    /**
     * 查询学习资源列表
     */
    @GetMapping("/course/list")
    @ApiOperation(value = "查询学习资源列表")
    public TableDataInfo<ElCourse> courseList(ElCourse elCourse, HttpServletRequest request) {
        elCourse.setStatus(1);
        startPage();
        List<ElCourse> list = elCourseService.selectElCourseListByUser(elCourse);

        String baseUrl = request.getServerName() ;

        String url;
        for(ElCourse course:list){
            if(baseUrl.contains("192.168")){
                url = fileConfigUtils.getLocalUrl()+ "/"+course.getImg();
            }else {
                url = fileConfigUtils.getRemoteUrl()+ "/"+course.getImg();
            }
            url=UrlFormatUtils.getHttpsORHttpUrl(url);
            course.setImg(url);
        }
        return getDataTable(list);
    }

    /**
     * 个人端获取学习资源详细信息
     */
    @ApiOperation(value = "个人端获取学习资源详细信息")
    @GetMapping(value = "/course/{id}")
    public R<ElCourse> getCourseInfo(@PathVariable("id") Long id, HttpServletRequest request) {
        ElCourse elCourse=elCourseService.selectUserCourseById(id,request);
        String baseUrl = request.getServerName() ;
        String img;
        if(baseUrl.contains("192.168")){
            img=fileConfigUtils.getLocalUrl()+"/"+elCourse.getImg();
        }else {
            img=fileConfigUtils.getRemoteUrl()+"/"+elCourse.getImg();
        }

        img= UrlFormatUtils.getHttpsORHttpUrl(img);
        elCourse.setImg(img);
        return R.ok(elCourse);
    }

    /**
     * 学习资源 开始学习接口
     */
    @ApiOperation(value = "学习资源 开始学习接口")
    @PostMapping(value = "/course/learn/start")
    public R learnStart(@Valid @RequestBody ElChapterLearnRecord learnRecord) {
        chapterLearnRecordService.learnStart(learnRecord);
        return R.ok();
    }

    /**
     * 学习资源 完成学习接口
     */
    @ApiOperation(value = "学习资源 完成学习接口")
    @PostMapping(value = "/course/learn/finish")
    public R<Map<String,Object>> learnFinish(@Valid @RequestBody ElChapterLearnRecord learnRecord) {

        return R.ok(chapterLearnRecordService.learnFinish(learnRecord));
    }

    /**
     * 个人学习记录接口
     */
    @ApiOperation(value = "个人学习记录接口")
    @PostMapping(value = "/course/learn/list")
    public TableDataInfo learnList(@RequestBody ElCourseVo courseVo) {
        courseVo.setJoinUserId(SecurityUtils.getUserId());
        startPage();
        List<ElCourseVo> list = chapterLearnRecordService.learnList(courseVo);
        return getDataTable(list);
    }

    /**-------------------------------安全考试------------------------------------*/
    /**
     * 安全考试 试用范围下拉框
     * "适用范围(1. 安全准入考试，2. 负面清单考试，3. 黑名单考试，4.模拟考试)")
     */
    @ApiOperation(value = "安全考试试用范围下拉框")
    @GetMapping(value = "/exam/scopeList")
    public R getExamScopeList() {
        List<Map<String, Object>> list = new ArrayList<>();
        Map<String, Object> map = new HashMap<>();
        map.put("id", null);
        map.put("name", "全部");
        list.add(map);
        map = new HashMap<>();
        map.put("id", ScopeType.SCOPE_1.getType());
        map.put("name", ScopeType.SCOPE_1.getDesc());
        list.add(map);
        map = new HashMap<>();
        map.put("id", ScopeType.SCOPE_2.getType());
        map.put("name", ScopeType.SCOPE_2.getDesc());
        list.add(map);
        map = new HashMap<>();
        map.put("id", ScopeType.SCOPE_3.getType());
        map.put("name", ScopeType.SCOPE_3.getDesc());
        list.add(map);
        map = new HashMap<>();
        map.put("id", ScopeType.SCOPE_4.getType());
        map.put("name", ScopeType.SCOPE_4.getDesc());
        list.add(map);

        return R.ok(list);
    }

    /**
     * 查询模拟列表
     */
    @ApiOperation(value = "查询模拟列表")
    @GetMapping(value = "/exam/onlineList")
    public TableDataInfo queryMyExamList(ElExam exam) {
        startPage();
        // 模拟考试列表
        exam.setScopeType(ScopeType.SCOPE_4.getType());
        List<ElExam> list = elExamService.queryMyExamList(exam);
        return getDataTable(list);
    }

    /**
     * 开始考试 校验是否需要人脸验证
     * @return
     */
    @ApiOperation(value = "开始考试 - 校验是否需要人脸验证")
    @GetMapping(value = "/exam/start/verify/{type}")
    public R<Map<String, Object>> examVerify(@ApiParam("type 考试适用范围") @PathVariable("type") Integer scopeType,
                                              @ApiParam("模拟考试ID，其他类型传-1") @RequestParam("examId") Long examId) {
        Map<String, Object> map = new HashMap<>();
        int preFaceVerify = 0, endFaceVerify = 0;
        if(Objects.equals(scopeType, ScopeType.SCOPE_4.getType())){
            if(examId == null || examId == -1){
                return R.fail("参数异常！");
            }
            ElExam exam = elExamService.queryById(examId);
            preFaceVerify = exam.getPreFaceVerify();
            endFaceVerify = exam.getEndFaceVerify();
        }else {
            Integer userStatus = bonusPointsService.getUserStatus(SecurityUtils.getUserId());
            if(userStatus == null){
                if(Objects.equals(scopeType, ScopeType.SCOPE_2.getType())){
                    return R.fail("您当前没有违规，无需参加" + ScopeType.SCOPE_2.getDesc());
                }else if(Objects.equals(scopeType, ScopeType.SCOPE_3.getType())){
                    return R.fail("您当前没有违规，无需参加" +  ScopeType.SCOPE_3.getDesc());
                }
            }else if(userStatus == 1 && Objects.equals(scopeType, ScopeType.SCOPE_3.getType())){
                return R.fail("不能参加" +  ScopeType.SCOPE_3.getDesc());
            }else if(userStatus == 2 && Objects.equals(scopeType, ScopeType.SCOPE_2.getType())){
                return R.fail("不能参加" +  ScopeType.SCOPE_2.getDesc());
            }

            ElExam exam = new ElExam();
            exam.setScopeType(scopeType);
            List<ElExam> list = elExamService.queryMyExamList(exam);
            // 根据权限只能查询一条数据
            if(CollectionUtils.isEmpty(list)){
                return R.fail("暂无对应的考试，请联系管理员！");
            }
            // 如果同一类型考试意外出现多条，暂取第一条处理
            examId = list.get(0).getId();
            preFaceVerify = list.get(0).getPreFaceVerify();
            endFaceVerify = list.get(0).getEndFaceVerify();
        }
        map.put("examId", examId);
        map.put("preFaceVerify", preFaceVerify);
        map.put("endFaceVerify", endFaceVerify);
        return R.ok(map);
    }

    /**
     * 开始考试 - 包括创建考试，返回考试信息内容
     */
    @ApiOperation(value = "开始考试 - 包括创建考试，返回考试信息内容")
    @GetMapping(value = "/exam/start/{type}")
    public R<ElPaper> createPaper(@ApiParam("type 考试适用范围") @PathVariable("type") Integer scopeType,
                         @ApiParam("模拟考试ID，其他类型传-1") @RequestParam("examId") Long examId) {
        if(Objects.equals(scopeType, ScopeType.SCOPE_4.getType())){
            if(examId == null || examId == -1){
                return R.fail("参数异常！");
            }
        }else {
            ElExam exam = new ElExam();
            exam.setScopeType(scopeType);
            List<ElExam> list = elExamService.queryMyExamList(exam);
            // 根据权限只能查询一条数据
            if(CollectionUtils.isEmpty(list)){
                return R.fail("暂无对应的考试，请联系管理员！");
            }
            // 如果同一类型考试意外出现多条，暂取第一条处理
            examId = list.get(0).getId();
        }

        // 需确认考试过程中人脸验证后端是否需要限制 - 暂定一体机进行流程控制

        Long paperId = elPaperService.createPaper(examId);
        return R.ok(elPaperService.selectElPaperById(paperId));
    }

    /**
     * 考试过程 查询当前考题的正确和错误数量
     */
    @ApiOperation(value = "考试过程 查询当前考题的正确和错误数量")
    @GetMapping(value = "/exam/paperStatistics/{id}")
    public R<Map<String, Object>> getPaperStatistics(@PathVariable("id") Long id) {
        return R.ok(elPaperService.getPaperStatistics(id));
    }

    /**
     * 答题过程根据 paperId 和 quId 查询问题和选项
     */
    @ApiOperation(value = "考试 查询问题和选项 - 一题一查")
    @PostMapping(value = "/exam/paperDetail")
    public R<ElPaperQu> queryQuDetail(@RequestBody ElPaperQu paperQu) {
        if (paperQu.getPaperId() == null || paperQu.getQuId() == null) {
            return R.fail("参数无效");
        }
        paperQu = elPaperQuService.queryQuDetail(paperQu);
        return R.ok(paperQu);
    }

    /**
     * 填充答案 下一题实时保存上题答案
     */
    @ApiOperation(value = "考试保存用户答案 - 一题一交")
    @PostMapping(value = "/exam/fillAnswer")
    public R fillAnswer(@RequestBody ElPaperQu paperQu) {
        if (paperQu.getPaperId() == null || paperQu.getQuId() == null) {
            return R.fail("参数异常！");
        }
        elPaperQuService.fillAnswer(paperQu);
        return R.ok();
    }

    /**
     * 交卷
     */
    @ApiOperation(value = "交卷- 完成考试")
    @PostMapping(value = "/exam/handPaper")
    public R<Map<String, Object>> handPaper(@RequestBody ElPaper elPaper,HttpServletRequest request) {

        // 需确认考试结束人脸验证后端是否需要限制-- 同考试开始- 暂定一体机进行流程控制
        return R.ok(elPaperService.handPaper(elPaper,request));
    }

    /**
     * 交卷查询考试结果
     */
    @ApiOperation(value = "查询考试结果")
    @PostMapping(value = "/exam/paperResult")
    public R<ElPaper> paperResult(@RequestBody ElPaper elPaper) {
        elPaper = elPaperService.paperResult(elPaper);
        return R.ok(elPaper);
    }

    /**-------------------------------成绩查询------------------------------------*/

    /**
     * 个人考试成绩列表查询
     */
    @ApiOperation(value = "个人考试成绩列表查询")
    @PostMapping("/paper/myList")
    public TableDataInfo myPaperList(@RequestBody ElPaper elPaper) {

        elPaper.setJoinUserId(SecurityUtils.getUserId());
        startPage();
        List<ElPaper> list = elPaperService.selectElPaperList(elPaper);
        return getDataTable(list);
    }

    /**
     * 个人考试成绩详情查询
     */
    @ApiOperation(value = "个人考试成绩详情查询")
    @GetMapping(value = "/paper/{id}")
    public R<ElPaper> getInfo(@PathVariable("id") Long id) {
        return R.ok(elPaperService.selectElPaperById(id));
    }

    /**-------------------------------模拟练习------------------------------------*/

    /**
     * 查询题目类型下拉框
     */
    @PostMapping("/classify/queryOption")
    @ApiOperation(value = "查询题目类型下拉框")
    public R<List<ElExamClassify>> queryClassifyOption(@RequestBody ElExamClassify elExamClassify) {
        List<ElExamClassify> list = elExamClassifyService.selectElExamClassifyList(elExamClassify);
        return R.ok(list);
    }

    /**
     * 选择题目类型，开始练习
     */
    @ApiOperation(value = "选择题目类型，开始练习")
    @GetMapping(value = "/practise/start/{ids}")
    public R<ElPractise> queryClassifyOption(@ApiParam("多个题目类型ID逗号分隔") @PathVariable("ids") String classifyIds) {
        Long practiseId = elPractiseService.createPractise(classifyIds);
        return R.ok(elPractiseService.selectElPractiseById(practiseId));
    }

    /**
     * 答题过程根据 paperId 和 quId 查询问题和选项
     */
    @ApiOperation(value = "练习 查询问题和选项 - 一题一查")
    @PostMapping(value = "/practise/paperDetail")
    public R<ElPractiseQu> queryPractiseQuDetail(@RequestBody ElPractiseQu practiseQu) {
        if (practiseQu.getPractiseId() == null || practiseQu.getQuId() == null) {
            return R.fail("参数无效");
        }
        practiseQu = practiseQuService.selectElPractiseQuDetail(practiseQu);
        return R.ok(practiseQu);
    }

    /**
     * 练习填充答案
     */
    @ApiOperation(value = "练习保存用户答案 - 一题一交")
    @PostMapping(value = "/practise/fillAnswer")
    public R fillPractiseAnswer(@RequestBody ElPractiseQu practiseQu) {
        if (practiseQu.getPractiseId() == null || practiseQu.getQuId() == null) {
            return R.fail("参数异常！");
        }
        elPractiseService.fillPractiseAnswer(practiseQu);
        return R.ok(practiseQu);
    }

    @ApiOperation(value = "选择题目类型，结束练习")
    @PostMapping(value = "/practise/handPractise")
    public R<Map<String, Object>> handPractise(@RequestBody ElPractise practise) {
        if(practise.getId() == null){
            return R.fail("ID不能为空！");
        }
        return R.ok(elPractiseService.handPractise(practise));
    }

    /**-------------------------------证书管理------------------------------------*/

    /**
     * 查询我的证书列表
     */
    @PostMapping("/queryMyCert")
    @ApiOperation(value = "查询我的证书列表")
    public TableDataInfo queryMyCert(@RequestBody ElUserCert userCert, HttpServletRequest request) {
        userCert.setJoinUserId(SecurityUtils.getUserId());
        startPage();
        List<ElUserCert> userCerts = userCertService.queryMyCert(userCert);
        String baseUrl = request.getServerName() ;
        String url;

        for(ElUserCert elUserCert: userCerts){
            if(baseUrl.contains("192.168")){
                url=fileConfigUtils.getLocalUrl()+ File.separator+elUserCert.getCertUrl();
            }else {
                url=fileConfigUtils.getRemoteUrl()+ File.separator+elUserCert.getCertUrl();
            }

            url= UrlFormatUtils.getHttpsORHttpUrl(url);
            elUserCert.setCertUrl(url);
        }
        return getDataTable(userCerts);
    }

    /**-------------------------------课程考核------------------------------------*/

    /**
     * 开始考核 -- 章节ID
     */
    @PostMapping("/assess/start/{id}")
    @ApiOperation(value = "开始考核")
    public R<ElPaper> startAssess(@PathVariable ("id") Long courseChapterId) {

        return R.ok(elPaperService.startAssess(courseChapterId));
    }

    /**
     * 考核提交返回结果 -- 考核ID(试卷ID)
     */
    @PostMapping("/assess/finish/{id}")
    @ApiOperation(value = "考核结果")
    public R<Map<String, Object>> finishAssess(@PathVariable ("id") Long paperId) {

        return R.ok(elPaperService.finishAssess(paperId));
    }

    /**
     * 考核列表 -- 章节ID
     */
    @PostMapping("/assess/list/{id}")
    @ApiOperation(value = "考核列表")
    public TableDataInfo assessList(@PathVariable ("id") Long courseChapterId) {
        startPage();
        return getDataTable(elPaperService.assessList(courseChapterId));
    }

    /**
     * 考核详情 -- 试卷ID
     */
    @PostMapping("/assess/detail/{id}")
    @ApiOperation(value = "考核详情")
    public R<ElPaper> assessDetail(@PathVariable ("id") Long paperId) {
        return R.ok(elPaperService.assessDetail(paperId));
    }

}
