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

# 数据保存文件
SAVE_FILE = "birthday_data.json"

class BirthdayReminder:
    def __init__(self, root):
        self.root = root
        self.root.title("生日提醒器")
        self.root.geometry("620x450")

        # 存储生日列表
        self.birth_list = self.load_data()

        # 顶部输入区域
        input_frame = tk.Frame(root, pady=8)
        input_frame.pack(fill=tk.X, padx=10)

        tk.Label(input_frame, text="姓名：").grid(row=0, column=0, padx=4)
        self.name_entry = tk.Entry(input_frame, width=12)
        self.name_entry.grid(row=0, column=1, padx=4)

        tk.Label(input_frame, text="生日(月/日)：").grid(row=0, column=2, padx=4)
        self.birth_entry = tk.Entry(input_frame, width=10)
        self.birth_entry.insert(0, "06/01")
        self.birth_entry.grid(row=0, column=3, padx=4)

        tk.Label(input_frame, text="备注：").grid(row=0, column=4, padx=4)
        self.note_entry = tk.Entry(input_frame, width=15)
        self.note_entry.grid(row=0, column=5, padx=4)

        # 按钮区
        btn_frame = tk.Frame(root, pady=5)
        btn_frame.pack()
        ttk.Button(btn_frame, text="添加生日", command=self.add_item).grid(row=0, column=0, padx=6)
        ttk.Button(btn_frame, text="删除选中", command=self.delete_item).grid(row=0, column=1, padx=6)
        ttk.Button(btn_frame, text="刷新排序", command=self.refresh_list).grid(row=0, column=2, padx=6)
        ttk.Button(btn_frame, text="清空全部", command=self.clear_all).grid(row=0, column=3, padx=6)

        # 表格列表
        table_frame = tk.Frame(root, padx=10, pady=5)
        table_frame.pack(fill=tk.BOTH, expand=True)

        columns = ("name", "birth", "days", "note")
        self.tree = ttk.Treeview(table_frame, columns=columns, show="headings")
        self.tree.heading("name", text="姓名")
        self.tree.heading("birth", text="生日 月/日")
        self.tree.heading("days", text="距离天数")
        self.tree.heading("note", text="备注")

        self.tree.column("name", width=110)
        self.tree.column("birth", width=90)
        self.tree.column("days", width=90)
        self.tree.column("note", width=240)

        scroll = ttk.Scrollbar(table_frame, orient=tk.VERTICAL, command=self.tree.yview)
        self.tree.configure(yscrollcommand=scroll.set)
        scroll.pack(side=tk.RIGHT, fill=tk.Y)
        self.tree.pack(fill=tk.BOTH, expand=True)

        # 底部提示
        tk.Label(root, text="说明：生日格式 月/日 例如 07/15，距离天数越小越临近生日", fg="#555").pack(pady=3)

        self.refresh_list()

    def load_data(self):
        """读取本地保存的数据"""
        try:
            with open(SAVE_FILE, "r", encoding="utf-8") as f:
                return json.load(f)
        except:
            return []

    def save_data(self):
        """保存数据到文件"""
        with open(SAVE_FILE, "w", encoding="utf-8") as f:
            json.dump(self.birth_list, f, ensure_ascii=False, indent=2)

    def calc_days(self, birth_str):
        """计算今年距离生日还有多少天"""
        try:
            month, day = map(int, birth_str.split("/"))
            today = datetime.now()
            this_year = today.year
            try:
                birth_date = datetime(this_year, month, day)
            except ValueError:
                return "日期错误"
            diff = (birth_date - today).days
            if diff < 0:
                # 今年已过，算明年
                birth_next = datetime(this_year + 1, month, day)
                diff = (birth_next - today).days
            return diff
        except:
            return "格式错"

    def add_item(self):
        name = self.name_entry.get().strip()
        birth = self.birth_entry.get().strip()
        note = self.note_entry.get().strip()
        if not name or not birth:
            messagebox.showwarning("提示", "姓名和生日不能为空！")
            return
        days = self.calc_days(birth)
        if isinstance(days, str):
            messagebox.showerror("错误", "生日格式请填写：月/日，如07/15")
            return
        self.birth_list.append({
            "name": name,
            "birth": birth,
            "note": note
        })
        self.save_data()
        self.refresh_list()
        # 清空输入框
        self.name_entry.delete(0, tk.END)
        self.note_entry.delete(0, tk.END)

    def refresh_list(self):
        # 清空表格
        for item in self.tree.get_children():
            self.tree.delete(item)
        # 按剩余天数从小到大排序
        sorted_list = sorted(self.birth_list, key=lambda x: self.calc_days(x["birth"]))
        for info in sorted_list:
            d = self.calc_days(info["birth"])
            tip = f"{d}天" if isinstance(d, int) else d
            self.tree.insert("", tk.END, values=(info["name"], info["birth"], tip, info["note"]))

    def delete_item(self):
        selected = self.tree.selection()
        if not selected:
            messagebox.showinfo("提示", "请先选中一行数据")
            return
        idx = self.tree.index(selected[0])
        del self.birth_list[idx]
        self.save_data()
        self.refresh_list()

    def clear_all(self):
        if messagebox.askyesno("确认", "确定要删除所有生日记录吗？不可恢复！"):
            self.birth_list.clear()
            self.save_data()
            self.refresh_list()

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