import pygame
import sys

# ---------- 初始化 ----------
pygame.init()

# ---------- 常量 ----------
WIDTH, HEIGHT = 1050, 780
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
GRAY = (200, 200, 200)
LIGHT_GRAY = (235, 235, 235)
BLUE = (70, 130, 180)
DARK_BLUE = (25, 25, 112)
RED = (220, 20, 60)
GREEN = (34, 139, 34)
PURPLE = (138, 43, 226)
ORANGE = (255, 140, 0)
YELLOW = (255, 215, 0)

# ---------- 课程颜色 ----------
COURSE_COLORS = {
    "Math": BLUE,
    "English": GREEN,
    "Physics": PURPLE,
    "Chemistry": ORANGE,
    "Biology": (50, 205, 50),
    "History": (210, 105, 30),
    "Geography": (0, 191, 255),
    "Politics": (186, 85, 211),
    "PE": YELLOW,
    "Music": (255, 182, 193),
    "Art": (221, 160, 221),
    "CS": (64, 224, 208),
    "Literature": RED,
    "Economics": (46, 139, 87),
    "Free Study": GRAY,
    "Break": LIGHT_GRAY,
    "Lunch Break": (255, 228, 181),
    "Morning Reading": (255, 250, 205),
    "": WHITE,
}

# ---------- 屏幕 & 字体（安全初始化）----------
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Weekly Class Schedule")

def make_font(size, bold=False):
    """优先尝试常用英文字体，失败则用默认字体"""
    for name in ["arial", "helvetica", "segoeui", "dejavusans", "freesans"]:
        try:
            return pygame.font.SysFont(name, size, bold=bold)
        except Exception:
            continue
    return pygame.font.Font(None, size)

font_large  = make_font(40, bold=True)
font_medium = make_font(22)
font_small  = make_font(18)
font_tiny   = make_font(14)

# ---------- 数据 ----------
days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"]
periods = [
    "Morning Reading\n(7:30-8:00)",
    "Period 1\n(8:10-8:55)",
    "Period 2\n(9:05-9:50)",
    "Break\n(9:50-10:15)",
    "Period 3\n(10:15-11:00)",
    "Period 4\n(11:10-11:55)",
    "Lunch Break\n(12:00-13:30)",
    "Period 5\n(13:30-14:15)",
    "Period 6\n(14:25-15:10)",
    "Period 7\n(15:20-16:05)",
    "Period 8\n(16:15-17:00)",
]

schedule = [
    ["Morning Reading","Math","English","Break","Physics","Chemistry","Lunch Break","Biology","History","PE","Free Study"],
    ["Morning Reading","English","Physics","Break","Math","Biology","Lunch Break","Chemistry","Geography","Music","Free Study"],
    ["Morning Reading","Physics","Chemistry","Break","English","Math","Lunch Break","History","Art","CS","Free Study"],
    ["Morning Reading","Chemistry","Math","Break","English","Physics","Lunch Break","Geography","PE","Literature","Free Study"],
    ["Morning Reading","Math","English","Break","Chemistry","Biology","Lunch Break","Economics","Music","Art","Free Study"],
]

selected_cell = None
current_week = 1

# ---------- 工具函数 ----------
def draw_text_centered(text, font, color, rect):
    surf = font.render(text, True, color)
    r = surf.get_rect(center=rect.center)
    screen.blit(surf, r)

def get_cell_at_pos(pos):
    x, y = pos
    cw, ch = 158, 54
    sx, sy = 50, 95
    if sx <= x < sx + cw * 6 and sy <= y < sy + ch * 12:
        col = (x - sx) // cw - 1
        row = (y - sy) // ch - 1
        if 0 <= col < 5 and 0 <= row < 11:
            return col, row
    return None

def save_schedule():
    try:
        with open("schedule_en.txt", "w", encoding="utf-8") as f:
            f.write(f"{current_week}\n")
            for row in schedule:
                f.write(",".join(row) + "\n")
        print("[OK] Schedule saved.")
    except Exception as e:
        print(f"[ERR] Save failed: {e}")

def load_schedule():
    global schedule, current_week
    try:
        with open("schedule_en.txt", "r", encoding="utf-8") as f:
            lines = f.readlines()
            current_week = int(lines[0].strip())
            new_sch = [l.strip().split(",") for l in lines[1:] if l.strip()]
            if len(new_sch) == 5 and all(len(r) == 11 for r in new_sch):
                schedule = new_sch
                print("[OK] Schedule loaded.")
            else:
                print("[ERR] Invalid data in file.")
    except FileNotFoundError:
        print("[ERR] No save file found.")
    except Exception as e:
        print(f"[ERR] Load failed: {e}")

# ---------- 绘图 ----------
def draw_schedule():
    screen.fill(WHITE)

    # 标题
    title = font_large.render(f"Fall Semester 2024 — Week {current_week}", True, DARK_BLUE)
    screen.blit(title, (WIDTH // 2 - title.get_width() // 2, 20))

    cw, ch = 158, 54
    sx, sy = 50, 95

    # 左上角
    pygame.draw.rect(screen, LIGHT_GRAY, (sx, sy, cw, ch))
    pygame.draw.rect(screen, BLACK, (sx, sy, cw, ch), 2)
    draw_text_centered("Time / Day", font_medium, BLACK, pygame.Rect(sx, sy, cw, ch))

    # 星期表头
    for i, day in enumerate(days):
        x = sx + cw * (i + 1)
        pygame.draw.rect(screen, LIGHT_GRAY, (x, sy, cw, ch))
        pygame.draw.rect(screen, BLACK, (x, sy, cw, ch), 2)
        draw_text_centered(day, font_medium, BLACK, pygame.Rect(x, sy, cw, ch))

    # 行内容
    for i, period in enumerate(periods):
        y = sy + ch * (i + 1)
        # 时间列
        pygame.draw.rect(screen, LIGHT_GRAY, (sx, y, cw, ch))
        pygame.draw.rect(screen, BLACK, (sx, y, cw, ch), 2)
        for j, line in enumerate(period.split("\n")):
            t = font_tiny.render(line, True, BLACK)
            screen.blit(t, (sx + cw // 2 - t.get_width() // 2, y + 8 + j * 18))

        # 课程格
        for j in range(5):
            x = sx + cw * (j + 1)
            course = schedule[j][i]
            bg = COURSE_COLORS.get(course, WHITE)

            if selected_cell == (j, i):
                pygame.draw.rect(screen, bg, (x + 2, y + 2, cw - 4, ch - 4))
                pygame.draw.rect(screen, RED, (x, y, cw, ch), 4)
            else:
                pygame.draw.rect(screen, bg, (x, y, cw, ch))
                pygame.draw.rect(screen, BLACK, (x, y, cw, ch), 1)

            if course:
                words = course.split()
                w = font_medium.size(course)[0]
                if len(words) > 1 and w > cw - 12:
                    m = len(words) // 2
                    l1, l2 = " ".join(words[:m]), " ".join(words[m:])
                    for k, line in enumerate([l1, l2]):
                        t = font_small.render(line, True, BLACK)
                        screen.blit(t, (x + cw // 2 - t.get_width() // 2, y + 12 + k * 20))
                else:
                    t = font_medium.render(course, True, BLACK)
                    screen.blit(t, (x + cw // 2 - t.get_width() // 2,
                                    y + ch // 2 - t.get_height() // 2))

    # 图例
    lx, ly = WIDTH - 250, 110
    screen.blit(font_medium.render("Legend:", True, BLACK), (lx, ly))
    for i, (name, color) in enumerate(list(COURSE_COLORS.items())[:12]):
        yp = ly + 35 + i * 26
        pygame.draw.rect(screen, color, (lx, yp, 18, 18))
        pygame.draw.rect(screen, BLACK, (lx, yp, 18, 18), 1)
        screen.blit(font_tiny.render(name, True, BLACK), (lx + 25, yp))

    # 操作说明
    inst = ["CONTROLS:", "Click: Select", "1-9: Assign", "Space: Clear",
            "N/B: Week +/-", "S: Save", "L: Load", "Esc: Deselect"]
    iy = HEIGHT - 230
    for i, t in enumerate(inst):
        c = RED if i == 0 else DARK_BLUE
        f = font_medium if i == 0 else font_tiny
        screen.blit(f.render(t, True, c), (20, iy + i * 26))

    # 状态栏
    if selected_cell:
        c, r = selected_cell
        txt = f"Selected: {days[c]} — {periods[r].split()[0]}"
        t = font_medium.render(txt, True, RED)
    else:
        t = font_medium.render("Ready. Click a cell to edit.", True, GREEN)
    screen.blit(t, (WIDTH // 2 - t.get_width() // 2, HEIGHT - 45))

# ---------- 主循环 ----------
def main():
    global selected_cell, current_week
    clock = pygame.time.Clock()
    running = True

    key_map = {
        pygame.K_1: "Math", pygame.K_2: "English", pygame.K_3: "Physics",
        pygame.K_4: "Chemistry", pygame.K_5: "Biology", pygame.K_6: "History",
        pygame.K_7: "Geography", pygame.K_8: "PE", pygame.K_9: "CS",
    }

    while running:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False

            elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
                selected_cell = get_cell_at_pos(event.pos)

            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    selected_cell = None
                elif event.key == pygame.K_s:
                    save_schedule()
                elif event.key == pygame.K_l:
                    load_schedule()
                elif event.key == pygame.K_n:
                    current_week += 1
                elif event.key == pygame.K_b:
                    current_week = max(1, current_week - 1)
                elif selected_cell:
                    col, row = selected_cell
                    if event.key == pygame.K_SPACE:
                        schedule[col][row] = ""
                    elif event.key in key_map:
                        schedule[col][row] = key_map[event.key]

        draw_schedule()
        pygame.display.flip()
        clock.tick(60)

    pygame.quit()

if __name__ == "__main__":
    main()