package cn.sh.stc.sict.theme.hphy.controller.mp;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import cn.sh.stc.sict.cloud.common.core.constant.Constant;
import cn.sh.stc.sict.cloud.common.core.util.NumberUtil;
import cn.sh.stc.sict.cloud.common.core.util.R;
import cn.sh.stc.sict.cloud.common.security.util.SecurityUtils;
import cn.sh.stc.sict.cloud.upms.dto.CurrentUser;
import cn.sh.stc.sict.theme.common.dto.SocketMsg;
import cn.sh.stc.sict.theme.handler.WebSocketServer;
import cn.sh.stc.sict.theme.hphy.constant.PatientConstant;
import cn.sh.stc.sict.theme.hphy.model.HphyDoctor;
import cn.sh.stc.sict.theme.hphy.model.HphyGuideQuestion;
import cn.sh.stc.sict.theme.hphy.model.HphyGuideRecord;
import cn.sh.stc.sict.theme.hphy.model.HphyPatientBase;
import cn.sh.stc.sict.theme.hphy.service.*;
import cn.sh.stc.sict.theme.hphy.util.GuideUtil;
import cn.sh.stc.sict.theme.hphy.util.PythonCompareParam;
import cn.sh.stc.sict.theme.hphy.util.PythonUtil;
import cn.sh.stc.sict.theme.hphy.vo.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.websocket.EncodeException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.List;

@Slf4j
@RestController
@RequestMapping("/hphy/c/eva")
@AllArgsConstructor
@Api(tags = "[C]导医问卷模块(自我评估)")
public class HphyEvaController {

    /**
     * 0. 输入用户id 获取用户信息
     * 1. 生成导医记录 & 获取第一题 + 答案
     * 2. 提交答案 【循环下一题 || python】
     * 2.1 题目有下一题 --》 下一题
     * 2.2 题目无下一题
     * 2.2.1 答案有下一题 --》 下一题
     * 2.2.2 答案无下一题 --》 python
     * 3. 输出导医结果
     */
    private final static Long START_ID = 1L;
    private final HphyPatientBaseService hphyPatientBaseService;
    private final HphyGuideRecordService hphyGuideRecordService;
    private final HphyQuestionService hphyQuestionService;
    private final HphyGuideQuestionService hphyGuideQuestionService;
    private final HphyDoctorService hphyDoctorService;


    /**
     * 生成导医记录
     * 获取第一题 + 答案
     *
     * @param patientId
     * @return
     */
    @ApiOperation("获取第一题")
    @GetMapping("/first")
    public R getFirstQuestion(@RequestParam Long patientId) {
        HphyPatientBase patient = hphyPatientBaseService.getById(patientId);
        if (ObjectUtil.isNull(patient) || NumberUtil.isNullOrZero(patient.getId())) {
            return new R().error("未找到用户有信息，请先注册！");
        }

        HphyGuideRecord record = hphyGuideRecordService.initGuide(patient);

        QuestionVO queston = hphyQuestionService.getVOById(START_ID);
        queston.setGuideId(record.getId());
        queston.setProgress(1L);

        return new R(queston);
    }


    @ApiOperation("上一题")
    @GetMapping("/prev")
    public R getPrevQuestion(@RequestParam("guideQuestionId") Long guideQuestionId) {
        HphyGuideQuestion gq = hphyGuideQuestionService.getById(guideQuestionId);
        if (null == gq || NumberUtil.isNullOrZero(gq.getId())) {
            return new R().error("未找到上一题！");
        }
        long questionId = NumberUtil.isNotNullOrZero(gq.getParentId()) ? gq.getParentId() : gq.getQuestionId();
        QuestionVO vo = hphyQuestionService.getVOById(questionId);
        vo.setPrevQuestionId(gq.getPrevId());
        vo.setGuideId(gq.getGuideId());
        vo.setAnswerList(hphyGuideQuestionService.getAnswerList(gq));
        vo.setProgress(questionId);
        return new R(vo);
    }

    /**
     * 2. 提交答案 【循环下一题 || python】   <---|
     * * 2.1 题目有下一题 --》 下一题            |
     * * 2.2 题目无下一题                      |
     * * 2.2.1 答案有下一题 --》 下一题     --->|
     * * // 2.2.2 答案无下一题 --》 python //
     * * 2.2.2 答案无下一题 --》 输出结果
     * * 3. 输出导医结果
     *
     * @return
     */
    @ApiOperation("提交答案并获取下一题")
    @PostMapping("/next")
    @Transactional(rollbackFor = Exception.class)
    public R getNextQuestion(@RequestBody EvaParamDTO dto) throws UnsupportedEncodingException {
        if (NumberUtil.isNullOrZero(dto.getGuideId())) {
            return new R().error("缺少参数： guideId");
        }
        if (NumberUtil.isNullOrZero(dto.getPatientId())) {
            return new R().error("缺少参数： patientId");
        }
        EvaSaveResult result = hphyGuideQuestionService.saveRecord(dto);
        boolean flag = PatientConstant.QUESTION_PREG_ID.equals(result.getNextQuestionId()) && Constant.BYTE_YES.equals(SecurityUtils.getCurrentUser().getGender());

        if (NumberUtil.isNullOrZero(result.getNextQuestionId()) || flag) {
            // 疾病判断
            // return hphyGuideRecordService.analysisDisease(dto.getPatientId(), dto.getGuideId());
            // 需要患者进行确认再进行导医
            // result.setResultList(hphyGuideRecordService.analysisDiseaseV2(dto.getPatientId(), dto.getGuideId()));
            result.setResultList(hphyGuideRecordService.analysisDiseaseV3(dto.getPatientId(), dto.getGuideId()));
            return new R(result).setBizCode(2);
            // 需要患者进行确认再进行导医
        } else {
            // 设置上一题id
            QuestionVO vo = hphyQuestionService.getVOById(result.getNextQuestionId());
            vo.setPrevQuestionId(result.getPrevQuestionId());
            vo.setGuideId(dto.getGuideId());
            vo.setProgress(result.getNextQuestionId());
            return new R(vo);
        }
    }


    @ApiOperation("调用python程序")
    @GetMapping("/python/result")
    public R getPythonResult(@RequestParam("guideId") Long guideId,
                             @RequestParam("")String a,
                             @RequestParam("")String b,
                             @RequestParam("")String c,
                             @RequestParam("")String d) throws UnsupportedEncodingException {
        return hphyGuideRecordService.getPythonResult(guideId);
    }

    /**
     * 获取导医逻辑 list
     * TODO 肖英的导医逻辑 python
     *
     * @return
     */
    @ApiOperation("获取导医逻辑 list")
    @GetMapping("/guide/list")
    public R getGuideList(@RequestParam("patientId") String patientId,
                          @RequestParam("guideId") Long guideId,
                          @RequestParam("doctorId") String doctorId) {
        /**
         * patientId
         * doctorId
         * patientAge
         * disease
         * 年龄，地址，disease
         */
        HphyPatientBase patient = hphyPatientBaseService.getById(patientId);
        HphyDoctor doctor = hphyDoctorService.getById(doctorId);
        HphyGuideRecord guide = hphyGuideRecordService.getById(guideId);
        List<LabelVO> patientList = GuideUtil.getPatientList(patient, guide);
        List<String> disease = GuideUtil.getPatientDisease(guide);
        PythonCompareParam param = new PythonCompareParam(patient.getCertId(), doctorId, patient.getAge(), disease);
        JSONArray doctorList = PythonUtil.getMatchLabel(JSONUtil.toJsonStr(param));
        DoctorPatientMatchVO vo = DoctorPatientMatchVO.builder()
                .patient(patient)
                .patientLabelList(patientList)
                .doctor(doctor)
                .doctorLabelList(doctorList)
                .build();
        return new R(vo);
    }

    @ApiOperation("test")
    @GetMapping("/test")
    public R test(@RequestParam("msg") String msg,
                  @RequestParam("patientId") Long patientId) throws IOException, EncodeException {
        SocketMsg socketMsg = new SocketMsg();
        socketMsg.setType(PatientConstant.STR_TYPE);
        socketMsg.setMsg("您的血压值在正常范围内，身体若有不适请到当地医院做详细检查以明确诊断！");
        WebSocketServer.sendInfo(socketMsg, PatientConstant.HPHY + patientId);
        return new R();
    }
}
