import pygame
import datetime
import json
import os

# 初始化Pygame
pygame.init()
WIDTH, HEIGHT = 750, 550
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("生日提醒工具")
clock = pygame.time.Clock()

# 颜色定义
COLOR_WHITE = (255, 255, 255)
COLOR_BLACK = (0, 0, 0)
COLOR_RED = (220, 20, 20)
COLOR_BLUE = (20, 70, 200)
COLOR_GRAY = (150, 150, 150)
COLOR_HIGHLIGHT = (255, 255, 190)
COLOR_LINE = (80, 80, 80)

# 兼容中文字体
try:
    font_title = pygame.font.Font("simhei.ttf", 32)
    font_content = pygame.font.Font("simhei.ttf", 22)
    font_tips = pygame.font.Font("simhei.ttf", 17)
except:
    font_title = pygame.font.SysFont("Microsoft YaHei", 32)
    font_content = pygame.font.SysFont("Microsoft YaHei", 22)
    font_tips = pygame.font.SysFont("Microsoft YaHei", 17)

# 生日文件路径，数据存在json，重启不丢失
birthday_file = "birthday_data.json"

# 加载生日列表，文件不存在则新建默认数据
def load_birthdays():
    if os.path.exists(birthday_file):
        with open(birthday_file, "r", encoding="utf-8") as f:
            return json.load(f)
    # 默认生日数据
    default_data = [
        {"name": "乐乐", "month": 8, "day": 1},
        {"name": "爸爸", "month": 11, "day": 6},
        {"name": "妈妈", "month": 3, "day": 18},
        {"name": "朋友A", "month": 8, "day": 8},
        {"name": "朋友B", "month": 12, "day": 25}
    ]
    save_birthdays(default_data)
    return default_data

# 保存生日到json文件
def save_birthdays(data):
    with open(birthday_file, "w", encoding="utf-8") as f:
        json.dump(data, f, ensure_ascii=False, indent=2)

# 计算距离下一次生日天数，兼容闰年2月29
def count_birthday_days(mon, day):
    today = datetime.date.today()
    current_year = today.year
    try:
        target = datetime.date(current_year, mon, day)
    except ValueError:
        # 2月29非闰年自动转为3月1日
        target = datetime.date(current_year, 3, 1)

    if target >= today:
        return (target - today).days
    else:
        # 今年生日已过，计算明年
        try:
            next_target = datetime.date(current_year + 1, mon, day)
        except ValueError:
            next_target = datetime.date(current_year + 1, 3, 1)
        return (next_target - today).days

# 加载生日并按倒计时天数升序排序
birthday_list = load_birthdays()
birthday_list.sort(key=lambda x: count_birthday_days(x["month"], x["day"]))

scroll_offset = 0  # 上下滚动偏移量
line_height = 42  # 每行高度
running = True

while running:
    screen.fill(COLOR_WHITE)
    # 绘制标题
    title_text = font_title.render("生日倒计时提醒器", True, COLOR_RED)
    screen.blit(title_text, (25, 15))

    # 表头
    headers = ["姓名", "生日(月/日)", "剩余天数", "状态"]
    x_coords = [30, 190, 360, 520]
    for index, word in enumerate(headers):
        render = font_content.render(word, True, COLOR_BLACK)
        screen.blit(render, (x_coords[index], 70))

    # 分割线
    pygame.draw.line(screen, COLOR_LINE, (20, 105), (WIDTH - 20, 105), 2)

    # 循环绘制所有生日条目
    draw_y = 115 + scroll_offset
    for people in birthday_list:
        days_left = count_birthday_days(people["month"], people["day"])
        birth_show = f"{people['month']:02d}/{people['day']:02d}"

        # 状态与配色逻辑
        if days_left == 0:
            # 今日生日，黄底红字
            pygame.draw.rect(screen, COLOR_HIGHLIGHT, (20, draw_y, WIDTH - 40, line_height))
            status_word = "🎉 今日生日"
            word_color = COLOR_RED
        elif days_left <= 7:
            status_word = "一周内临近"
            word_color = COLOR_RED
        else:
            status_word = "正常"
            word_color = COLOR_BLACK

        # 绘制四列文字
        name_render = font_content.render(people["name"], True, word_color)
        birth_render = font_content.render(birth_show, True, word_color)
        day_render = font_content.render(f"{days_left}天", True, word_color)
        status_render = font_content.render(status_word, True, word_color)

        screen.blit(name_render, (x_coords[0], draw_y + 7))
        screen.blit(birth_render, (x_coords[1], draw_y + 7))
        screen.blit(day_render, (x_coords[2], draw_y + 7))
        screen.blit(status_render, (x_coords[3], draw_y + 7))

        draw_y += line_height

    # 底部操作提示
    hint = font_tips.render("↑↓方向键上下滚动 | 关闭窗口自动保存生日数据", True, COLOR_GRAY)
    screen.blit(hint, (20, HEIGHT - 28))

    # 事件循环
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            # 退出前保存最新生日列表
            save_birthdays(birthday_list)
            running = False
        # 键盘上下滚动
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_UP:
                scroll_offset += 35
            if event.key == pygame.K_DOWN:
                scroll_offset -= 35

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

pygame.quit()