package com.yizhi.application.course.controller;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.plugins.Page;
import com.yizhi.application.Certificate.CertificateUtills.PushCertificateUtil;

import com.yizhi.application.tools.PageTools;
import com.yizhi.core.application.context.ContextHolder;
import com.yizhi.core.application.context.RequestContext;
import com.yizhi.course.application.feign.*;
import com.yizhi.course.application.vo.*;
import com.yizhi.course.application.vo.domain.RecordeEntityVo;
import com.yizhi.site.application.enums.FunctionTypeCode;
import com.yizhi.site.application.feign.api.FunctionDisplayConfigApiClients;
import com.yizhi.site.application.vo.domain.FunctionDisplayConfigVo;
import com.yizhi.system.application.system.remote.SiteClient;
import com.yizhi.system.application.vo.SiteVO;
import com.yizhi.util.application.domain.Response;
import com.yizhi.util.application.enums.i18n.Constants;
import com.yizhi.util.application.sensitive.annotation.SensitiveWords;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author: XieHaijun
 * @Description:
 * @Date: Created in 15:01 2018/12/19
 * @Modified By
 */
@Api(tags = "课程pc端接口")
@RestController
@RequestMapping("/pc/course/")
public class CoursePcController {

    @Autowired
    private CoursePcClient coursePcClient;

    @Autowired
    RecordeClient recordeClient;

    @Autowired
    CommClient commClient;

    @Autowired
    CourseClient courseClient;

    @Autowired
    CourseStudyClient courseStudyClient;

    @Autowired
    FunctionDisplayConfigApiClients configApiClients;

    @Autowired
    private PushCertificateUtil pushCertificateUtil;

    @Autowired
    private SiteClient siteClient;

    private static final Logger logger = LoggerFactory.getLogger(CoursePcController.class);

    @GetMapping("/status/init")
    public Response<Boolean> studeyStatusInit(@RequestParam(value = "siteId",required = false) Long siteId){
        coursePcClient.studeyStatusInit(siteId);
        return Response.ok(Boolean.TRUE);
    }

    @GetMapping("/point/init")
    public Response<Boolean> coursePointInit(@RequestParam(value = "siteId",required = false) Long siteId){
        courseStudyClient.coursePointInit(siteId);
        return Response.ok(Boolean.TRUE);
    }

    @ApiOperation(value = "课程列表", response = HomePageCoursePageVo.class)
    @GetMapping("/list")
    public Response<HomePageCoursePageVo> listCourseInfo(
            @ApiParam(name = "classifyId", value = "营销分类Id，不传查询全部课程", required = false)
            @RequestParam(value="classifyId",required = false) Long classifyId,
            @RequestParam(value = "pageNo",required = false ,defaultValue = "1") Integer pageNo,
            @RequestParam(value = "pageSize",required = false,defaultValue = "20") Integer pageSize,
            @ApiParam(name = "isQueryChildren", value = "是否查询子分类课程，不传和传true表示查询该分类字节的课程，false表示只查询当前分类的课程")
            @RequestParam(value = "isQueryChildren",required = false) Boolean isQueryChildren ){
        Page<HomePageCoursePageVo> data = coursePcClient.listCourseInfo(classifyId,pageNo,pageSize,isQueryChildren);
        // 添加课程是否显示学时
        List<HomePageCoursePageVo> inData = data.getRecords();
        if(CollectionUtils.isNotEmpty(inData)){
            List<FunctionDisplayConfigVo> dataFunction = configApiClients.getAllBySiteId();
            boolean courseDurationShow = false;
            if(CollectionUtils.isNotEmpty(dataFunction)){
                for(FunctionDisplayConfigVo item : dataFunction){
                    if(FunctionTypeCode.COURSE.getCode()
                            .equals(item.getFunctionType())){
                        courseDurationShow = item.getShowDisplay();
                    }
                }
            }
            // 增加课程学习状态显示
            List<Long> courseIds = inData.stream().map(objItem->objItem.getCourseId()).collect(Collectors.toList());
            logger.info("课程id列表={}", JSON.toJSONString(courseIds));
            List<CourseStudentStatusVO> statusList = coursePcClient.getStatusByIds(courseIds);
            Map<Long,Integer> statusMap = new HashMap<>();
            if(CollectionUtils.isNotEmpty(statusList)){
                statusMap = statusList.stream().collect(Collectors.toMap(key->key.getCourseId(),val->val.getStudentStatus()));
            }
            logger.info("课程statusMap={}", JSON.toJSONString(statusMap));
            for(HomePageCoursePageVo obj : inData){
                Long courseIdTmp = obj.getCourseId();
                // 增加课程学习状态显示
                obj.setStudentStatus(-1);
                if(statusMap.containsKey(courseIdTmp)){
                    Integer statu = statusMap.get(courseIdTmp);
                    logger.info("课程学习状态statu={}", JSON.toJSONString(statusMap));
                    if(Objects.nonNull(statu)){
                        obj.setStudentStatus(statu);
                    }
                }
                obj.setCourseDurationShow(courseDurationShow);
            }
        }
        return Response.ok(PageTools.split(data));
    }

    /**
     * 课程列表 版本2
     * 新增 好评优先排序；人气最高排序
     * @param hotDesc 人气最高倒叙 默认为空；
     * @param gradeDesc 好评优先排序  默认为空
     */
    @ApiOperation(value = "课程列表V2版本", response = HomePageCoursePageVoV2.class)
    @GetMapping("/v2/list")
    public Response<HomePageCoursePageVoV2> listCourseInfoV2(
            @ApiParam(name = "classifyId", value = "营销分类Id，不传查询全部课程", required = false)
            @RequestParam(value="classifyId",required = false) Long classifyId,
            @RequestParam(value = "pageNo",required = false ,defaultValue = "1") Integer pageNo,
            @RequestParam(value = "pageSize",required = false,defaultValue = "20") Integer pageSize,
            @ApiParam(name = "isQueryChildren", value = "是否查询子分类课程，不传和传true表示查询该分类字节的课程，false表示只查询当前分类的课程")
            @RequestParam(value = "isQueryChildren",required = false) Boolean isQueryChildren,
            @RequestParam(value = "hotDesc",required = false) Boolean hotDesc,
            @RequestParam(value = "gradeDesc",required = false) Boolean gradeDesc){
        Page<HomePageCoursePageVoV2> data = coursePcClient.listCourseInfoV2(classifyId,pageNo,pageSize,isQueryChildren,hotDesc,gradeDesc);
        // 添加课程是否显示学时
        List<HomePageCoursePageVoV2> inData = data.getRecords();
        if(CollectionUtils.isNotEmpty(inData)){
            List<FunctionDisplayConfigVo> dataFunction = configApiClients.getAllBySiteId();
            boolean courseDurationShow = false;
            if(CollectionUtils.isNotEmpty(dataFunction)){
                for(FunctionDisplayConfigVo item : dataFunction){
                    if(FunctionTypeCode.COURSE.getCode()
                            .equals(item.getFunctionType())){
                        courseDurationShow = item.getShowDisplay();
                    }
                }
            }
            // 增加课程学习状态显示
            List<Long> courseIds = inData.stream().map(objItem->objItem.getCourseId()).collect(Collectors.toList());
            logger.info("课程id列表={}", JSON.toJSONString(courseIds));
            List<CourseStudentStatusVO> statusList = coursePcClient.getStatusByIds(courseIds);
            Map<Long,Integer> statusMap = new HashMap<>();
            if(CollectionUtils.isNotEmpty(statusList)){
                statusMap = statusList.stream().collect(Collectors.toMap(key->key.getCourseId(),val->val.getStudentStatus()));
            }
            logger.info("课程statusMap={}", JSON.toJSONString(statusMap));
            for(HomePageCoursePageVoV2 obj : inData){
                Long courseIdTmp = obj.getCourseId();
                // 增加课程学习状态显示
                obj.setStudentStatus(-1);
                if(statusMap.containsKey(courseIdTmp)){
                    Integer statu = statusMap.get(courseIdTmp);
                    logger.info("课程学习状态statu={}", JSON.toJSONString(statusMap));
                    if(Objects.nonNull(statu)){
                        obj.setStudentStatus(statu);
                    }
                }
                obj.setCourseDurationShow(courseDurationShow);
            }
        }
        return Response.ok(PageTools.split(data));
    }

    @ApiOperation(value = "推荐课程列表", response = HomePageCoursePageVo.class)
    @GetMapping("/recommend")
    public Response<HomePageCoursePageVoV2> recommend(){
        return Response.ok(coursePcClient.recommendV2());
    }
    @ApiOperation(value = "课程分类列表", response = ClassifyVo.class)
    @GetMapping("/classify/list")
    public Response<ClassifyVo> listClassifyInfo(
            @ApiParam(name = "classifyId", value = "营销分类Id，不传查询全部一级分类", required = false)
            @RequestParam(value="classifyId",required = false) Long classifyId){
        List<ClassifyVo> data = coursePcClient.listClassifyInfo(classifyId);
        return Response.ok(data);
    }


    @ApiOperation(value = "记录最后一次学习章节记录")
    @PostMapping("/last/study/chapter")
    public Response recordeCompleted(@RequestBody RecordeEntityVo recorde) {
        Long chapterId = recorde.getChapterId();
        Long courseId = recorde.getCourseId();
        if(Objects.isNull(chapterId) || Objects.isNull(courseId)){
            return Response.fail("章节id或者课程id信息为空");
        }
        RequestContext requestContext = ContextHolder.get();
        recorde.setAccountId(requestContext.getAccountId());
        recorde.setCompanyId(requestContext.getCompanyId());
        recorde.setSiteId(requestContext.getSiteId());
        recorde.setOrgId(requestContext.getOrgId());
        recorde.setCreateTime(new Date());
        recorde.setDuration(0);
        recorde.setStartTime(new Date());
        recorde.setEndTime(new Date());
        recorde.setOvered(0);
        recorde.setValid(0);// 默认设置为未完成 todo 可以根据完成策略设置章节是否完成，并发放积分等
        recorde.setDataType(1);
        /*if (recordeClient.save(recorde)) {
            // 课程完成状态更新（发放积分等处理）
            LOG.info("课程章节完成是，提交的数据的={}", JSON.toJSONString(recorde));
            courseStudyClient.completionStatus(recorde);
            *//*getPoint(recorde.getChapterId(),requestContext.getAccountName(),
            		recorde.getAccountId(), recorde.getCompanyId(), recorde.getSiteId(), recorde.getOrgId());*//*
            toProject(recorde, requestContext.getSiteId());
            return Response.ok();
        }*/
        Boolean saveStatus = recordeClient.lastStudySave(recorde);
        return Response.ok();
    }


    @GetMapping("/comment/list")
    @SensitiveWords
    @ApiOperation(value = "课程查看评论", notes = "课程查看评论", response = ApiCommnentVo.class)
    public Response<ApiCommnentVo> commentList(
            @ApiParam(value = "课程主键id", required = true) @RequestParam("id") Long id,
            @ApiParam(name = "pageNo", value = "跳转页数,默认第一页", required = true) @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
            @ApiParam(name = "pageSize", value = "每页条数,默认20条", required = true) @RequestParam(name = "pageSize", defaultValue = "20") Integer pageSize
    ) {
        RequestContext requestContext = ContextHolder.get();
        Page<ApiCommnentVo> page = commClient.apiList(id, requestContext.getAccountId(), pageNo, pageSize);
        return Response.ok(PageTools.split(page));
    }

    /**
          * PC端课程详情
          * 包含  课程分类的回写 章节列表  课程默认的第一个素材内容和类型
          * 课程平均分  我的评分  是否收藏  课程学习时长
          *
          * @param courseId 课程ID
          * @return
          */
        @GetMapping("/pc/getCourseDetailsVo")
        @ApiOperation(value = "PC端课程详情")
        public Response<CourseDetailsVo> get(@ApiParam(value = "courseId")@RequestParam(value = "courseId") Long courseId) {
            RequestContext requestContext = ContextHolder.get();
            Long accountId = requestContext.getAccountId();

            CourseDetailsVo courseDetailsVo = courseClient.get(courseId, accountId);
            if (null == courseDetailsVo) {
                return Response.fail(Constants.COURSE_MSG_COURSE_DETAIL_QUERY_FAIL.getCode().toString(),
                        Constants.COURSE_MSG_COURSE_DETAIL_QUERY_FAIL.getName());
            }

            // 自动发放证书（异步调用）
            CourseVo courseVo = courseDetailsVo.getCourseVo();
            // 获取站点佩在信息
            SiteVO siteVO = siteClient.selectById(courseVo.getSiteId());
            if(siteVO != null){
                courseVo.setVideoRate(siteVO.getVideoRate());
            }
            if(Boolean.TRUE.equals(courseVo.getGrantCertificate()) && courseDetailsVo.getStudentStatus().intValue()==1){
                // Arrays.asList() 数组转list
                String[] certificateStr = courseVo.getCertificateStr().split(",");
                List<Long> cIds = new ArrayList<>();
                for(String str:certificateStr){
                    cIds.add(Long.valueOf(str));
                }
                pushCertificateUtil.pushCertificate(1,courseVo.getId(),courseVo.getName(),cIds);
            }
            return Response.ok(courseDetailsVo);
        }

    @GetMapping("/chapter/test/last")
    @ApiOperation(value = "PC端课程章节时测验时，获取用户最后一次做的测验试卷",response = TestCaseRecordVO.class )
    public Response<TestCaseRecordVO> chapterTestList(@ApiParam(value = "testId" ,name = "章节关联的测验ID")
                                                          @RequestParam(name="testId") Long testId){
        RequestContext requestContext = ContextHolder.get();
        Long accountId = requestContext.getAccountId();
        List<TestCaseRecordVO> data = coursePcClient.chapterTestList(testId,accountId);
        TestCaseRecordVO vo = null;
        if(CollectionUtils.isNotEmpty(data)){
            vo = data.get(0);

        }
        return Response.ok(vo);
    }

    @GetMapping("/my/study/count")
    @ApiOperation(value = "我的学习数据统计", response = MyCourseStudyCountVo.class )
    public Response<MyCourseStudyCountVo> getMyCourseStudyCount() {
        RequestContext requestContext = ContextHolder.get();
        MyCourseStudyCountVo vo = coursePcClient.getMyCourseStudyCount(requestContext.getSiteId(),
                requestContext.getAccountId());
        return Response.ok(vo);
    }

    @GetMapping("/my/study/list")
    @ApiOperation(value = "我的课程列表（通过type字段区分进行中和已完成课程）",response = MyCourseRecordeVo.class )
    public Response<MyCourseRecordeVo> getMyCourseStudyList(
            @ApiParam(name = "name", value = "搜索", required = false) @RequestParam(name = "name", required = false) String name,
            @ApiParam(name = "type", value = "课程是否完成 0 为进行中 1 为已完成 ,不传则查询所有", required = false) @RequestParam(name = "type", required = false) Integer type,
            @ApiParam(name = "pageNo") @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
            @ApiParam(name = "pageSize") @RequestParam(name = "pageSize", defaultValue = "20") Integer pageSize,
            @ApiParam(name = "startDate" ,value="开始时间", required=false) @RequestParam(name = "startDate", required=false) Long startDate,
            @ApiParam(name = "endDate",value="结束时间", required=false) @RequestParam(name = "endDate", required=false) Long endDate
    ) {
        RequestContext rt = ContextHolder.get();

        Page<MyCourseRecordeVo> data = coursePcClient.getMyCourseStudyList(
                rt.getSiteId(),rt.getAccountId(),name,type,pageNo,pageSize,startDate,endDate);

        return Response.ok(PageTools.split(data));
    }

}
