package com.yizhi.application.exam.controller;

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

import com.yizhi.core.application.cache.RedisCache;
import com.yizhi.core.application.context.ContextHolder;
import com.yizhi.core.application.context.RequestContext;
import com.yizhi.exam.application.feign.ExamApiClient;
import com.yizhi.exam.application.feign.ExamAuthorizeClient;
import com.yizhi.exam.application.feign.ExamClient;
import com.yizhi.exam.application.vo.AnswerQuestionDetailVO;
import com.yizhi.exam.application.vo.ExamAnswerApiListVO;
import com.yizhi.exam.application.vo.MyExamParameterVO;
import com.yizhi.exam.application.vo.domain.Exam;
import com.yizhi.exam.application.vo.domain.TrExamAuthorize;
import com.yizhi.exam.application.vo.exam.*;
import com.yizhi.point.application.feign.PointRedisFeignClients;
import com.yizhi.site.application.feign.api.EventTrackApiClients;
import com.yizhi.util.application.constant.ReturnCode;
import com.yizhi.util.application.domain.Response;
import com.yizhi.util.application.enums.i18n.Constants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
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.RequestParam;
import org.springframework.web.bind.annotation.RestController;


import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;

import javax.servlet.http.HttpServletRequest;

@Api(tags = "学员端考试", description = "学员端接口")
@RestController
@RequestMapping("/api/exam")
public class ExamApiController {

    private static final Logger LOG = LoggerFactory.getLogger(ExamApiController.class);

    @Autowired
    ExamApiClient examApiClient;

    @Autowired
    ExamClient examClient;

    @Autowired
    ExamAuthorizeClient examAuthorizeClient;

    @Autowired
    private PointRedisFeignClients pointRedisClient;

    @Autowired
    private EventTrackApiClients eventTrackApiClients;
    @Autowired
    private RedisCache redisCache;

    /*@Autowired
    private RabbitTemplate rabbitTemplate;*/


    @ApiOperation(value = "查询考试结果（答卷列表）", notes = "查询考试结果（答卷列表）", response = ExamAnswerApiListVO.class)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "examId", value = "考试ID")
    })
    @PostMapping("/result")
    public Response<ExamAnswerApiListVO> getExamResultList(@RequestBody ExamAnswerApiListVO examAnswerApiListVo) {
        ExamAnswerApiListVO answerApiListVO;
        try {
            examAnswerApiListVo.setAccountId(ContextHolder.get().getAccountId());
            answerApiListVO = examApiClient.getExamResultList(examAnswerApiListVo);
            if (null != answerApiListVO) {
                return Response.ok(answerApiListVO);
            } else {
                return Response.fail(ReturnCode.RESOURCE_NOT_FOUND.getCode(), ReturnCode.RESOURCE_NOT_FOUND.getMsg());
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            LOG.error("", e);
            e.printStackTrace();
            return Response.fail(ReturnCode.BIZ_FAIL.getCode(), ReturnCode.BIZ_FAIL.getMsg());
        }


    }

    //2018.09.13添加扫码查看接口
    @ApiOperation(value = "考试详情扫码查看", notes = "考试详情扫码查看）", response = ExamDetailsVO.class)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "examId", value = "考试ID")
    })
    @PostMapping("/details/scan")
    public Response<ExamDetailsVO> examDetailScan(@RequestBody ExamAnswerApiListVO examAnswerApiListVo) {
        RequestContext res = ContextHolder.get();
        List<Long> relationIds = res.getRelationIds();
        Long siteId = res.getSiteId();
        Long accountId = res.getAccountId();
        Long examId = examAnswerApiListVo.getExamId();
        Exam exam = examClient.selectExamById(examId);
        boolean isPass = false;

        if (exam.getVisibleRange() != null && exam.getVisibleRange() == 1) {
            if ((exam.getSiteId() != null) && (siteId != null) && (exam.getSiteId().equals(siteId))) {
                isPass = true;
            }
        } else if (exam.getVisibleRange() != null && exam.getVisibleRange() == 2) {
            List<TrExamAuthorize> trExamAuthorizes = examAuthorizeClient.examCount(examId);
            List<Long> rangeIds = trExamAuthorizes.stream().map(TrExamAuthorize::getRelationId).collect(Collectors.toList());
            if (rangeIds.contains(accountId)) {
                isPass = true;
            } else {
                for (Long relationId : relationIds) {
                    if (rangeIds.contains(relationId)) {
                        isPass = true;
                        break;
                    }
                }
            }
        }
        if (isPass) {
            return examDetail(examAnswerApiListVo);
        } else {
            return Response.fail("4001", "无权访问");
        }
    }

    @ApiOperation(value = "考试详情", notes = "考试详情）", response = ExamDetailsVO.class)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "examId", value = "考试ID")
    })
    @PostMapping("/details")
    public Response<ExamDetailsVO> examDetail(@RequestBody ExamAnswerApiListVO examAnswerApiListVo) {
        try {
            examAnswerApiListVo.setAccountId(ContextHolder.get().getAccountId());
            ExamDetailsVO examDetailsVO = examApiClient.examDetail(examAnswerApiListVo);
            if (examDetailsVO != null) {
                return Response.ok(examDetailsVO);
            } else {
                return Response.fail(ReturnCode.RESOURCE_NOT_FOUND.getCode(), ReturnCode.RESOURCE_NOT_FOUND.getMsg());
            }
        } catch (Exception e) {
            LOG.error("", e);
            return Response.fail(ReturnCode.BIZ_FAIL.getCode(), ReturnCode.BIZ_FAIL.getMsg());
        }
    }

    @ApiOperation(value = "pc端学员查看答卷答题卡", notes = "pc端学员查看答卷答题卡）", response = PcCardVO.class)
    @GetMapping("/show/my/answerCard")
    public Response<PcCardVO> showMyExamAnswerCards(
            @ApiParam(name = "pageNo", value = "当前页") @RequestParam(name = "pageNo", required = false) Integer pageNo,
            @ApiParam(name = "pageSize", value = "每页的个数") @RequestParam(name = "pageSize", required = false) Integer pageSize,
            @ApiParam(name = "answerId", value = "答卷ID") @RequestParam("answerId") Long answerId) {
        try {
            if (pageNo == null) {
                pageNo = 1;
            }
            if (pageSize == null) {
                pageSize = Integer.MAX_VALUE;
            }
            PcCardVO pcCardVO = examApiClient.showMyPcExamAnswerCards(pageNo, pageSize, answerId);
            Map<String, Integer> pageMap = new HashMap<String, Integer>();
            if (pageNo == null) {
                pageNo = 1;
            }
            if (pageSize == null) {
                pageSize = Integer.MAX_VALUE;
            }
            pageMap.put("pageNo", pageNo);
            pageMap.put("pageSize", pageSize);
            if (null != pcCardVO) {
                pageMap.put("pageRecords", pcCardVO.getTotal());
            }
            return Response.ok(pcCardVO, pageMap);
        } catch (Exception e) {
            LOG.error("exam接口出现异常", e);
            return Response.fail(Constants.MSG_BIZ_FAIL);
        }
    }

    @ApiOperation(value = "学员查看答卷", notes = "学员查看答卷）", response = PcStudentExamAnswerVo.class)
    @GetMapping("/show/my/pcAnswer")
    Response<Object> showMyPcExamAnswer(
            @ApiParam(name = "type", value = "考试状态, 0未阅卷 1未通过 2通过") @RequestParam(name = "type", required = true) Integer type,
            @ApiParam(name = "answerId", value = "答卷ID") @RequestParam(value = "answerId", required = true) Long answerId) {
        RequestContext requestContext = ContextHolder.get();
        PcStudentExamAnswerVo studentExamAnswerVo = examApiClient.showMyPcExamAnswer(type, requestContext.getAccountId(), answerId);
        return Response.ok(studentExamAnswerVo);
    }

    /**
     * 学员考试答卷查看
     *
     * @param pageNo
     * @param pageSize
     * @param answerId
     * @return
     */
    @ApiOperation(value = "学员查看答卷", notes = "学员查看答卷）", response = StudentExamAnswerVo.class)
    @GetMapping("/show/my/answer")
    Response<Object> showMyExamAnswer(
            @ApiParam(name = "pageNo", value = "当前页") @RequestParam(name = "pageNo", required = false, defaultValue = "1") Integer pageNo,
            @ApiParam(name = "pageSize", value = "每页的个数") @RequestParam(name = "pageSize", required = false, defaultValue = "20") Integer pageSize,
            @ApiParam(name = "type", value = "考卷状态 0:待阅卷 1:不骑过 2:通过") @RequestParam(name = "type", required = true) Integer type,
            @ApiParam(name = "answerId", value = "答卷ID") @RequestParam("answerId") Long answerId) {
        RequestContext requestContext = ContextHolder.get();
        StudentExamAnswerVo studentExamAnswerVo = examApiClient.showMyExamAnswer(pageNo, pageSize, type, requestContext.getAccountId(), answerId);

        try {
            List<AnswerQuestionDetailVO> questionDetailVOS = studentExamAnswerVo.getQuestions();
            questionDetailVOS.forEach( answer -> {
                if (answer.getScore().equals("批阅中")) {
                    answer.setScore("readOver001");
                }
            });
        }catch (Exception e) {
            LOG.error("设置批阅中国际化失败",e);
        }

        Map<String, Integer> pageMap = new HashMap<String, Integer>();
        pageMap.put("pageNo", pageNo);
        pageMap.put("pageSize", pageSize);
        pageMap.put("pageTotal", studentExamAnswerVo.getPageTotal());
        return Response.ok(studentExamAnswerVo, pageMap);
    }

    /**
     * 学员考试结果页查看（考试结束后）
     *
     * @param
     * @param
     * @return
     */
    @ApiOperation(value = "学员考试结果页查看（考试结束后）", notes = "学员考试结果页查看（考试结束后））", response = ExamResultVO.class)
    @GetMapping("/show/my/answer/result")
    Response<ExamResultVO> showMyExamResult(@ApiParam(name = "examId", value = "考试ID") @RequestParam("examId") Long examId) {
        RequestContext requestContext = ContextHolder.get();
        ExamResultVO examResultVO = examApiClient.showMyExamResult(requestContext.getAccountId(), examId);
        return Response.ok(examResultVO);
    }

    @ApiOperation(value = "pc端查看考试历史记录", notes = "pc端查看考试历史记录", response = ExamResultVO.class)
    @GetMapping("/show/my/answer/pcResult")
    Response<ExamResultVO> showMyPcExamResult(@ApiParam(name = "examId", value = "考试ID") @RequestParam("examId") Long examId) {
        try {
            RequestContext requestContext = ContextHolder.get();
            ExamResultVO examResultVO = examApiClient.showMyExamResult(requestContext.getAccountId(), examId);
            return Response.ok(examResultVO);
        } catch (Exception e) {
            LOG.error("", e);
            return Response.fail(Constants.MSG_BIZ_FAIL);
        }
    }

    /**
     * 扫描二维码参加考试
     *
     * @param examAnswerApiListVo
     * @return
     */
    @ApiOperation(value = "扫描二维码考试", notes = "扫描二维码考试）", response = ExamDetailsVO.class)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "examId", value = "考试ID")
    })
    @PostMapping("/code/scan")
    public Response<ExamDetailsVO> scanCodeExam(HttpServletRequest request, @RequestBody ExamAnswerApiListVO examAnswerApiListVo) {
        RequestContext requestContext = ContextHolder.get();
        ExamDetailsVO examDetailsVO = null;
        if (requestContext == null) {
            examDetailsVO = new ExamDetailsVO();
            examDetailsVO.setScanCode(0);
            examDetailsVO.setScanMsg("扫码考试失败");
            Response.ok(examDetailsVO);
        }

        //获取权限信息
        List<Long> ids = requestContext.getRelationIds();
        MyExamParameterVO myExamParameterVO = new MyExamParameterVO();
        myExamParameterVO.setAccountId(requestContext.getAccountId());
        if (null != ids) {
            myExamParameterVO.setIds(ids);
        } else {
            ids = new ArrayList<Long>();
            ids.add(requestContext.getAccountId());
            myExamParameterVO.setIds(ids);
        }
        myExamParameterVO.setSiteId(requestContext.getSiteId());
        myExamParameterVO.setExamId(examAnswerApiListVo.getExamId());

        examDetailsVO = examApiClient.scanCodeExam(myExamParameterVO);

        // 添加培训测试埋点
        if(request.getHeader("Cookie")!=null&& Objects.equals(redisCache.get(request.getHeader("Cookie").replace("JSESSIONID=","")),"2")){
            eventTrackApiClients.addEvent("event_scan_exam",examAnswerApiListVo.getExamId());
        }
        return Response.ok(examDetailsVO);
    }
}
