import pygame
import json
import os
from datetime import date, datetime
import calendar

# ==================== 基础配置 ====================
SCREEN_WIDTH = 850
SCREEN_HEIGHT = 700
FPS = 60

# 颜色定义
BG_COLOR = (255, 255, 255)
TEXT_BLACK = (20, 20, 20)
GRID_GRAY = (210, 210, 210)
TODAY_COLOR = (170, 220, 255)
SELECT_COLOR = (60, 140, 220)
HAS_PLAN_COLOR = (255, 242, 190)
BTN_BLUE = (45, 110, 200)
BTN_GREEN = (35, 170, 70)
BTN_RED = (210, 50, 50)
PANEL_BG = (248, 248, 248)

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

# Pygame初始化
pygame.init()
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("日历提醒计划表")
clock = pygame.time.Clock()

# ========== 修复字体加载（重点修改部分）==========
def create_font(size):
    """安全创建中文字体，多层兜底，解决你的报错"""
    try:
        # Windows系统自带微软雅黑，用系统名读取，不用文件
        return pygame.font.SysFont("Microsoft YaHei", size)
    except:
        pass
    try:
        return pygame.font.SysFont("SimHei", size)
    except:
        pass
    try:
        return pygame.font.SysFont("PingFang SC", size)
    except:
        # 终极兜底：pygame默认字体，一定不会报错
        return pygame.font.Font(None, size)

# 统一生成字体
font_big = create_font(32)
font_mid = create_font(22)
font_normal = create_font(18)
font_small = create_font(15)

# ==================== 数据读写函数 ====================
def load_schedule():
    if os.path.exists(DATA_FILE):
        with open(DATA_FILE, "r", encoding="utf-8") as f:
            return json.load(f)
    return {}

def save_schedule(data):
    with open(DATA_FILE, "w", encoding="utf-8") as f:
        json.dump(data, f, ensure_ascii=False, indent=2)

# 全局变量
schedule_data = load_schedule()
now = datetime.now()
curr_year = now.year
curr_month = now.month
today_date = date(now.year, now.month, now.day)
select_day = today_date.day
input_content = ""

# 按钮坐标
btn_last_month = pygame.Rect(100, 30, 90, 38)
btn_next_month = pygame.Rect(660, 30, 90, 38)
btn_add_task = pygame.Rect(610, 520, 90, 38)
btn_clear_all = pygame.Rect(710, 520, 90, 38)

# 日历格子布局参数
cell_width = 105
cell_height = 82
calendar_start_x = 30
calendar_start_y = 90
week_title = ["周一", "周二", "周三", "周四", "周五", "周六", "周日"]

# ==================== 绘制工具函数 ====================
def draw_round_rect(surface, rect, color, radius=6, border=0, border_color=(0,0,0)):
    if border > 0:
        pygame.draw.rect(surface, border_color, rect, border, border_radius=radius)
    pygame.draw.rect(surface, color, rect.inflate(-border*2, -border*2), border_radius=radius)

def draw_button(rect, text, bg_color):
    draw_round_rect(screen, rect, bg_color, radius=7, border=2, border_color=TEXT_BLACK)
    text_surf = font_normal.render(text, True, (255,255,255))
    x = rect.centerx - text_surf.get_width() // 2
    y = rect.centery - text_surf.get_height() // 2
    screen.blit(text_surf, (x, y))

def draw_calendar_grid():
    # 绘制星期表头
    for index, week in enumerate(week_title):
        x = calendar_start_x + index * cell_width
        text = font_mid.render(week, True, TEXT_BLACK)
        screen.blit(text, (x + cell_width//2 - text.get_width()//2, calendar_start_y - 40))

    month_cal = calendar.monthcalendar(curr_year, curr_month)
    for row_idx, row_data in enumerate(month_cal):
        for col_idx, day in enumerate(row_data):
            cell_x = calendar_start_x + col_idx * cell_width
            cell_y = calendar_start_y + row_idx * cell_height
            cell_rect = pygame.Rect(cell_x, cell_y, cell_width - 6, cell_height - 6)

            if day == 0:
                draw_round_rect(screen, cell_rect, GRID_GRAY, 5)
                continue

            date_key = f"{curr_year}-{curr_month:02d}-{day:02d}"
            is_today = (date(curr_year, curr_month, day) == today_date)
            is_selected = (day == select_day)
            have_task = date_key in schedule_data and len(schedule_data[date_key]) > 0

            # 格子底色判断
            if is_today:
                fill_color = TODAY_COLOR
            elif is_selected:
                fill_color = SELECT_COLOR
            elif have_task:
                fill_color = HAS_PLAN_COLOR
            else:
                fill_color = BG_COLOR

            draw_round_rect(screen, cell_rect, fill_color, 5, border=1, border_color=GRID_GRAY)
            # 绘制日期数字
            day_text = font_mid.render(str(day), True, TEXT_BLACK)
            screen.blit(day_text, (cell_x + 8, cell_y + 5))
            # 有任务右上角圆点标记
            if have_task:
                pygame.draw.circle(screen, (255, 120, 0), (cell_x + cell_width - 22, cell_y + 12), 7)

def draw_task_panel():
    # 右侧任务面板
    panel_rect = pygame.Rect(550, 90, 270, 400)
    draw_round_rect(screen, panel_rect, PANEL_BG, 8, border=2, border_color=TEXT_BLACK)

    key = f"{curr_year}-{curr_month:02d}-{select_day:02d}"
    title_text = font_mid.render(f"{key} 日程列表", True, TEXT_BLACK)
    screen.blit(title_text, (panel_rect.x + 12, panel_rect.y + 8))

    task_list = schedule_data.get(key, [])
    offset_y = 40
    for task in task_list:
        task_surf = font_small.render(f"● {task}", True, TEXT_BLACK)
        screen.blit(task_surf, (panel_rect.x + 10, panel_rect.y + offset_y))
        offset_y += 30

    # 输入框
    input_box = pygame.Rect(550, 570, 270, 36)
    draw_round_rect(screen, input_box, (255,255,255), 5, border=2, border_color=TEXT_BLACK)
    input_surf = font_normal.render(input_content, True, TEXT_BLACK)
    screen.blit(input_surf, (input_box.x + 8, input_box.y + 4))

# ==================== 主循环 ====================
running = True
while running:
    screen.fill(BG_COLOR)
    mouse_pos = pygame.mouse.get_pos()

    # 事件循环
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            save_schedule(schedule_data)
            running = False

        # 鼠标左键点击
        if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
            # 切换月份
            if btn_last_month.collidepoint(mouse_pos):
                curr_month -= 1
                if curr_month < 1:
                    curr_month = 12
                    curr_year -= 1
            if btn_next_month.collidepoint(mouse_pos):
                curr_month += 1
                if curr_month > 12:
                    curr_month = 1
                    curr_year += 1

            # 点击选中日期
            cal_matrix = calendar.monthcalendar(curr_year, curr_month)
            for row_idx, row in enumerate(cal_matrix):
                for col_idx, d in enumerate(row):
                    if d == 0:
                        continue
                    cx = calendar_start_x + col_idx * cell_width
                    cy = calendar_start_y + row_idx * cell_height
                    rect = pygame.Rect(cx, cy, cell_width-6, cell_height-6)
                    if rect.collidepoint(mouse_pos):
                        select_day = d
                        input_content = ""

            # 添加任务
            if btn_add_task.collidepoint(mouse_pos):
                text = input_content.strip()
                if text:
                    k = f"{curr_year}-{curr_month:02d}-{select_day:02d}"
                    if k not in schedule_data:
                        schedule_data[k] = []
                    schedule_data[k].append(text)
                    input_content = ""
                    save_schedule(schedule_data)

            # 清空当日所有任务
            if btn_clear_all.collidepoint(mouse_pos):
                k = f"{curr_year}-{curr_month:02d}-{select_day:02d}"
                if k in schedule_data:
                    del schedule_data[k]
                    save_schedule(schedule_data)

        # 键盘输入
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_BACKSPACE:
                input_content = input_content[:-1]
            elif event.key == pygame.K_RETURN:
                text = input_content.strip()
                if text:
                    k = f"{curr_year}-{curr_month:02d}-{select_day:02d}"
                    if k not in schedule_data:
                        schedule_data[k] = []
                    schedule_data[k].append(text)
                    input_content = ""
                    save_schedule(schedule_data)
            else:
                if len(input_content) <= 45:
                    input_content += event.unicode

    # 顶部年月标题
    head_text = font_big.render(f"{curr_year} 年 {curr_month} 月", True, TEXT_BLACK)
    screen.blit(head_text, (SCREEN_WIDTH//2 - head_text.get_width()//2, 25))

    # 绘制按钮
    draw_button(btn_last_month, "上月", BTN_BLUE)
    draw_button(btn_next_month, "下月", BTN_BLUE)
    draw_button(btn_add_task, "添加任务", BTN_GREEN)
    draw_button(btn_clear_all, "清空日程", BTN_RED)

    draw_calendar_grid()
    draw_task_panel()

    pygame.display.update()
    clock.tick(FPS)

pygame.quit()