import tkinter as tk
from tkinter import ttk, messagebox
import matplotlib
import numpy as np
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
import random
import time

# 设置matplotlib支持中文显示
matplotlib.rcParams["font.family"] = [
    "SimHei", "WenQuanYi Micro Hei", "Heiti TC"]
matplotlib.rcParams["axes.unicode_minus"] = False  # 解决负号显示问题


class DynamicScoreChart:
    def __init__(self, root):
        self.root = root
        self.root.title("动态成绩走势图")
        self.root.geometry("900x600")
        self.root.resizable(True, True)

        # 核心变量
        self.subjects = ["语文", "数学", "英语", "物理", "化学"]  # 学科列表
        self.max_weeks = 16  # 总周数
        self.current_week = 1  # 当前周数
        self.is_running = False  # 是否正在动态播放
        self.score_data = {subject: [] for subject in self.subjects}  # 成绩数据

        # 初始化成绩数据（第一周）
        self.init_score_data()

        # 创建Matplotlib图表
        self.fig = Figure(figsize=(10, 6), dpi=100)
        self.ax = self.fig.add_subplot(111)

        # 搭建界面
        self.create_widgets()

        # 初始绘制图表
        self.update_chart()

    def init_score_data(self):
        """初始化第一周的成绩数据（随机生成60-95分）"""
        for subject in self.subjects:
            self.score_data[subject] = [random.randint(60, 95)]

    def create_widgets(self):
        # 1. 控制面板
        control_frame = ttk.Frame(self.root)
        control_frame.pack(fill=tk.X, padx=20, pady=10)

        # 播放/暂停按钮
        self.play_btn = ttk.Button(
            control_frame, text="开始播放", command=self.toggle_play)
        self.play_btn.pack(side=tk.LEFT, padx=5)

        # 重置按钮
        reset_btn = ttk.Button(control_frame, text="重置数据",
                               command=self.reset_data)
        reset_btn.pack(side=tk.LEFT, padx=5)

        # 速度调节
        ttk.Label(control_frame, text="播放速度:").pack(side=tk.LEFT, padx=5)
        self.speed_var = tk.DoubleVar(value=0.5)
        speed_scale = ttk.Scale(
            control_frame,
            from_=0.1,
            to=2.0,
            variable=self.speed_var,
            orient=tk.HORIZONTAL,
            length=150
        )
        speed_scale.pack(side=tk.LEFT, padx=5)

        # 周数显示
        self.week_label = ttk.Label(control_frame, text=f"当前周数: 第1周")
        self.week_label.pack(side=tk.LEFT, padx=20)

        # 2. 图表显示区域
        self.canvas = FigureCanvasTkAgg(self.fig, master=self.root)
        self.canvas.draw()
        self.canvas.get_tk_widget().pack(fill=tk.BOTH, expand=True, padx=20, pady=10)

    def generate_next_week_score(self):
        """生成下一周的成绩（基于上一周小幅波动）"""
        for subject in self.subjects:
            last_score = self.score_data[subject][-1]
            # 随机波动 ±5分，确保成绩在0-100之间
            change = random.randint(-5, 5)
            new_score = max(0, min(100, last_score + change))
            self.score_data[subject].append(new_score)

    def update_chart(self):
        """更新成绩走势图"""
        # 清空原有图表
        self.ax.clear()

        # 设置图表样式
        self.ax.set_title(f"学期成绩变化趋势 (第{self.current_week}周)", fontsize=14)
        self.ax.set_xlabel("周数", fontsize=12)
        self.ax.set_ylabel("成绩 (分)", fontsize=12)
        self.ax.set_xlim(1, self.max_weeks)
        self.ax.set_ylim(0, 100)
        self.ax.grid(True, alpha=0.3)

        # 绘制各学科折线
        colors = ["#FF6B6B", "#4ECDC4", "#45B7D1", "#96CEB4", "#FFEAA7"]
        markers = ["o", "s", "^", "D", "p"]

        weeks = list(range(1, self.current_week + 1))
        for idx, subject in enumerate(self.subjects):
            scores = self.score_data[subject]
            self.ax.plot(
                weeks,
                scores,
                label=subject,
                color=colors[idx],
                marker=markers[idx],
                markersize=6,
                linewidth=2,
                alpha=0.8
            )

        # 添加图例
        self.ax.legend(loc="upper right", fontsize=10)

        # 更新画布
        self.canvas.draw()

    def toggle_play(self):
        """切换播放/暂停状态"""
        if self.is_running:
            # 暂停播放
            self.is_running = False
            self.play_btn.config(text="继续播放")
        else:
            # 开始/继续播放
            self.is_running = True
            self.play_btn.config(text="暂停播放")
            self.play_animation()

    def play_animation(self):
        """播放动态成绩变化动画"""
        if not self.is_running:
            return

        # 如果已经到最后一周，停止播放
        if self.current_week >= self.max_weeks:
            self.is_running = False
            self.play_btn.config(text="开始播放")
            messagebox.showinfo("提示", "已播放完整个学期的成绩数据！")
            return

        # 生成下一周数据
        self.current_week += 1
        self.generate_next_week_score()

        # 更新图表和周数显示
        self.update_chart()
        self.week_label.config(text=f"当前周数: 第{self.current_week}周")

        # 延迟后继续播放（根据速度调节）
        delay = int(self.speed_var.get() * 1000)  # 转换为毫秒
        self.root.after(delay, self.play_animation)

    def reset_data(self):
        """重置所有数据"""
        self.is_running = False
        self.current_week = 1
        self.play_btn.config(text="开始播放")

        # 重新初始化数据
        self.init_score_data()

        # 更新图表和周数显示
        self.update_chart()
        self.week_label.config(text=f"当前周数: 第1周")


if __name__ == "__main__":
    root = tk.Tk()
    app = DynamicScoreChart(root)
    root.mainloop()
