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

class CalendarApp:
    def __init__(self, root):
        self.root = root
        self.root.title("📅 日历提醒与计划表")
        self.root.geometry("1100x700")
        
        # 存储任务的数据结构
        self.tasks = {}
        self.data_file = "tasks.json"
        self.current_date = datetime.now()
        self.load_tasks()
        
        self.setup_ui()
        self.update_display()
        
    def setup_ui(self):
        # 创建主框架
        main_frame = ttk.Frame(self.root)
        main_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
        
        # 左侧日历框架
        left_frame = ttk.Frame(main_frame, relief=tk.RAISED, borderwidth=2)
        left_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=False, padx=(0, 10))
        
        # 日历标题
        cal_title = ttk.Label(left_frame, text="📅 日历", font=("Arial", 14, "bold"))
        cal_title.pack(pady=10)
        
        # 年月选择框架
        year_month_frame = ttk.Frame(left_frame)
        year_month_frame.pack(pady=5)
        
        self.year_var = tk.StringVar()
        self.month_var = tk.StringVar()
        
        years = [str(i) for i in range(2020, 2031)]
        months = [f"{i:02d}" for i in range(1, 13)]
        
        year_combo = ttk.Combobox(year_month_frame, textvariable=self.year_var, values=years, width=6)
        year_combo.set(str(self.current_date.year))
        year_combo.pack(side=tk.LEFT, padx=5)
        
        month_combo = ttk.Combobox(year_month_frame, textvariable=self.month_var, values=months, width=4)
        month_combo.set(f"{self.current_date.month:02d}")
        month_combo.pack(side=tk.LEFT, padx=5)
        
        go_btn = ttk.Button(year_month_frame, text="跳转", command=self.change_month)
        go_btn.pack(side=tk.LEFT, padx=5)
        
        # 日历网格
        self.calendar_frame = ttk.Frame(left_frame)
        self.calendar_frame.pack(pady=10)
        
        # 星期标题
        weekdays = ["周一", "周二", "周三", "周四", "周五", "周六", "周日"]
        for i, day in enumerate(weekdays):
            label = ttk.Label(self.calendar_frame, text=day, font=("Arial", 10, "bold"))
            label.grid(row=0, column=i, padx=5, pady=5)
        
        self.calendar_buttons = {}
        self.build_calendar()
        
        # 快速添加任务区域
        quick_frame = ttk.LabelFrame(left_frame, text="✨ 快速添加任务", padding=10)
        quick_frame.pack(fill=tk.X, pady=10)
        
        ttk.Label(quick_frame, text="标题:").pack(anchor=tk.W)
        self.quick_title = ttk.Entry(quick_frame, width=25)
        self.quick_title.pack(fill=tk.X, pady=(0, 5))
        
        ttk.Label(quick_frame, text="描述:").pack(anchor=tk.W)
        self.quick_desc = scrolledtext.ScrolledText(quick_frame, height=4, width=25)
        self.quick_desc.pack(fill=tk.X, pady=(0, 5))
        
        add_btn = ttk.Button(quick_frame, text="➕ 添加到所选日期", command=self.add_task_quick)
        add_btn.pack(fill=tk.X)
        
        # 右侧任务框架
        right_frame = ttk.Frame(main_frame, relief=tk.RAISED, borderwidth=2)
        right_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True)
        
        # 日期显示
        self.date_label = ttk.Label(right_frame, font=("Arial", 16, "bold"))
        self.date_label.pack(pady=10)
        
        # 任务列表
        self.task_listbox = tk.Listbox(right_frame, height=20, font=("Arial", 10))
        self.task_listbox.pack(fill=tk.BOTH, expand=True, padx=10, pady=5)
        self.task_listbox.bind('<Double-Button-1>', self.edit_task)
        
        # 按钮框架
        button_frame = ttk.Frame(right_frame)
        button_frame.pack(pady=10)
        
        complete_btn = ttk.Button(button_frame, text="✅ 标记完成/未完成", command=self.toggle_complete)
        complete_btn.pack(side=tk.LEFT, padx=5)
        
        delete_btn = ttk.Button(button_frame, text="🗑️ 删除任务", command=self.delete_task)
        delete_btn.pack(side=tk.LEFT, padx=5)
        
        edit_desc_btn = ttk.Button(button_frame, text="✏️ 编辑描述", command=self.edit_description)
        edit_desc_btn.pack(side=tk.LEFT, padx=5)
        
        # 今日按钮
        today_btn = ttk.Button(button_frame, text="📌 今天", command=self.go_today)
        today_btn.pack(side=tk.LEFT, padx=5)
        
        # 状态栏
        self.status_var = tk.StringVar()
        status_bar = ttk.Label(self.root, textvariable=self.status_var, relief=tk.SUNKEN, anchor=tk.W)
        status_bar.pack(side=tk.BOTTOM, fill=tk.X)
        
    def build_calendar(self):
        # 清除旧的日历按钮
        for widget in self.calendar_frame.winfo_children():
            if isinstance(widget, tk.Button):
                widget.destroy()
        
        year = int(self.year_var.get())
        month = int(self.month_var.get())
        
        # 获取当月第一天和天数
        first_day = datetime(year, month, 1)
        _, days_in_month = calendar.monthrange(year, month)
        
        # 获取第一天是星期几（周一为0）
        first_weekday = first_day.weekday()
        
        # 填充日历
        row = 1
        col = first_weekday
        day = 1
        
        while day <= days_in_month:
            btn = tk.Button(self.calendar_frame, text=str(day), width=8, height=3,
                           command=lambda d=day: self.select_date(d))
            
            # 高亮今天
            today = datetime.now()
            if year == today.year and month == today.month and day == today.day:
                btn.config(bg='lightblue')
            
            btn.grid(row=row, column=col, padx=2, pady=2)
            self.calendar_buttons[day] = btn
            
            col += 1
            if col > 6:
                col = 0
                row += 1
            day += 1
    
    def select_date(self, day):
        """选择日期"""
        self.current_date = datetime(int(self.year_var.get()), int(self.month_var.get()), day)
        self.update_display()
    
    def change_month(self):
        """改变月份"""
        self.build_calendar()
        # 如果当前有选中的日期，更新显示
        if hasattr(self, 'current_date'):
            self.update_display()
    
    def go_today(self):
        """跳转到今天"""
        today = datetime.now()
        self.year_var.set(str(today.year))
        self.month_var.set(f"{today.month:02d}")
        self.current_date = today
        self.build_calendar()
        self.update_display()
    
    def get_date_str(self, date):
        """日期转字符串"""
        return date.strftime("%Y-%m-%d")
    
    def update_display(self):
        """更新任务列表显示"""
        date_str = self.get_date_str(self.current_date)
        self.date_label.config(text=f"📆 {date_str}")
        
        self.task_listbox.delete(0, tk.END)
        
        if date_str in self.tasks:
            for idx, task in enumerate(self.tasks[date_str]):
                title = task["title"]
                completed = task["completed"]
                
                if completed:
                    display_text = f"✅ [已完成] {title}"
                else:
                    display_text = f"⏳ {title}"
                
                if task["desc"]:
                    desc_preview = task["desc"][:30] + "..." if len(task["desc"]) > 30 else task["desc"]
                    display_text += f"\n   📝 {desc_preview}"
                
                self.task_listbox.insert(tk.END, display_text)
                # 存储任务索引
                self.task_listbox.itemconfig(tk.END, fg='gray' if completed else 'black')
                
                # 设置背景色（需要额外处理）
                if completed:
                    self.task_listbox.itemconfig(tk.END, bg='lightgreen')
        else:
            self.task_listbox.insert(tk.END, "🎉 暂无计划，添加一个吧！")
        
        task_count = len(self.tasks.get(date_str, []))
        self.status_var.set(f"当前日期: {date_str} 共有 {task_count} 个任务")
    
    def add_task_quick(self):
        """快速添加任务"""
        title = self.quick_title.get().strip()
        if not title:
            messagebox.showwarning("警告", "任务标题不能为空！")
            return
        
        desc = self.quick_desc.get("1.0", tk.END).strip()
        date_str = self.get_date_str(self.current_date)
        
        if date_str not in self.tasks:
            self.tasks[date_str] = []
        
        new_task = {
            "title": title,
            "desc": desc,
            "completed": False
        }
        self.tasks[date_str].append(new_task)
        
        self.save_tasks()
        self.update_display()
        
        # 清空输入框
        self.quick_title.delete(0, tk.END)
        self.quick_desc.delete("1.0", tk.END)
        
        self.status_var.set(f"已添加任务: {title}")
    
    def get_current_selected_task(self):
        """获取当前选中的任务"""
        selection = self.task_listbox.curselection()
        if not selection:
            messagebox.showinfo("提示", "请先选择一个任务")
            return None, None, None
        
        idx = selection[0]
        date_str = self.get_date_str(self.current_date)
        
        if date_str not in self.tasks or idx >= len(self.tasks[date_str]):
            return None, None, None
        
        return date_str, idx, self.tasks[date_str][idx]
    
    def toggle_complete(self):
        """切换任务完成状态"""
        result = self.get_current_selected_task()
        if result[0] is None:
            return
        
        date_str, idx, task = result
        task["completed"] = not task["completed"]
        self.save_tasks()
        self.update_display()
        
        status = "已完成" if task["completed"] else "未完成"
        self.status_var.set(f"任务标记为{status}: {task['title']}")
    
    def delete_task(self):
        """删除任务"""
        result = self.get_current_selected_task()
        if result[0] is None:
            return
        
        date_str, idx, task = result
        
        if messagebox.askyesno("确认删除", f'确定要删除任务 "{task["title"]}" 吗？'):
            del self.tasks[date_str][idx]
            self.save_tasks()
            self.update_display()
            self.status_var.set(f"已删除任务: {task['title']}")
    
    def edit_task(self, event):
        """编辑任务标题"""
        result = self.get_current_selected_task()
        if result[0] is None:
            return
        
        date_str, idx, task = result
        
        new_title = simpledialog.askstring("编辑标题", "请输入新的任务标题:", initialvalue=task["title"])
        if new_title and new_title.strip():
            task["title"] = new_title.strip()
            self.save_tasks()
            self.update_display()
            self.status_var.set(f"标题已更新: {new_title}")
    
    def edit_description(self):
        """编辑任务描述"""
        result = self.get_current_selected_task()
        if result[0] is None:
            return
        
        date_str, idx, task = result
        
        new_desc = simpledialog.askstring("编辑描述", "请输入任务详细描述:", initialvalue=task["desc"])
        if new_desc is not None:
            task["desc"] = new_desc.strip()
            self.save_tasks()
            self.update_display()
            self.status_var.set("描述已更新")
    
    def load_tasks(self):
        """加载任务"""
        if os.path.exists(self.data_file):
            try:
                with open(self.data_file, "r", encoding="utf-8") as f:
                    self.tasks = json.load(f)
            except Exception as e:
                print(f"加载文件失败: {e}")
                self.tasks = {}
        else:
            # 创建示例数据
            today = datetime.now().strftime("%Y-%m-%d")
            tomorrow = (datetime.now() + timedelta(days=1)).strftime("%Y-%m-%d")
            self.tasks = {
                today: [
                    {"title": "检查日历提醒功能", "desc": "确保所有功能正常", "completed": False},
                    {"title": "写周报", "desc": "整理本周工作内容", "completed": False}
                ],
                tomorrow: [
                    {"title": "参加会议", "desc": "项目进度会议 下午2点", "completed": False}
                ]
            }
            self.save_tasks()
    
    def save_tasks(self):
        """保存任务"""
        try:
            with open(self.data_file, "w", encoding="utf-8") as f:
                json.dump(self.tasks, f, ensure_ascii=False, indent=2)
        except Exception as e:
            messagebox.showerror("错误", f"保存任务失败: {e}")

def main():
    root = tk.Tk()
    app = CalendarApp(root)
    root.mainloop()

if __name__ == "__main__":
    import calendar
    from tkinter import simpledialog
    main()