package thyyxxk.webserver.service.outpatient.interactive.clinicsatisfied;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import thyyxxk.webserver.config.exception.ExceptionEnum;
import thyyxxk.webserver.dao.his.outpatient.interactive.ClinicSatisfiedDao;
import thyyxxk.webserver.entity.ResultVo;
import thyyxxk.webserver.entity.inpatient.nursemodule.response.PatientBriefInfo;
import thyyxxk.webserver.entity.outpatient.interactive.clinicsatisfied.request.ClinicSatisfiedInquiry;
import thyyxxk.webserver.entity.outpatient.interactive.clinicsatisfied.request.ModifyStatus;
import thyyxxk.webserver.entity.outpatient.interactive.clinicsatisfied.request.VisitType;
import thyyxxk.webserver.entity.outpatient.interactive.clinicsatisfied.response.*;
import thyyxxk.webserver.utils.DecimalUtil;
import thyyxxk.webserver.utils.ResultVoUtil;
import thyyxxk.webserver.utils.StringUtil;
import thyyxxk.webserver.utils.TokenUtil;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

@Service
public class QuestionnaireService {
    private final ClinicSatisfiedDao dao;

    @Autowired
    public QuestionnaireService(ClinicSatisfiedDao dao) {
        this.dao = dao;
    }

    public ResultVo<SatisfiedResponse> getQuestionnaireBodies(ClinicSatisfiedInquiry inquiry) {
        QueryWrapper<?> wrapper = makeQueryWrapper(inquiry);
        String table = inquiry.getVisitType() == VisitType.INPATIENT ?
                "t_inpatient_questionnaire_v2" : "t_outpatient_questionnaire_v2";
        List<QuestionnaireV2> list = dao.selectQuestionnaireBodies(wrapper, inquiry.getPageNum(), inquiry.getPageSize(), table);
        if (list.isEmpty()) {
            return ResultVoUtil.fail(ExceptionEnum.NO_DATA_EXIST);
        }
        analyzeAssessmentItems(inquiry.getVisitType(), list);
        SatisfiedResponse response = new SatisfiedResponse();
        response.setVisitType(inquiry.getVisitType());
        response.setTotalSize(dao.selectValidCount(wrapper, table));
        response.setListV2(list);
        return ResultVoUtil.success(response);
    }

    public ResultVo<List<Patientinfo>> getPatInfoList(ClinicSatisfiedInquiry inquiry) {
        if (StringUtil.notBlank(inquiry.getWard())) {
            inquiry.setStatement(" and dis_ward='" + inquiry.getWard() + "'");
        }
        return ResultVoUtil.success(dao.getPatientinfoList(inquiry));
    }

    public ResultVo<List<QuestionnaireV2>> getAllQuestionnaireBodies(ClinicSatisfiedInquiry inquiry) {
        QueryWrapper<?> wrapper = makeQueryWrapper(inquiry);
        String table = inquiry.getVisitType() == VisitType.INPATIENT ?
                "t_inpatient_questionnaire_v2" : "t_outpatient_questionnaire_v2";
        List<QuestionnaireV2> list = dao.selectAllQuestionnaireBodies(wrapper, table);
        if (list.isEmpty()) {
            return ResultVoUtil.fail(ExceptionEnum.NO_DATA_EXIST);
        }
        analyzeAssessmentItems(inquiry.getVisitType(), list);
        return ResultVoUtil.success(list);
    }

    private QueryWrapper<?> makeQueryWrapper(ClinicSatisfiedInquiry inquiry) {
        QueryWrapper<?> wrapper = new QueryWrapper<>();
        wrapper.apply("1=1");
        if (null != inquiry.getDeleted()) {
            wrapper.eq("deleted", inquiry.getDeleted());
        }
        if (StringUtil.notBlank(inquiry.getStart())) {
            wrapper.ge("create_datetime", inquiry.getStart());
        }
        if (StringUtil.notBlank(inquiry.getEnd())) {
            wrapper.le("create_datetime", inquiry.getEnd());
        }
        if (StringUtil.notBlank(inquiry.getPatNo())) {
            wrapper.eq("inpatient_no", inquiry.getPatNo());
            if (null != inquiry.getTimes()) {
                wrapper.eq("times", inquiry.getTimes());
            }
        }
        if (inquiry.getVisitType() == VisitType.EMERGENCY) {
            wrapper.eq("jz_flag", 1);
        } else if (inquiry.getVisitType() == VisitType.OUTPATIENT) {
            wrapper.eq("jz_flag", 0);
        }
        if (StringUtil.isBlank(inquiry.getPatNo()) && StringUtil.notBlank(inquiry.getWard())) {
            wrapper.eq("ward_code", inquiry.getWard());
        }
        if (inquiry.getOnlyShowUnsatisfied()) {
            String header = "(yjk='不满意' or fsk='不满意' or csyxk='不满意' or jyk='不满意' or sfck='不满意' or ybk='不满意' or yyhjws='不满意' ";
            String tail = inquiry.getVisitType() == VisitType.INPATIENT ?
                    " or zykshl='不满意' or zyksys='不满意' or yyst='不满意' or mzyh='不满意' or jzyh='不满意')"
                    : " or mjzdzjhl='不满意' or mjzys='不满意')";
            wrapper.apply(header + tail);
        }
        return wrapper;
    }

    private void analyzeAssessmentItems(VisitType visitType, List<QuestionnaireV2> list) {
        list.forEach(item -> {
            item.setYjk(combineAnswerAndOptions(item.getYjk(), item.getYjkBmyyy(), item.getYjkInput()));
            item.setFsk(combineAnswerAndOptions(item.getFsk(), item.getFskBmyyy(), item.getFskInput()));
            item.setCsyxk(combineAnswerAndOptions(item.getCsyxk(), item.getCsyxkBmyyy(), item.getCsyxkInput()));
            item.setJyk(combineAnswerAndOptions(item.getJyk(), item.getJykBmyyy(), item.getJykInput()));
            item.setSfck(combineAnswerAndOptions(item.getSfck(), item.getSfckBmyyy(), item.getSfckInput()));
            item.setYbk(combineAnswerAndOptions(item.getYbk(), item.getYbkBmyyy(), item.getYbkInput()));
            item.setYyhjws(combineAnswerAndOptions(item.getYyhjws(), item.getYyhjwsBmyyy(), item.getYyhjwsInput()));
            item.setXzwyyy(combineAnswerAndOptions(item.getXzwyyy(), null, item.getXzwyyyInput()));
            if (visitType == VisitType.INPATIENT) {
                item.setZykshl(combineAnswerAndOptions(item.getZykshl(), item.getZykshlBmyyy(), item.getZykshlInput()));
                item.setZyksys(combineAnswerAndOptions(item.getZyksys(), item.getZyksysBmyyy(), item.getZyksysInput()));
                item.setYyst(combineAnswerAndOptions(item.getYyst(), item.getYystBmyyy(), item.getYystInput()));
                item.setMzyh(combineAnswerAndOptions(item.getMzyh(), item.getMzyhBmyyy(), item.getMzyhInput()));
                item.setJzyh(combineAnswerAndOptions(item.getJzyh(), item.getJzyhBmyyy(), item.getJzyhInput()));
            } else {
                item.setMjzdzjhl(combineAnswerAndOptions(item.getMjzdzjhl(), item.getMjzdzjhlBmyyy(), item.getMjzdzjhlInput()));
                item.setMjzys(combineAnswerAndOptions(item.getMjzys(), item.getMjzysBmyyy(), item.getMjzysInput()));
            }
        });
    }

    private String combineAnswerAndOptions(String answer, String options, String input) {
        if (StringUtil.isBlank(answer)) {
            return "";
        }
        if (!answer.equals("不满意")) {
            return answer;
        }
        return answer + "：" + analyzedCheckboxOptions(options, input);
    }

    private String analyzedCheckboxOptions(String checkboxString, String input) {
        if (StringUtil.isBlank(input)) {
            input = "";
        } else {
            input = "【" + input + "】";
        }
        if (StringUtil.isBlank(checkboxString)) {
            return input;
        }
        return checkboxString + "。" + input;
    }

    public PatientBriefInfo getPatientBriefInfo(String patNo, Integer times) {
        if (times == 0) {
            return dao.selectOutpatientBriefInfo(patNo);
        }
        PatientBriefInfo info = dao.selectInpatientBriefInfo("zy_inactpatient", patNo, times);
        if (null == info) {
            info = dao.selectInpatientBriefInfo("zy_actpatient", patNo, times);
        }
        return info;
    }

    public ResultVo<String> updateAssessmentStatus(ModifyStatus modifyStatus) {
        String table = modifyStatus.getVisitType() == VisitType.INPATIENT ?
                "t_inpatient_questionnaire_v2" : "t_outpatient_questionnaire_v2";
        modifyStatus.setTable(table);
        if (modifyStatus.getDeleted() == 1) {
            modifyStatus.setStaff(TokenUtil.getInstance().getTokenUserId());
            modifyStatus.setDate(new Date());
        }
        int count = dao.updateAssessmentStatus(modifyStatus);
        if (count == 1) {
            return ResultVoUtil.success("操作成功。");
        }
        return ResultVoUtil.fail(ExceptionEnum.NO_DATA_EXIST);
    }

    public ResultVo<AnalyzeResultV2> assessmentsAnalyse(ClinicSatisfiedInquiry inquiry) {
        inquiry.setDeleted(0);
        QueryWrapper<?> wrapper = makeQueryWrapper(inquiry);
        AnalyzeResultV2 result = new AnalyzeResultV2();
        VisitType visitType = inquiry.getVisitType();
        List<BriefSuggestion> suggestions;
        if (visitType == VisitType.INPATIENT) {
            suggestions = dao.selectInpatientSuggestionsV2(wrapper);
        } else {
            suggestions = dao.selectOutpatientSuggestionsV2(wrapper);
        }
        result.setSuggestions(suggestions);
        String table = visitType == VisitType.INPATIENT ?
                "t_inpatient_questionnaire_v2" : "t_outpatient_questionnaire_v2";
        List<QuestionnaireV2> list = dao.selectAllQuestionnaireBodies(wrapper, table);
        result.setTotalQuestionnaireCount(list.size());
        if (!inquiry.getOnlyShowUnsatisfied()) {
            inquiry.setOnlyShowUnsatisfied(true);
            wrapper = makeQueryWrapper(inquiry);
        }
        result.setTotalUnsatisfiedCount(dao.selectUnsatisfiedCount(wrapper, table));
        result.setTotalUnsatisfiedPercentage(makePercentage(result.getTotalUnsatisfiedCount(),result.getTotalQuestionnaireCount()));

        int totalOptionCount = 0;
        int totalUnsatisfiedOptionCount = 0;

        int yjkAssessmentCount = 0;
        int yjkUnsatisfiedCount = 0;
        int fskAssessmentCount = 0;
        int fskUnsatisfiedCount = 0;
        int csyxkAssessmentCount = 0;
        int csyxkUnsatisfiedCount = 0;
        int jykAssessmentCount = 0;
        int jykUnsatisfiedCount = 0;
        int sfckAssessmentCount = 0;
        int sfckUnsatisfiedCount = 0;
        int ybkAssessmentCount = 0;
        int ybkUnsatisfiedCount = 0;
        int yyhjwsAssessmentCount = 0;
        int yyhjwsUnsatisfiedCount = 0;
        // <-- 以下门诊独有
        int mjzdzjhlAssessmentCount = 0;
        int mjzdzjhlUnsatisfiedCount = 0;
        int mjzysAssessmentCount = 0;
        int mjzysUnsatisfiedCount = 0;
        // -->
        // <-- 以下住院独有
        int zykshlAssessmentCount = 0;
        int zykshlUnsatisfiedCount = 0;
        int zyksysAssessmentCount = 0;
        int zyksysUnsatisfiedCount = 0;
        int yystAssessmentCount = 0;
        int yystUnsatisfiedCount = 0;
        int mzyhAssessmentCount = 0;
        int mzyhUnsatisfiedCount = 0;
        int jzyhAssessmentCount = 0;
        int jzyhUnsatisfiedCount = 0;
        // -->

        String defaultOptions = "{\"叫号服务\": 0,\"等待时长\": 0,\"服务态度\": 0,\"沟通解释\": 0,\"及时响应\": 0,\"服装礼仪\": 0,\"准确率\": 0}";
        String ybkOptions = "{\"专业能力\": 0,\"等待时长\": 0,\"服务态度\": 0,\"沟通解释\": 0,\"及时响应\": 0,\"服装礼仪\": 0,\"服务流程\": 0}";
        String hjwsOptions = "{\"食堂卫生\": 0,\"门诊大厅卫生\": 0,\"诊间卫生\": 0,\"病房卫生\": 0,\"卫生间卫生\": 0,\"电梯卫生\": 0,\"楼道卫生\": 0,\"座椅卫生\": 0,\"公共区域\": 0}";
        String xzlwyyy = "{\"慕名而来\": 0,\"就近选择\": 0,\"朋友推荐\": 0,\"网络查询\": 0,\"服务水平\": 0,\"环境设备\": 0,\"医疗价格\": 0}";

        String mjzdzjhlOptions = "{\"技术水平\": 0,\"隐私保护\": 0,\"服务态度\": 0,\"沟通解释\": 0,\"病情巡视\": 0,\"服装礼仪\": 0}";
        String mjzysOptions = "{\"技术水平\": 0,\"隐私保护\": 0,\"服务态度\": 0,\"沟通解释\": 0,\"按时坐诊\": 0,\"服装礼仪\": 0}";

        String zykshlOptions = "{\"技术水平\": 0,\"隐私保护\": 0,\"服务态度\": 0,\"沟通解释\": 0,\"病情巡视\": 0,\"服装礼仪\": 0,\"其他\": 0}";
        String zyksysOptions = "{\"技术水平\": 0,\"隐私保护\": 0,\"服务态度\": 0,\"沟通解释\": 0,\"按时查房\": 0,\"服装礼仪\": 0,\"其他\": 0}";
        String yystOptions = "{\"卫生情况\": 0,\"口味\": 0,\"菜品\": 0,\"服务态度\": 0,\"服装礼仪\": 0,\"其他\": 0}";

        int yjkCheckedOptionsCount = 0;
        JSONObject yjkOptionsJson = JSONObject.parseObject(defaultOptions);
        int fskCheckedOptionsCount = 0;
        JSONObject fskOptionsJson = JSONObject.parseObject(defaultOptions);
        int csyxkCheckedOptionsCount = 0;
        JSONObject csyxkOptionsJson = JSONObject.parseObject(defaultOptions);
        int jykCheckedOptionsCount = 0;
        JSONObject jykOptionsJson = JSONObject.parseObject(defaultOptions);
        int sfckCheckedOptionsCount = 0;
        JSONObject sfckOptionsJson = JSONObject.parseObject(defaultOptions);
        int ybkCheckedOptionsCount = 0;
        JSONObject ybkOptionsJson = JSONObject.parseObject(ybkOptions);
        int yyhjwsCheckedOptionsCount = 0;
        JSONObject yyhjwsOptionsJson = JSONObject.parseObject(hjwsOptions);
        // <-- 以下门诊独有
        int mjzdzjhlCheckedOptionsCount = 0;
        JSONObject mjzdzjhlOptionsJson = JSONObject.parseObject(mjzdzjhlOptions);
        int mjzysCheckedOptionsCount = 0;
        JSONObject mjzysOptionsJson = JSONObject.parseObject(mjzysOptions);
        // -->
        // <-- 以下住院独有
        int zykshlCheckedOptionsCount = 0;
        JSONObject zykshlOptionsJson = JSONObject.parseObject(zykshlOptions);
        int zyksysCheckedOptionsCount = 0;
        JSONObject zyksysOptionsJson = JSONObject.parseObject(zyksysOptions);
        int yystCheckedOptionsCount = 0;
        JSONObject yystOptionsJson = JSONObject.parseObject(yystOptions);
        int mzyhCheckedOptionsCount = 0;
        JSONObject mzyhOptionsJson = JSONObject.parseObject(defaultOptions);
        int jzyhCheckedOptionsCount = 0;
        JSONObject jzyhOptionsJson = JSONObject.parseObject(defaultOptions);
        // -->

        int whyComeHereOptionsCount = 0;
        JSONObject whyComeHereOptionsJson = JSONObject.parseObject(xzlwyyy);
        int willComeAgainOptionsCount = 0;
        JSONObject willComeAgainOptionsJson = JSONObject.parseObject("{\"会\": 0,\"不会\": 0}");
        int[] gradeNumDetails = new int[] {0,0,0,0,0,0,0,0,0,0};
        int gradeSum = 0;
        for (QuestionnaireV2 body : list) {

            if (StringUtil.notBlank(body.getYjk()) && !body.getYjk().equals("未接触")) {
                totalOptionCount += 1;
                yjkAssessmentCount += 1;
            }
            if (Objects.equals("不满意", body.getYjk())) {
                totalUnsatisfiedOptionCount += 1;
                yjkUnsatisfiedCount += 1;
                yjkCheckedOptionsCount = getCheckedOptionsCount(yjkCheckedOptionsCount, yjkOptionsJson, body.getYjkBmyyy());
            }

            if (StringUtil.notBlank(body.getFsk()) && !body.getFsk().equals("未接触")) {
                totalOptionCount += 1;
                fskAssessmentCount += 1;
            }
            if (Objects.equals("不满意", body.getFsk())) {
                totalUnsatisfiedOptionCount += 1;
                fskUnsatisfiedCount += 1;
                fskCheckedOptionsCount = getCheckedOptionsCount(fskCheckedOptionsCount, fskOptionsJson, body.getFskBmyyy());
            }

            if (StringUtil.notBlank(body.getCsyxk()) && !body.getCsyxk().equals("未接触")) {
                totalOptionCount += 1;
                csyxkAssessmentCount += 1;
            }
            if (Objects.equals("不满意", body.getCsyxk())) {
                totalUnsatisfiedOptionCount += 1;
                csyxkUnsatisfiedCount += 1;
                csyxkCheckedOptionsCount = getCheckedOptionsCount(csyxkCheckedOptionsCount, csyxkOptionsJson, body.getCsyxkBmyyy());
            }

            if (StringUtil.notBlank(body.getJyk()) && !body.getJyk().equals("未接触")) {
                totalOptionCount += 1;
                jykAssessmentCount += 1;
            }
            if (Objects.equals("不满意", body.getJyk())) {
                totalUnsatisfiedOptionCount += 1;
                jykUnsatisfiedCount += 1;
                jykCheckedOptionsCount = getCheckedOptionsCount(jykCheckedOptionsCount, jykOptionsJson, body.getJykBmyyy());
            }

            if (StringUtil.notBlank(body.getSfck()) && !body.getSfck().equals("未接触")) {
                totalOptionCount += 1;
                sfckAssessmentCount += 1;
            }
            if (Objects.equals("不满意", body.getSfck())) {
                totalUnsatisfiedOptionCount += 1;
                sfckUnsatisfiedCount += 1;
                sfckCheckedOptionsCount = getCheckedOptionsCount(sfckCheckedOptionsCount, sfckOptionsJson, body.getSfckBmyyy());
            }

            if (StringUtil.notBlank(body.getYbk()) && !body.getYbk().equals("未接触")) {
                totalOptionCount += 1;
                ybkAssessmentCount += 1;
            }
            if (Objects.equals("不满意", body.getYbk())) {
                totalUnsatisfiedOptionCount += 1;
                ybkUnsatisfiedCount += 1;
                ybkCheckedOptionsCount = getCheckedOptionsCount(ybkCheckedOptionsCount, ybkOptionsJson, body.getYbkBmyyy());
            }

            if (StringUtil.notBlank(body.getYyhjws())) {
                totalOptionCount += 1;
                yyhjwsAssessmentCount += 1;
            }
            if (Objects.equals("不满意", body.getYyhjws())) {
                totalUnsatisfiedOptionCount += 1;
                yyhjwsUnsatisfiedCount += 1;
                yyhjwsCheckedOptionsCount = getCheckedOptionsCount(yyhjwsCheckedOptionsCount, yyhjwsOptionsJson, body.getYyhjwsBmyyy());
            }

            if (StringUtil.notBlank(body.getXzwyyy())) {
                whyComeHereOptionsCount = getCheckedOptionsCount(whyComeHereOptionsCount,
                        whyComeHereOptionsJson, body.getXzwyyy());
            }

            if (StringUtil.notBlank(body.getSfhxzzl())) {
                willComeAgainOptionsCount = getCheckedOptionsCount(willComeAgainOptionsCount,
                        willComeAgainOptionsJson, body.getSfhxzzl());
            }

            if (null != body.getZtpj()) {
                int grade = body.getZtpj();
                gradeSum += grade;
                gradeNumDetails[grade - 1] = gradeNumDetails[grade - 1] + 1;
            }

            if (visitType == VisitType.INPATIENT) {
                if (StringUtil.notBlank(body.getZykshl())) {
                    totalOptionCount += 1;
                    zykshlAssessmentCount += 1;
                }
                if (Objects.equals("不满意", body.getZykshl())) {
                    totalUnsatisfiedOptionCount += 1;
                    zykshlUnsatisfiedCount += 1;
                    zykshlCheckedOptionsCount = getCheckedOptionsCount(zykshlCheckedOptionsCount, zykshlOptionsJson, body.getZykshlBmyyy());
                }

                if (StringUtil.notBlank(body.getZyksys())) {
                    totalOptionCount += 1;
                    zyksysAssessmentCount += 1;
                }
                if (Objects.equals("不满意", body.getZyksys())) {
                    totalUnsatisfiedOptionCount += 1;
                    zyksysUnsatisfiedCount += 1;
                    zyksysCheckedOptionsCount = getCheckedOptionsCount(zyksysCheckedOptionsCount, zyksysOptionsJson, body.getZyksysBmyyy());
                }

                if (StringUtil.notBlank(body.getYyst()) && !body.getYyst().equals("未接触")) {
                    totalOptionCount += 1;
                    yystAssessmentCount += 1;
                }
                if (Objects.equals("不满意", body.getYyst())) {
                    totalUnsatisfiedOptionCount += 1;
                    yystUnsatisfiedCount += 1;
                    yystCheckedOptionsCount = getCheckedOptionsCount(yystCheckedOptionsCount, yystOptionsJson, body.getYystBmyyy());
                }

                if (StringUtil.notBlank(body.getMzyh()) && !body.getMzyh().equals("未接触")) {
                    totalOptionCount += 1;
                    mzyhAssessmentCount += 1;
                }
                if (Objects.equals("不满意", body.getMzyh())) {
                    totalUnsatisfiedOptionCount += 1;
                    mzyhUnsatisfiedCount += 1;
                    mzyhCheckedOptionsCount = getCheckedOptionsCount(mzyhCheckedOptionsCount, mzyhOptionsJson, body.getMzyhBmyyy());
                }

                if (StringUtil.notBlank(body.getJzyh()) && !body.getJzyh().equals("未接触")) {
                    totalOptionCount += 1;
                    jzyhAssessmentCount += 1;
                }
                if (Objects.equals("不满意", body.getJzyh())) {
                    totalUnsatisfiedOptionCount += 1;
                    jzyhUnsatisfiedCount += 1;
                    jzyhCheckedOptionsCount = getCheckedOptionsCount(jzyhCheckedOptionsCount, jzyhOptionsJson, body.getJzyhBmyyy());
                }

            } else {
                if (StringUtil.notBlank(body.getMjzdzjhl()) && !body.getMjzdzjhl().equals("未接触")) {
                    totalOptionCount += 1;
                    mjzdzjhlAssessmentCount += 1;
                }
                if (Objects.equals("不满意", body.getMjzdzjhl())) {
                    totalUnsatisfiedOptionCount += 1;
                    mjzdzjhlUnsatisfiedCount += 1;
                    mjzdzjhlCheckedOptionsCount = getCheckedOptionsCount(mjzdzjhlCheckedOptionsCount, mjzdzjhlOptionsJson, body.getMjzdzjhlBmyyy());
                }

                if (StringUtil.notBlank(body.getMjzys()) && !body.getMjzys().equals("未接触")) {
                    totalOptionCount += 1;
                    mjzysAssessmentCount += 1;
                }
                if (Objects.equals("不满意", body.getMjzys())) {
                    totalUnsatisfiedOptionCount += 1;
                    mjzysUnsatisfiedCount += 1;
                    mjzysCheckedOptionsCount = getCheckedOptionsCount(mjzysCheckedOptionsCount, mjzysOptionsJson, body.getMjzysBmyyy());
                }
            }
        }
        result.setTotalOptionCount(totalOptionCount);
        result.setTotalUnsatisfiedOptionCount(totalUnsatisfiedOptionCount);
        result.setTotalUnsatisfiedOptionPercentage(makePercentage(totalUnsatisfiedOptionCount, totalOptionCount));

        result.setYjkQuestionnaireCount(yjkAssessmentCount);
        result.setFskQuestionnaireCount(fskAssessmentCount);
        result.setCsyxkQuestionnaireCount(csyxkAssessmentCount);
        result.setJykQuestionnaireCount(jykAssessmentCount);
        result.setSfckQuestionnaireCount(sfckAssessmentCount);
        result.setYbkQuestionnaireCount(ybkAssessmentCount);
        result.setYyhjwsQuestionnaireCount(yyhjwsAssessmentCount);
        // <-- 以下门诊独有
        result.setMjzdzjhlQuestionnaireCount(mjzdzjhlAssessmentCount);
        result.setMjzysQuestionnaireCount(mjzysAssessmentCount);
        // -->
        // <-- 以下住院独有
        result.setZykshlQuestionnaireCount(zykshlAssessmentCount);
        result.setZyksysQuestionnaireCount(zyksysAssessmentCount);
        result.setYystQuestionnaireCount(yystAssessmentCount);
        result.setMzyhQuestionnaireCount(mzyhAssessmentCount);
        result.setJzyhQuestionnaireCount(jzyhAssessmentCount);
        // -->

        result.setYjkUnsatisfiedCount(yjkUnsatisfiedCount);
        result.setFskUnsatisfiedCount(fskUnsatisfiedCount);
        result.setCsyxkUnsatisfiedCount(csyxkUnsatisfiedCount);
        result.setJykUnsatisfiedCount(jykUnsatisfiedCount);
        result.setSfckUnsatisfiedCount(sfckUnsatisfiedCount);
        result.setYbkUnsatisfiedCount(ybkUnsatisfiedCount);
        result.setYyhjwsUnsatisfiedCount(yyhjwsUnsatisfiedCount);
        // <-- 以下门诊独有
        result.setMjzdzjhlUnsatisfiedCount(mjzdzjhlUnsatisfiedCount);
        result.setMjzysUnsatisfiedCount(mjzysUnsatisfiedCount);
        // -->
        // <-- 以下住院独有
        result.setZykshlUnsatisfiedCount(zykshlUnsatisfiedCount);
        result.setZyksysUnsatisfiedCount(zyksysUnsatisfiedCount);
        result.setYystUnsatisfiedCount(yystUnsatisfiedCount);
        result.setMzyhUnsatisfiedCount(mzyhUnsatisfiedCount);
        result.setJzyhUnsatisfiedCount(jzyhUnsatisfiedCount);
        // -->

        result.setYjkUnsatisfiedPercentage(makePercentage(yjkUnsatisfiedCount, yjkAssessmentCount));
        result.setFskUnsatisfiedPercentage(makePercentage(fskUnsatisfiedCount, fskAssessmentCount));
        result.setCsyxkUnsatisfiedPercentage(makePercentage(csyxkUnsatisfiedCount, csyxkAssessmentCount));
        result.setJykUnsatisfiedPercentage(makePercentage(jykUnsatisfiedCount, jykAssessmentCount));
        result.setSfckUnsatisfiedPercentage(makePercentage(sfckUnsatisfiedCount, sfckAssessmentCount));
        result.setYbkUnsatisfiedPercentage(makePercentage(ybkUnsatisfiedCount, ybkAssessmentCount));
        result.setYyhjwsUnsatisfiedPercentage(makePercentage(yyhjwsUnsatisfiedCount, yyhjwsAssessmentCount));
        // <-- 以下门诊独有
        result.setMjzdzjhlUnsatisfiedPercentage(makePercentage(mjzdzjhlUnsatisfiedCount, mjzdzjhlAssessmentCount));
        result.setMjzysUnsatisfiedPercentage(makePercentage(mjzysUnsatisfiedCount, mjzysAssessmentCount));
        // -->
        // <-- 以下住院独有
        result.setZykshlUnsatisfiedPercentage(makePercentage(zykshlUnsatisfiedCount, zykshlAssessmentCount));
        result.setZyksysUnsatisfiedPercentage(makePercentage(zyksysUnsatisfiedCount, zyksysAssessmentCount));
        result.setYystUnsatisfiedPercentage(makePercentage(yystUnsatisfiedCount, yystAssessmentCount));
        result.setMzyhUnsatisfiedPercentage(makePercentage(mzyhUnsatisfiedCount, mzyhAssessmentCount));
        result.setJzyhUnsatisfiedPercentage(makePercentage(jzyhUnsatisfiedCount, jzyhAssessmentCount));
        // -->

        result.setYjkUnsatisfiedOption(fillOptionDetails(yjkAssessmentCount, yjkCheckedOptionsCount, yjkOptionsJson));
        result.setFskUnsatisfiedOption(fillOptionDetails(fskAssessmentCount, fskCheckedOptionsCount, fskOptionsJson));
        result.setCsyxkUnsatisfiedOption(fillOptionDetails(csyxkAssessmentCount, csyxkCheckedOptionsCount, csyxkOptionsJson));
        result.setJykUnsatisfiedOption(fillOptionDetails(jykAssessmentCount, jykCheckedOptionsCount, jykOptionsJson));
        result.setSfckUnsatisfiedOption(fillOptionDetails(sfckAssessmentCount, sfckCheckedOptionsCount, sfckOptionsJson));
        result.setYbkUnsatisfiedOption(fillOptionDetails(ybkAssessmentCount, ybkCheckedOptionsCount, ybkOptionsJson));
        result.setYyhjwsUnsatisfiedOption(fillOptionDetails(yyhjwsAssessmentCount, yyhjwsCheckedOptionsCount, yyhjwsOptionsJson));
        // <-- 以下门诊独有
        result.setMjzdzjhlUnsatisfiedOption(fillOptionDetails(mjzdzjhlAssessmentCount, mjzdzjhlCheckedOptionsCount, mjzdzjhlOptionsJson));
        result.setMjzysUnsatisfiedOption(fillOptionDetails(mjzysAssessmentCount, mjzysCheckedOptionsCount, mjzysOptionsJson));
        // -->
        // <-- 以下住院独有
        result.setZykshlUnsatisfiedOption(fillOptionDetails(zykshlAssessmentCount, zykshlCheckedOptionsCount, zykshlOptionsJson));
        result.setZyksysUnsatisfiedOption(fillOptionDetails(zyksysAssessmentCount, zyksysCheckedOptionsCount, zyksysOptionsJson));
        result.setYystUnsatisfiedOption(fillOptionDetails(yystAssessmentCount, yystCheckedOptionsCount, yystOptionsJson));
        result.setMzyhUnsatisfiedOption(fillOptionDetails(mzyhAssessmentCount, mzyhCheckedOptionsCount, mzyhOptionsJson));
        result.setJzyhUnsatisfiedOption(fillOptionDetails(jzyhAssessmentCount, jzyhCheckedOptionsCount, jzyhOptionsJson));
        // -->

        WhyChooseHere why = new WhyChooseHere();
        WillComeAgain will = new WillComeAgain();
        GradeNum grade = new GradeNum();

        why.setTotalCount(whyComeHereOptionsCount);
        why.setMmelCount(whyComeHereOptionsJson.getInteger("慕名而来"));
        why.setJjxzCount(whyComeHereOptionsJson.getInteger("就近选择"));
        why.setPytjCount(whyComeHereOptionsJson.getInteger("朋友推荐"));
        why.setWlcxCount(whyComeHereOptionsJson.getInteger("网络查询"));
        why.setFwspCount(whyComeHereOptionsJson.getInteger("服务水平"));
        why.setHjsbCount(whyComeHereOptionsJson.getInteger("环境设备"));
        why.setYljgCount(whyComeHereOptionsJson.getInteger("医疗价格"));

        why.setMmelPercentage(makePercentage(why.getMmelCount(), whyComeHereOptionsCount));
        why.setJjxzPercentage(makePercentage(why.getJjxzCount(), whyComeHereOptionsCount));
        why.setPytjPercentage(makePercentage(why.getPytjCount(), whyComeHereOptionsCount));
        why.setWlcxPercentage(makePercentage(why.getWlcxCount(), whyComeHereOptionsCount));
        why.setFwspPercentage(makePercentage(why.getFwspCount(), whyComeHereOptionsCount));
        why.setHjsbPercentage(makePercentage(why.getHjsbCount(), whyComeHereOptionsCount));
        why.setYljgPercentage(makePercentage(why.getYljgCount(), whyComeHereOptionsCount));

        will.setTotalCount(willComeAgainOptionsCount);
        will.setYesCount(willComeAgainOptionsJson.getInteger("会"));
        will.setNoCount(willComeAgainOptionsJson.getInteger("不会"));

        will.setYesPercentage(makePercentage(will.getYesCount(), willComeAgainOptionsCount));
        will.setNoPercentage(makePercentage(will.getNoCount(), willComeAgainOptionsCount));

        int gradeCount = 0;
        for (int item : gradeNumDetails) {
            gradeCount += item;
        }
        grade.setTotalCount(gradeCount);
        grade.setOneCount(gradeNumDetails[0]);
        grade.setTwoCount(gradeNumDetails[1]);
        grade.setThreeCount(gradeNumDetails[2]);
        grade.setFourCount(gradeNumDetails[3]);
        grade.setFiveCount(gradeNumDetails[4]);
        grade.setSixCount(gradeNumDetails[5]);
        grade.setSevenCount(gradeNumDetails[6]);
        grade.setEightCount(gradeNumDetails[7]);
        grade.setNineCount(gradeNumDetails[8]);
        grade.setTenCount(gradeNumDetails[9]);
        grade.setAverageGrade(DecimalUtil.divide(new BigDecimal(gradeSum), new BigDecimal(gradeCount), 2));

        grade.setOnePercentage(makePercentage(grade.getOneCount(), gradeCount));
        grade.setTwoPercentage(makePercentage(grade.getTwoCount(), gradeCount));
        grade.setThreePercentage(makePercentage(grade.getThreeCount(), gradeCount));
        grade.setFourPercentage(makePercentage(grade.getFourCount(), gradeCount));
        grade.setFivePercentage(makePercentage(grade.getFiveCount(), gradeCount));
        grade.setSixPercentage(makePercentage(grade.getSixCount(), gradeCount));
        grade.setSevenPercentage(makePercentage(grade.getSevenCount(), gradeCount));
        grade.setEightPercentage(makePercentage(grade.getEightCount(), gradeCount));
        grade.setNinePercentage(makePercentage(grade.getNineCount(), gradeCount));
        grade.setTenPercentage(makePercentage(grade.getTenCount(), gradeCount));

        result.setWhyChooseHere(why);
        result.setWillComeAgain(will);
        result.setGradeNum(grade);

        return ResultVoUtil.success(result);
    }

    private UnsatisfiedOption fillOptionDetails(int assessmentCount, int checkedOptionSize, JSONObject optionsJson) {
        UnsatisfiedOption unsatisfiedOption = new UnsatisfiedOption();
        int totalOptionSize = assessmentCount * optionsJson.size();
        unsatisfiedOption.setTotalOptionSize(totalOptionSize);
        unsatisfiedOption.setCheckedOptionSize(checkedOptionSize);
        unsatisfiedOption.setCheckedOptionPercentage(makePercentage(checkedOptionSize, totalOptionSize));

        unsatisfiedOption.setFwtdCount(optionsJson.getInteger("服务态度"));
        unsatisfiedOption.setFwtdPercentage(makePercentage(unsatisfiedOption.getFwtdCount(), checkedOptionSize));
        unsatisfiedOption.setFzlyCount(optionsJson.getInteger("服装礼仪"));
        unsatisfiedOption.setFzlyPercentage(makePercentage(unsatisfiedOption.getFzlyCount(), checkedOptionSize));
        unsatisfiedOption.setWsqkCount(optionsJson.getInteger("卫生情况"));
        unsatisfiedOption.setWsqkPercentage(makePercentage(unsatisfiedOption.getWsqkCount(), checkedOptionSize));
        unsatisfiedOption.setKwCount(optionsJson.getInteger("口味"));
        unsatisfiedOption.setKwPercentage(makePercentage(unsatisfiedOption.getKwCount(), checkedOptionSize));
        unsatisfiedOption.setCpCount(optionsJson.getInteger("菜品"));
        unsatisfiedOption.setCpPercentage(makePercentage(unsatisfiedOption.getCpCount(), checkedOptionSize));
        unsatisfiedOption.setQtCount(optionsJson.getInteger("其他"));
        unsatisfiedOption.setQtPercentage(makePercentage(unsatisfiedOption.getQtCount(), checkedOptionSize));
        unsatisfiedOption.setGtjsCount(optionsJson.getInteger("沟通解释"));
        unsatisfiedOption.setGtjsPercentage(makePercentage(unsatisfiedOption.getGtjsCount(), checkedOptionSize));
        unsatisfiedOption.setJsspCount(optionsJson.getInteger("技术水平"));
        unsatisfiedOption.setJsspPercentage(makePercentage(unsatisfiedOption.getJsspCount(), checkedOptionSize));
        unsatisfiedOption.setYsbhCount(optionsJson.getInteger("隐私保护"));
        unsatisfiedOption.setYsbhPercentage(makePercentage(unsatisfiedOption.getYsbhCount(), checkedOptionSize));
        unsatisfiedOption.setBqxsCount(optionsJson.getInteger("病情巡视"));
        unsatisfiedOption.setBqxsPercentage(makePercentage(unsatisfiedOption.getBqxsCount(), checkedOptionSize));
        unsatisfiedOption.setAscfCount(optionsJson.getInteger("按时查房"));
        unsatisfiedOption.setAscfPercentage(makePercentage(unsatisfiedOption.getAscfCount(), checkedOptionSize));
        unsatisfiedOption.setAszzCount(optionsJson.getInteger("按时坐诊"));
        unsatisfiedOption.setAszzPercentage(makePercentage(unsatisfiedOption.getAszzCount(), checkedOptionSize));
        unsatisfiedOption.setJhfwCount(optionsJson.getInteger("叫号服务"));
        unsatisfiedOption.setJhfwPercentage(makePercentage(unsatisfiedOption.getJhfwCount(), checkedOptionSize));
        unsatisfiedOption.setDdscCount(optionsJson.getInteger("等待时长"));
        unsatisfiedOption.setDdscPercentage(makePercentage(unsatisfiedOption.getDdscCount(), checkedOptionSize));
        unsatisfiedOption.setJsxyCount(optionsJson.getInteger("及时响应"));
        unsatisfiedOption.setJsxyPercentage(makePercentage(unsatisfiedOption.getJsxyCount(), checkedOptionSize));
        unsatisfiedOption.setZqlCount(optionsJson.getInteger("准确率"));
        unsatisfiedOption.setZqlPercentage(makePercentage(unsatisfiedOption.getZqlCount(), checkedOptionSize));
        unsatisfiedOption.setZynlCount(optionsJson.getInteger("专业能力"));
        unsatisfiedOption.setZynlPercentage(makePercentage(unsatisfiedOption.getZynlCount(), checkedOptionSize));
        unsatisfiedOption.setFwlcCount(optionsJson.getInteger("服务流程"));
        unsatisfiedOption.setFwlcPercentage(makePercentage(unsatisfiedOption.getFwlcCount(), checkedOptionSize));
        unsatisfiedOption.setStwsCount(optionsJson.getInteger("食堂卫生"));
        unsatisfiedOption.setStwsPercentage(makePercentage(unsatisfiedOption.getStwsCount(), checkedOptionSize));
        unsatisfiedOption.setMzdtwsCount(optionsJson.getInteger("门诊大厅卫生"));
        unsatisfiedOption.setMzdtwsPercentage(makePercentage(unsatisfiedOption.getMzdtwsCount(), checkedOptionSize));
        unsatisfiedOption.setZjwsCount(optionsJson.getInteger("诊间卫生"));
        unsatisfiedOption.setZjwsPercentage(makePercentage(unsatisfiedOption.getZjwsCount(), checkedOptionSize));
        unsatisfiedOption.setBfwsCount(optionsJson.getInteger("病房卫生"));
        unsatisfiedOption.setBfwsPercentage(makePercentage(unsatisfiedOption.getBfwsCount(), checkedOptionSize));
        unsatisfiedOption.setWsjwsCount(optionsJson.getInteger("卫生间卫生"));
        unsatisfiedOption.setWsjwsPercentage(makePercentage(unsatisfiedOption.getWsjwsCount(), checkedOptionSize));
        unsatisfiedOption.setDtwsCount(optionsJson.getInteger("电梯卫生"));
        unsatisfiedOption.setDtwsPercentage(makePercentage(unsatisfiedOption.getDtwsCount(), checkedOptionSize));
        unsatisfiedOption.setLdwsCount(optionsJson.getInteger("楼道卫生"));
        unsatisfiedOption.setLdwsPercentage(makePercentage(unsatisfiedOption.getLdwsCount(), checkedOptionSize));
        unsatisfiedOption.setZywsCount(optionsJson.getInteger("座椅卫生"));
        unsatisfiedOption.setZywsPercentage(makePercentage(unsatisfiedOption.getZywsCount(), checkedOptionSize));
        unsatisfiedOption.setGgqyCount(optionsJson.getInteger("公共区域"));
        unsatisfiedOption.setGgqyPercentage(makePercentage(unsatisfiedOption.getGgqyCount(), checkedOptionSize));
        return unsatisfiedOption;
    }

    private int getCheckedOptionsCount(int optionsCount, JSONObject optionsJson, String options) {
        if (StringUtil.notBlank(options)) {
            String[] arr = options.split(",");
            optionsCount += arr.length;
            for (String option : arr) {
                int temp = optionsJson.getIntValue(option) + 1;
                optionsJson.replace(option, temp);
            }
        }
        return optionsCount;
    }

    private String makePercentage(Integer a, Integer b) {
        if (null == a || null == b) {
            return null;
        }
        if (a == 0 || b == 0) {
            return "0.00%";
        }
        BigDecimal aDecimal = new BigDecimal(a);
        BigDecimal bDecimal = new BigDecimal(b);
        BigDecimal percentage = aDecimal.multiply(new BigDecimal(100))
                .divide(bDecimal, 2, RoundingMode.HALF_UP);
        return percentage + "%";
    }
}
