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

SAVE_FILE = "birthday_data.json"

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

        self.birthdays = []
        self.load_data()

        # 输入区域
        frame_input = ttk.LabelFrame(root, text="添加生日")
        frame_input.pack(padx=10, pady=5, fill="x")

        ttk.Label(frame_input, text="姓名：").grid(row=0, column=0, padx=5, pady=5)
        self.name_entry = ttk.Entry(frame_input)
        self.name_entry.grid(row=0, column=1, padx=5, pady=5)

        ttk.Label(frame_input, text="生日(月-日)：").grid(row=0, column=2, padx=5, pady=5)
        self.birth_entry = ttk.Entry(frame_input)
        self.birth_entry.grid(row=0, column=3, padx=5, pady=5)
        self.birth_entry.insert(0, "MM-DD")

        ttk.Button(frame_input, text="添加", command=self.add_birthday).grid(row=0, column=4, padx=5, pady=5)

        # 列表表格
        frame_list = ttk.LabelFrame(root, text="生日列表")
        frame_list.pack(padx=10, pady=5, fill="both", expand=True)

        self.tree = ttk.Treeview(frame_list, columns=("name", "bday", "days"), show="headings")
        self.tree.heading("name", text="姓名")
        self.tree.heading("bday", text="生日")
        self.tree.heading("days", text="距离天数")
        self.tree.column("name", width=140)
        self.tree.column("bday", width=120)
        self.tree.column("days", width=120)

        scroll = ttk.Scrollbar(frame_list, orient="vertical", command=self.tree.yview)
        self.tree.configure(yscrollcommand=scroll.set)
        self.tree.pack(side="left", fill="both", expand=True)
        scroll.pack(side="right", fill="y")

        # 按钮区
        frame_btn = ttk.Frame(root)
        frame_btn.pack(pady=5)
        ttk.Button(frame_btn, text="刷新", command=self.refresh_list).grid(row=0, column=0, padx=4)
        ttk.Button(frame_btn, text="删除选中", command=self.del_selected).grid(row=0, column=1, padx=4)
        ttk.Button(frame_btn, text="检查今日提醒", command=self.check_today).grid(row=0, column=2, padx=4)

        self.refresh_list()

    def load_data(self):
        if os.path.exists(SAVE_FILE):
            try:
                with open(SAVE_FILE, "r", encoding="utf-8") as f:
                    self.birthdays = json.load(f)
            except Exception:
                self.birthdays = []

    def save_data(self):
        with open(SAVE_FILE, "w", encoding="utf-8") as f:
            json.dump(self.birthdays, f, ensure_ascii=False, indent=2)

    def calc_days(self, month_day):
        try:
            m, d = map(int, month_day.split("-"))
            today = datetime.now()
            this_year = today.year
            bday_this = datetime(this_year, m, d)
            if bday_this < today:
                bday_next = datetime(this_year + 1, m, d)
            else:
                bday_next = bday_this
            delta = bday_next - today
            return delta.days
        except Exception:
            return None

    def add_birthday(self):
        name = self.name_entry.get().strip()
        bday_str = self.birth_entry.get().strip()
        if not name or not bday_str:
            messagebox.showwarning("提示", "姓名和生日不能为空！")
            return
        days = self.calc_days(bday_str)
        if days is None:
            messagebox.showerror("错误", "日期格式错误！请使用 09-15 这种月-日格式")
            return
        self.birthdays.append({"name": name, "bday": bday_str})
        self.save_data()
        self.refresh_list()
        self.name_entry.delete(0, tk.END)
        self.birth_entry.delete(0, tk.END)

    def refresh_list(self):
        for item in self.tree.get_children():
            self.tree.delete(item)
        temp_list = []
        for item in self.birthdays:
            d = self.calc_days(item["bday"])
            temp_list.append((item["name"], item["bday"], d))
        # 按距离生日天数从小到大排序
        temp_list.sort(key=lambda x: x[2])
        for name, bday, days in temp_list:
            self.tree.insert("", tk.END, values=(name, bday, f"{days} 天"))

    def del_selected(self):
        sel = self.tree.selection()
        if not sel:
            messagebox.showinfo("提示", "请先选中一行记录")
            return
        for s in sel:
            vals = self.tree.item(s)["values"]
            name, bday = vals[0], vals[1]
            self.birthdays = [x for x in self.birthdays if not (x["name"] == name and x["bday"] == bday)]
        self.save_data()
        self.refresh_list()

    def check_today(self):
        today_str = datetime.now().strftime("%m-%d")
        happy_list = []
        for p in self.birthdays:
            if p["bday"] == today_str:
                happy_list.append(p["name"])
        if happy_list:
            msg = "🎉 今天是这些人的生日：\n" + "\n".join(happy_list)
            messagebox.showinfo("生日提醒", msg)
        else:
            messagebox.showinfo("提醒", "今天没有人生日~")

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