import pygame
import sys

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

WIDTH, HEIGHT = 700, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("✨ 星座 & 生肖查询器")
clock = pygame.time.Clock()

# ---------- 颜色 ----------
BG           = (20, 20, 30)
CARD_BG      = (35, 35, 50)
ACCENT       = (0, 200, 255)
GOLD         = (255, 215, 0)
TEXT_WHITE    = (240, 240, 240)
TEXT_GRAY     = (130, 130, 150)
BTN_BG       = (50, 50, 70)
BTN_HOVER    = (70, 70, 95)
BORDER       = (60, 60, 80)
RESULT_BG    = (40, 40, 60)

# ---------- 字体 ----------
def get_font(size):
    for name in ["simhei", "microsoftyahei", "pingfang", "notosanscjk", "wenquanyimicrohei"]:
        try:
            f = pygame.font.SysFont(name, size)
            f.render("测试", True, TEXT_WHITE)
            return f
        except Exception:
            continue
    return pygame.font.Font(None, size)

font_title  = get_font(36)
font_big    = get_font(32)
font_mid    = get_font(24)
font_small  = get_font(18)
font_tiny   = get_font(14)

# ---------- 星座数据 ----------
ZODIAC_NAMES = [
    "摩羯座", "水瓶座", "双鱼座", "白羊座", "金牛座", "双子座",
    "巨蟹座", "狮子座", "处女座", "天秤座", "天蝎座", "射手座", "摩羯座"
]
ZODIAC_RANGES = [
    (1, 20), (2, 19), (3, 21), (4, 20), (5, 21), (6, 22),
    (7, 23), (8, 23), (9, 23), (10, 24), (11, 23), (12, 22)
]
ZODIAC_EMOJI = [
    "🐐", "🏺", "🐟", "🐏", "🐂", "👯",
    "🦀", "🦁", "👧", "⚖️", "🦂", "🏹", "🐐"
]
ZODIAC_TRAITS = [
    "踏实、耐心、有责任感", "独立、友善、有创意",
    "浪漫、敏感、有同情心", "勇敢、热情、有领导力",
    "可靠、务实、有耐心", "机智、好奇、善交际",
    "温柔、顾家、有直觉", "自信、大方、有魅力",
    "细心、完美主义、谦虚", "优雅、公正、善合作",
    "神秘、果断、有洞察力", "乐观、自由、有哲学心",
    "踏实、耐心、有责任感"
]

# ---------- 生肖数据 ----------
SHENGXIAO_NAMES = ["鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊", "猴", "鸡", "狗", "猪"]
SHENGXIAO_EMOJI = ["🐭", "🐮", "🐯", "🐰", "🐲", "🐍", "🐴", "🐑", "🐵", "🐔", "🐶", "🐷"]
SHENGXIAO_YEARS = {
    "鼠": [2020, 2008, 1996, 1984, 1972],
    "牛": [2021, 2009, 1997, 1985, 1973],
    "虎": [2022, 2010, 1998, 1986, 1974],
    "兔": [2023, 2011, 1999, 1987, 1975],
    "龙": [2024, 2012, 2000, 1988, 1976],
    "蛇": [2025, 2013, 2001, 1989, 1977],
    "马": [2026, 2014, 2002, 1990, 1978],
    "羊": [2027, 2015, 2003, 1991, 1979],
    "猴": [2028, 2016, 2004, 1992, 1980],
    "鸡": [2029, 2017, 2005, 1993, 1981],
    "狗": [2030, 2018, 2006, 1994, 1982],
    "猪": [2031, 2019, 2007, 1995, 1983],
}

# ---------- 核心查询函数 ----------
def get_zodiac(month, day):
    """根据月日返回星座索引 (0-11)"""
    for i in range(12):
        m, d = ZODIAC_RANGES[i]
        next_m, next_d = ZODIAC_RANGES[i + 1]
        if (month == m and day >= d) or (month == next_m and day < next_d):
            return i
    return 0  # 默认摩羯座

def get_shengxiao(year):
    """根据年份返回生肖索引 (0-11)"""
    # 2026年是马年(索引6)，往前推
    base_year = 2026
    base_idx = 6
    diff = year - base_year
    idx = (base_idx + diff) % 12
    return idx

# ---------- 状态 ----------
selected_month = 7   # 默认7月
selected_day = 16    # 默认16日
selected_year = 2000 # 默认2000年（查生肖用）
show_result = False
result_zodiac_idx = 0
result_shengxiao_idx = 0

# 月份天数
MONTH_DAYS = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]

# 滚动选择器状态
scroll_month_offset = 0
scroll_day_offset = 0
scroll_year_offset = 0

# ---------- 布局常量 ----------
SCROLL_W = 120
SCROLL_H = 200
SCROLL_ITEM_H = 40
SCROLL_Y = 160

MONTH_SCROLL_X = 80
DAY_SCROLL_X = 290
YEAR_SCROLL_X = 500

QUERY_BTN = pygame.Rect(220, 420, 260, 50)

# ---------- 绘制滚动选择器 ----------
def draw_scroller(x, items, current_idx, label):
    """绘制一个垂直滚动选择器，返回新的偏移量"""
    # 标签
    lbl = font_small.render(label, True, TEXT_GRAY)
    screen.blit(lbl, (x + SCROLL_W // 2 - lbl.get_width() // 2, SCROLL_Y - 25))

    # 背景
    rect = pygame.Rect(x, SCROLL_Y, SCROLL_W, SCROLL_H)
    pygame.draw.rect(screen, CARD_BG, rect, border_radius=10)
    pygame.draw.rect(screen, BORDER, rect, 1, border_radius=10)

    # 高亮当前项
    highlight_y = SCROLL_Y + SCROLL_H // 2 - SCROLL_ITEM_H // 2
    pygame.draw.rect(screen, ACCENT, pygame.Rect(x + 4, highlight_y, SCROLL_W - 8, SCROLL_ITEM_H), border_radius=6)

    # 绘制可见项
    visible_count = SCROLL_H // SCROLL_ITEM_H
    start_idx = max(0, current_idx - visible_count // 2)
    end_idx = min(len(items), start_idx + visible_count + 1)

    for i in range(start_idx, end_idx):
        item_y = SCROLL_Y + (i - current_idx) * SCROLL_ITEM_H + SCROLL_H // 2 - SCROLL_ITEM_H // 2
        if item_y < SCROLL_Y - SCROLL_ITEM_H or item_y > SCROLL_Y + SCROLL_H:
            continue

        txt = font_mid.render(str(items[i]), True, TEXT_WHITE if i == current_idx else TEXT_GRAY)
        screen.blit(txt, (x + SCROLL_W // 2 - txt.get_width() // 2, item_y + 8))

    # 上下渐变遮罩
    for dy in range(30):
        alpha = int(255 * (1 - dy / 30))
        overlay = pygame.Surface((SCROLL_W, 1), pygame.SRCALPHA)
        overlay.fill((20, 20, 30, alpha))
        screen.blit(overlay, (x, SCROLL_Y + dy))
        screen.blit(overlay, (x, SCROLL_Y + SCROLL_H - 1 - dy))

    return rect

# ---------- 绘制结果卡片 ----------
def draw_result_card():
    overlay = pygame.Surface((WIDTH, HEIGHT), pygame.SRCALPHA)
    overlay.fill((0, 0, 0, 160))
    screen.blit(overlay, (0, 0))

    card = pygame.Rect(100, 100, 500, 400)
    pygame.draw.rect(screen, RESULT_BG, card, border_radius=16)
    pygame.draw.rect(screen, ACCENT, card, 2, border_radius=16)

    # 星座
    z_name = ZODIAC_NAMES[result_zodiac_idx]
    z_emoji = ZODIAC_EMOJI[result_zodiac_idx]
    z_trait = ZODIAC_TRAITS[result_zodiac_idx]

    z_title = font_big.render(f"{z_emoji} {z_name}", True, GOLD)
    screen.blit(z_title, (card.centerx - z_title.get_width() // 2, 130))

    z_date = font_small.render(f"{selected_month}月{selected_day}日", True, TEXT_GRAY)
    screen.blit(z_date, (card.centerx - z_date.get_width() // 2, 175))

    z_trait_lbl = font_small.render("性格关键词:", True, TEXT_GRAY)
    screen.blit(z_trait_lbl, (card.x + 40, 210))
    z_trait_txt = font_mid.render(z_trait, True, TEXT_WHITE)
    screen.blit(z_trait_txt, (card.x + 40, 235))

    # 分隔线
    pygame.draw.line(screen, BORDER, (card.x + 40, 275), (card.right - 40, 275), 1)

    # 生肖
    s_idx = result_shengxiao_idx
    s_name = SHENGXIAO_NAMES[s_idx]
    s_emoji = SHENGXIAO_EMOJI[s_idx]

    s_title = font_big.render(f"{s_emoji} 生肖: {s_name}", True, GOLD)
    screen.blit(s_title, (card.centerx - s_title.get_width() // 2, 295))

    s_year = font_small.render(f"{selected_year}年出生", True, TEXT_GRAY)
    screen.blit(s_year, (card.centerx - s_year.get_width() // 2, 340))

    # 同生肖年份
    same_years = SHENGXIAO_YEARS.get(s_name, [])
    years_str = "、".join(str(y) for y in same_years[:5])
    s_same = font_tiny.render(f"同生肖年份: {years_str}", True, TEXT_GRAY)
    screen.blit(s_same, (card.centerx - s_same.get_width() // 2, 375))

    # 关闭提示
    close = font_small.render("点击任意处关闭 | Esc 退出", True, (100, 100, 120))
    screen.blit(close, (card.centerx - close.get_width() // 2, 440))

# ---------- 主循环 ----------
running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                if show_result:
                    show_result = False
                else:
                    running = False
            elif event.key == pygame.K_UP:
                if not show_result:
                    if selected_month > 1:
                        selected_month -= 1
                        selected_day = min(selected_day, MONTH_DAYS[selected_month - 1])
            elif event.key == pygame.K_DOWN:
                if not show_result:
                    if selected_month < 12:
                        selected_month += 1
                        selected_day = min(selected_day, MONTH_DAYS[selected_month - 1])
            elif event.key == pygame.K_LEFT:
                if not show_result:
                    if selected_day > 1:
                        selected_day -= 1
            elif event.key == pygame.K_RIGHT:
                if not show_result:
                    max_d = MONTH_DAYS[selected_month - 1]
                    if selected_day < max_d:
                        selected_day += 1
            elif event.key == pygame.K_RETURN:
                if not show_result:
                    result_zodiac_idx = get_zodiac(selected_month, selected_day)
                    result_shengxiao_idx = get_shengxiao(selected_year)
                    show_result = True

        elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
            mx, my = event.pos

            if show_result:
                show_result = False
                continue

            # 月份滚动区域点击
            month_rect = pygame.Rect(MONTH_SCROLL_X, SCROLL_Y, SCROLL_W, SCROLL_H)
            if month_rect.collidepoint(mx, my):
                rel_y = my - SCROLL_Y
                click_idx = rel_y // SCROLL_ITEM_H
                visible_count = SCROLL_H // SCROLL_ITEM_H
                start_idx = max(0, selected_month - 1 - visible_count // 2)
                new_month = start_idx + click_idx + 1
                if 1 <= new_month <= 12:
                    selected_month = new_month
                    selected_day = min(selected_day, MONTH_DAYS[selected_month - 1])

            # 日期滚动区域点击
            day_rect = pygame.Rect(DAY_SCROLL_X, SCROLL_Y, SCROLL_W, SCROLL_H)
            if day_rect.collidepoint(mx, my):
                max_d = MONTH_DAYS[selected_month - 1]
                rel_y = my - SCROLL_Y
                click_idx = rel_y // SCROLL_ITEM_H
                visible_count = SCROLL_H // SCROLL_ITEM_H
                start_idx = max(0, selected_day - 1 - visible_count // 2)
                new_day = start_idx + click_idx + 1
                if 1 <= new_day <= max_d:
                    selected_day = new_day

            # 年份滚动区域点击
            year_rect = pygame.Rect(YEAR_SCROLL_X, SCROLL_Y, SCROLL_W, SCROLL_H)
            if year_rect.collidepoint(mx, my):
                rel_y = my - SCROLL_Y
                click_idx = rel_y // SCROLL_ITEM_H
                visible_count = SCROLL_H // SCROLL_ITEM_H
                base_year = 2000
                start_idx = max(0, selected_year - base_year - visible_count // 2)
                new_year = base_year + start_idx + click_idx
                if 1900 <= new_year <= 2100:
                    selected_year = new_year

            # 查询按钮
            if QUERY_BTN.collidepoint(mx, my):
                result_zodiac_idx = get_zodiac(selected_month, selected_day)
                result_shengxiao_idx = get_shengxiao(selected_year)
                show_result = True

        # 鼠标滚轮
        elif event.type == pygame.MOUSEWHEEL and not show_result:
            mx, my = pygame.mouse.get_pos()
            month_rect = pygame.Rect(MONTH_SCROLL_X, SCROLL_Y, SCROLL_W, SCROLL_H)
            day_rect = pygame.Rect(DAY_SCROLL_X, SCROLL_Y, SCROLL_W, SCROLL_H)
            year_rect = pygame.Rect(YEAR_SCROLL_X, SCROLL_Y, SCROLL_W, SCROLL_H)

            if month_rect.collidepoint(mx, my):
                new_m = selected_month - event.y
                selected_month = max(1, min(12, new_m))
                selected_day = min(selected_day, MONTH_DAYS[selected_month - 1])
            elif day_rect.collidepoint(mx, my):
                max_d = MONTH_DAYS[selected_month - 1]
                new_d = selected_day - event.y
                selected_day = max(1, min(max_d, new_d))
            elif year_rect.collidepoint(mx, my):
                new_y = selected_year - event.y * 5
                selected_year = max(1900, min(2100, new_y))

    # ---------- 绘制 ----------
    screen.fill(BG)

    # 标题
    title = font_title.render("✨ 星座 & 生肖查询", True, TEXT_WHITE)
    screen.blit(title, (WIDTH // 2 - title.get_width() // 2, 20))

    # 副标题
    sub = font_small.render("选择日期和出生年份，查看你的星座与生肖", True, TEXT_GRAY)
    screen.blit(sub, (WIDTH // 2 - sub.get_width() // 2, 65))

    # 滚动选择器
    months = list(range(1, 13))
    days = list(range(1, MONTH_DAYS[selected_month - 1] + 1))
    years = list(range(1900, 2101))

    draw_scroller(MONTH_SCROLL_X, months, selected_month - 1, "月份")
    draw_scroller(DAY_SCROLL_X, days, selected_day - 1, "日期")
    draw_scroller(YEAR_SCROLL_X, years, selected_year - 1900, "出生年份")

    # 当前选择预览
    preview = font_mid.render(f"已选: {selected_month}月{selected_day}日  {selected_year}年", True, ACCENT)
    screen.blit(preview, (WIDTH // 2 - preview.get_width() // 2, 380))

    # 查询按钮
    mouse = pygame.mouse.get_pos()
    hovered = QUERY_BTN.collidepoint(mouse)
    btn_bg = BTN_HOVER if hovered else BTN_BG
    pygame.draw.rect(screen, btn_bg, QUERY_BTN, border_radius=12)
    pygame.draw.rect(screen, ACCENT, QUERY_BTN, 2, border_radius=12)
    btn_txt = font_mid.render("🔮 开始查询", True, TEXT_WHITE)
    screen.blit(btn_txt, (QUERY_BTN.centerx - btn_txt.get_width() // 2, QUERY_BTN.centery - btn_txt.get_height() // 2))

    # 底部提示
    tip = font_tiny.render("滚轮/点击选择 | 方向键调整 | Enter查询 | Esc退出", True, (80, 80, 100))
    screen.blit(tip, (WIDTH // 2 - tip.get_width() // 2, HEIGHT - 25))

    # 结果卡片
    if show_result:
        draw_result_card()

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

pygame.quit()
sys.exit()