/*
 * 自然写互动课堂应用开发SDK软件 V1.0
 * RecognitionResult - 识别结果数据模型
 *
 * 描述：封装OCR识别、数学公式识别、笔顺评分等各类识别结果
 */

package com.writech.sdk.model;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 * 识别结果统一模型
 * 支持多种识别类型的结果封装
 */
public class RecognitionResult implements Serializable {

    private static final long serialVersionUID = 1L;

    /* ========== 识别类型常量 ========== */

    /** 手写文字识别 */
    public static final int TYPE_HANDWRITING = 0;

    /** 数学公式识别 */
    public static final int TYPE_MATH = 1;

    /** 笔顺评分 */
    public static final int TYPE_STROKE_ORDER = 2;

    /** 作文评分 */
    public static final int TYPE_ESSAY = 3;

    /* ========== 候选结果内部类 ========== */

    /** 单个候选识别结果 */
    public static class Candidate implements Serializable {
        private static final long serialVersionUID = 1L;

        /** 识别文本 */
        public String text;

        /** 置信度（0.0~1.0） */
        public float confidence;

        /** 候选排名 */
        public int rank;

        public Candidate() {}

        public Candidate(String text, float confidence, int rank) {
            this.text = text;
            this.confidence = confidence;
            this.rank = rank;
        }

        @Override
        public String toString() {
            return "Candidate{'" + text + "', conf=" + confidence + "}";
        }
    }

    /** 笔顺评分详情 */
    public static class StrokeOrderDetail implements Serializable {
        private static final long serialVersionUID = 1L;

        /** 评分笔画序号 */
        public int strokeIndex;

        /** 该笔是否正确 */
        public boolean isCorrect;

        /** 标准笔顺名称（如"横"、"竖"、"撇"） */
        public String standardStrokeName;

        /** 实际书写的笔画类型 */
        public String actualStrokeName;

        /** 笔画形态相似度（0.0~1.0） */
        public float shapeSimilarity;

        public StrokeOrderDetail() {}

        @Override
        public String toString() {
            return "Stroke#" + strokeIndex + ": " + (isCorrect ? "正确" : "错误")
                   + " (标准:" + standardStrokeName + ", 实际:" + actualStrokeName + ")";
        }
    }

    /** 作文评分详情 */
    public static class EssayScoreDetail implements Serializable {
        private static final long serialVersionUID = 1L;

        /** 内容分（百分制） */
        public float contentScore;

        /** 结构分 */
        public float structureScore;

        /** 语言分 */
        public float languageScore;

        /** 书写规范分 */
        public float handwritingScore;

        /** 总分 */
        public float totalScore;

        /** 评语 */
        public String comment;

        /** 优点列表 */
        public List<String> highlights = new ArrayList<>();

        /** 改进建议列表 */
        public List<String> suggestions = new ArrayList<>();

        public EssayScoreDetail() {}
    }

    /* ========== 结果字段 ========== */

    /** 识别请求ID（对应任务ID） */
    private int requestId;

    /** 识别类型 */
    private int recognitionType;

    /** 识别是否成功 */
    private boolean success;

    /** 错误码（成功时为0） */
    private int errorCode;

    /** 错误消息 */
    private String errorMessage;

    /** 主要识别结果文本 */
    private String resultText;

    /** 主要结果置信度 */
    private float confidence;

    /** 候选结果列表（按置信度降序） */
    private List<Candidate> candidates;

    /** 笔顺评分详情（仅笔顺类型） */
    private List<StrokeOrderDetail> strokeOrderDetails;

    /** 笔顺总分（0-100） */
    private float strokeOrderScore;

    /** 笔顺正确笔画数 */
    private int correctStrokeCount;

    /** 笔顺总笔画数 */
    private int totalStrokeCount;

    /** 作文评分详情（仅作文类型） */
    private EssayScoreDetail essayDetail;

    /** 数学公式LaTeX表示（仅数学类型） */
    private String mathLatex;

    /** 数学计算结果（如果是计算题） */
    private String mathAnswer;

    /** 识别耗时（毫秒） */
    private long processingTimeMs;

    /** 结果来源（"online"在线 / "offline"离线 / "cache"缓存） */
    private String source;

    /** 识别时间戳 */
    private long timestamp;

    /* ========== 构造函数 ========== */

    public RecognitionResult() {
        this.candidates = new ArrayList<>();
        this.strokeOrderDetails = new ArrayList<>();
        this.timestamp = System.currentTimeMillis();
    }

    /** 创建成功结果 */
    public static RecognitionResult success(int requestId, int type, String text, float confidence) {
        RecognitionResult result = new RecognitionResult();
        result.requestId = requestId;
        result.recognitionType = type;
        result.success = true;
        result.errorCode = 0;
        result.resultText = text;
        result.confidence = confidence;
        return result;
    }

    /** 创建失败结果 */
    public static RecognitionResult failure(int requestId, int errorCode, String message) {
        RecognitionResult result = new RecognitionResult();
        result.requestId = requestId;
        result.success = false;
        result.errorCode = errorCode;
        result.errorMessage = message;
        return result;
    }

    /* ========== Getter / Setter ========== */

    public int getRequestId() { return requestId; }
    public void setRequestId(int id) { this.requestId = id; }

    public int getRecognitionType() { return recognitionType; }
    public void setRecognitionType(int type) { this.recognitionType = type; }

    public boolean isSuccess() { return success; }
    public void setSuccess(boolean success) { this.success = success; }

    public int getErrorCode() { return errorCode; }
    public void setErrorCode(int code) { this.errorCode = code; }

    public String getErrorMessage() { return errorMessage; }
    public void setErrorMessage(String msg) { this.errorMessage = msg; }

    public String getResultText() { return resultText; }
    public void setResultText(String text) { this.resultText = text; }

    public float getConfidence() { return confidence; }
    public void setConfidence(float c) { this.confidence = c; }

    public List<Candidate> getCandidates() { return candidates; }
    public void setCandidates(List<Candidate> c) { this.candidates = c; }

    public void addCandidate(String text, float confidence, int rank) {
        candidates.add(new Candidate(text, confidence, rank));
    }

    public List<StrokeOrderDetail> getStrokeOrderDetails() { return strokeOrderDetails; }
    public void setStrokeOrderDetails(List<StrokeOrderDetail> d) { this.strokeOrderDetails = d; }

    public float getStrokeOrderScore() { return strokeOrderScore; }
    public void setStrokeOrderScore(float s) { this.strokeOrderScore = s; }

    public int getCorrectStrokeCount() { return correctStrokeCount; }
    public void setCorrectStrokeCount(int c) { this.correctStrokeCount = c; }

    public int getTotalStrokeCount() { return totalStrokeCount; }
    public void setTotalStrokeCount(int t) { this.totalStrokeCount = t; }

    public EssayScoreDetail getEssayDetail() { return essayDetail; }
    public void setEssayDetail(EssayScoreDetail d) { this.essayDetail = d; }

    public String getMathLatex() { return mathLatex; }
    public void setMathLatex(String latex) { this.mathLatex = latex; }

    public String getMathAnswer() { return mathAnswer; }
    public void setMathAnswer(String answer) { this.mathAnswer = answer; }

    public long getProcessingTimeMs() { return processingTimeMs; }
    public void setProcessingTimeMs(long ms) { this.processingTimeMs = ms; }

    public String getSource() { return source; }
    public void setSource(String source) { this.source = source; }

    public long getTimestamp() { return timestamp; }
    public void setTimestamp(long t) { this.timestamp = t; }

    /* ========== 便捷方法 ========== */

    /** 获取最佳候选结果 */
    public Candidate getBestCandidate() {
        return candidates.isEmpty() ? null : candidates.get(0);
    }

    /** 获取笔顺正确率 */
    public float getStrokeOrderAccuracy() {
        return totalStrokeCount > 0 ? (float) correctStrokeCount / totalStrokeCount : 0;
    }

    /** 获取识别类型的中文描述 */
    public String getTypeDescription() {
        switch (recognitionType) {
            case TYPE_HANDWRITING: return "手写识别";
            case TYPE_MATH: return "数学识别";
            case TYPE_STROKE_ORDER: return "笔顺评分";
            case TYPE_ESSAY: return "作文评分";
            default: return "未知类型";
        }
    }

    @Override
    public String toString() {
        if (success) {
            return "RecognitionResult{type=" + getTypeDescription()
                   + ", text='" + resultText + "'"
                   + ", confidence=" + confidence
                   + ", source=" + source
                   + ", time=" + processingTimeMs + "ms}";
        } else {
            return "RecognitionResult{FAILED, code=" + errorCode
                   + ", msg='" + errorMessage + "'}";
        }
    }
}
