package studentsystem

import std.convert.*
import std.collection.*
import std.env.*

/**
 * 成绩 管理类(单例模式)
 *
 * 拓展任务:仿照 StudentManager、CourseManager 完成。
 * 提供录入、查询、修改、删除成绩,以及班级内某一课程成绩单显示等功能。
 */
public class ScoreManager {

    // 单例模式:无法从外部访问构造函数
    private ScoreManager(
        var scores!: ArrayList<Score> = ArrayList<Score>() // 成绩列表
    ) {}

    // 单例对象
    private static let instance: ScoreManager = ScoreManager()

    // 通过属性获取单例对象
    static prop propInstance: ScoreManager {
        get() {
            instance
        }
    }

    // ─────────────────────────────────────────────────────────────────────────
    // 增:录入成绩
    // ─────────────────────────────────────────────────────────────────────────

    /**
     * 录入成绩
     */
    func inputScore() {
        println("开始录入成绩信息:")
        try {
            // 输入学号,并验证学生是否存在
            print("请输入学生学号:")
            let studentId = inputInfo<UInt32>()
            let stuMgr = StudentManager.propInstance
            if (stuMgr.findById(studentId).isNone()) {
                println("错误:学号 ${studentId} 不存在,请先录入学生信息!")
                return
            }

            // 输入课程 ID,并验证课程是否存在
            print("请输入课程编号:")
            let courseId = inputInfo<UInt32>()
            let courMgr = CourseManager.propInstance
            if (courMgr.findById(courseId).isNone()) {
                println("错误:课程 ${courseId} 不存在,请先录入课程信息!")
                return
            }

            // 检查是否已存在相同记录
            for (sc in scores) {
                if (sc.propStudentId == studentId && sc.propCourseId == courseId) {
                    println("该学生此课程的成绩已存在,如需修改请使用【修改成绩】功能!")
                    return
                }
            }

            // 输入成绩(0 ~ 100)
            print("请输入成绩(0 ~ 100):")
            let value = inputInfo<Float32>(0.0, 100.0)

            // 创建成绩对象并添加
            let score = Score(studentId, courseId, value)
            scores.add(score)
            println("成绩录入成功!")
        } catch (e: Exception) {
            println(e.message)
        }
    }

    // ─────────────────────────────────────────────────────────────────────────
    // 查:查询成绩(按学号 + 课程 ID)
    // ─────────────────────────────────────────────────────────────────────────

    /**
     * 查询指定学生某门课程的成绩
     */
    func queryScore() {
        print("请输入学生学号:")
        let studentId = inputInfo<UInt32>()
        print("请输入课程编号:")
        let courseId = inputInfo<UInt32>()

        for (sc in scores) {
            if (sc.propStudentId == studentId && sc.propCourseId == courseId) {
                println("查询成功,详情如下:")
                println(buildDetailString(sc))
                return
            }
        }
        println("未找到对应成绩记录!")
    }

    // ─────────────────────────────────────────────────────────────────────────
    // 改:修改成绩
    // ─────────────────────────────────────────────────────────────────────────

    /**
     * 修改指定学生某门课程的成绩
     */
    func modifyScore() {
        print("请输入学生学号:")
        let studentId = inputInfo<UInt32>()
        print("请输入课程编号:")
        let courseId = inputInfo<UInt32>()

        for (sc in scores) {
            if (sc.propStudentId == studentId && sc.propCourseId == courseId) {
                println("当前成绩信息:")
                println(buildDetailString(sc))
                print("请输入新成绩(0 ~ 100):")
                try {
                    sc.propValue = inputInfo<Float32>(0.0, 100.0)
                    println("修改成功!")
                } catch (e: Exception) {
                    println(e.message)
                }
                return
            }
        }
        println("未找到对应成绩记录!")
    }

    // ─────────────────────────────────────────────────────────────────────────
    // 删:删除成绩
    // ─────────────────────────────────────────────────────────────────────────

    /**
     * 删除指定学生某门课程的成绩记录
     */
    func deleteScore() {
        print("请输入学生学号:")
        let studentId = inputInfo<UInt32>()
        print("请输入课程编号:")
        let courseId = inputInfo<UInt32>()

        for (i in 0..scores.size) {
            if (scores[i].propStudentId == studentId && scores[i].propCourseId == courseId) {
                scores.remove(at: i)
                println("成绩记录删除成功!")
                return
            }
        }
        println("未找到对应成绩记录!")
    }

    // ─────────────────────────────────────────────────────────────────────────
    // 查:班级内某一课程成绩单显示
    // ─────────────────────────────────────────────────────────────────────────

    /**
     * 显示某门课程所有学生的成绩单(按课程 ID 筛选)
     */
    func printCourseScores() {
        print("请输入要查询的课程编号:")
        let courseId = inputInfo<UInt32>()

        // 验证课程是否存在
        let courMgr = CourseManager.propInstance
        if (courMgr.findById(courseId).isNone()) {
            println("课程 ${courseId} 不存在!")
            return
        }

        var count = 0
        var total: Float32 = 0.0
        println("─────── 课程 ${courseId} 成绩单 ───────")
        for (sc in scores) {
            if (sc.propCourseId == courseId) {
                println(buildDetailString(sc))
                total = total + sc.propValue
                count++
            }
        }

        if (count == 0) {
            println("暂无该课程的成绩记录。")
        } else {
            let avg: Float32 = total / Float32(count)
            println("共 ${count} 条记录,平均分: ${avg.format(".1")}")
        }
    }

    // ─────────────────────────────────────────────────────────────────────────
    // 查:某学生所有课程成绩显示
    // ─────────────────────────────────────────────────────────────────────────

    /**
     * 显示某学生所有课程的成绩(按学号筛选)
     */
    func printStudentScores() {
        print("请输入学生学号:")
        let studentId = inputInfo<UInt32>()

        // 验证学生是否存在
        let stuMgr = StudentManager.propInstance
        if (stuMgr.findById(studentId).isNone()) {
            println("学号 ${studentId} 不存在!")
            return
        }

        var count = 0
        println("─────── 学号 ${studentId} 全课程成绩单 ───────")
        for (sc in scores) {
            if (sc.propStudentId == studentId) {
                println(buildDetailString(sc))
                count++
            }
        }

        if (count == 0) {
            println("暂无该学生的成绩记录。")
        }
    }

    // ─────────────────────────────────────────────────────────────────────────
    // 私有工具:拼装详细信息字符串(通过 ID 去各管理器查找名称)
    // ─────────────────────────────────────────────────────────────────────────

    private func buildDetailString(sc: Score): String {
        let stuMgr  = StudentManager.propInstance
        let courMgr = CourseManager.propInstance

        let studentName = match (stuMgr.findById(sc.propStudentId)) {
            case Some(s) => s.propName
            case None    => "未知学生"
        }
        let courseName = match (courMgr.findById(sc.propCourseId)) {
            case Some(c) => c.propName
            case None    => "未知课程"
        }

        sc.toDetailString(studentName,  courseName)
    }
}