import tkinter as tk
from tkinter import ttk, messagebox
import json
import os
from datetime import date

DATA_FILE = "study_plan.json"

class DailyStudyPlan:
    def __init__(self, root):
        self.root = root
        self.root.title("每日学习计划")
        self.root.geometry("600x500")
        self.root.resizable(True, True)

        self.today = str(date.today())
        self.tasks = []  # 每个任务: {"name": str, "duration": str, "done": bool, "date": str}
        self.task_vars = []  # 与复选框关联的 BooleanVar
        self.task_frames = []  # 每行任务的 Frame

        self.load_tasks()
        self.create_widgets()
        self.refresh_task_list()

    # ---------- 数据持久化 ----------
    def load_tasks(self):
        if os.path.exists(DATA_FILE):
            try:
                with open(DATA_FILE, "r", encoding="utf-8") as f:
                    data = json.load(f)
                # 如果日期不是今天，重置所有任务的完成状态
                if data.get("date") != self.today:
                    self.tasks = []
                    for task in data.get("tasks", []):
                        task["done"] = False
                        task["date"] = self.today
                        self.tasks.append(task)
                else:
                    self.tasks = data.get("tasks", [])
                return
            except Exception as e:
                messagebox.showwarning("加载数据失败", f"无法读取计划文件：{e}")
        # 文件不存在或出错，使用空列表
        self.tasks = []

    def save_tasks(self):
        data = {
            "date": self.today,
            "tasks": self.tasks
        }
        try:
            with open(DATA_FILE, "w", encoding="utf-8") as f:
                json.dump(data, f, ensure_ascii=False, indent=2)
        except Exception as e:
            messagebox.showerror("保存失败", f"无法保存计划：{e}")

    # ---------- UI 构建 ----------
    def create_widgets(self):
        # 顶部：日期与重置按钮
        top_frame = ttk.Frame(self.root)
        top_frame.pack(fill=tk.X, padx=10, pady=10)

        self.date_label = ttk.Label(top_frame, text=f"📅 {self.today}", font=("Arial", 12, "bold"))
        self.date_label.pack(side=tk.LEFT)

        reset_btn = ttk.Button(top_frame, text="重置今日计划", command=self.reset_today)
        reset_btn.pack(side=tk.RIGHT)

        # 中部：可滚动的任务列表
        list_container = ttk.Frame(self.root)
        list_container.pack(fill=tk.BOTH, expand=True, padx=10, pady=(0, 10))

        self.canvas = tk.Canvas(list_container, borderwidth=0, highlightthickness=0)
        scrollbar = ttk.Scrollbar(list_container, orient=tk.VERTICAL, command=self.canvas.yview)
        self.scroll_frame = ttk.Frame(self.canvas)

        self.scroll_frame.bind("<Configure>", lambda e: self.canvas.configure(scrollregion=self.canvas.bbox("all")))
        self.canvas.create_window((0, 0), window=self.scroll_frame, anchor="nw")
        self.canvas.configure(yscrollcommand=scrollbar.set)

        self.canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)

        # 底部：添加任务区域
        bottom_frame = ttk.Frame(self.root)
        bottom_frame.pack(fill=tk.X, padx=10, pady=(0, 10))

        ttk.Label(bottom_frame, text="任务名称:").grid(row=0, column=0, sticky=tk.W, padx=(0, 5))
        self.task_entry = ttk.Entry(bottom_frame, width=25)
        self.task_entry.grid(row=0, column=1, padx=(0, 10))

        ttk.Label(bottom_frame, text="预计时长:").grid(row=0, column=2, sticky=tk.W, padx=(0, 5))
        self.duration_combo = ttk.Combobox(bottom_frame, values=["15分钟", "30分钟", "45分钟", "1小时", "1.5小时", "2小时", "自定义"], width=10)
        self.duration_combo.set("30分钟")
        self.duration_combo.grid(row=0, column=3, padx=(0, 10))

        add_btn = ttk.Button(bottom_frame, text="➕ 添加任务", command=self.add_task)
        add_btn.grid(row=0, column=4)

        # 绑定回车键添加任务
        self.task_entry.bind("<Return>", lambda event: self.add_task())

    def refresh_task_list(self):
        # 清空原有组件
        for frame in self.task_frames:
            frame.destroy()
        self.task_frames.clear()
        self.task_vars.clear()

        if not self.tasks:
            empty_label = ttk.Label(self.scroll_frame, text="今天还没有学习任务，快添加一个吧！", foreground="gray")
            empty_label.pack(pady=20)
            self.task_frames.append(empty_label)  # 借用列表存储，用于清理
            return

        for idx, task in enumerate(self.tasks):
            var = tk.BooleanVar(value=task.get("done", False))
            self.task_vars.append(var)

            # 每行一个 Frame
            row_frame = ttk.Frame(self.scroll_frame)
            row_frame.pack(fill=tk.X, pady=2)

            # 复选框
            cb = ttk.Checkbutton(row_frame, variable=var, command=lambda i=idx: self.toggle_done(i))
            cb.pack(side=tk.LEFT)

            # 任务信息
            name = task.get("name", "")
            duration = task.get("duration", "")
            text = f"{name}  【{duration}】" if duration else name
            if task.get("done"):
                text += "  ✅"
            label = ttk.Label(row_frame, text=text, font=("Arial", 11))
            label.pack(side=tk.LEFT, padx=(5, 20))

            # 删除按钮
            del_btn = ttk.Button(row_frame, text="🗑️", width=3, command=lambda i=idx: self.delete_task(i))
            del_btn.pack(side=tk.RIGHT)

            self.task_frames.append(row_frame)

    def add_task(self):
        name = self.task_entry.get().strip()
        if not name:
            messagebox.showwarning("输入为空", "请输入任务名称")
            return

        duration = self.duration_combo.get()
        if duration == "自定义":
            duration = "自定义"
        # 简单处理，无需额外验证

        self.tasks.append({
            "name": name,
            "duration": duration,
            "done": False,
            "date": self.today
        })
        self.save_tasks()
        self.task_entry.delete(0, tk.END)
        self.refresh_task_list()

    def toggle_done(self, index):
        if 0 <= index < len(self.tasks):
            self.tasks[index]["done"] = self.task_vars[index].get()
            self.save_tasks()
            # 更新显示文字（尤其完成状态标记）
            self.refresh_task_list()

    def delete_task(self, index):
        if 0 <= index < len(self.tasks):
            del self.tasks[index]
            self.save_tasks()
            self.refresh_task_list()

    def reset_today(self):
        if messagebox.askyesno("重置", "确定要重置今日所有任务的完成状态吗？"):
            for task in self.tasks:
                task["done"] = False
            self.save_tasks()
            self.refresh_task_list()

if __name__ == "__main__":
    root = tk.Tk()
    app = DailyStudyPlan(root)
    root.mainloop()