package com.rf.psychological.scale.resultBusiness.scaleResult;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.rf.psychological.dao.dto.scale.NewResultDto;
import com.rf.psychological.dao.model.AnswerEntity;
import com.rf.psychological.dao.model.DimensionEntity;
import com.rf.psychological.scale.dao.model.ScaleMarksEntity;
import com.rf.psychological.scale.scaleresult.ScaleConstant;

import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
/**
 * @author zsy
 * @description:匹兹堡睡眠质量指数
 * 备注：2022年7月21日Gaoyixuan已改正，数据格式由version1转换为version2，但是仍有问题
 * @date 2021/7/20 15:55
 */
public class PSQIScale extends BaseScale{

    public PSQIScale(JSONArray jsonArray, JSONObject resultJson) {
        super(jsonArray, resultJson);
    }

    public  JSONObject scaleCalculate() throws Exception {

        // 自定义路径使用
        /*ScaleUtil.getScaleDll("PSQISCALE.dll");
        System.out.println("JSONArray:"+jsonArray);
        System.out.println("resultJson:"+resultJson);
        XScale xScale = new XScale(jsonArray,resultJson);
        String result = xScale.PSQIScale(jsonArray.toString(), resultJson.toString());
        //System.out.println("dllresult:"+result);
        //解决排序问题
        LinkedHashMap<String, Object> jsonMap = JSON.parseObject(result,LinkedHashMap.class, Feature.OrderedField);
        JSONObject jsonObject = new JSONObject(true);
        jsonObject.putAll(jsonMap);
        System.out.println("jsonObject:"+jsonObject);
        return jsonObject;*/

        //睡眠质量
        int scoreQuality = checkQuality(jsonArray);
        //入睡时间
        int scoreTime = checkTime(jsonArray);
        //睡眠时间
        int scoreHour = checkHour(jsonArray);
        //睡眠效率
        int scoreEfficiency = checkEfficiency(jsonArray);
        //睡眠障碍
        int scoreObstruct = checkObstruct(jsonArray);
        //催眠药物
        int scoreMedicine = checkMedicine(jsonArray);
        //日间功能障碍
        int scoreDay = checkDay(jsonArray);
        System.out.println("A睡眠质量："+scoreQuality+";B入睡时间："+scoreTime+";C睡眠时间："+scoreHour+";D睡眠效率："+scoreEfficiency+";E失眠障碍："+scoreObstruct+";F催眠药物："+scoreMedicine+";日间工程障碍："+scoreDay);
        int score = scoreQuality+scoreTime+scoreHour+scoreEfficiency+scoreObstruct+scoreMedicine+scoreDay;
        System.out.println("PSQI总分："+score);
        Map<String,String> resultMap = new LinkedHashMap<>();
        resultMap.put("睡眠质量得分",String.valueOf(scoreQuality));
        resultMap.put("入睡时间得分",String.valueOf(scoreTime));
        resultMap.put("睡眠时间得分",String.valueOf(scoreHour));
        resultMap.put("睡眠效率得分",String.valueOf(scoreEfficiency));
        resultMap.put("睡眠障碍得分",String.valueOf(scoreObstruct));
        resultMap.put("催眠药物得分",String.valueOf(scoreMedicine));
        resultMap.put("日间工程障碍得分",String.valueOf(scoreDay));
        resultMap.put("PSQI总分",String.valueOf(score));
        resultJson.put("睡眠质量得分",String.valueOf(scoreQuality));
        resultJson.put("入睡时间得分",String.valueOf(scoreTime));
        resultJson.put("睡眠时间得分",String.valueOf(scoreHour));
        resultJson.put("睡眠效率得分",String.valueOf(scoreEfficiency));
        resultJson.put("睡眠障碍得分",String.valueOf(scoreObstruct));
        resultJson.put("催眠药物得分",String.valueOf(scoreMedicine));
        resultJson.put("日间工能障碍得分",String.valueOf(scoreDay));
        resultJson.put("PSQI总分",String.valueOf(score));
        if (score<= 5){
            resultMap.put("结论","睡眠质量很好");
            resultJson.put("结论","睡眠质量很好");
        }else if (score >= 6 && score <= 10){
            resultMap.put("结论","睡眠质量还行");
            resultJson.put("结论","睡眠质量还行");
        }else if (score >= 11 && score <= 15){
            resultMap.put("结论","睡眠质量一般");
            resultJson.put("结论","睡眠质量一般");
        }else {
            resultMap.put("结论","睡眠质量很差");
            resultJson.put("结论","睡眠质量很差");
        }

        List<Map<String,String>> resultMapList = new ArrayList<>();
        resultMapList.add(resultMap);

        JSONObject returnJson = new JSONObject(true);
        returnJson.put("resultMapList",resultMapList);
        returnJson.put("resultJson",resultJson);

        return returnJson;
    }

    public JSONObject scaleCalculateV2() throws Exception {

        //总分
        double score = 0;
        Map<String, String> resultMap0 = new LinkedHashMap<>();
        List<Map<String, String>> resultMapList = new ArrayList<>();

        //新版本数据格式
        Map<String, Object> newResult = new LinkedHashMap<>();

        //返回值以及存数据库格式
        List<NewResultDto> newResultDtos = new ArrayList<>();

        //获取答案列表
        List<AnswerEntity> answerEntities = (List<AnswerEntity>) resultJson.get("answerEntities");
        //获取评分规则列表
        List<ScaleMarksEntity> scaleMarksEntities = (List<ScaleMarksEntity>) resultJson.get("scaleMarksEntities");
        //获取维度信息列表
        List<DimensionEntity> dimensionEntities = (List<DimensionEntity>) resultJson.get("dimensionEntities");
        if (jsonArray.size() > 0) {
            score += checkSleepTime(jsonArray) + checkWaitTime(jsonArray) + checkWakeTime(jsonArray) + checkSleepHour(jsonArray) + checkSleepQuality(jsonArray) + checkQuality(jsonArray) + checkEnergy(jsonArray);
            resultMap0.put("总分", String.valueOf(score));
            resultJson.put("总分", String.valueOf(score));
            if (score >= 0 && score <= 12) {
                newResultDtos.add(new NewResultDto("总分", String.valueOf(score), "睡眠质量很好。", "睡眠质量，很好，入睡速度非常快，夜间不会有频繁醒来的情况，早上起床之后精神状态良好", "无",
                        "无", "无", "无", "是"));
                resultMap0.put("总分解释", "睡眠质量很好。");
                resultMap0.put("总分说明", "睡眠质量，很好，入睡速度非常快，夜间不会有频繁醒来的情况，早上起床之后精神状态良好");
                resultMap0.put("总分解读", "无");
                resultMap0.put("总分建议", "无");
                resultJson.put("总分解释", "睡眠质量很好。");
                resultJson.put("总分说明", "睡眠质量，很好，入睡速度非常快，夜间不会有频繁醒来的情况，早上起床之后精神状态良好");
                resultJson.put("总分解读", "无");
                resultJson.put("总分建议", "无");
            } else if (score >= 13 && score <= 26) {
                newResultDtos.add(new NewResultDto("总分", String.valueOf(score), "睡眠质量还行", "睡眠质量一般,健康状况有所下降，如果再不引起足够的重视，您的状况会向一般发展。", "无",
                        "无", "无", "坚持有规律的作息时间，在周末不要睡得太晚，睡前不要暴饮暴食，也不要喝太多的水。", "是"));
                resultMap0.put("总分解释", "睡眠质量还行");
                resultMap0.put("总分说明", "睡眠质量一般,健康状况有所下降，如果再不引起足够的重视，您的状况会向一般发展。");
                resultMap0.put("总分解读", "无");
                resultMap0.put("总分建议", "坚持有规律的作息时间，在周末不要睡得太晚，睡前不要暴饮暴食，也不要喝太多的水。");
                resultJson.put("总分解释", "睡眠质量还行");
                resultJson.put("总分说明", "睡眠质量一般,健康状况有所下降，如果再不引起足够的重视，您的状况会向一般发展。");
                resultJson.put("总分解读", "无");
                resultJson.put("总分建议", "坚持有规律的作息时间，在周末不要睡得太晚，睡前不要暴饮暴食，也不要喝太多的水。");
            } else if (score >= 27 && score <= 40) {
                newResultDtos.add(new NewResultDto("总分", String.valueOf(score), "睡眠质量一般", "睡眠质量比较糟糕,健康状况明显受损,容易被一些声音吵醒，饮食起居失去规律。在不引起重视的话,会发展到更严重的地步", "无",
                        "无", "无", "舒缓的心情就可以让患者早日睡眠，还有就是患者要积极锻炼，在肌体劳累之时就可以很快入眠。", "是"));
                resultMap0.put("总分解释", "睡眠质量一般");
                resultMap0.put("总分说明", "睡眠质量比较糟糕,健康状况明显受损,容易被一些声音吵醒，饮食起居失去规律。在不引起重视的话,会发展到更严重的地步");
                resultMap0.put("总分解读", "无");
                resultMap0.put("总分建议", "舒缓的心情就可以让患者早日睡眠，还有就是患者要积极锻炼，在肌体劳累之时就可以很快入眠。");
                resultJson.put("总分解释", "睡眠质量一般");
                resultJson.put("总分说明", "睡眠质量比较糟糕,健康状况明显受损,容易被一些声音吵醒，饮食起居失去规律。在不引起重视的话,会发展到更严重的地步");
                resultJson.put("总分解读", "无");
                resultJson.put("总分建议", "舒缓的心情就可以让患者早日睡眠，还有就是患者要积极锻炼，在肌体劳累之时就可以很快入眠。");
            } else if (score >= 41 && score <= 54) {
                newResultDtos.add(new NewResultDto("总分", String.valueOf(score), "睡眠质量很差", "睡眠质量已经到了令您非常头痛的地步,长期的睡眠不足,精神状态较差，难以入睡，导致健康状况的严重恶化,应付工作力不从心,情绪不稳定。", "无",
                        "无", "无", "建议您及时就医了，必要时采用药物治疗。", "是"));
                resultMap0.put("总分解释", "睡眠质量很差");
                resultMap0.put("总分说明", "睡眠质量已经到了令您非常头痛的地步,长期的睡眠不足,精神状态较差，难以入睡，导致健康状况的严重恶化,应付工作力不从心,情绪不稳定。");
                resultMap0.put("总分解读", "无");
                resultMap0.put("总分建议", "建议您及时就医了，必要时采用药物治疗。");
                resultJson.put("总分解释", "睡眠质量很差");
                resultJson.put("总分说明", "睡眠质量已经到了令您非常头痛的地步,长期的睡眠不足,精神状态较差，难以入睡，导致健康状况的严重恶化,应付工作力不从心,情绪不稳定。");
                resultJson.put("总分解读", "无");
                resultJson.put("总分建议", "建议您及时就医了，必要时采用药物治疗。");
            }

            resultMapList.add(resultMap0);
        }


        //需要图表展示的
        newResult.put("iconInfo", "");
        newResult.put("result", newResultDtos);

        JSONObject returnJson = new JSONObject(true);
        returnJson.put("resultMapList", resultMapList);
        //returnJson.put("scaleName",resultJson.getString("scaleName"));
        returnJson.put("resultJson", resultJson);
        returnJson.put(ScaleConstant.ResultEnum.RESULT_NEW_FIELD.getKeyword(), newResult);

        return returnJson;
    }

    /**
     * 获取第一题分数
     * @param jsonArray
     * @return
     */
    private static int checkSleepTime(JSONArray jsonArray){
        //第一题：睡觉时间：22:00前0分，22:00到23:001分；23:00到24:002分；24:00到1:003分
        //获取睡觉时间小时
        Integer hour = Integer.parseInt(jsonArray.getJSONObject(0).getString("checkItems").substring(0, jsonArray.getJSONObject(0).getString("checkItems").indexOf(":")));
        if ((hour > 3) && (hour < 22)){
            return 0;
        } else if ((hour == 22) || (hour == 23)){
            return 1;
        } else if ((hour == 24) || (hour == 1)){
            return 2;
        } else {
            return 3;
        }
    }

    /**
     * 获取第二题分数
     * @param jsonArray
     * @return
     */
    private static int checkWaitTime(JSONArray jsonArray){
        JSONObject jsonObject1 = jsonArray.getJSONObject(1);
        String minute = jsonObject1.getString("checkItems");
        if(minute.equals("16~30min")){
            return 1;
        } else if(minute.equals("31~60min")){
            return 2;
        } else if(minute.equals(">=60min")){
            return 3;
        } else {
            return 0;
        }
    }
    /**
     * 获取第三题分数
     * @param jsonArray
     * @return
     */
    private static int checkWakeTime(JSONArray jsonArray){
        Integer hour = Integer.parseInt(jsonArray.getJSONObject(3).getString("checkItems").substring(0, jsonArray.getJSONObject(0).getString("checkItems").indexOf(":")));
        if (hour < 6){
            return 0;
        } else if ((hour == 6) || (hour == 7)){
            return 1;
        } else if ((hour == 8) || (hour == 9)){
            return 2;
        } else {
            return 3;
        }
    }
    /**
     * 获取第四题分数
     * @param jsonArray
     * @return
     */
    private int checkSleepHour(JSONArray jsonArray) {

        //睡眠时间 根据条⽬ 4 的应答计分， >7 ⼩时计 0 分，6~7 计 1 分，5~6计 2 分，<5 ⼩时计 3 分。
        int scoreHour = 0;
        //JSONObject jsonObject1 = jsonArray.getJSONObject(3);
        String hourSleepString = jsonArray.getJSONObject(3).getString("checkItems");
        int hour =Integer.parseInt(hourSleepString.substring(0,hourSleepString.indexOf(":")));
        if(hour>6&&hour<=7){
            scoreHour = 1;
        }else if (hour>=5&&hour<=6){
            scoreHour = 2 ;
        }else if (hour<5){
            scoreHour = 3 ;
        }
        return scoreHour;
    }
    /**
     * 获取第五-十四题分数/十六-十七题分数
    * @param jsonArray
    * @return
    */
    private static int checkSleepQuality(JSONArray jsonArray){
        //睡眠障碍
        int score = 0;
        for(int i=4;i<14;i++){
            JSONObject jsonObject = jsonArray.getJSONObject(i);
            String checkItems = jsonObject.getString("checkItems").trim();
            if(checkItems.equals("<1次／周")){
                score += 1;
            }else if(checkItems.equals("1-2次／周")){
                score += 2;
            }else if(checkItems.equals("≥3次／周")){
                score += 3;
            }
        }
        for(int i=15;i<17;i++){
            JSONObject jsonObject = jsonArray.getJSONObject(i);
            String checkItems = jsonObject.getString("checkItems").trim();
            if(checkItems.equals("<1次／周")){
                score += 1;
            }else if(checkItems.equals("1-2次／周")){
                score += 2;
            }else if(checkItems.equals("≥3次／周")){
                score += 3;
            }
        }
        return score;
    }
    /**
     * 获取第十五题分数
     * @param jsonArray
     * @return
     */
    private static int checkQuality(JSONArray jsonArray){
        //睡眠质量,第六题，很好0分 较好1分  较差2分 很差3分
        int scoreQuality = 0 ;
        JSONObject jsonObject1 = jsonArray.getJSONObject(14);
        String checkItems = jsonObject1.getString("checkItems");
        if(checkItems.equals("较好")){
            scoreQuality +=1;
        }else if(checkItems.equals("较差")){
            scoreQuality +=2;
        }else if(checkItems.equals("很差")){
            scoreQuality +=3;
        }
        return scoreQuality;
    }
    /**
     * 获取第十八题分数
     * @param jsonArray
     * @return
     */
    private static int checkEnergy(JSONArray jsonArray){
        //睡眠质量,第六题，很好0分 较好1分  较差2分 很差3分
        int scoreQuality = 0 ;
        JSONObject jsonObject1 = jsonArray.getJSONObject(17);
        String checkItems = jsonObject1.getString("checkItems");
        if(checkItems.equals("偶尔有")){
            scoreQuality +=1;
        }else if(checkItems.equals("有时有")){
            scoreQuality +=2;
        }else if(checkItems.equals("经常有")){
            scoreQuality +=3;
        }
        return scoreQuality;
    }
    private static int checkTime(JSONArray jsonArray){
        //入睡时间 ，
        // 1、第二题 计分为≤ 15 分计 0 分，16～30 分计 1 分，31~60计 2 分，≥60 分计 3 分
        // 2、 5a⽆计 0 分，<1 周/ 次计 1 分，1~2 周/ 次计 2 分，≥3周/ 次计 3 分3.
        // 累加条⽬ 2 和 5a 的计分，若累加分为 0 计 0 分，1~2计 1 分，3~4分 2 ，5~6 计 3 分
        int scoreTime = 0;
        int scoreTime5a=0;
        int scoreTime2=0;
        JSONObject jsonObject1 = jsonArray.getJSONObject(1);
        String minute = jsonObject1.getString("checkItems");
        if(minute.equals("16~30min")){
            scoreTime2 =1;
        }else if(minute.equals("31~60min")){
            scoreTime2 =2;
        }else if(minute.equals(">=60min")){
            scoreTime2 =3;
        }
        jsonObject1=jsonArray.getJSONObject(4);
        String checkItems = jsonObject1.getString("checkItems").trim();
        if(checkItems.equals("<1次／周")){
            scoreTime5a = 1;
        }else if(checkItems.equals("1-2次／周")){
            scoreTime5a = 2;
        }else if(checkItems.equals("≥3次／周")){
            scoreTime5a=3;
        }
        int scoreTemp = scoreTime2+scoreTime5a;
        if(scoreTemp==0){
            scoreTime = 0;
        }else if(scoreTemp>=1 && scoreTemp<= 2 ){
            scoreTime = 1;
        }else if(scoreTemp>=3 && scoreTemp<= 4 ){
            scoreTime = 2;
        }else if(scoreTemp>=5 && scoreTemp<= 6 ){
            scoreTime = 3;
        }
        return scoreTime;
    }

    private int checkHour(JSONArray jsonArray) {

        //睡眠时间 根据条⽬ 4 的应答计分， >7 ⼩时计 0 分，6~7 计 1 分，5~6计 2 分，<5 ⼩时计 3 分。
        int scoreHour = 0;
        //JSONObject jsonObject1 = jsonArray.getJSONObject(3);
        String hourSleepString = jsonArray.getJSONObject(3).getString("checkItems");
        int hour =Integer.parseInt(hourSleepString.substring(0,hourSleepString.indexOf(":")));
        if(hour>6&&hour<=7){
            scoreHour = 1;
        }else if (hour>=5&&hour<=6){
            scoreHour = 2 ;
        }else if (hour<5){
            scoreHour = 3 ;
        }
        return scoreHour;
    }

    private static int checkEfficiency(JSONArray jsonArray){
//        床上时间 = 条⽬ 3（起床时间） - 条⽬ 1（上床时间）
        String goBad = "2021-01-27 "+jsonArray.getJSONObject(2).getString("checkItems")+"";
        LocalDateTime engDate = LocalDateTime.parse(goBad, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));
        String leaveBad = "2021-01-26 "+jsonArray.getJSONObject(0).getString("checkItems");
        LocalDateTime beginDate = LocalDateTime.parse(leaveBad,DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));
        Duration duration = Duration.between(beginDate,engDate);
        //相差的分钟数
        long hourOnBed = duration.toMinutes();
        String hourSleepString = jsonArray.getJSONObject(3).getString("checkItems");
        int hourSleep = Integer.parseInt(hourSleepString.substring(0,hourSleepString.indexOf(":")))*60 + Integer.parseInt(hourSleepString.substring(hourSleepString.indexOf(":")+1));
        double efficiencyTemp  = (double)hourSleep/hourOnBed;
        if(efficiencyTemp>0.85){
            return 0;
        }else if(efficiencyTemp>=0.75&&efficiencyTemp<=0.84){
            return 1;
        }else if(efficiencyTemp>=0.65&&efficiencyTemp<0.74){
            return 2;
        }else{
            return 3;
        }

    }
    private static  int checkObstruct(JSONArray jsonArray){
        //睡眠障碍
        int scoreTemp = 0;
        int score = 0;
        for(int i=5;i<14;i++){
            JSONObject jsonObject = jsonArray.getJSONObject(i);
            String checkItems = jsonObject.getString("checkItems").trim();
            if(checkItems.equals("<1次／周")){
                scoreTemp += 1;
            }else if(checkItems.equals("1-2次／周")){
                scoreTemp += 2;
            }else if(checkItems.equals("≥3次／周")){
                scoreTemp += 3;
            }
            if(scoreTemp==0){
                score = 0;
            }else if(scoreTemp>=1 && scoreTemp<10){
                score = 1;
            }else if(scoreTemp>=10 && scoreTemp<=18){
                score = 2;
            }else if(scoreTemp >=19 && scoreTemp<=27){
                score = 3;
            }
        }
        return score;
    }

    private int checkMedicine(JSONArray jsonArray){
        //催眠药物
        int scoreMedicine = 0 ;
        JSONObject jsonObject = jsonArray.getJSONObject(15);
        String checkItems = jsonObject.getString("checkItems").trim();
        if(checkItems.equals("<1次／周")){
            scoreMedicine = 1;
        }else if(checkItems.equals("1-2次／周")){
            scoreMedicine = 2;
        }else if(checkItems.equals("≥3次／周")){
            scoreMedicine = 3;
        }
        return scoreMedicine;
    }

    private static int checkDay(JSONArray jsonArray){
        //日间功能障碍
        int scoreDay=0;
        JSONObject jsonObject = jsonArray.getJSONObject(16);
        String checkItems = jsonObject.getString("checkItems").trim();
        if(checkItems.equals("<1次／周")){
            scoreDay += 1;
        }else if(checkItems.equals("1-2次／周")){
            scoreDay += 2;
        }else if(checkItems.equals("≥3次／周")){
            scoreDay += 3;
        }

        jsonObject = jsonArray.getJSONObject(17);
        checkItems = jsonObject.getString("checkItems").trim();
        if(checkItems.equals("没有")){
            scoreDay += 0;
        }else if(checkItems.equals("偶尔有")){
            scoreDay += 1;
        }else if(checkItems.equals("有时有")){
            scoreDay += 2;
        }else if(checkItems.equals("经常有")){
            scoreDay += 3;
        }
        if(scoreDay == 0){
            scoreDay = 0;
        }else if(scoreDay == 1 || scoreDay == 2){
            scoreDay = 1;
        }else if(scoreDay == 3 || scoreDay == 4){
            scoreDay = 2;
        }else if(scoreDay == 5 || scoreDay == 6){
            scoreDay = 3;
        }
        return scoreDay;
    }

}
