package com.emoon.tongue.domain.vo;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;

import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 舌诊信息
 *
 * @author destiny
 * @date 2025-12-09
 */
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class TongueDiagnosisInfo implements Serializable {

    @Serial
    private static final long serialVersionUID = 1L;

    /**
     * 舌象整体描述
     */
    private String tongueGeneralDesc;

    /**
     * 舌象（本地模型输出拆分字段）
     *
     * <p>兼容：如果本字段为空，可使用 tongueGeneralDesc 作为兜底展示。</p>
     */
    private String tongueManifestation;

    /**
     * 关键特征列表
     */
    private List<KeyFeatures> keyFeatures;

    /**
     * 舌象状态评估
     */
    private String tongueStateAssessment;

    /**
     * 整体置信度
     */
    private BigDecimal overallConfidence;

    /**
     * 推理完成时间（UTC）
     */
    private Date inferTime;

    /**
     * 舌色诊断结果
     */
    private String tongueColorResult;

    /**
     * 舌苔诊断结果
     */
    private String tongueCoatingResult;

    /**
     * 舌形诊断结果
     */
    private String tongueShapeResult;

    /**
     * 中医体质分析
     */
    private String constitutionAnalysis;

    /**
     * 健康建议
     */
    private String healthAdvice;

    /**
     * 症候/证型（本地模型输出拆分字段）
     */
    private String syndrome;

    /**
     * 诊断（预留：当前按需求先空着）
     */
    private String diagnosis;

    /**
     * 处方（本地模型输出拆分字段）
     */
    private String prescription;


    /**
     * 生成Mock诊断结果
     */
    public static TongueDiagnosisInfo generateMockResult() {
        TongueDiagnosisInfo result = new TongueDiagnosisInfo();
        Random random = new Random();

        // 设置推理时间
        result.setInferTime(new Date());

        // 舌象分析结果
        String[] tongueColors = {"淡红舌", "红舌", "暗红舌", "淡白舌", "紫暗舌"};
        String[] tongueCoatings = {"薄白苔", "薄黄苔", "白厚苔", "黄厚苔", "腻苔", "剥苔"};
        String[] tongueShapes = {"正常舌形", "胖大舌", "瘦薄舌", "裂纹舌", "齿痕舌"};
        String[] constitutions = {
            "平和质", "气虚质", "阳虚质", "阴虚质", "痰湿质", "湿热质", "血瘀质", "气郁质"
        };

        // 设置舌象分析结果
        result.setTongueColorResult(tongueColors[random.nextInt(tongueColors.length)]);
        result.setTongueCoatingResult(tongueCoatings[random.nextInt(tongueCoatings.length)]);
        result.setTongueShapeResult(tongueShapes[random.nextInt(tongueShapes.length)]);

        String constitution = constitutions[random.nextInt(constitutions.length)];
        result.setConstitutionAnalysis("根据舌象特征分析，您属于" + constitution + "体质。");

        // 根据体质生成健康建议
        result.setHealthAdvice(generateHealthAdvice(constitution));

        // 生成置信度（75-95之间），保留两位小数
        BigDecimal confidence = BigDecimal.valueOf(75 + random.nextInt(21))
            .setScale(2, RoundingMode.HALF_UP);

        // 随机生成2个关键特征
        result.setKeyFeatures(generateRandomKeyFeatures(result.getTongueColorResult(),
            result.getTongueCoatingResult(), result.getTongueShapeResult(), random));

        // 整体舌象描述
        result.setTongueGeneralDesc(String.format("舌象呈现%s，舌苔%s，舌形%s。根据中医理论分析，%s。",
            result.getTongueColorResult(), result.getTongueCoatingResult(),
            result.getTongueShapeResult(), result.getConstitutionAnalysis()));

        // 置信度转换为百分比，保留两位小数
        result.setOverallConfidence(confidence.divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP));

        result.setTongueStateAssessment("舌象状态" + (confidence.compareTo(BigDecimal.valueOf(85)) > 0 ? "良好" : "需要关注"));

        return result;
    }

    /**
     * 根据体质生成健康建议
     */
    private static String generateHealthAdvice(String constitution) {
        return switch (constitution) {
            case "平和质" -> "您的体质较为平和，建议保持良好的生活习惯，适度运动，均衡饮食。";
            case "气虚质" -> "建议多食用益气健脾的食物，如山药、大枣、人参等，避免过度劳累。";
            case "阳虚质" -> "建议温补阳气，多食用温热性食物，如羊肉、生姜、桂圆等，注意保暖。";
            case "阴虚质" -> "建议滋阴润燥，多食用梨、百合、银耳等润肺养阴食物，避免辛辣刺激性食物。";
            case "痰湿质" -> "建议健脾化湿，多食用薏米、赤小豆等利湿食物，少食甜腻油腻之品。";
            case "湿热质" -> "建议清热利湿，多食用绿豆、苦瓜等清热食物，避免辛辣油腻。";
            case "血瘀质" -> "建议活血化瘀，多食用山楂、红花等活血食物，适度运动促进血液循环。";
            case "气郁质" -> "建议疏肝解郁，保持心情舒畅，多食用玫瑰花、陈皮等理气食物。";
            default -> "建议根据具体情况咨询专业中医师，制定个性化调理方案。";
        };
    }

    /**
     * 随机生成2个关键特征
     */
    private static List<KeyFeatures> generateRandomKeyFeatures(String tongueColor, String tongueCoating,
                                                               String tongueShape, Random random) {
        List<KeyFeatures> keyFeatures = new ArrayList<>();

        // 10组不同的舌象特征诊断结果
        String[][] diagnosticResults = {
            // 舌象偏黄系列
            {"舌象偏黄，多见于热证或湿热体质", "舌苔黄腻，提示体内有湿热", "舌质偏黄，表示内有热邪", "舌边尖偏黄，多为肝胆湿热"},
            // 舌象偏红系列
            {"舌象偏红，常见于阴虚火旺或实热证", "舌尖红赤，多为心火亢盛", "舌质红绛，提示热入营血", "全舌鲜红，表示体内有热"},
            // 舌象红肿系列
            {"舌体红肿，多为热毒炽盛", "舌红肿痛，提示火热上炎", "舌体肿胀发红，常见于急性热病", "舌红肿大，多为痰热互结"},
            // 舌象淡白系列
            {"舌象淡白，多为气血两虚", "舌质淡白，提示阳气不足", "舌色苍白，常见于血虚或寒证", "舌淡白胖嫩，多为脾肾阳虚"},
            // 舌象紫暗系列
            {"舌象紫暗，多为血瘀证", "舌质紫暗，提示血液循环不畅", "舌色青紫，常见于寒凝血瘀", "舌下静脉紫暗，多为血瘀体质"},
            // 舌象裂纹系列
            {"舌象裂纹，多为阴虚血燥", "舌质裂纹，提示津液不足", "舌有深裂纹，常见于阴虚火旺", "舌裂纹纵横，多为气血两虚"},
            // 舌象齿痕系列
            {"舌象齿痕，多为脾虚湿盛", "舌边齿痕，提示脾虚不能运化水湿", "舌体胖大有齿痕，常见于气虚湿阻", "舌淡胖有齿痕，多为脾肾阳虚"},
            // 舌象剥落系列
            {"舌象剥落，多为胃阴不足", "舌苔剥落，提示气血虚弱", "舌光剥无苔，常见于胃阴枯竭", "地图舌剥落，多为脾胃虚弱"},
            // 舌象腻苔系列
            {"舌象腻苔，多为痰湿内阻", "舌苔厚腻，提示湿浊困脾", "舌腻而黄，常见于湿热内蕴", "舌白腻苔，多为寒湿困脾"},
            // 舌象瘦薄系列
            {"舌象瘦薄，多为气血两虚", "舌质瘦薄，提示阴虚火旺", "舌体瘦薄色红，常见于阴虚内热", "舌瘦薄而淡，多为气血虚弱"}
        };

        // 根据舌色、舌苔、舌形选择相关的特征
        List<String> applicableFeatures = new ArrayList<>();

        // 添加颜色相关特征
        if (tongueColor.contains("红")) {
            applicableFeatures.add(diagnosticResults[1][random.nextInt(diagnosticResults[1].length)]);
            applicableFeatures.add(diagnosticResults[2][random.nextInt(diagnosticResults[2].length)]);
        } else if (tongueColor.contains("黄")) {
            applicableFeatures.add(diagnosticResults[0][random.nextInt(diagnosticResults[0].length)]);
            if (tongueCoating.contains("黄")) {
                applicableFeatures.add(diagnosticResults[0][random.nextInt(diagnosticResults[0].length)]);
            }
        } else if (tongueColor.contains("淡白")) {
            applicableFeatures.add(diagnosticResults[3][random.nextInt(diagnosticResults[3].length)]);
        } else if (tongueColor.contains("紫暗")) {
            applicableFeatures.add(diagnosticResults[4][random.nextInt(diagnosticResults[4].length)]);
        }

        // 添加舌苔相关特征
        if (tongueCoating.contains("腻")) {
            applicableFeatures.add(diagnosticResults[8][random.nextInt(diagnosticResults[8].length)]);
        } else if (tongueCoating.contains("剥")) {
            applicableFeatures.add(diagnosticResults[7][random.nextInt(diagnosticResults[7].length)]);
        }

        // 添加舌形相关特征
        if (tongueShape.contains("裂纹")) {
            applicableFeatures.add(diagnosticResults[5][random.nextInt(diagnosticResults[5].length)]);
        } else if (tongueShape.contains("齿痕")) {
            applicableFeatures.add(diagnosticResults[6][random.nextInt(diagnosticResults[6].length)]);
        } else if (tongueShape.contains("胖大")) {
            applicableFeatures.add(diagnosticResults[6][random.nextInt(diagnosticResults[6].length)]);
        } else if (tongueShape.contains("瘦薄")) {
            applicableFeatures.add(diagnosticResults[9][random.nextInt(diagnosticResults[9].length)]);
        }

        // 如果没有特定匹配，随机选择通用特征
        if (applicableFeatures.isEmpty()) {
            int groupIndex = random.nextInt(diagnosticResults.length);
            applicableFeatures.add(diagnosticResults[groupIndex][random.nextInt(diagnosticResults[groupIndex].length)]);
            int differentGroup = random.nextInt(diagnosticResults.length);
            while (differentGroup == groupIndex) {
                differentGroup = random.nextInt(diagnosticResults.length);
            }
            applicableFeatures.add(diagnosticResults[differentGroup][random.nextInt(diagnosticResults[differentGroup].length)]);
        }

        // 随机选择2个特征，如果适用特征少于2个，则全部使用
        if (applicableFeatures.size() <= 2) {
            for (String feature : applicableFeatures) {
                KeyFeatures keyFeature = new KeyFeatures();
                keyFeature.setFeature(feature);
                BigDecimal confidence = BigDecimal.valueOf(0.75 + random.nextDouble() * 0.2)
                    .setScale(2, RoundingMode.HALF_UP);
                keyFeature.setConfidence(confidence);
                keyFeatures.add(keyFeature);
            }
        } else {
            // 随机选择2个不同的特征
            Set<Integer> selectedIndices = new HashSet<>();
            while (selectedIndices.size() < 2) {
                selectedIndices.add(random.nextInt(applicableFeatures.size()));
            }

            for (int index : selectedIndices) {
                KeyFeatures keyFeature = new KeyFeatures();
                keyFeature.setFeature(applicableFeatures.get(index));
                BigDecimal confidence = BigDecimal.valueOf(0.75 + random.nextDouble() * 0.2)
                    .setScale(2, RoundingMode.HALF_UP);
                keyFeature.setConfidence(confidence);
                keyFeatures.add(keyFeature);
            }
        }

        return keyFeatures;
    }
}
