package com.qmth.jkserver.controller.api;

import cn.hutool.http.HttpStatus;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.qmth.jkserver.constant.SystemConstant;
import com.qmth.jkserver.controller.system.BaseSystemController;
import com.qmth.jkserver.core.annotation.TokenValidate;
import com.qmth.jkserver.core.exception.JkServerException;
import com.qmth.jkserver.enums.TokenPolicy;
import com.qmth.jkserver.model.ExamStudent;
import com.qmth.jkserver.model.ExamThirdOrg;
import com.qmth.jkserver.model.SyncData;
import com.qmth.jkserver.service.ExamStudentService;
import com.qmth.jkserver.service.ExamThirdOrgService;
import com.qmth.jkserver.service.SyncDataService;
import com.qmth.jkserver.signature.SignatureInfo;
import com.qmth.jkserver.signature.SignatureType;
import com.qmth.jkserver.util.JacksonUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Lazy;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.net.URLDecoder;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * @Description: 机考开放接口
 * @Param:
 * @return:
 * @Author: wangliang
 * @Date: 2021/10/20
 */
@Api(tags = "开放接口管理Controller")
@RestController
@RequestMapping("/" + SystemConstant.API_OPEN)
public class OpenController extends BaseSystemController {
    private static final Logger log = LoggerFactory.getLogger(OpenController.class);

    @Resource
    @Lazy
    ExamThirdOrgService examThirdOrgService;

    @Resource
    @Lazy
    ExamStudentService examStudentService;

    @Resource
    SyncDataService syncDataService;

    protected static final String uri = "/api/open/hm/registration/sync";

    @ApiOperation(value = "检录系统同步接口")
    @RequestMapping(value = "/hm/registration/sync", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "检录系统同步信息", response = Object.class)})
    @TokenValidate(policy = TokenPolicy.IGNORE)
    @Transactional
    public void registrationSync(@RequestBody String result, HttpServletRequest request, HttpServletResponse response) throws IOException {
        String token = request.getHeader("authorization-token");
        Optional.ofNullable(token).orElseThrow(() -> new JkServerException("authorization-token不能为空"));
        String requestHeaderTime = request.getHeader(SystemConstant.HEADER_TIME);
        Optional.ofNullable(requestHeaderTime).orElseThrow(() -> new JkServerException("time不能为空"));
        long time = SignatureInfo.validateTime(requestHeaderTime);
        SignatureInfo signatureInfo = SignatureInfo.parse(SystemConstant.METHOD, request.getServletPath(), time, token);
        Optional.ofNullable(signatureInfo).orElseThrow(() -> new JkServerException("密钥验证失败：signature decode error"));
        if (SignatureType.SECRET != signatureInfo.getType()) {
            log.warn("Authorization faile: signature type is not Secret");
            throw new JkServerException("密钥验证失败：signature type is not Secret");
        }
        ExamThirdOrg examThirdOrg = examThirdOrgService.validByCode(SystemConstant.THIRD_ORG_CODE_HMJL);
        if (!Objects.equals(examThirdOrg.getAccessKey(), signatureInfo.getInvoker())) {
            log.warn("Authorization faile: signature access key invalid");
            throw new JkServerException("密钥验证失败：access key invalid");
        }
        if (!signatureInfo.validate(examThirdOrg.getAccessSecret())) {
            log.warn("Authorization faile: access secret invalid, access secret is " + examThirdOrg.getAccessSecret());
            throw new JkServerException("密钥验证失败：access secret invalid");
        }
        log.info("signatureInfo:{}", JacksonUtil.parseJson(signatureInfo));
        //解析内容
        if (Objects.nonNull(result)) {
            String json = URLDecoder.decode(result, SystemConstant.CHARSET_NAME);

            SyncData syncData = new SyncData(SystemConstant.THIRD_ORG_NAME_HMJL, SystemConstant.THIRD_ORG_CODE_HMJL, json);
//            syncDataDao.save(syncData);
            syncDataService.saveOrUpdate(syncData);

            JSONObject jsonObject = JSON.parseObject(json);

            // 考试识别吗
            String examCode = String.valueOf(jsonObject.get("examCode"));
            // 身份证号
            String idCard = String.valueOf(jsonObject.get("idCard"));
            // 准考证号
            String ticketNo = String.valueOf(jsonObject.get("ticketNo"));
            // 批次编号
            String batchId = String.valueOf(jsonObject.get("batchId"));
            // 场次编号
            String stageId = String.valueOf(jsonObject.get("stageId"));
            // 考点编号
            String placeCode = String.valueOf(jsonObject.get("placeCode"));
            // 考场编号
            String roomCode = String.valueOf(jsonObject.get("roomCode"));
            // 课程代码
            String courseCode = String.valueOf(jsonObject.get("courseCode"));
            // 课程名称
            String courseName = String.valueOf(jsonObject.get("courseName"));
            // 匹配度
            String percent = String.valueOf(jsonObject.get("percent"));
            // 是否检录通过
            Boolean registrationStatus = (Boolean) jsonObject.get("pass");
            if (SystemConstant.isOneNull(idCard, ticketNo, batchId, stageId, placeCode, roomCode, courseCode, courseName, percent, registrationStatus)) {
                throw new JkServerException("身份证号(idCard)、准考证号(ticketNo)、批次编号(batchId)、" +
                        "场次编号(stageId)、考点编号(placeCode)、考场编号(roomCode)、课程代码(courseCode)、课程名称(courseName)、匹配度(percent)、是否检录通过(pass)");
            }

            List<ExamStudent> examStudentList = examStudentService.findExamStudentByQuery(examCode, idCard, ticketNo, batchId, stageId, placeCode, roomCode, courseCode, courseName);
            if (examStudentList.size() == 0) {
                throw new JkServerException("无法找到考生信息");
            }
            ExamStudent examStudent = examStudentList.get(0);
            examStudent.setRegistrationStatus(registrationStatus);
            examStudent.setPercent(new BigDecimal(percent));
//            examStudentDao.save(examStudent);
            examStudentService.saveOrUpdate(examStudent);
        }
        response.setStatus(HttpStatus.HTTP_OK);
        response.setCharacterEncoding(SystemConstant.CHARSET_NAME);
        response.setContentType(SystemConstant.CONTENT_TYPE_JSON + ";charset=" + SystemConstant.CHARSET_NAME);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("success", true);
        response.getWriter().print(jsonObject.toJSONString());
    }

//    @ApiOperation(value = "检录系统同步接口测试")
//    @RequestMapping(value = "/hm/registration/sync/test", method = RequestMethod.POST)
//    @ApiResponses({@ApiResponse(code = 200, message = "检录系统同步信息", response = Object.class)})
//    @TokenValidate(policy = TokenPolicy.IGNORE)
//    public void registrationSyncTest(HttpServletRequest request) throws IOException {
//        ExamThirdOrg examThirdOrg = examThirdOrgService.validByCode(SystemConstant.THIRD_ORG_CODE_HMJL);
//        long time = System.currentTimeMillis();
//        log.info("time:{}", time);
//        String token = SignatureInfo.build(SignatureType.SECRET, SystemConstant.METHOD, uri, time, examThirdOrg.getAccessKey(), examThirdOrg.getAccessSecret());
//        log.info("token:{}", token);
//        JSONObject jsonObject = new JSONObject();
//        jsonObject.put("examCode", "MwRV");
//        jsonObject.put("idCard", "4209230002");
//        jsonObject.put("ticketNo", "1700002");
//        jsonObject.put("batchId", "1");
//        jsonObject.put("stageId", "1");
//        jsonObject.put("placeCode", "420101");
//        jsonObject.put("roomCode", "42010101");
//        jsonObject.put("courseCode", "J0001");
//        jsonObject.put("courseName", "职院技能高考");
//        jsonObject.put("percent", "70");
//        jsonObject.put("pass", true);
//        String result = HttpUtil.postJson("http://192.168.11.237:8060/api/open/hm/registration/sync", JSON.toJSONString(jsonObject), token, time);
//    }
}
