package com.davos.assessment.assessment;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.springframework.stereotype.Service;

@Service
public class ScoringService {
  public ScoringResult score(Assessment assessment, List<Question> questions, Map<String, Integer> answers) {
    String paperId = assessment.getTestPaperId();
    if (paperId.contains("2058")) return epq(answers);
    if (paperId.contains("2078")) return scl90(answers);
    if (paperId.contains("2081")) return pf16(answers);
    if (paperId.contains("2082")) return sds(answers);
    if (paperId.contains("2083")) return sas(answers);
    if (paperId.contains("2084")) return sqa(answers);
    return generic(assessment, questions, answers);
  }

  private ScoringResult epq(Map<String, Integer> a) {
    Map<String, Integer> d = new LinkedHashMap<>();
    int e = count(a, 2058, new int[]{1,5,10,13,14,17,25,33,37,41,49,53,55,61,65,71,80,84}, 1)
        + count(a, 2058, new int[]{21,29,45}, 2);
    int n = count(a, 2058, new int[]{3,7,12,15,19,23,27,31,35,39,43,47,51,57,59,63,67,69,73,74,77,78,82,86}, 1);
    int p = count(a, 2058, new int[]{22,26,30,34,46,50,66,68,75,76,81,85}, 1)
        + count(a, 2058, new int[]{2,6,9,11,18,38,42,56,62,72,88}, 2);
    int l = count(a, 2058, new int[]{20,32,36,58,87}, 1)
        + count(a, 2058, new int[]{4,8,16,24,28,40,44,48,52,54,60,64,70,79,83}, 2);
    d.put("P精神质", p);
    d.put("E内外向", e);
    d.put("N情绪稳定性", n);
    d.put("L掩饰性", l);
    String level = l > 18 ? "效度关注" : "有效";
    String summary = "人格类型：" + epqPersonalityType(e, n) + "；P=" + p + "，E=" + e + "，N=" + n + "，L=" + l + "。";
    String suggestions = epqTemperamentAdvice(e, n) + (l > 18 ? " L 分偏高，建议结合访谈复核答题一致性。" : "");
    return result(sum(d), level, d, summary, suggestions);
  }

  private ScoringResult scl90(Map<String, Integer> a) {
    Map<String, Integer> d = new LinkedHashMap<>();
    int qth = sum(a, 2078, 1,4,12,27,40,42,48,49,52,53,56,58);
    int qbzz = sum(a, 2078, 3,9,10,28,38,45,46,51,55,65);
    int rjgxmg = sum(a, 2078, 6,21,34,36,37,41,61,69,73);
    int yy = sum(a, 2078, 5,14,15,20,22,26,29,30,31,32,54,71,79);
    int jl = sum(a, 2078, 2,17,23,33,39,57,72,78,80,86);
    int dd = sum(a, 2078, 11,24,63,67,74,81);
    int kb = sum(a, 2078, 13,25,47,50,70,75,82);
    int pz = sum(a, 2078, 8,18,43,68,76,83);
    int jsbx = sum(a, 2078, 7,16,35,62,77,84,85,87,88,90);
    int qt = sum(a, 2078, 19,44,59,60,64,66,89);
    d.put("躯体化", qth);
    d.put("强迫症状", qbzz);
    d.put("人际关系敏感", rjgxmg);
    d.put("抑郁", yy);
    d.put("焦虑", jl);
    d.put("敌对", dd);
    d.put("恐怖", kb);
    d.put("偏执", pz);
    d.put("精神病性", jsbx);
    d.put("其他", qt);
    int total = sum(d);
    int positive = 0;
    for (int i = 1; i <= 90; i++) if (q(a, 2078, i) >= 2) positive++;
    int negative = 90 - positive;
    int positiveScore = 0;
    int negativeScore = 0;
    for (int i = 1; i <= 90; i++) {
      int score = q(a, 2078, i);
      if (score >= 2) positiveScore += score;
      else negativeScore += score;
    }
    float totalAvg = round2f(total / 90f);
    float positiveAvg = positive == 0 ? 0f : round2f(positiveScore / (float) positive);
    float negativeAvg = negative == 0 ? 0f : round2f(negativeScore / (float) negative);
    float qthAvg = round2f(qth / 12f);
    float qbzzAvg = round2f(qbzz / 10f);
    float rjgxmgAvg = round2f(rjgxmg / 9f);
    float yyAvg = round2f(yy / 13f);
    float jlAvg = round2f(jl / 10f);
    float ddAvg = round2f(dd / 6f);
    float kbAvg = round2f(kb / 7f);
    float pzAvg = round2f(pz / 6f);
    float jsbxAvg = round2f(jsbx / 10f);
    // 旧系统这里是 /9（即便“其他”是7题，按旧实现原样保留）
    float qtAvg = round2f(qt / 9f);

    d.put("总分", total);
    d.put("阳性项目数", positive);
    d.put("阴性项目数", negative);
    d.put("阳性项目总得分数", positiveScore);
    d.put("阴性项目总得分数", negativeScore);
    d.put("总均分", Math.round(totalAvg * 100));
    d.put("阳性均分", Math.round(positiveAvg * 100));
    d.put("阴性均分", Math.round(negativeAvg * 100));
    d.put("躯体化均分", Math.round(qthAvg * 100));
    d.put("强迫症状均分", Math.round(qbzzAvg * 100));
    d.put("人际关系敏感均分", Math.round(rjgxmgAvg * 100));
    d.put("抑郁均分", Math.round(yyAvg * 100));
    d.put("焦虑均分", Math.round(jlAvg * 100));
    d.put("敌对均分", Math.round(ddAvg * 100));
    d.put("恐怖均分", Math.round(kbAvg * 100));
    d.put("偏执均分", Math.round(pzAvg * 100));
    d.put("精神病性均分", Math.round(jsbxAvg * 100));
    d.put("其他均分", Math.round(qtAvg * 100));

    String level = total > 160 && positive > 43 ? "阳性" : "阴性";
    String summary = level + "SCL总分:" + total + " 阳性项目数：" + positive;
    String suggestions = buildScl90LegacySuggestions(
        qthAvg, qbzzAvg, rjgxmgAvg, yyAvg, jlAvg,
        ddAvg, kbAvg, pzAvg, jsbxAvg, qtAvg);
    return result(total, level, d, summary, suggestions);
  }

  private String buildScl90LegacySuggestions(
      float qth, float qbzz, float rjgxmg, float yy, float jl,
      float dd, float kb, float pz, float jsbx, float qt) {
    return sclAdviceQth(sclDegree(qth))
        + "\n" + sclAdviceQbzz(sclDegree(qbzz))
        + "\n" + sclAdviceRjgxmg(sclDegree(rjgxmg))
        + "\n" + sclAdviceYy(sclDegree(yy))
        + "\n" + sclAdviceJl(sclDegree(jl))
        + "\n" + sclAdviceDd(sclDegree(dd))
        + "\n" + sclAdviceKb(sclDegree(kb))
        + "\n" + sclAdvicePz(sclDegree(pz))
        + "\n" + sclAdviceJsbx(sclDegree(jsbx))
        + "\n";
  }

  private int sclDegree(float score) {
    if (score < 1.5f) return 1;
    if (score < 2.5f) return 2;
    if (score < 3.5f) return 3;
    if (score < 4.5f) return 4;
    return 5;
  }

  private String sclAdviceQth(int degree) {
    return switch (degree) {
      case 2 -> "有时感到头晕或头部不适感，如紧绷、胀等。偶而会有胃部不适、胀气、嗳气，有时出现心跳加快、心慌，有时常有疲倦的感觉。建议您经常检查自身的心理压力水平，建议保持积极、乐观的心态和良好的生活习惯，如注意科学饮食，加强体育锻炼。";
      case 3 -> "经常有躯体不适的感觉，常有头晕、头胀、紧绷等症状，胃部不适较多，食欲不振、嗳气、胃胀，经常有心慌、心跳快，有时感到胸闷、呼吸急促，常有疲乏、虚弱感觉。建议您首先到医院检查排除病理性原因后寻求心理工作者的帮助，疏解心理压力，改善躯体症状。";
      case 4 -> "躯体不适明显，如胃口差，腹胀等，且常伴有烦躁不安的情绪；经常感到头部不适，紧绷，头晕，头胀，或胸闷气急，心慌，有时担心自己会突然死去。建议您及时寻求心理工作者的帮助，通过心理咨询知道到引起躯体症状的真正原因，并检查自身的压力感是否过大。";
      case 5 -> "躯体不适显著，如食欲不振、胃胀等，常常情绪烦躁；且常常感到头晕，头胀，胸闷，心慌，非常疲惫，常常担心自己会突然死去。建议您及时就医，寻求专业医生的帮助。";
      default -> "主要反映身体不适感，包括心血管、胃肠道、呼吸和其他系统的不适，和头痛、背痛、肌肉酸痛，以及焦虑等躯体不适表现。您在该因子中表现正常。";
    };
  }

  private String sclAdviceQbzz(int degree) {
    return switch (degree) {
      case 2 -> "有时会表现为担心、害怕而需要反复去思考某些念头或想法。有时表现为出现反复的重复做动作，如洗手或一些特殊的动作，但时间较短，可以有掩饰的行为，虽有些痛苦，但尚能工作。建议您保持平稳的生活状态，用自然平和的心态面对生活。";
      case 3 -> "反复的重复做的动作明显增多，或反复思考一些想法，感到没有必要，想作抵抗，但无法克制内心的冲动，只能重复，伴有较明显焦虑，有一定求医行为。一天中有2～4小时会做反复动作或竭力思考等强迫行为。建议您可以尝试采用森田疗法中的一些理念对待自己的强迫性想法或行为，如对症状的存在不予理睬、与症状做朋友等，必要时可以寻求帮助。";
      case 4 -> "每天有4～6小时重复某些动作或反复思考某些想法，甚至影响到日常生活，使其社会功能和生活功能部分受损，患者明知这些动作和思虑没有必要，但无法控制，极其焦虑，不得不以重复的的动作和反复的思虑来换取暂时的心理轻松，但过后又为焦虑所支配去重复动作和思虑。建议您及时寻求心理工作者的帮助，通过心理咨询找到强迫症状的原因，缓解强迫性想法和行为的产生。";
      case 5 -> "每天有6～8小时去做些反复的动作或思考某些想法，已经明显的影响到社会功能和生活功能。患者明知没有必要，但无法抗拒，而内心十分痛苦。每次完成之后，心里有轻松感或舒适的感觉，但不多久，又被焦虑、担心所支配，再次做重复的动作。建议您及时就医，寻求专业医生的帮助。";
      default -> "主要指那些明知没有必要，但又无法摆脱的无意义的思想、冲动和行为，还有一些比较一般的认知障碍的行为征象也在这一因子中反映。您在该因子中表现正常。";
    };
  }

  private String sclAdviceRjgxmg(int degree) {
    return switch (degree) {
      case 2 -> "性格基础是内向、敏感、胆小且易害羞。在陌生人面前不多开口讲话，显得害羞。心理较脆弱，有时会产生别人对自己不理解而感到痛苦。建议您增强对自己的信心，在与人交往时不要过分关注自我形象，在人际关系中形成乐观、自信的心境。";
      case 3 -> "很少在生人面前多讲话，表现为敏感、多疑且易害羞。对别人讲话比较留心，常担心别人会议论自己，有时对别人有警惕心理状态，做事小心谨慎。建议您增强对自己的信心，敢于面对内心的想法和感受，仔细分析这些想法和感受，就会发现他们都是来自内心不合理的观念，逐渐放弃这些观念，就可以自如的与他人交往。";
      case 4 -> "内向，敏感，不大主动与人交谈，但对别人的评价非常在意，有时显得神经过敏，偶尔会表现出被动攻击，影响其人际关系，使之朋友较少。建议您增强对自己的信心，多参加集体活动，必要时接受心理咨询师的帮助，通过接受心理咨询改善人际交往问题。";
      case 5 -> "平时很内向，常因过分敏感而少与人讲话，而对别人的谈论经常加倍注意，担心有人议论而显得神经过敏状态，并有时会采取指责别人的方法，而使得朋友极少。建议您及时就医，寻求专业医生的帮助。";
      default -> "主要是指某些人际的不自在与自卑感，特别是与其他人相比较时更加突出。在人际交往中的自卑感，心神不安，明显的不自在，以及人际交流中的不良自我暗示，消极的期待等是这方面症状的典型原因。您在该因子中表现正常。";
    };
  }

  private String sclAdviceYy(int degree) {
    return switch (degree) {
      case 2 -> "自我评价稍低，平时落落寡欢、心情欠佳、兴趣也有些下降，偶而会心情烦躁，不愿意与人交往，有时夜眠差些、多梦。建议您保持快乐明朗的心态，即使心态健康的人也会出现暂时的情绪低落、态度消沉，选择适当的应对方法，就可以从低沉、悲观的情绪中走出来。";
      case 3 -> "自我评价比较低，情绪低落明显，常有愁眉苦脸状态，兴趣也减退。有时会哭泣或感到活着太累的想法，失眠常见，食欲不振。建议您合理调整自我情绪，充分面对这种情绪并且恰当地调节好自己的情绪，适当选择应对方法，积极地面对生活的挑战。";
      case 4 -> "自我评价低，情绪低落，悲观，失望，有时控制不住要哭泣，甚至出现厌世的消极念头，有明显的抑郁体征如失眠早醒，食欲减退，体重下降等。建议您及时寻求心理咨询师的帮助，通过心理咨询手段改变自身的不良认知，消除不良情绪和行为，强迫自己走出去，多接触朋友，参加社会活动或出去旅游。";
      case 5 -> "自我评价很低，常感到自己像无用的人，情绪低落明显，整日愁眉不展，自己责怪自己。有时会产生无助感或绝望感，有消极观念出现，食欲减退，饮食不振。建议您及时就医，寻求专业医生的帮助。";
      default -> "苦闷的情感与心境为代表性症状，还以生活兴趣的减退，动力缺乏，活力丧失等为特征。还表现出失望、悲观以及与抑郁相联系的认知和躯体方面的感受，另外，还包括有关死亡的思想和自杀观念。您在该因子中表现正常。";
    };
  }

  private String sclAdviceJl(int degree) {
    return switch (degree) {
      case 2 -> "经常有莫名的担心，有时会有害怕的感觉，但有时不明白为什么会这样。可伴有心慌、心跳快的感受，易紧张，偶可见出汗，也会采取一些掩饰举动。建议您在焦虑情绪尚不明显时，学习一些控制和消除焦虑的方法，如肌肉放松法、深呼吸法等，维系自身的身心健康。";
      case 3 -> "经常有不明所以的担心、紧张，无法掩饰的焦虑状态，如心跳、心慌，常有出汗，手指轻微的颤抖，有时出现坐立不安的现象。建议您通过适当的调节缓解焦虑症状，维持健康的心理状态，如肌肉放松法、深呼吸法等，用以应对突发的紧张局面。";
      case 4 -> "坐立不安，经常显得紧张，担心即将面临灭顶之灾而出现明显的焦虑体征，如胸闷、气急、心跳快、心慌，浑身发抖，四肢出汗，尿频等。建议您寻求心理工作者的帮助，通过心理咨询有效缓解焦虑情绪，控制焦虑状态。同时建议您试着以更加平和、理智的心态面对生活。";
      case 5 -> "明显的紧张不安，总感到有不好的事要发生，坐立不安，来回徘徊。经常大汗淋漓，心跳快、心慌、胸闷气急，严重的惊恐发作时，可有疑死的感觉而非常紧张。建议您及时就医，寻求专业医生的帮助。";
      default -> "一般指那些烦躁，坐立不安，神经过敏，紧张以及由此产生的躯体征象，如震颤等。您在该因子中表现正常。";
    };
  }

  private String sclAdviceDd(int degree) {
    return switch (degree) {
      case 2 -> "偶有怀疑的想法，感到别人不是真心的友好，经常表现警惕性增高，注意别人的举动，是否对自己友好，偶而发脾气。建议您在未来的生活中保持豁达大度、开朗达观的心态，使您的生活充满和谐、快乐。";
      case 3 -> "平时警惕性就比较高，经常注意或怀疑别人的一举一动，谈话议论都要加以注意，是否有不利于自己的举动，常与人难以相处，偶然有破坏性行为如以摔东西来发泄对别人的不满。建议您在与人交往的时候，有意识的控制自己的脾气，试着站在对方的角度理解对方的做法。";
      case 4 -> "平时充满敌意，经常疑心别人有意与他作对，内心对环境忿忿不满，常常想叫骂，摔东西，还常为小事与人争斗，终使之难以与周围人相处。建议您与人交往的时候，有意识的控制自己的脾气，如果有可能最好求助于心理专业人士，可以更快、更好的改善敌对症状，并且可以帮助您弥补个性上不成熟的方面。";
      case 5 -> "怀疑心十分明显，甚至会怀疑别人采取了迫害自己的事。经常会发怒，激惹性增强，以叫骂，摔东西来发泄，与人难以相处，甚至连亲人都无法友好相处。建议您及时就医，寻求专业医生的帮助。";
      default -> "主要从三方面来反映敌对的表现：思想、感情及行为。其项目包括厌烦的感觉，摔物，争论直到不可控制的脾气暴发等各方面。您在该因子中表现正常。";
    };
  }

  private String sclAdviceKb(int degree) {
    return switch (degree) {
      case 2 -> "有时不敢独自一人留在家中，与他人相处有一种安全感，有的表现为不敢去空旷处，有的则不敢与生人交往，但能够尽力的克制或掩饰自己，对工作影响不明显。建议您保持希望，调整心态。";
      case 3 -> "经常会采取某些逃避行为，主要是担心、缺少安全感，所以表现为不敢独自一人留在家中，不敢去空旷的地方，强制去时有紧张、焦虑、手足出汗的症状出现，也会有心跳加快、心慌的表现。建议您明确自身害怕的事情，通过分层的方法逐步消除恐惧。";
      case 4 -> "无法接触恐怖的对象，经常采取主动逃避行为，有焦虑，紧张，心慌的感觉。一旦接触到恐怖对象会引起惊恐发作和濒死感。已影响到日常工作和生活。建议您在心理工作者的指导下采用系统脱敏的方法慢慢地加以消除。";
      case 5 -> "对自己所恐怖的对象无法去接触，会采取强烈的逃避行为，伴有紧张、焦虑的心情，严重时会产生昏厥的担心，甚至有胸闷气急或疑死感受，明显的影响工作和日常生活。建议您及时就医，寻求专业医生的帮助。";
      default -> "恐惧的对象包括出门旅行，空旷场地，人群或公共场所和交通工具。此外，还有社交恐怖。您在该因子中表现正常。";
    };
  }

  private String sclAdvicePz(int degree) {
    return switch (degree) {
      case 2 -> "性格固执，即使是错误的观点，亦不大能改变。有时会有敌对性，经常有怀疑心，而无法相信别人，偶而认为会被人跟踪。建议您对周边的人或事能够以客观、理智的态度来对待，不会苛求、走极端。";
      case 3 -> "怀疑性明显，经常认为别人和自己过不去，要迫害他，对别人的一举一动也认为与自己有关系，常感到被人跟踪或被人监视。建议您积极转变自己看待事物的方法和角度，听取他人意见，表达自身想法。";
      case 4 -> "不信任别人，经常怀疑别人捉弄他，迫害他，为此去收集别人加害了他的依据，如走在路上感到被跟踪，看到报导认为在含沙射影针对他等，内心紧张，害怕，忿忿不平，经常影响工作与生活。建议您寻求专业的心理咨询改善偏执症状，逐渐纠正自身不合理的认识和想法。";
      case 5 -> "无法信任别人，经常怀疑别人要阴谋迫害他，认为是受到监视，被人跟踪，经常会采取逃避的行为，或者紧张、害怕、不敢出门，无法去工作，日常生活也受到影响。建议您及时就医，寻求专业医生的帮助。";
      default -> "主要指投射性思维，敌对，猜疑，妄想，被动体验和夸大等。您在该因子中表现正常。";
    };
  }

  private String sclAdviceJsbx(int degree) {
    return switch (degree) {
      case 2 -> "偶而有幻听，大多是被人批评、责怪，有时认为是别人迫害他的行为，偶而会出现自己脑子里想的东西没有讲出来，别人就知道了，常有敌对性。可能会有自责的倾向，还可能有孤独感。建议您要足够重视该情况，寻求心理工作者的帮助，找到引起症状的原因。";
      case 3 -> "经常有幻听，内容多为批评、责骂，有时与幻听互相对夸、对骂，认为别人要害他，跟踪他，伴有紧张情绪，有时认为自己的思维被别人知道了，还会播散出去。或有些自责倾向，感到孤独。建议您积极寻求心理工作者的帮助，必要时接受进一步精神科的检查。";
      case 4 -> "经常有幻听，内容多为批评责骂，且把幻觉当作真实，有时与之对骂，有时为之受惊吓，有时听从幻听去伤人，自残和破坏环境，有时则显得淡漠，发呆。或经常自责，难以摆脱孤独感。建议您接受进一步的精神科检查，以便及早判定其症状是否属于精神疾病的表现。";
      case 5 -> "经常有幻听，其内容多为批评、责骂，少数为表扬，有时沉浸在幻听中，而不与人接触交谈，且伴有明显的独自发呆，喃喃自语，或与幻听对骂，有时感到思维被别人了解了，或被人控制了，而没有行动的自由了。有时在命令性幻听的支配下做出伤人或自伤的举动。或有严重自责和孤独感。建议您接受进一步精神科检查，必要时通过药物或其他手段减少或消除症状。";
      default -> "反映各式各样的急性症状和行为，即限定不严的精神病性过程的症状表现。您在该因子中表现正常。";
    };
  }

  private ScoringResult sds(Map<String, Integer> a) {
    int raw = sum(a, 2082, 1,3,4,7,8,9,10,13,15,19) + reverse4(a, 2082, 2,5,6,11,12,14,16,17,18,20);
    int standard = (int) (raw * 1.25);
    Map<String, Integer> d = new LinkedHashMap<>();
    d.put("粗分", raw);
    d.put("标准分", standard);
    String level = standard >= 73 ? "重度参考" : standard >= 63 ? "中度参考" : standard >= 53 ? "轻度参考" : "常规范围";
    String summary = String.valueOf(standard);
    String suggestions;
    if (standard < 53) {
      suggestions = "根据测评得分情况来看，您的情绪平和，没有抑郁症状，自身情绪基本处于愉快、开心的境况，对自己和生活感到满意，不会经常被不开心的事情困扰。即使是偶尔遇到挫折和不幸，也比较容易自我调节，或从他人那里得到支持帮助，从而克服难关。希望您能继续保持这种快乐明朗的心态，积极面对生活中的挑战。";
    } else if (standard <= 62) {
      suggestions = "根据测评得分情况来看，您有时情绪低落，睡眠不佳、容易疲劳，经常犹疑不决、有空虚、无望等感觉。您此时的抑郁程度为轻度。建议先自我调整，通过运动，逛街，跟朋友聊天，听音乐等体育和娱乐活动调整一下情绪状态。如无好转请及时求助专业人员。";
    } else if (standard < 72) {
      suggestions = "根据测评得分情况来看，您经常有情绪低落的时候，特别是早晨比较严重傍晚稍好一些。总想哭，经常失眠或者总是睡不醒。食欲不振，体重减轻，感觉四肢无力，对什么事情都提不起兴趣，觉得自己什么都做不好。时常自责，有自杀的念头。您此时的抑郁程度为中度。建议您积极进行自我调整，改变不合理认知，寻求支持的社会资源，适当转移注意力。而且要与专业人士保持联系，以便获得及时的帮助，协助您抵御不良情绪。";
    } else {
      suggestions = "根据测评得分情况来看，您总有情绪低落的状况，特别是早晨比较严重傍晚稍好一些。经常不由自主的泪流满面，严重的失眠，不想吃东西，不想动，性欲减退，反应迟钝，有很强的无望感，自罪自责，有强烈的自杀意念甚至已经有了自杀的行为表现。您此时为重度抑郁。建议您在家人的协助下寻求医生的帮助，按医嘱服用药物或住院治疗，辅助定期的心理咨询。让自己尽快摆脱抑郁症的困扰。";
    }
    return result(standard, level, d, summary, suggestions);
  }

  private ScoringResult sas(Map<String, Integer> a) {
    int raw = sum(a, 2083, 1,2,3,4,6,7,8,10,11,12,14,15,16,18,20) + reverse4(a, 2083, 5,9,13,17,19);
    int standard = (int) (raw * 1.25);
    Map<String, Integer> d = new LinkedHashMap<>();
    d.put("粗分", raw);
    d.put("标准分", standard);
    String level = standard >= 70 ? "重度参考" : standard >= 60 ? "中度参考" : standard >= 50 ? "轻度参考" : "常规范围";
    String summary = String.valueOf(standard);
    String suggestions;
    if (standard < 50) {
      suggestions = "根据测评得分情况来看，您过去一周内情绪比较稳定，心态平和很少焦虑，您很少感到有压力感，较少感觉到交际、烦躁的情绪或者对未来事件不确定性的担心和忧虑。这可能是出于您对生活中的各种挫折和压力，能够以比较平和的心态去面对，善于用适当的方式去化解。";
    } else if (standard <= 59) {
      suggestions = "根据测评得分情况来看，您过去一周内偶尔会感到紧张、害怕、恐惧，但焦虑程度较轻。建议你先通过适量有氧运动、冥想以及其他娱乐活动进行自我调节。如无好转，请及时求助专业人士。";
    } else if (standard <= 69) {
      suggestions = "根据测评得分情况来看，您过去一周内经常感到恐惧、担心，甚至会有不幸的预感以及心悸等躯体症状。您此时的焦虑程度为中度。建议您可以通过转移注意力、做有氧运动、调整认知、换个角度思考问题等方式进行自我调整。同时寻求专业人士的帮助，进行系统的身心调整。";
    } else {
      suggestions = "根据测评得分情况来看，您过去一周绝大部分时间内都感到害怕、坐立不安，甚至会有胃痛、头晕、呼吸困难等躯体症状。您此时为重度焦虑。建议您尽快寻求专业人士的帮助，到医院、心理诊所等正规机构进行系统的身心调整，按照医嘱服用药物并辅助定期的心理咨询。让自己尽快摆脱焦虑症的困扰。";
    }
    return result(standard, level, d, summary, suggestions);
  }

  private ScoringResult sqa(Map<String, Integer> a) {
    Map<String, Integer> d = new LinkedHashMap<>();
    int s1 = sum(a, 2084, 17,19,23,26,29) + reverse5(a, 2084, 1,7,12,22);
    int s2 = sum(a, 2084, 2,9,13,24,25) + reverse5(a, 2084, 3,8,14,18,20);
    int s3 = sum(a, 2084, 4,6) + reverse5(a, 2084, 10,15,28);
    int s4 = sum(a, 2084, 5,16,21,27) + reverse5(a, 2084, 11);
    d.put("F1 自杀行为性质认识", scale100(s1, 9));
    d.put("F2 对自杀者态度", scale100(s2, 10));
    d.put("F3 对自杀者家属态度", scale100(s3, 5));
    d.put("F4 对安乐死态度", scale100(s4, 5));
    double f1 = s1 / 9.0;
    double f2 = s2 / 10.0;
    double f3 = s3 / 5.0;
    double f4 = s4 / 5.0;
    String level = "态度画像";
    String summary = "对自杀行为性质得分:" + round2(f1)
        + "；对自杀者态度得分:" + round2(f2)
        + "；对自杀者家属态度得分:" + round2(f3)
        + "；对安乐死态度得分:" + round2(f4) + "。";
    String suggestions = sqaAttitudeText("自杀行为性质", f1)
        + "\n" + sqaAttitudeText("自杀者", f2)
        + "\n" + sqaAttitudeText("自杀者家属", f3)
        + "\n" + sqaAttitudeText("安乐死", f4);
    return result(sum(d), level, d, summary, suggestions);
  }

  private ScoringResult pf16(Map<String, Integer> a) {
    Map<String, Integer> d = new LinkedHashMap<>();
    d.put("A乐群性", pos3(a, 2081, 26,27,51,76,151) + neg3(a, 2081, 3,52,101,126,176));
    d.put("B聪慧性", count(a, 2081, new int[]{177,178}, 1) + count(a, 2081, new int[]{28,53,54,78,103,128,152}, 2) + count(a, 2081, new int[]{77,102,127,153}, 3));
    d.put("C稳定性", pos3(a, 2081, 5,29,79,80,154) + neg3(a, 2081, 4,30,55,104,105,129,130,179));
    d.put("E恃强性", pos3(a, 2081, 6,31,32,57,81,106) + neg3(a, 2081, 7,56,131,155,156,180,181));
    d.put("F兴奋性", pos3(a, 2081, 8,82,83,107,108,157,158) + neg3(a, 2081, 33,58,132,133,182,183));
    d.put("G有恒性", pos3(a, 2081, 9,34,84,159) + neg3(a, 2081, 59,109,134,160,184,185));
    d.put("H敢为性", pos3(a, 2081, 35,60,61,85,86,135,161) + neg3(a, 2081, 10,36,110,111,136,186));
    d.put("I敏感性", pos3(a, 2081, 11,12,62,87,137,162) + neg3(a, 2081, 37,112,138,163));
    d.put("L怀疑性", pos3(a, 2081, 63,64,89,139) + neg3(a, 2081, 13,38,88,113,114,164));
    d.put("M幻想性", pos3(a, 2081, 14,15,90,141,165,166) + neg3(a, 2081, 39,40,65,91,115,116,140));
    d.put("N世故性", pos3(a, 2081, 16,41,66,67,92) + neg3(a, 2081, 17,42,117,142,167));
    d.put("O忧虑性", pos3(a, 2081, 19,44,68,93,94,144) + neg3(a, 2081, 18,43,69,118,119,143,168));
    d.put("Q1实验性", pos3(a, 2081, 45,95,120,170) + neg3(a, 2081, 20,21,46,70,145,169));
    d.put("Q2独立性", pos3(a, 2081, 22,96,97,121,122) + neg3(a, 2081, 47,71,72,146,171));
    d.put("Q3自律性", pos3(a, 2081, 23,24,123,172) + neg3(a, 2081, 48,73,98,147,148,173));
    d.put("Q4紧张性", pos3(a, 2081, 75,100,125,175) + neg3(a, 2081, 25,49,50,74,99,124,149,150,174));
    return result(sum(d), dominantLevel(d), d, "16PF 卡特尔人格测试完成。系统按 16 个基本人格因素计算原始分。", "16PF 解释建议结合岗位、参会目标和访谈信息综合使用；本系统不在前端暴露任何计分键。");
  }

  private ScoringResult generic(Assessment assessment, List<Question> questions, Map<String, Integer> answers) {
    Map<String, Integer> d = new LinkedHashMap<>();
    for (Question question : questions) d.merge(question.getDimension(), answers.getOrDefault(question.getCode(), 0), Integer::sum);
    return result(sum(d), dominantLevel(d), d, assessment.getTitle() + "已完成。", "请结合后台维度得分进行解释。");
  }

  private int q(Map<String, Integer> a, int paper, int index) {
    return a.getOrDefault(String.format("%d%03d", paper, index), 0);
  }

  private int sum(Map<String, Integer> a, int paper, int... indexes) {
    int total = 0;
    for (int index : indexes) total += q(a, paper, index);
    return total;
  }

  private int sum(Map<String, Integer> d) {
    return d.values().stream().mapToInt(Integer::intValue).sum();
  }

  private int count(Map<String, Integer> a, int paper, int[] indexes, int expected) {
    int total = 0;
    for (int index : indexes) if (q(a, paper, index) == expected) total++;
    return total;
  }

  private int reverse4(Map<String, Integer> a, int paper, int... indexes) {
    int total = 0;
    for (int index : indexes) total += 5 - q(a, paper, index);
    return total;
  }

  private int reverse5(Map<String, Integer> a, int paper, int... indexes) {
    int total = 0;
    for (int index : indexes) total += 6 - q(a, paper, index);
    return total;
  }

  private int pos3(Map<String, Integer> a, int paper, int... indexes) {
    int total = 0;
    for (int index : indexes) total += Math.max(0, q(a, paper, index) - 1);
    return total;
  }

  private int neg3(Map<String, Integer> a, int paper, int... indexes) {
    int total = 0;
    for (int index : indexes) total += Math.max(0, 3 - q(a, paper, index));
    return total;
  }

  private int scale100(int score, int count) {
    return BigDecimal.valueOf(score / (double) count * 20).setScale(0, RoundingMode.HALF_UP).intValue();
  }

  private String dominantLevel(Map<String, Integer> d) {
    return d.entrySet().stream().max(Map.Entry.comparingByValue()).map(Map.Entry::getKey).orElse("综合结果");
  }

  private String epqPersonalityType(int e, int n) {
    if (e > 14 && n > 16) return "胆汁质";
    if (e > 14 && n < 9) return "多血质";
    if (e < 9 && n > 16) return "抑郁质";
    if (e < 9 && n < 9) return "粘液质";
    return "混合型";
  }

  private String epqTemperamentAdvice(int e, int n) {
    if (e > 14 && n > 16) {
      return "胆汁质：您的气质类型属于胆汁质。热情，直爽，精力旺盛，脾气急躁，易动感情，反应迅速。但易冲动、自制力差、办事粗心，缺少坚韧性和持久力。在学习和工作中经常“三分钟热血”，难以获得较高成就。您适合做反应迅速、动作有力、应急性强、危险性较大、难度较高且费力的工作，如：导游员、勘探工作者、推销员、节目主持人、演讲者、外事接待员等。";
    }
    if (e > 14 && n < 9) {
      return "多血质：您的气质类型属于多血质。活泼、好动、敏感、反应迅速、喜欢与人交往、注意力容易转移、兴趣和情感易变换。您精于调整、调和各类关系，有经营管理、分析设计和规划能力，适宜做反应迅速而灵活的工作，如：经济规划、统计、设计、商业推销、演员等。";
    }
    if (e < 9 && n > 16) {
      return "抑郁质：您的气质类型属于抑郁质。为人小心谨慎，不太合群、非常敏感、在困难面前容易优柔寡断。但观察细致、思考透彻，对情感的体验深刻、有力、持久。您比较适合的职业，如：作家、编辑、质检员、艺术工作者、哲学家等。";
    }
    if (e < 9 && n < 9) {
      return "粘液质：您的气质类型属于粘液质。稳重，考虑问题全面周到，安静沉默，善于克制自己。情绪不外露，注意力稳定不容易转移，外部动作少而缓慢。但不够灵活，容易因循守旧，对事业缺乏热情。比较适合从事的工作，如：外科医生、法官、会计、审计、人力资源管理者等。";
    }
    return "混合型：您的气质类型是属于混合型的。既能够顺畅的与人交流和互动，也能够一个人独处安心做事。您的情绪平和稳定，比较善解人意。您的注意力、耐受力等人格特质都处于人群之中的平均水平。混合型的气质类型有助于您从事各级各类的工作。只要勤奋努力，持之以恒，都能够获得学业与职业发展的成功。";
  }

  private String sqaAttitudeText(String name, double score) {
    if ("自杀行为性质".equals(name)) {
      if (score <= 2.5) return "您将自杀看作一种自然的生命现象，是人对生命所作的一种自由的选择，不应有道德好坏的评判。您认为个人有选择生死的权利，在人生某些特殊时候采取自杀的行为是值得肯定的。虽然您对自杀的态度是肯定和认可的，但是仍希望您能够保重自己，珍爱生命。";
      if (score < 3.5) return "您对自杀行为还未形成清晰而明确的态度，尤其是对自杀尚缺乏一定的认识。这可能是由于您的年龄和社会阅历的限制，也有可能是出于矛盾的心理，既认同生死是个体自由的选择，同时又认为应该珍惜生命，不该随意结束生命，因而对于自杀很难有比较明确的态度。";
      return "您倾向于认为自杀行为是非理性的、冲动的、不负责任的逃避、是对生命的不尊重，是对生命权力的滥用；您认为自杀行为是不被认可的，无论什么样的理由都不足以构成自杀的借口。您对自杀行为是持反对否定态度的。当然这并不意味着您会排斥或歧视自杀者及其家属。";
    }
    if ("自杀者".equals(name)) {
      if (score <= 2.5) return "您是尊重、同情、理解自杀者的，不赞同对自杀者加以任何的道德评判，尤其是对自杀未遂者不表示歧视，愿意与其建立和保持正常的情感关系，并且愿意为其提供情感和物质上的支持和帮助。您对自杀者或者自杀未遂者是同情、理解和宽容的。";
      if (score < 3.5) return "您对自杀者还未形成清晰而明确的态度，您很模棱两可，对其既同情又不赞同，存在着矛盾的心理，因而对自杀的态度不置可否。";
      return "您不认同自杀者或者自杀未遂者，不赞同给予其与自然死亡者同等的待遇，习惯对其作道德上的评判，倾向于认为其自私，不负责任。您与自杀未遂者相处时关系淡漠，不愿与其建立和保持亲密关系，不愿表示同情、关心和爱护。对那些反复尝试自杀的人特别反感、排斥和否定。";
    }
    if ("自杀者家属".equals(name)) {
      if (score <= 2.5) return "您对自杀者家属所受的痛苦和压力有深切的共鸣，愿意尽可能的同情、关心和帮助他们，并且不愿追究其对自杀者是否负有责任，不歧视他们。对自杀者家属是同情、理解和宽容的。";
      if (score < 3.5) return "您尚未形成对自杀者家属清晰而明确的态度，可能既同情他们，又埋怨他们，或者只愿意为其提供物质支持，而不愿意有情感上的接触，因此您对自杀者家属的态度是不置可否的。";
      return "您认为自杀者的家属应对自杀者的自杀行为承担一定的责任，不太能够感受其所受的痛苦，尽量避免与其交往，不愿意对其提供情感和物质的帮助和支持。您对自杀者家属的态度是排斥和歧视的。";
    }
    if (score <= 2.5) return "您对安乐死持肯定、认可、理解和宽容的态度，这说明您对安乐死有一定的了解，能理解他人采取安乐死的做法，并且认为自己在适当的时候也可以接受安乐死。您能够理解和接受安乐死，对他人或自己采取安乐死的作法较为宽容。";
    if (score < 3.5) return "您对安乐死持矛盾或中立的态度，这说明您可能是不太理解安乐死，或者是对生与死的选择还比较犹豫和矛盾，您对安乐死的态度尚未形成清晰而明确的答案。";
    return "您对安乐死持反对、否定、排斥和歧视态度，您不认同安乐死，认为绝症或垂死病人都不应选择安乐死，安乐死是对生命的轻视和不尊重。您对他人或自己采取安乐死的作法较为排斥。";
  }

  private String round2(double value) {
    return BigDecimal.valueOf(value).setScale(2, RoundingMode.HALF_UP).toPlainString();
  }

  private float round2f(float value) {
    return BigDecimal.valueOf(value).setScale(2, RoundingMode.HALF_UP).floatValue();
  }

  private ScoringResult result(int rawScore, String level, Map<String, Integer> d, String summary, String suggestions) {
    return new ScoringResult(rawScore, level, d, summary, suggestions);
  }

  public record ScoringResult(int rawScore, String level, Map<String, Integer> dimensionScores, String summary, String suggestions) {}
}
