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

# 数据文件
DATA_FILE = "birthday_data.json"

# 读取本地存储数据
def load_data():
    try:
        with open(DATA_FILE, "r", encoding="utf-8") as f:
            return json.load(f)
    except (FileNotFoundError, json.JSONDecodeError):
        return []

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

# 计算距离下次生日还有多少天
def get_days_left(month, day):
    today = datetime.now()
    next_birth = datetime(year=today.year, month=month, day=day)
    if next_birth < today:
        next_birth = datetime(year=today.year + 1, month=month, day=day)
    delta = next_birth - today
    return delta.days

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

        # 顶部输入区域
        frame_top = tk.Frame(root, pady=10)
        frame_top.pack(fill="x")

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

        tk.Label(frame_top, text="月：").grid(row=0, column=2, padx=5)
        self.month_entry = tk.Entry(frame_top, width=4)
        self.month_entry.grid(row=0, column=3, padx=5)

        tk.Label(frame_top, text="日：").grid(row=0, column=4, padx=5)
        self.day_entry = tk.Entry(frame_top, width=4)
        self.day_entry.grid(row=0, column=5, padx=5)

        tk.Button(frame_top, text="添加", command=self.add_item).grid(row=0, column=6, padx=8)
        tk.Button(frame_top, text="刷新列表", command=self.refresh_table).grid(row=0, column=7, padx=5)

        # 表格区域
        frame_table = tk.Frame(root)
        frame_table.pack(pady=5, fill="both", expand=True)

        columns = ("name", "month_day", "days")
        self.tree = ttk.Treeview(frame_table, columns=columns, show="headings")
        self.tree.heading("name", text="姓名")
        self.tree.heading("month_day", text="生日(月/日)")
        self.tree.heading("days", text="剩余天数")

        self.tree.column("name", width=180)
        self.tree.column("month_day", width=150)
        self.tree.column("days", width=150)

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

        # 底部按钮
        frame_bottom = tk.Frame(root, pady=8)
        frame_bottom.pack()
        tk.Button(frame_bottom, text="删除选中项", command=self.delete_selected).pack(side="left", padx=10)
        tk.Button(frame_bottom, text="清空全部记录", command=self.clear_all).pack(side="left", padx=10)

        self.refresh_table()

    # 添加生日
    def add_item(self):
        name = self.name_entry.get().strip()
        m_str = self.month_entry.get().strip()
        d_str = self.day_entry.get().strip()

        if not name or not m_str or not d_str:
            messagebox.showwarning("提示", "姓名、月份、日期不能为空！")
            return
        try:
            month = int(m_str)
            day = int(d_str)
            if not (1 <= month <= 12 and 1 <= day <= 31):
                raise ValueError
        except ValueError:
            messagebox.showerror("错误", "请输入合法的月份和日期！")
            return

        self.data.append({"name": name, "month": month, "day": day})
        save_data(self.data)
        self.name_entry.delete(0, tk.END)
        self.month_entry.delete(0, tk.END)
        self.day_entry.delete(0, tk.END)
        self.refresh_table()

    # 刷新表格
    def refresh_table(self):
        # 清空原有内容
        for item in self.tree.get_children():
            self.tree.delete(item)
        # 按剩余天数从小到大排序
        sorted_list = sorted(self.data, key=lambda x: get_days_left(x["month"], x["day"]))
        for info in sorted_list:
            days = get_days_left(info["month"], info["day"])
            birth_str = f"{info['month']:02d}/{info['day']:02d}"
            self.tree.insert("", "end", values=(info["name"], birth_str, f"{days} 天"))

    # 删除选中
    def delete_selected(self):
        selected = self.tree.selection()
        if not selected:
            messagebox.showinfo("提示", "请先选中一条记录")
            return
        idx = self.tree.index(selected[0])
        del self.data[idx]
        save_data(self.data)
        self.refresh_table()

    # 清空所有
    def clear_all(self):
        if messagebox.askyesno("确认", "确定要删除所有生日记录吗？"):
            self.data = []
            save_data(self.data)
            self.refresh_table()

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