import tkinter as tk
from tkinter import messagebox, simpledialog
import json
import os

# ========================
# 配置
# ========================
DAYS = ["周一", "周二", "周三", "周四", "周五", "周六", "周日"]
PERIODS = 8
WEEKDAYS = 5  # 默认显示5天

COLORS = {
    "语文": "#E53935",
    "数学": "#1E88E5",
    "英语": "#43A047",
    "物理": "#8E24AA",
    "化学": "#F4511E",
    "生物": "#00897B",
    "历史": "#FFB300",
    "地理": "#5C6BC0",
    "政治": "#6D4C41",
    "音乐": "#EC407A",
    "美术": "#26A69A",
    "体育": "#7CB342",
    "信息": "#00ACC1",
    "通用": "#78909C",
}

THEMES = {
    "🌸 樱花粉": {"bg": "#FFF0F5", "header": "#F8BBD0", "grid": "#FCE4EC", "fg": "#AD1457", "btn": "#F48FB1"},
    "💙 天空蓝": {"bg": "#E3F2FD", "header": "#90CAF9", "grid": "#BBDEFB", "fg": "#0D47A1", "btn": "#64B5F6"},
    "💚 抹茶绿": {"bg": "#E8F5E9", "header": "#A5D6A7", "grid": "#C8E6C9", "fg": "#1B5E20", "btn": "#81C784"},
    "🧡 蜜桔橙": {"bg": "#FFF3E0", "header": "#FFCC80", "grid": "#FFE0B2", "fg": "#E65100", "btn": "#FF8A65"},
    "💜 梦幻紫": {"bg": "#F3E5F5", "header": "#CE93D8", "grid": "#E1BEE7", "fg": "#4A148C", "btn": "#AB47BC"},
    "🌈 糖果色": {"bg": "#FFF9C4", "header": "#FFF176", "grid": "#FFF59D", "fg": "#F57F17", "btn": "#FFD54F"},
}
cur_theme = "🌸 樱花粉"

# ========================
# 数据
# ========================
DATA_FILE = "course_data.json"

default_courses = {}
for d in range(WEEKDAYS):
    for p in range(PERIODS):
        default_courses[f"{d}_{p}"] = {"name": "", "teacher": "", "room": ""}

courses = {}
loaded_weekdays = WEEKDAYS

# ========================
# UI 引用
# ========================
root = None
table_frame = None
header_labels = []
cell_labels = {}
theme_btns = []
all_widgets = []
status_label = None

# ========================
# 工具
# ========================
def get_color(name):
    """获取课程颜色"""
    if not name:
        return "#FFFFFF"
    for key, col in COLORS.items():
        if key in name:
            return col
    # 哈希颜色
    h = hash(name) % 360
    import colorsys
    r, g, b = colorsys.hsv_to_rgb(h / 360, 0.6, 0.9)
    return f"#{int(r*255):02x}{int(g*255):02x}{int(b*255):02x}"

def get_text_color(bg):
    """根据背景色决定文字颜色"""
    bg = bg.lstrip("#")
    r, g, b = int(bg[:2], 16), int(bg[2:4], 16), int(bg[4:6], 16)
    luminance = 0.299 * r + 0.587 * g + 0.114 * b
    return "#FFFFFF" if luminance < 140 else "#212121"

# ========================
# 数据操作
# ========================
def load_data():
    global courses, loaded_weekdays
    if os.path.exists(DATA_FILE):
        try:
            with open(DATA_FILE, "r", encoding="utf-8") as f:
                data = json.load(f)
                courses = data.get("courses", {})
                loaded_weekdays = data.get("weekdays", WEEKDAYS)
                # 填充默认值
                for d in range(loaded_weekdays):
                    for p in range(PERIODS):
                        key = f"{d}_{p}"
                        if key not in courses:
                            courses[key] = {"name": "", "teacher": "", "room": ""}
        except:
            reset_courses()
    else:
        reset_courses()

def save_data():
    global loaded_weekdays
    data = {"courses": courses, "weekdays": loaded_weekdays}
    with open(DATA_FILE, "w", encoding="utf-8") as f:
        json.dump(data, f, ensure_ascii=False, indent=2)

def reset_courses():
    global courses
    courses = {}
    for d in range(loaded_weekdays):
        for p in range(PERIODS):
            courses[f"{d}_{p}"] = {"name": "", "teacher": "", "room": ""}

# ========================
# 课程编辑
# ========================
def edit_course(day, period):
    """编辑课程"""
    key = f"{day}_{period}"
    cur = courses.get(key, {"name": "", "teacher": "", "room": ""})

    dialog = tk.Toplevel(root)
    dialog.title(f"📝 编辑课程 - {DAYS[day]} 第{period+1}节")
    dialog.geometry("340x260")
    dialog.resizable(False, False)
    dialog.transient(root)
    dialog.grab_set()

    t = THEMES[cur_theme]
    dialog.configure(bg=t["bg"])

    # 课程名
    tk.Label(dialog, text="📖 课程名称：", font=("Comic Sans MS", 11, "bold"),
             bg=t["bg"], fg=t["fg"]).pack(anchor="w", padx=20, pady=(15, 2))
    entry_name = tk.Entry(dialog, font=("Comic Sans MS", 12), width=25, justify="center")
    entry_name.insert(0, cur.get("name", ""))
    entry_name.pack(padx=20, pady=2)
    entry_name.focus_set()

    # 老师
    tk.Label(dialog, text="👩‍🏫 任课教师：", font=("Comic Sans MS", 11, "bold"),
             bg=t["bg"], fg=t["fg"]).pack(anchor="w", padx=20, pady=(10, 2))
    entry_teacher = tk.Entry(dialog, font=("Comic Sans MS", 12), width=25, justify="center")
    entry_teacher.insert(0, cur.get("teacher", ""))
    entry_teacher.pack(padx=20, pady=2)

    # 教室
    tk.Label(dialog, text="🏫 教室地点：", font=("Comic Sans MS", 11, "bold"),
             bg=t["bg"], fg=t["fg"]).pack(anchor="w", padx=20, pady=(10, 2))
    entry_room = tk.Entry(dialog, font=("Comic Sans MS", 12), width=25, justify="center")
    entry_room.insert(0, cur.get("room", ""))
    entry_room.pack(padx=20, pady=2)

    # 快速选择
    quick_frame = tk.Frame(dialog, bg=t["bg"])
    quick_frame.pack(pady=8)
    tk.Label(quick_frame, text="⚡ 快速选择：", font=("Comic Sans MS", 9),
             bg=t["bg"], fg=t["fg"]).pack(side="left")
    for cname in ["语文", "数学", "英语", "物理"]:
        btn = tk.Button(quick_frame, text=cname, font=("Comic Sans MS", 8),
                         bg=COLORS.get(cname, "#AAA"), fg="white", width=5,
                         command=lambda n=cname: entry_name.delete(0, "end") or entry_name.insert(0, n))
        btn.pack(side="left", padx=2)

    # 按钮
    btn_frame = tk.Frame(dialog, bg=t["bg"])
    btn_frame.pack(pady=10)

    def save():
        courses[key] = {
            "name": entry_name.get().strip(),
            "teacher": entry_teacher.get().strip(),
            "room": entry_room.get().strip(),
        }
        save_data()
        render_table()
        dialog.destroy()

    def delete():
        courses[key] = {"name": "", "teacher": "", "room": ""}
        save_data()
        render_table()
        dialog.destroy()

    tk.Button(btn_frame, text="✅ 保存", font=("Comic Sans MS", 11, "bold"),
              bg="#4CAF50", fg="white", width=8, command=save).pack(side="left", padx=5)
    tk.Button(btn_frame, text="🗑️ 删除", font=("Comic Sans MS", 11),
              bg="#F44336", fg="white", width=8, command=delete).pack(side="left", padx=5)
    tk.Button(btn_frame, text="❌ 取消", font=("Comic Sans MS", 11),
              bg="#9E9E9E", fg="white", width=8, command=dialog.destroy).pack(side="left", padx=5)

    dialog.bind("<Return>", lambda e: save())
    dialog.bind("<Escape>", lambda e: dialog.destroy())

# ========================
# 渲染表格
# ========================
def render_table():
    """渲染课程表"""
    global table_frame, cell_labels, header_labels

    # 清除旧表格
    for w in table_frame.winfo_children():
        w.destroy()
    cell_labels.clear()
    header_labels.clear()

    t = THEMES[cur_theme]

    # 左上角
    corner = tk.Label(table_frame, text="📅", font=("Comic Sans MS", 14, "bold"),
                      bg=t["header"], fg=t["fg"], width=6, height=2,
                      relief="solid", bd=1)
    corner.grid(row=0, column=0, sticky="nsew", padx=1, pady=1)

    # 星期表头
    for d in range(loaded_weekdays):
        lbl = tk.Label(table_frame, text=DAYS[d], font=("Comic Sans MS", 12, "bold"),
                        bg=t["header"], fg=t["fg"], width=12, height=2,
                        relief="solid", bd=1)
        lbl.grid(row=0, column=d+1, sticky="nsew", padx=1, pady=1)
        header_labels.append(lbl)

    # 节次 + 课程格子
    period_names = ["第1节", "第2节", "第3节", "第4节",
                    "第5节", "第6节", "第7节", "第8节"]
    times = ["08:00\n08:45", "08:55\n09:40", "10:00\n10:45", "10:55\n11:40",
             "14:00\n14:45", "14:55\n15:40", "15:50\n16:35", "16:45\n17:30"]

    for p in range(PERIODS):
        # 节次
        time_text = f"{period_names[p]}\n{times[p]}"
        lbl = tk.Label(table_frame, text=time_text, font=("Comic Sans MS", 9),
                        bg=t["header"], fg=t["fg"], width=6, height=3,
                        relief="solid", bd=1, justify="center")
        lbl.grid(row=p+1, column=0, sticky="nsew", padx=1, pady=1)

        for d in range(loaded_weekdays):
            key = f"{d}_{p}"
            c = courses.get(key, {"name": "", "teacher": "", "room": ""})
            name = c.get("name", "")
            teacher = c.get("teacher", "")
            room = c.get("room", "")

            bg = get_color(name) if name else t["grid"]
            fg = get_text_color(bg)

            text = name if name else "➕ 点击添加"
            detail = ""
            if teacher:
                detail += f"👩‍🏫{teacher}"
            if room:
                detail += f"  🏫{room}"

            display = text + ("\n" + detail if detail else "")

            cell = tk.Label(
                table_frame, text=display,
                font=("Comic Sans MS", 10, "bold" if name else "normal"),
                bg=bg, fg=fg,
                width=12, height=3,
                relief="solid", bd=1, justify="center",
                cursor="hand2"
            )
            cell.grid(row=p+1, column=d+1, sticky="nsew", padx=1, pady=1)
            cell.bind("<Button-1>", lambda e, d=d, p=p: edit_course(d, p))
            cell.bind("<Double-Button-1>", lambda e, d=d, p=p: edit_course(d, p))
            cell_labels[key] = cell

    # 设置行/列权重
    for i in range(PERIODS + 1):
        table_frame.rowconfigure(i, weight=1)
    table_frame.columnconfigure(0, weight=0, minsize=70)
    for i in range(1, loaded_weekdays + 1):
        table_frame.columnconfigure(i, weight=1, minsize=100)

    # 统计
    total = sum(1 for k, v in courses.items() if v.get("name"))
    status_label.config(text=f"📊 已安排 {total} 节课 | {DAYS[loaded_weekdays-1] if loaded_weekdays <= len(DAYS) else ''}")

# ========================
# 换肤
# ========================
def apply_theme(name):
    global cur_theme
    cur_theme = name
    t = THEMES[name]

    root.configure(bg=t["bg"])
    for w in all_widgets:
        try:
            w.configure(bg=t["bg"], fg=t["fg"])
        except:
            pass

    for btn in theme_btns:
        btn.configure(bg=t["btn"], fg="white")

    render_table()

# ========================
# 周数设置
# ========================
def set_weekdays(n):
    global loaded_weekdays
    loaded_weekdays = n
    save_data()
    render_table()

# ========================
# 导入/导出
# ========================
def export_data():
    """导出为文本"""
    lines = ["📅 我的课程表", "=" * 40]
    for p in range(PERIODS):
        row = [f"第{p+1}节"]
        for d in range(loaded_weekdays):
            c = courses.get(f"{d}_{p}", {})
            name = c.get("name", "")
            row.append(name if name else "—")
        lines.append(" | ".join(row))
    text = "\n".join(lines)
    try:
        with open("课程表导出.txt", "w", encoding="utf-8") as f:
            f.write(text)
        messagebox.showinfo("导出成功", "已保存为「课程表导出.txt」📄")
    except Exception as e:
        messagebox.showerror("导出失败", str(e))

def clear_all():
    if messagebox.askyesno("确认清空", "确定要清空所有课程吗？"):
        reset_courses()
        save_data()
        render_table()

# ========================
# 构建界面
# ========================
def build_ui():
    global root, table_frame, status_label, theme_btns, all_widgets

    root = tk.Tk()
    root.title("📅 卡通课程表")
    root.geometry("900x620")
    root.resizable(True, True)
    root.minsize(700, 500)

    # ====== 顶部 ======
    top = tk.Frame(root)
    top.pack(fill="x", pady=5)

    title = tk.Label(top, text="📅 卡通课程表 ✨", font=("Comic Sans MS", 20, "bold"))
    title.pack()

    # 主题栏
    theme_frame = tk.Frame(top)
    theme_frame.pack(pady=3)

    tk.Label(theme_frame, text="🎨 主题：", font=("Comic Sans MS", 9, "bold")).pack(side="left")

    for name in THEMES:
        btn = tk.Button(theme_frame, text=name, font=("Comic Sans MS", 8, "bold"),
                        relief="raised", bd=1, padx=4, pady=1,
                        command=lambda n=name: apply_theme(n))
        btn.pack(side="left", padx=2)
        theme_btns.append(btn)

    # ====== 工具栏 ======
    toolbar = tk.Frame(root)
    toolbar.pack(fill="x", padx=5, pady=2)

    tk.Label(toolbar, text="📅 显示天数：", font=("Comic Sans MS", 10)).pack(side="left")
    for n in [5, 6, 7]:
        btn = tk.Button(toolbar, text=f"{n}天", font=("Comic Sans MS", 9),
                         command=lambda x=n: set_weekdays(x))
        btn.pack(side="left", padx=2)

    tk.Button(toolbar, text="📤 导出", font=("Comic Sans MS", 10),
              command=export_data).pack(side="right", padx=5)
    tk.Button(toolbar, text="🗑️ 清空全部", font=("Comic Sans MS", 10),
              command=clear_all).pack(side="right", padx=5)

    # ====== 表格区域（Canvas + Scrollbar）======
    canvas_wrap = tk.Frame(root)
    canvas_wrap.pack(fill="both", expand=True, padx=5, pady=5)

    h_scroll = tk.Scrollbar(canvas_wrap, orient="horizontal")
    h_scroll.pack(side="bottom", fill="x")

    v_scroll = tk.Scrollbar(canvas_wrap, orient="vertical")
    v_scroll.pack(side="right", fill="y")

    canvas = tk.Canvas(canvas_wrap, highlightthickness=0,
                        xscrollcommand=h_scroll.set,
                        yscrollcommand=v_scroll.set)
    canvas.pack(side="left", fill="both", expand=True)

    h_scroll.config(command=canvas.xview)
    v_scroll.config(command=canvas.yview)

    table_frame = tk.Frame(canvas)
    canvas.create_window((0, 0), window=table_frame, anchor="nw")

    def on_configure(e):
        canvas.configure(scrollregion=canvas.bbox("all"))

    table_frame.bind("<Configure>", on_configure)

    # ====== 底部状态栏 ======
    bottom = tk.Frame(root)
    bottom.pack(fill="x", side="bottom")

    status_label = tk.Label(bottom, text="", font=("Comic Sans MS", 10))
    status_label.pack(side="left", padx=10)

    tk.Label(bottom, text="💡 单击格子编辑课程 | 双击快速编辑 | 数据自动保存",
             font=("Comic Sans MS", 9)).pack(side="right", padx=10)

    # 收集控件
    all_widgets.extend([title, status_label, toolbar, bottom, theme_frame])

# ========================
# 启动
# ========================
def init():
    build_ui()
    load_data()
    apply_theme("🌸 樱花粉")
    render_table()

if __name__ == "__main__":
    init()
    root.mainloop()
