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

class CourseSchedule:
    def __init__(self, root):
        self.root = root
        self.root.title("📚 智能课程表")
        self.root.geometry("1000x700")
        self.root.resizable(False, False)
        
        # 设置颜色主题
        self.colors = {
            'bg': '#f0f4f8',
            'header': '#2c3e50',
            'accent': '#3498db',
            'text': '#2c3e50',
            'light': '#ecf0f1',
            'white': '#ffffff',
            'weekend': '#e74c3c',
            'today': '#f39c12'
        }
        
        # 数据文件
        self.data_file = "schedule_data.json"
        
        # 星期和节次
        self.weekdays = ['星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期日']
        self.time_slots = [
            '第1节 08:00-08:45',
            '第2节 08:55-09:40',
            '第3节 09:50-10:35',
            '第4节 10:45-11:30',
            '第5节 11:40-12:25',
            '第6节 14:00-14:45',
            '第7节 14:55-15:40',
            '第8节 15:50-16:35',
            '第9节 16:45-17:30'
        ]
        
        # 课程数据
        self.courses = {}
        self.load_data()
        
        # 创建界面
        self.create_widgets()
        
        # 显示课程表
        self.display_schedule()
        
        # 更新状态
        self.update_status()
        
    def load_data(self):
        """加载课程数据"""
        default_courses = {
            '星期一': {
                '第1节 08:00-08:45': {'name': '数学', 'teacher': '张老师', 'room': '101', 'color': '#e74c3c'},
                '第2节 08:55-09:40': {'name': '语文', 'teacher': '李老师', 'room': '102', 'color': '#3498db'},
                '第3节 09:50-10:35': {'name': '英语', 'teacher': '王老师', 'room': '103', 'color': '#2ecc71'}
            },
            '星期二': {
                '第1节 08:00-08:45': {'name': '物理', 'teacher': '刘老师', 'room': '201', 'color': '#e67e22'},
                '第2节 08:55-09:40': {'name': '化学', 'teacher': '陈老师', 'room': '202', 'color': '#9b59b6'},
                '第3节 09:50-10:35': {'name': '生物', 'teacher': '杨老师', 'room': '203', 'color': '#1abc9c'}
            },
            '星期三': {
                '第1节 08:00-08:45': {'name': '历史', 'teacher': '赵老师', 'room': '301', 'color': '#e74c3c'},
                '第2节 08:55-09:40': {'name': '地理', 'teacher': '孙老师', 'room': '302', 'color': '#3498db'},
                '第3节 09:50-10:35': {'name': '政治', 'teacher': '周老师', 'room': '303', 'color': '#2ecc71'}
            },
            '星期四': {
                '第1节 08:00-08:45': {'name': '数学', 'teacher': '张老师', 'room': '101', 'color': '#e74c3c'},
                '第2节 08:55-09:40': {'name': '英语', 'teacher': '王老师', 'room': '103', 'color': '#2ecc71'},
                '第3节 09:50-10:35': {'name': '物理', 'teacher': '刘老师', 'room': '201', 'color': '#e67e22'}
            },
            '星期五': {
                '第1节 08:00-08:45': {'name': '语文', 'teacher': '李老师', 'room': '102', 'color': '#3498db'},
                '第2节 08:55-09:40': {'name': '数学', 'teacher': '张老师', 'room': '101', 'color': '#e74c3c'},
                '第3节 09:50-10:35': {'name': '体育', 'teacher': '吴老师', 'room': '操场', 'color': '#f39c12'}
            }
        }
        
        if os.path.exists(self.data_file):
            try:
                with open(self.data_file, 'r', encoding='utf-8') as f:
                    self.courses = json.load(f)
            except:
                self.courses = default_courses
        else:
            self.courses = default_courses
            
        # 确保所有星期都有数据
        for day in self.weekdays:
            if day not in self.courses:
                self.courses[day] = {}
    
    def save_data(self):
        """保存课程数据"""
        with open(self.data_file, 'w', encoding='utf-8') as f:
            json.dump(self.courses, f, ensure_ascii=False, indent=2)
    
    def create_widgets(self):
        """创建界面组件"""
        # 主框架
        main_frame = tk.Frame(self.root, bg=self.colors['bg'])
        main_frame.pack(fill='both', expand=True, padx=20, pady=20)
        
        # 标题
        title_frame = tk.Frame(main_frame, bg=self.colors['bg'])
        title_frame.pack(fill='x', pady=(0, 20))
        
        title_label = tk.Label(
            title_frame,
            text="📚 智能课程表",
            font=('微软雅黑', 28, 'bold'),
            bg=self.colors['bg'],
            fg=self.colors['header']
        )
        title_label.pack(side='left')
        
        # 工具栏
        tool_frame = tk.Frame(title_frame, bg=self.colors['bg'])
        tool_frame.pack(side='right')
        
        # 添加课程按钮
        add_btn = tk.Button(
            tool_frame,
            text="➕ 添加课程",
            command=self.add_course,
            font=('微软雅黑', 12),
            bg='#2ecc71',
            fg='white',
            padx=20,
            pady=8,
            cursor='hand2'
        )
        add_btn.pack(side='left', padx=5)
        
        # 清空课程按钮
        clear_btn = tk.Button(
            tool_frame,
            text="🗑️ 清空课程表",
            command=self.clear_schedule,
            font=('微软雅黑', 12),
            bg='#e74c3c',
            fg='white',
            padx=20,
            pady=8,
            cursor='hand2'
        )
        clear_btn.pack(side='left', padx=5)
        
        # 导出按钮
        export_btn = tk.Button(
            tool_frame,
            text="💾 导出",
            command=self.export_schedule,
            font=('微软雅黑', 12),
            bg='#3498db',
            fg='white',
            padx=20,
            pady=8,
            cursor='hand2'
        )
        export_btn.pack(side='left', padx=5)
        
        # 课程表框架
        schedule_frame = tk.Frame(main_frame, bg=self.colors['white'])
        schedule_frame.pack(fill='both', expand=True)
        
        # 滚动条
        canvas = tk.Canvas(schedule_frame, bg=self.colors['white'])
        scrollbar = tk.Scrollbar(schedule_frame, orient="vertical", command=canvas.yview)
        scrollable_frame = tk.Frame(canvas, bg=self.colors['white'])
        
        scrollable_frame.bind(
            "<Configure>",
            lambda e: canvas.configure(scrollregion=canvas.bbox("all"))
        )
        
        canvas.create_window((0, 0), window=scrollable_frame, anchor="nw")
        canvas.configure(yscrollcommand=scrollbar.set)
        
        # 创建课程表表格
        self.create_table(scrollable_frame)
        
        canvas.pack(side="left", fill="both", expand=True)
        scrollbar.pack(side="right", fill="y")
        
        # 状态栏
        status_frame = tk.Frame(main_frame, bg=self.colors['bg'])
        status_frame.pack(fill='x', pady=(10, 0))
        
        self.status_label = tk.Label(
            status_frame,
            text="",
            font=('微软雅黑', 10),
            bg=self.colors['bg'],
            fg=self.colors['text']
        )
        self.status_label.pack(side='left')
        
        # 图例
        legend_frame = tk.Frame(status_frame, bg=self.colors['bg'])
        legend_frame.pack(side='right')
        
        tk.Label(legend_frame, text="图例：", font=('微软雅黑', 10),
                bg=self.colors['bg']).pack(side='left')
        
        # 今天标记
        today_color = tk.Frame(legend_frame, bg=self.colors['today'], width=20, height=20)
        today_color.pack(side='left', padx=5)
        tk.Label(legend_frame, text="今天", font=('微软雅黑', 9),
                bg=self.colors['bg']).pack(side='left', padx=(0, 10))
        
        # 周末标记
        weekend_color = tk.Frame(legend_frame, bg=self.colors['weekend'], width=20, height=20)
        weekend_color.pack(side='left', padx=5)
        tk.Label(legend_frame, text="周末", font=('微软雅黑', 9),
                bg=self.colors['bg']).pack(side='left')
    
    def create_table(self, parent):
        """创建课程表表格"""
        # 创建表头
        headers = ['节次'] + self.weekdays
        for col, header in enumerate(headers):
            label = tk.Label(
                parent,
                text=header,
                font=('微软雅黑', 12, 'bold'),
                bg=self.colors['header'],
                fg='white',
                relief='ridge',
                bd=1,
                width=12 if col > 0 else 16,
                height=2
            )
            label.grid(row=0, column=col, padx=1, pady=1, sticky='nsew')
        
        # 获取当前星期
        today_index = datetime.now().weekday()
        today_name = self.weekdays[today_index]
        
        # 创建课程表格
        for row, time_slot in enumerate(self.time_slots, 1):
            # 时间列
            time_label = tk.Label(
                parent,
                text=time_slot,
                font=('微软雅黑', 10),
                bg=self.colors['light'],
                relief='ridge',
                bd=1,
                height=2
            )
            time_label.grid(row=row, column=0, padx=1, pady=1, sticky='nsew')
            
            # 课程列
            for col, day in enumerate(self.weekdays, 1):
                # 判断是否为周末
                is_weekend = col >= 6
                # 判断是否为今天
                is_today = day == today_name
                
                # 获取课程信息
                course = self.courses.get(day, {}).get(time_slot)
                
                if course:
                    # 有课程
                    bg_color = course.get('color', '#95a5a6')
                    text = f"{course['name']}\n{course['teacher']}\n{course['room']}"
                    
                    # 创建课程卡片
                    card = tk.Frame(
                        parent,
                        bg=bg_color,
                        relief='raised',
                        bd=2,
                        cursor='hand2'
                    )
                    card.grid(row=row, column=col, padx=1, pady=1, sticky='nsew')
                    
                    # 课程信息标签
                    info_label = tk.Label(
                        card,
                        text=text,
                        font=('微软雅黑', 9),
                        bg=bg_color,
                        fg='white',
                        justify='center'
                    )
                    info_label.pack(expand=True, fill='both')
                    
                    # 绑定点击事件
                    info_label.bind('<Button-1>', lambda e, d=day, t=time_slot: self.edit_course(d, t))
                    card.bind('<Button-1>', lambda e, d=day, t=time_slot: self.edit_course(d, t))
                    
                    # 右键删除
                    info_label.bind('<Button-3>', lambda e, d=day, t=time_slot: self.delete_course(d, t))
                    card.bind('<Button-3>', lambda e, d=day, t=time_slot: self.delete_course(d, t))
                    
                    # 如果有今天标记
                    if is_today:
                        card.config(highlightbackground=self.colors['today'], highlightthickness=3)
                    
                else:
                    # 空课程
                    bg_color = self.colors['weekend'] if is_weekend else self.colors['white']
                    empty_label = tk.Label(
                        parent,
                        text="📝 点击添加" if not is_weekend else "休息",
                        font=('微软雅黑', 9),
                        bg=bg_color,
                        fg=self.colors['text'],
                        relief='groove',
                        bd=1,
                        cursor='hand2'
                    )
                    empty_label.grid(row=row, column=col, padx=1, pady=1, sticky='nsew')
                    
                    # 绑定点击事件添加课程
                    if not is_weekend:
                        empty_label.bind('<Button-1>', lambda e, d=day, t=time_slot: self.add_course_to_slot(d, t))
        
        # 设置网格权重
        for i in range(len(headers)):
            parent.grid_columnconfigure(i, weight=1)
        for i in range(len(self.time_slots) + 1):
            parent.grid_rowconfigure(i, weight=1)
    
    def display_schedule(self):
        """刷新课程表显示"""
        # 重新创建表格
        for widget in self.root.winfo_children():
            widget.destroy()
        self.create_widgets()
    
    def add_course(self):
        """添加课程"""
        dialog = tk.Toplevel(self.root)
        dialog.title("添加课程")
        dialog.geometry("400x350")
        dialog.configure(bg='white')
        dialog.transient(self.root)
        dialog.grab_set()
        
        # 居中
        dialog.update_idletasks()
        x = (dialog.winfo_screenwidth() // 2) - (400 // 2)
        y = (dialog.winfo_screenheight() // 2) - (350 // 2)
        dialog.geometry(f"+{x}+{y}")
        
        # 标题
        tk.Label(dialog, text="📝 添加课程", font=('微软雅黑', 16, 'bold'),
                fg=self.colors['header']).pack(pady=(20, 10))
        
        # 表单
        form_frame = tk.Frame(dialog, bg='white')
        form_frame.pack(fill='both', expand=True, padx=30)
        
        # 星期选择
        tk.Label(form_frame, text="星期：", font=('微软雅黑', 11),
                bg='white').pack(anchor='w', pady=(0, 5))
        day_var = tk.StringVar(value='星期一')
        day_combo = ttk.Combobox(form_frame, textvariable=day_var,
                                 values=self.weekdays, state='readonly')
        day_combo.pack(fill='x', pady=(0, 10))
        
        # 节次选择
        tk.Label(form_frame, text="节次：", font=('微软雅黑', 11),
                bg='white').pack(anchor='w', pady=(0, 5))
        time_var = tk.StringVar(value=self.time_slots[0])
        time_combo = ttk.Combobox(form_frame, textvariable=time_var,
                                  values=self.time_slots, state='readonly')
        time_combo.pack(fill='x', pady=(0, 10))
        
        # 课程名称
        tk.Label(form_frame, text="课程名称：", font=('微软雅黑', 11),
                bg='white').pack(anchor='w', pady=(0, 5))
        name_entry = tk.Entry(form_frame, font=('微软雅黑', 11))
        name_entry.pack(fill='x', pady=(0, 10))
        
        # 教师
        tk.Label(form_frame, text="教师：", font=('微软雅黑', 11),
                bg='white').pack(anchor='w', pady=(0, 5))
        teacher_entry = tk.Entry(form_frame, font=('微软雅黑', 11))
        teacher_entry.pack(fill='x', pady=(0, 10))
        
        # 教室
        tk.Label(form_frame, text="教室：", font=('微软雅黑', 11),
                bg='white').pack(anchor='w', pady=(0, 5))
        room_entry = tk.Entry(form_frame, font=('微软雅黑', 11))
        room_entry.pack(fill='x', pady=(0, 10))
        
        # 颜色选择
        color_frame = tk.Frame(form_frame, bg='white')
        color_frame.pack(fill='x', pady=(0, 10))
        
        tk.Label(color_frame, text="颜色：", font=('微软雅黑', 11),
                bg='white').pack(side='left')
        
        color_var = tk.StringVar(value='#3498db')
        color_preview = tk.Label(color_frame, bg=color_var.get(),
                                 width=10, height=1, relief='ridge')
        color_preview.pack(side='left', padx=10)
        
        def choose_color():
            color = colorchooser.askcolor(title="选择颜色")[1]
            if color:
                color_var.set(color)
                color_preview.config(bg=color)
        
        tk.Button(color_frame, text="选择颜色", command=choose_color,
                 font=('微软雅黑', 10)).pack(side='left')
        
        def confirm():
            day = day_var.get()
            time_slot = time_var.get()
            name = name_entry.get().strip()
            teacher = teacher_entry.get().strip()
            room = room_entry.get().strip()
            
            if not name:
                messagebox.showerror("错误", "请输入课程名称！")
                return
            
            if day not in self.courses:
                self.courses[day] = {}
            
            self.courses[day][time_slot] = {
                'name': name,
                'teacher': teacher or '未指定',
                'room': room or '未指定',
                'color': color_var.get()
            }
            
            self.save_data()
            self.display_schedule()
            self.update_status()
            dialog.destroy()
            messagebox.showinfo("成功", f"已添加课程：{name}")
        
        # 按钮
        btn_frame = tk.Frame(dialog, bg='white')
        btn_frame.pack(pady=20)
        
        tk.Button(btn_frame, text="确认添加", command=confirm,
                 font=('微软雅黑', 12, 'bold'), bg='#2ecc71',
                 fg='white', padx=30, pady=8).pack(side='left', padx=5)
        
        tk.Button(btn_frame, text="取消", command=dialog.destroy,
                 font=('微软雅黑', 12), bg='#e74c3c',
                 fg='white', padx=30, pady=8).pack(side='left', padx=5)
    
    def add_course_to_slot(self, day, time_slot):
        """在特定格子添加课程"""
        self.add_course()
    
    def edit_course(self, day, time_slot):
        """编辑课程"""
        course = self.courses.get(day, {}).get(time_slot)
        if not course:
            return
        
        dialog = tk.Toplevel(self.root)
        dialog.title("编辑课程")
        dialog.geometry("400x350")
        dialog.configure(bg='white')
        dialog.transient(self.root)
        dialog.grab_set()
        
        dialog.update_idletasks()
        x = (dialog.winfo_screenwidth() // 2) - (400 // 2)
        y = (dialog.winfo_screenheight() // 2) - (350 // 2)
        dialog.geometry(f"+{x}+{y}")
        
        tk.Label(dialog, text="✏️ 编辑课程", font=('微软雅黑', 16, 'bold'),
                fg=self.colors['header']).pack(pady=(20, 10))
        
        form_frame = tk.Frame(dialog, bg='white')
        form_frame.pack(fill='both', expand=True, padx=30)
        
        # 课程名称
        tk.Label(form_frame, text="课程名称：", font=('微软雅黑', 11),
                bg='white').pack(anchor='w', pady=(0, 5))
        name_entry = tk.Entry(form_frame, font=('微软雅黑', 11))
        name_entry.insert(0, course['name'])
        name_entry.pack(fill='x', pady=(0, 10))
        
        # 教师
        tk.Label(form_frame, text="教师：", font=('微软雅黑', 11),
                bg='white').pack(anchor='w', pady=(0, 5))
        teacher_entry = tk.Entry(form_frame, font=('微软雅黑', 11))
        teacher_entry.insert(0, course.get('teacher', ''))
        teacher_entry.pack(fill='x', pady=(0, 10))
        
        # 教室
        tk.Label(form_frame, text="教室：", font=('微软雅黑', 11),
                bg='white').pack(anchor='w', pady=(0, 5))
        room_entry = tk.Entry(form_frame, font=('微软雅黑', 11))
        room_entry.insert(0, course.get('room', ''))
        room_entry.pack(fill='x', pady=(0, 10))
        
        # 颜色
        color_frame = tk.Frame(form_frame, bg='white')
        color_frame.pack(fill='x', pady=(0, 10))
        
        tk.Label(color_frame, text="颜色：", font=('微软雅黑', 11),
                bg='white').pack(side='left')
        
        color_var = tk.StringVar(value=course.get('color', '#3498db'))
        color_preview = tk.Label(color_frame, bg=color_var.get(),
                                 width=10, height=1, relief='ridge')
        color_preview.pack(side='left', padx=10)
        
        def choose_color():
            color = colorchooser.askcolor(title="选择颜色")[1]
            if color:
                color_var.set(color)
                color_preview.config(bg=color)
        
        tk.Button(color_frame, text="选择颜色", command=choose_color,
                 font=('微软雅黑', 10)).pack(side='left')
        
        def confirm():
            name = name_entry.get().strip()
            teacher = teacher_entry.get().strip()
            room = room_entry.get().strip()
            
            if not name:
                messagebox.showerror("错误", "请输入课程名称！")
                return
            
            self.courses[day][time_slot] = {
                'name': name,
                'teacher': teacher or '未指定',
                'room': room or '未指定',
                'color': color_var.get()
            }
            
            self.save_data()
            self.display_schedule()
            self.update_status()
            dialog.destroy()
            messagebox.showinfo("成功", "课程已更新！")
        
        btn_frame = tk.Frame(dialog, bg='white')
        btn_frame.pack(pady=20)
        
        tk.Button(btn_frame, text="确认更新", command=confirm,
                 font=('微软雅黑', 12, 'bold'), bg='#3498db',
                 fg='white', padx=30, pady=8).pack(side='left', padx=5)
        
        tk.Button(btn_frame, text="取消", command=dialog.destroy,
                 font=('微软雅黑', 12), bg='#e74c3c',
                 fg='white', padx=30, pady=8).pack(side='left', padx=5)
    
    def delete_course(self, day, time_slot):
        """删除课程"""
        if messagebox.askyesno("确认删除", f"确定要删除 {day} {time_slot} 的课程吗？"):
            if day in self.courses and time_slot in self.courses[day]:
                del self.courses[day][time_slot]
                self.save_data()
                self.display_schedule()
                self.update_status()
                messagebox.showinfo("成功", "课程已删除！")
    
    def clear_schedule(self):
        """清空课程表"""
        if messagebox.askyesno("确认清空", "确定要清空所有课程吗？"):
            self.courses = {day: {} for day in self.weekdays}
            self.save_data()
            self.display_schedule()
            self.update_status()
            messagebox.showinfo("成功", "课程表已清空！")
    
    def export_schedule(self):
        """导出课程表为文本"""
        if not any(self.courses.values()):
            messagebox.showwarning("提示", "课程表为空，无法导出！")
            return
        
        export_text = "=" * 60 + "\n"
        export_text += "📚 课程表\n"
        export_text += f"导出时间：{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n"
        export_text += "=" * 60 + "\n\n"
        
        for day in self.weekdays:
            export_text += f"\n【{day}】\n"
            export_text += "-" * 50 + "\n"
            
            day_courses = self.courses.get(day, {})
            if day_courses:
                for time_slot, course in day_courses.items():
                    export_text += f"  {time_slot:15} | {course['name']:10} | {course['teacher']:8} | {course['room']}\n"
            else:
                export_text += "  （无课程）\n"
        
        export_text += "\n" + "=" * 60 + "\n"
        
        # 保存到文件
        file_path = f"课程表_{datetime.now().strftime('%Y%m%d')}.txt"
        with open(file_path, 'w', encoding='utf-8') as f:
            f.write(export_text)
        
        messagebox.showinfo("成功", f"课程表已导出到：{file_path}")
    
    def update_status(self):
        """更新状态栏"""
        total_courses = sum(len(day_courses) for day_courses in self.courses.values())
        
        # 今天的课程
        today = self.weekdays[datetime.now().weekday()]
        today_courses = self.courses.get(today, {})
        today_count = len(today_courses)
        
        status_text = f"📊 总课程：{total_courses} 节  |  📅 今天({today})：{today_count} 节"
        self.status_label.config(text=status_text)

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

if __name__ == "__main__":
    main()