
package com.yihu.wlyy.service.app.consult;


import com.yihu.wlyy.entity.consult.ConsultTeam;
import com.yihu.wlyy.entity.consult.Evaluate;
import com.yihu.wlyy.entity.consult.EvaluateLabel;
import com.yihu.wlyy.entity.consult.EvaluateScore;
import com.yihu.wlyy.repository.consult.ConsultTeamDoctorDao;
import com.yihu.wlyy.repository.consult.EvaluateDao;
import com.yihu.wlyy.repository.consult.EvaluateScoreDao;
import com.yihu.wlyy.service.BaseService;
import com.yihu.wlyy.util.ClazzReflect;
import com.yihu.wlyy.util.ImUtill;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;


@Component
@Transactional
public class EvaluateService extends BaseService {
    @Autowired
    EvaluateDao evaluateDao;
    @Autowired
    ConsultTeamService consultTeamService;
    @Autowired
    EvaluateLabelService evaluateLabelService;
    @Autowired
    JdbcTemplate jdbcTemplate;
    @Autowired
    ConsultTeamDoctorDao consultTeamDoctorDao;
    @Autowired
    EvaluateScoreDao evaluateScoreDao;

    private void save(Map<String, List<Evaluate>> docEvaMap) {
        for (String key : docEvaMap.keySet())
            evaluateDao.save(docEvaMap.get(key));
    }

    public void saveByJson(String jsonData, String patient) {
        JSONObject jsonObject = new JSONObject(jsonData);
        String consult = jsonObject.getString("consult");
        ConsultTeam consultTeam = consultTeamService.findByCode(consult);
        //评价的分数
        JSONArray evaluateArray = jsonObject.getJSONArray("evaluate");
        //标签
        JSONArray labelArray = jsonObject.getJSONArray("label");
        List<Evaluate> evaluateList = null;
        List<EvaluateLabel> evaluateLabelList = new ArrayList<>();
        Map<String, List<Evaluate>> docEvaMap = new HashMap<>();
        //反射生成评价对象
        for (Object evaluateObj : evaluateArray) {
            Evaluate evaluate = new Evaluate();
            JSONObject obj = (JSONObject) evaluateObj;
            ClazzReflect clazzReflect = new ClazzReflect();
            evaluate = (Evaluate) clazzReflect.formatToClazz(evaluate, obj);
            evaluate.setConsult(consult);
            evaluate.setPatient(patient);
            //把分数放入map中 给参与此次咨询的医生都评分
            if (docEvaMap.get(evaluate.getDoctor()) == null) {
                evaluateList = new ArrayList<>();
                evaluateList.add(evaluate);
                docEvaMap.put(evaluate.getDoctor(), evaluateList);
            } else {
                docEvaMap.get(evaluate.getDoctor()).add(evaluate);
            }
        }
        //反射得到标签内容
        for (Object labelObj : labelArray) {
            EvaluateLabel evaluateLabel = new EvaluateLabel();
            JSONObject obj = (JSONObject) labelObj;
            ClazzReflect clazzReflect = new ClazzReflect();
            evaluateLabel = (EvaluateLabel) clazzReflect.formatToClazz(evaluateLabel, obj);
            evaluateLabel.setConsult(consult);
            evaluateLabel.setPatient(patient);
            evaluateLabelList.add(evaluateLabel);
        }
        //计算单条得分
        evaluateScoreCal(docEvaMap, consult);
        this.save(docEvaMap);
        evaluateLabelService.save(evaluateLabelList);
        consultTeam.setEvaluate(1);
        consultTeam.setEvaluateTime(new Date());
        JSONObject topicObject = new JSONObject();
        topicObject.put("evaluate", 1);
        topicObject.put("evaluate_time", new Date());
        ImUtill.updateTopics(consult, topicObject.toString());
        this.consultTeamService.save(consultTeam);
    }

    /**
     * 查询某个咨询某种类型的评价
     *
     * @param consult
     * @param type
     * @return
     */
    public List<Evaluate> getEvaluateByConsultAndType(String consult, int type) {
        List<Evaluate> evaluates = evaluateDao.findByConsultAndType(consult, type);
        return evaluates;
    }

    /**
     * 查询某个咨询的评价
     *
     * @param consult
     * @return
     */
    public List<Evaluate> getEvaluateByConsult(String consult) {
        List<Evaluate> evaluates = evaluateDao.findByConsult(consult);
        return evaluates;
    }

    /**
     * 获取某个医生的某种类型的评价
     *
     * @param doctor
     * @param type
     * @return
     */
    public List<Evaluate> getEvaluateByDoctorAndType(String doctor, int type) {
        List<Evaluate> evaluates = evaluateDao.findByDoctorAndType(doctor, type);
        return evaluates;
    }


    private void evaluateScoreCal(Map<String, List<Evaluate>> docEvaMap, String consult) {
        for (String doctor : docEvaMap.keySet()) {
            List<Evaluate> evaluates = docEvaMap.get(doctor);
            if (evaluates.size() == 1) {
                //如果一条那么这条一定是实名，只有实名那么分数按实名的来存
                EvaluateScore evaluateScore = new EvaluateScore();
                evaluateScore.setConsult(consult);
                evaluateScore.setDoctor(doctor);
                evaluateScore.setScore(Double.valueOf(evaluates.get(0).getScore()));
                evaluateScoreDao.save(evaluateScore);
            } else {
                //如果既有实名和匿名的那么按照公式来存
                BigDecimal realScore = new BigDecimal(REAL_SCORE_DEFAULT);//实名评价
                BigDecimal anonymousScore1 = new BigDecimal(ANONYMOUS_SCORE_DEFAULT_ONE);//专业能力
                BigDecimal anonymousScore2 = new BigDecimal(ANONYMOUS_SCORE_DEFAULT_TWO);//服务态度
                BigDecimal anonymousScore3 = new BigDecimal(ANONYMOUS_SCORE_DEFAULT_THREE);//回复速度
                //计算此次评价的分数来源
                for (Evaluate evaluate : docEvaMap.get(doctor)) {
                    if (evaluate.getEvaluateType() == 0) {
                        realScore = BigDecimal.valueOf(evaluate.getScore());
                    } else if (evaluate.getEvaluateType() == 1) {
                        anonymousScore1 = BigDecimal.valueOf(evaluate.getScore());
                    } else if (evaluate.getEvaluateType() == 2) {
                        anonymousScore2 = BigDecimal.valueOf(evaluate.getScore());
                    } else if (evaluate.getEvaluateType() == 3) {
                        anonymousScore3 = BigDecimal.valueOf(evaluate.getScore());
                    }
                }
                String evaluateTimesSql = "select count(1) as count from wlyy_evaluate w where w.doctor =? GROUP BY w.consult,w.doctor";
                //有效评价次数
                List<Map<String, Object>> evaluateTimesList = jdbcTemplate.queryForList(evaluateTimesSql, new Object[]{doctor});
                //有效咨询次数
                int consultTimes = consultTeamDoctorDao.countByDoctorAndType(2, doctor);
                BigDecimal score = BigDecimal.ZERO;//总分
                BigDecimal anonymousScore = BigDecimal.ZERO;//加权平均分笔直综合
                BigDecimal jiaquan = BigDecimal.ZERO;//加权平均分
                //加权平均分=（实名评分×30%+专业能力×20%+服务态度×25%+回复速度×25%）/有效评价次数
                anonymousScore = anonymousScore.add(realScore.multiply(new BigDecimal("0.3")));
                anonymousScore = anonymousScore.add(anonymousScore1.multiply(new BigDecimal("0.2")));
                anonymousScore = anonymousScore.add(anonymousScore2.multiply(new BigDecimal("0.25")));
                anonymousScore = anonymousScore.add(anonymousScore3.multiply(new BigDecimal("0.25")));
//			int evaTimes = 0;
//			if(evaluateTimesList.size()>0){
//				evaTimes = evaluateTimesList.size();
//			}else{
//				evaTimes = 1;
//			}
//			jiaquan  = anonymousScore.divide(BigDecimal.valueOf(evaTimes),2,BigDecimal.ROUND_HALF_UP);//算的加权平均分
//			//满意度=80+（加权平均分-80）/系数
//			//咨询系数 咨询次数≤100次，对应系数为3；
//			//100次<咨询次数≤1000次，对应系数为2；
//			//咨询次数>1000次，对应系数为1。
//			if (consultTimes <= 100) {  //咨询系数 咨询次数≤100次，对应系数为3；
//				//100次<咨询次数≤1000次，对应系数为2；
//				//咨询次数>1000次，对应系数为1。
//				jiaquan = (jiaquan.subtract(BigDecimal.valueOf(80L))).divide(BigDecimal.valueOf(3L),2,BigDecimal.ROUND_HALF_UP);
//			} else if (consultTimes > 100 && consultTimes <= 1000) {
//				jiaquan = (jiaquan.subtract(BigDecimal.valueOf(80L))).divide(BigDecimal.valueOf(2L),2,BigDecimal.ROUND_HALF_UP);
//			} else {
//				jiaquan = (jiaquan.subtract(BigDecimal.valueOf(80L))).divide(BigDecimal.valueOf(1L),2,BigDecimal.ROUND_HALF_UP);
//			}
//			score = jiaquan.add(BigDecimal.valueOf(80L)).setScale(1, BigDecimal.ROUND_HALF_UP);
                score = anonymousScore;
                EvaluateScore evaluateScore = new EvaluateScore();
                evaluateScore.setConsult(consult);
                evaluateScore.setDoctor(doctor);
                evaluateScore.setScore(score.doubleValue());
                evaluateScoreDao.save(evaluateScore);
            }
        }
    }

    ;


    public static Long REAL_SCORE_DEFAULT = 100L;
    public static Long ANONYMOUS_SCORE_DEFAULT_ONE = 100L;
    public static Long ANONYMOUS_SCORE_DEFAULT_TWO = 100L;
    public static Long ANONYMOUS_SCORE_DEFAULT_THREE = 100L;
}
