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

# --- 数据存储文件 ---
DATA_FILE = "my_planner_data.json"

class CalendarPlannerApp:
    def __init__(self, root):
        self.root = root
        self.root.title("我的日历计划表")
        self.root.geometry("900x600")
        self.root.minsize(800, 500)
        
        # 初始化数据
        self.current_year = datetime.now().year
        self.current_month = datetime.now().month
        self.selected_date = None
        self.plans = self.load_data()
        
        # 界面布局
        self.setup_ui()
        
        # 初始显示
        self.render_calendar()
        self.check_daily_reminder()

    def setup_ui(self):
        # 顶部工具栏
        top_frame = tk.Frame(self.root, bg="#4A90E2", height=60)
        top_frame.pack(fill=tk.X)
        top_frame.pack_propagate(False)
        
        tk.Label(top_frame, text="📅 日历计划表", font=("Microsoft YaHei", 20, "bold"), 
                 bg="#4A90E2", fg="white").pack(side=tk.LEFT, padx=20, pady=15)
        
        # 月份切换按钮
        btn_prev = tk.Button(top_frame, text="< 上个月", command=self.prev_month, bg="#357ABD", fg="white", relief=tk.FLAT)
        btn_prev.pack(side=tk.RIGHT, padx=10, pady=15)
        
        btn_next = tk.Button(top_frame, text="下个月 >", command=self.next_month, bg="#357ABD", fg="white", relief=tk.FLAT)
        btn_next.pack(side=tk.RIGHT, padx=10, pady=15)

        # 主内容区
        main_frame = tk.Frame(self.root)
        main_frame.pack(fill=tk.BOTH, expand=True, padx=20, pady=20)
        
        # 左侧：日历区域
        cal_frame = tk.Frame(main_frame, width=500)
        cal_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        cal_frame.pack_propagate(False)
        
        # 星期标题
        week_header = tk.Frame(cal_frame)
        week_header.pack(fill=tk.X)
        week_days = ["一", "二", "三", "四", "五", "六", "日"]
        for day in week_days:
            tk.Label(week_header, text=day, font=("Arial", 12, "bold"), width=10, bg="#f0f0f0", relief=tk.RIDGE).pack(side=tk.LEFT, expand=True, fill=tk.X)
        
        # 日期网格
        self.cal_grid_frame = tk.Frame(cal_frame)
        self.cal_grid_frame.pack(fill=tk.BOTH, expand=True)
        
        # 右侧：计划详情区域
        detail_frame = tk.LabelFrame(main_frame, text="📝 当日计划", font=("Arial", 12, "bold"), width=350, padx=15, pady=15)
        detail_frame.pack(side=tk.RIGHT, fill=tk.Y, padx=(20, 0))
        detail_frame.pack_propagate(False)
        
        # 选中日期显示
        self.lbl_selected_date = tk.Label(detail_frame, text="未选择日期", font=("Arial", 14, "bold"), fg="#4A90E2")
        self.lbl_selected_date.pack(anchor=tk.W, pady=(0, 15))
        
        # 计划列表 (Listbox + Scrollbar)
        list_frame = tk.Frame(detail_frame)
        list_frame.pack(fill=tk.BOTH, expand=True)
        
        scrollbar = ttk.Scrollbar(list_frame)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        
        self.plan_listbox = tk.Listbox(list_frame, height=15, font=("Consolas", 12), yscrollcommand=scrollbar.set, selectmode=tk.SINGLE)
        self.plan_listbox.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        scrollbar.config(command=self.plan_listbox.yview)
        
        # 输入区域
        input_frame = tk.Frame(detail_frame)
        input_frame.pack(fill=tk.X, pady=(15, 0))
        
        self.entry_plan = tk.Entry(input_frame, font=("Arial", 12))
        self.entry_plan.pack(side=tk.LEFT, fill=tk.X, expand=True)
        self.entry_plan.bind("<Return>", lambda e: self.add_plan()) # 回车添加
        
        btn_add = tk.Button(input_frame, text="添加", command=self.add_plan, bg="#4A90E2", fg="white", relief=tk.FLAT, padx=10)
        btn_add.pack(side=tk.LEFT, padx=(10, 0))
        
        btn_delete = tk.Button(detail_frame, text="删除选中项", command=self.delete_plan, bg="#E74C3C", fg="white", relief=tk.FLAT, pady=5)
        btn_delete.pack(fill=tk.X, pady=(10, 0))

    def render_calendar(self):
        # 清除旧的日期按钮
        for widget in self.cal_grid_frame.winfo_children():
            widget.destroy()
            
        # 获取当月日历数据
        cal = calendar.Calendar(firstweekday=0) # 0 代表周一
        month_days = cal.monthdayscalendar(self.current_year, self.current_month)
        
        # 更新顶部标题 (如果需要可以加一个Label显示年月)
        self.root.title(f"我的日历计划表 - {self.current_year}年{self.current_month}月")
        
        # 生成日期按钮
        for row_idx, week in enumerate(month_days):
            for col_idx, day in enumerate(week):
                if day == 0:
                    continue # 空白天数
                
                # 检查该日期是否有计划
                date_key = f"{self.current_year}-{self.current_month:02d}-{day:02d}"
                has_plan = date_key in self.plans and len(self.plans[date_key]) > 0
                
                # 按钮样式
                bg_color = "white"
                fg_color = "black"
                if has_plan:
                    bg_color = "#E3F2FD" # 有计划的日期淡蓝色背景
                    fg_color = "#1565C0"
                
                btn = tk.Button(
                    self.cal_grid_frame, 
                    text=str(day), 
                    font=("Arial", 12), 
                    width=10, 
                    height=3, 
                    bg=bg_color, 
                    fg=fg_color,
                    relief=tk.RAISED,
                    command=lambda d=day: self.select_date(d)
                )
                btn.grid(row=row_idx, column=col_idx, padx=2, pady=2, sticky="nsew")
        
        # 配置网格权重，使按钮自动填充
        for i in range(6):
            self.cal_grid_frame.rowconfigure(i, weight=1)
        for i in range(7):
            self.cal_grid_frame.columnconfigure(i, weight=1)

    def prev_month(self):
        self.current_month -= 1
        if self.current_month == 0:
            self.current_month = 12
            self.current_year -= 1
        self.render_calendar()

    def next_month(self):
        self.current_month += 1
        if self.current_month == 13:
            self.current_month = 1
            self.current_year += 1
        self.render_calendar()

    def select_date(self, day):
        self.selected_date = f"{self.current_year}-{self.current_month:02d}-{day:02d}"
        self.lbl_selected_date.config(text=self.selected_date)
        self.load_plans_for_date()

    def add_plan(self):
        if not self.selected_date:
            messagebox.showwarning("提示", "请先在左侧选择一个日期！")
            return
            
        plan_text = self.entry_plan.get().strip()
        if not plan_text:
            return
            
        if self.selected_date not in self.plans:
            self.plans[self.selected_date] = []
            
        self.plans[self.selected_date].append(plan_text)
        self.entry_plan.delete(0, tk.END)
        self.save_data()
        self.load_plans_for_date() # 刷新列表
        self.render_calendar()     # 刷新日历背景色

    def delete_plan(self):
        if not self.selected_date:
            return
            
        selected_index = self.plan_listbox.curselection()
        if not selected_index:
            messagebox.showwarning("提示", "请先选中要删除的计划！")
            return
            
        index = selected_index[0]
        self.plans[self.selected_date].pop(index)
        
        # 如果该日期计划为空，删除键
        if not self.plans[self.selected_date]:
            del self.plans[self.selected_date]
            
        self.save_data()
        self.load_plans_for_date()
        self.render_calendar()

    def load_plans_for_date(self):
        self.plan_listbox.delete(0, tk.END)
        if self.selected_date and self.selected_date in self.plans:
            for plan in self.plans[self.selected_date]:
                self.plan_listbox.insert(tk.END, plan)

    def check_daily_reminder(self):
        # 检查今天是否有计划
        today_key = datetime.now().strftime("%Y-%m-%d")
        if today_key in self.plans:
            plans = self.plans[today_key]
            plan_str = "\n".join([f"• {p}" for p in plans])
            messagebox.showinfo("今日提醒", f"今天是 {today_key}，你有以下计划：\n\n{plan_str}")

    def save_data(self):
        try:
            with open(DATA_FILE, "w", encoding="utf-8") as f:
                json.dump(self.plans, f, ensure_ascii=False, indent=4)
        except Exception as e:
            messagebox.showerror("错误", f"保存数据失败：{e}")

    def load_data(self):
        if os.path.exists(DATA_FILE):
            try:
                with open(DATA_FILE, "r", encoding="utf-8") as f:
                    return json.load(f)
            except Exception as e:
                messagebox.showerror("错误", f"读取数据失败：{e}")
                return {}
        return {}

if __name__ == "__main__":
    root = tk.Tk()
    # 尝试优化高分屏显示
    try:
        from ctypes import windll
        windll.shcore.SetProcessDpiAwareness(1)
    except:
        pass
        
    app = CalendarPlannerApp(root)
    root.mainloop()