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

DATA_FILE = "古风日程本.json"

# 加载保存日程
def load_schedule():
    if os.path.exists(DATA_FILE):
        with open(DATA_FILE, "r", encoding="utf-8") as f:
            return json.load(f)
    return {}

def save_schedule(data):
    with open(DATA_FILE, "w", encoding="utf-8") as f:
        json.dump(data, f, ensure_ascii=False, indent=2)

schedule = load_schedule()
now = datetime.now()
cur_year = now.year
cur_month = now.month
select_day = now.day

# 古风配色
BG_MAIN = "#f8efe0"
BG_HEAD = "#8b4513"
TEXT_LIGHT = "#fff8e8"
TEXT_NORMAL = "#4b2e1b"
BTN_COLOR = "#c8a478"

class AncientCalendarApp:
    def __init__(self, root):
        self.root = root
        self.root.title("古风 · 光阴记事日程簿")
        self.root.geometry("800x650")
        self.root.configure(bg=BG_MAIN)

        self.year = cur_year
        self.month = cur_month

        # 顶部标题栏
        head_frame = tk.Frame(root, bg=BG_HEAD)
        head_frame.pack(fill="x")
        title_label = tk.Label(head_frame, text=" 光阴记事 · 日历计划表 ",
                                font=("KaiTi‑GB2312", 20), bg=BG_HEAD, fg=TEXT_LIGHT)
        title_label.pack(pady=10)

        # 年月切换区
        top_frame = tk.Frame(root, bg=BG_MAIN)
        top_frame.pack(pady=10)

        ttk.Style().configure("A.TButton", background=BTN_COLOR)
        self.btn_last = ttk.Button(top_frame, text="◀ 上月", command=self.prev_month, style="A.TButton")
        self.btn_last.grid(row=0, column=0, padx=8)

        self.ym_label = tk.Label(top_frame, font=("KaiTi‑GB2312",16), bg=BG_MAIN, fg=TEXT_NORMAL)
        self.ym_label.grid(row=0, column=1, padx=20)

        self.btn_next = ttk.Button(top_frame, text="下月 ▶", command=self.next_month, style="A.TButton")
        self.btn_next.grid(row=0, column=2, padx=8)

        # 星期表头
        week_name = ["朔日","一","二","三","四","五","六"]
        week_frame = tk.Frame(root, bg=BG_MAIN)
        week_frame.pack()
        for idx, w in enumerate(week_name):
            l = tk.Label(week_frame, text=w, width=8, height=2,
                           bg=BG_HEAD, fg=TEXT_LIGHT, font=("KaiTi‑GB2312",11))
            l.grid(row=0, column=idx)

        # 日历画布
        self.calendar_frame = tk.Frame(root, bg=BG_MAIN)
        self.calendar_frame.pack(pady=6)
        self.day_btns = []

        # 右侧日程面板
        right_box = tk.LabelFrame(root, text="待办记事", font=("KaiTi‑GB2312",13),
                                   bg=BG_MAIN, fg=TEXT_NORMAL)
        right_box.place(x=560, y=80, width=210, height=480)

        self.select_date_text = tk.Label(right_box, text="暂未择取日期",
                                          bg=BG_MAIN, fg="#992222", font=("KaiTi‑GB2312",11))
        self.select_date_text.pack(pady=6)

        tk.Label(right_box, text="记事标题", bg=BG_MAIN, fg=TEXT_NORMAL).pack()
        self.entry_title = ttk.Entry(right_box, width=22)
        self.entry_title.pack(pady=2)

        tk.Label(right_box, text="提醒时辰(HH:MM)", bg=BG_MAIN, fg=TEXT_NORMAL).pack()
        self.entry_time = ttk.Entry(right_box, width=22)
        self.entry_time.insert(0,"08:00")
        self.entry_time.pack(pady=2)

        tk.Label(right_box, text="备注详情", bg=BG_MAIN, fg=TEXT_NORMAL).pack()
        self.text_note = tk.Text(right_box, width=20, height=6)
        self.text_note.pack(pady=3)

        ttk.Button(right_box, text="新增记事", command=self.add_plan, style="A.TButton").pack(pady=3)
        ttk.Button(right_box, text="删除选中记事", command=self.del_plan, style="A.TButton").pack(pady=3)

        tk.Label(right_box,text="当日清单",bg=BG_MAIN,fg=TEXT_NORMAL).pack()
        self.list_box = tk.Listbox(right_box,width=22,height=8,font=("KaiTi‑GB2312",9))
        self.list_box.pack(pady=3)

        self.refresh_calendar()
        self.check_alarm()

    def get_month_days(self,y,m):
        if m == 12:
            nd = date(y+1,1,1)
        else:
            nd = date(y,m+1,1)
        first = date(y,m,1)
        days_count = (nd - first).days
        start_week = first.weekday() + 1
        if start_week ==7:
            start_week=0
        return days_count, start_week

    def refresh_calendar(self):
        for widget in self.calendar_frame.winfo_children():
            widget.destroy()
        self.ym_label.config(text=f"{self.year} 年 {self.month} 月")
        total_days,start_pos = self.get_month_days(self.year,self.month)
        row = 0
        for i in range(start_pos):
            tk.Label(self.calendar_frame,text="",width=8,height=2,bg=BG_MAIN).grid(row=row,column=i)
        col = start_pos
        for d in range(1,total_days+1):
            def callback(day=d):
                self.pick_day(day)
            has_task = self.check_day_has_task(d)
            btn_bg = "#ddc2a0" if has_task else "#f3e6d2"
            b = tk.Button(self.calendar_frame, text=str(d), width=8, height=2,
                           bg=btn_bg, activebackground="#b98b6b",
                           command=callback, font=("KaiTi‑GB2312",10))
            b.grid(row=row,column=col)
            self.day_btns.append(b)
            col += 1
            if col >=7:
                col = 0
                row +=1

    def check_day_has_task(self,day):
        key = f"{self.year}-{self.month:02d}-{day:02d}"
        return key in schedule and len(schedule[key])>0

    def pick_day(self,day):
        global select_day
        select_day = day
        self.now_key = f"{self.year}-{self.month:02d}-{day:02d}"
        self.select_date_text.config(text=f"{self.year}年{self.month}月{day}日")
        self.load_day_task()

    def load_day_task(self):
        self.list_box.delete(0,"end")
        self.plan_list = schedule.get(self.now_key,[])
        for item in self.plan_list:
            self.list_box.insert("end",f"[{item['time']}] {item['title']}")

    def add_plan(self):
        title = self.entry_title.get().strip()
        remind_t = self.entry_time.get().strip()
        note = self.text_note.get("1.0","end").strip()
        if not title:
            messagebox.showerror("提示","记事名称不可为空！")
            return
        if not hasattr(self,"now_key"):
            messagebox.showwarning("择选日期","请先在日历挑选一日")
            return
        if self.now_key not in schedule:
            schedule[self.now_key] = []
        new_item = {"title":title,"time":remind_t,"note":note}
        schedule[self.now_key].append(new_item)
        save_schedule(schedule)
        self.load_day_task()
        self.refresh_calendar()
        messagebox.showinfo("告成","记事已经录入簿册")
        self.entry_title.delete(0,"end")
        self.text_note.delete("1.0","end")

    def del_plan(self):
        sel = self.list_box.curselection()
        if not sel:
            messagebox.showwarning("选取","请选中一条记事")
            return
        index = sel[0]
        del schedule[self.now_key][index]
        save_schedule(schedule)
        self.load_day_task()
        self.refresh_calendar()

    def prev_month(self):
        self.month -= 1
        if self.month < 1:
            self.month =12
            self.year -=1
        self.refresh_calendar()

    def next_month(self):
        self.month +=1
        if self.month>12:
            self.month = 1
            self.year +=1
        self.refresh_calendar()

    def check_alarm(self):
        today_key = f"{now.year}-{now.month:02d}-{now.day:02d}"
        if today_key in schedule:
            hhmm = now.strftime("%H:%M")
            for task in schedule[today_key]:
                if task["time"] == hhmm:
                    messagebox.showinfo("时辰提醒",f"该办事啦：{task['title']}\n备注:{task['note']}")
        self.root.after(60000,self.check_alarm)


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