import tkinter as tk
import random
from datetime import datetime

# ========================
# 全局配置
# ========================
WIDTH, HEIGHT = 780, 560

# ========================
# 主题
# ========================
THEMES = {
    "🌸 樱花粉": {"bg": "#FFF0F5", "fg": "#C2185B", "panel": "#FCE4EC", "btn": "#F48FB1", "accent": "#E91E63", "card": "#FFF9FC", "star": "#FF69B4"},
    "💙 星空蓝": {"bg": "#0D1B2A", "fg": "#E0E1DD", "panel": "#1B263B", "btn": "#415A77", "accent": "#778DA9", "card": "#1B263B", "star": "#FFD700"},
    "💜 梦幻紫": {"bg": "#F3E5F5", "fg": "#4A148C", "panel": "#E1BEE7", "btn": "#AB47BC", "accent": "#7B1FA2", "card": "#FBF0FF", "star": "#CE93D8"},
    "🧡 蜜桔橙": {"bg": "#FFF3E0", "fg": "#E65100", "panel": "#FFE0B2", "btn": "#FF9800", "accent": "#EF6C00", "card": "#FFF8F0", "star": "#FF8F00"},
    "💚 抹茶绿": {"bg": "#E8F5E9", "fg": "#1B5E20", "panel": "#C8E6C9", "btn": "#66BB6A", "accent": "#2E7D32", "card": "#F5FFF5", "star": "#43A047"},
    "🖤 暗夜占星": {"bg": "#0a0a1a", "fg": "#B388FF", "panel": "#1a1a3e", "btn": "#4A148C", "accent": "#7C4DFF", "card": "#151530", "star": "#FFD700"},
}
cur_theme = "🌸 樱花粉"

# ========================
# 星座数据
# ========================
ZODIAC = [
    {"name": "白羊座", "icon": "♈", "date": "3.21-4.19", "element": "火", "ruler": "火星", "lucky": ["红", "橙"], "gem": "钻石"},
    {"name": "金牛座", "icon": "♉", "date": "4.20-5.20", "element": "土", "ruler": "金星", "lucky": ["绿", "粉"], "gem": "祖母绿"},
    {"name": "双子座", "icon": "♊", "date": "5.21-6.20", "element": "风", "ruler": "水星", "lucky": ["黄", "蓝"], "gem": "珍珠"},
    {"name": "巨蟹座", "icon": "♋", "date": "6.21-7.22", "element": "水", "ruler": "月亮", "lucky": ["白", "银"], "gem": "月光石"},
    {"name": "狮子座", "icon": "♌", "date": "7.23-8.22", "element": "火", "ruler": "太阳", "lucky": ["金", "橙"], "gem": "红宝石"},
    {"name": "处女座", "icon": "♍", "date": "8.23-9.22", "element": "土", "ruler": "水星", "lucky": ["灰", "米"], "gem": "蓝宝石"},
    {"name": "天秤座", "icon": "♎", "date": "9.23-10.22", "element": "风", "ruler": "金星", "lucky": ["粉", "蓝"], "gem": "蛋白石"},
    {"name": "天蝎座", "icon": "♏", "date": "10.23-11.21", "element": "水", "ruler": "冥王星", "lucky": ["深红", "黑"], "gem": "碧玺"},
    {"name": "射手座", "icon": "♐", "date": "11.22-12.21", "element": "火", "ruler": "木星", "lucky": ["紫", "蓝"], "gem": "黄玉"},
    {"name": "摩羯座", "icon": "♑", "date": "12.22-1.19", "element": "土", "ruler": "土星", "lucky": ["棕", "黑"], "gem": "石榴石"},
    {"name": "水瓶座", "icon": "♒", "date": "1.20-2.18", "element": "风", "ruler": "天王星", "lucky": ["蓝", "银"], "gem": "紫水晶"},
    {"name": "双鱼座", "icon": "♓", "date": "2.19-3.20", "element": "水", "ruler": "海王星", "lucky": ["海蓝", "紫"], "gem": "海蓝宝"},
]

# ========================
# 运势内容库
# ========================
LUCKY_COLORS = ["红色", "橙色", "黄色", "绿色", "蓝色", "紫色", "粉色", "金色", "银色", "白色", "黑色", "棕色", "海蓝色", "玫红色", "薄荷绿"]
LUCKY_NUMS = list(range(1, 50))
LUCKY_ITEMS = ["四叶草", "水晶球", "许愿瓶", "幸运币", "羽毛", "贝壳", "彩虹", "星星", "月亮", "太阳", "风铃", "木马"]

LOVE_TEXTS = [
    "今天桃花运爆棚，说不定转角遇到爱~",
    "单身汪注意：暗恋的人今天会多看你好几眼",
    "有伴的今天适合约会，哪怕只是散步也好",
    "今天不适合表白，先默默观察几天吧",
    "你和TA之间缺少的只是一个开口的机会",
    "今日宜撒娇，宜吃甜，宜牵手",
    "感情升温中，小小的惊喜能带来大大的感动",
    "今天适合独处，享受一个人的浪漫",
    "旧人旧事可能浮现，放下才能迎接新的美好",
    "你的魅力指数今天拉满，自信就对了",
]

CAREER_TEXTS = [
    "今天灵感爆棚，适合攻克难题",
    "小心细节出错，三思而后行",
    "贵人运很强，有人暗中帮你",
    "今天适合学习新技能，效率翻倍",
    "别拖延了，今天动手是最好的时机",
    "团队合作顺畅，你是最佳助攻手",
    "创意工作者今天会产出惊喜之作",
    "可能会收到意外好消息，保持期待",
    "今天宜主动出击，等不来机会就自己造",
    "工作再忙也别忘了喝水休息哦",
]

WEALTH_TEXTS = [
    "今天偏财运不错，说不定有小惊喜",
    "花钱别冲动，购物车先放一放",
    "适合做理财规划，长远来看稳赚",
    "今天不宜大额支出，守好钱包",
    "有意外收入的可能，留意通知",
    "投资需谨慎，今天宜观望不宜出手",
    "今天适合谈薪资/加薪",
    "开源节流两手抓，月底不心慌",
    "捡到钱的概率：0.01%（但心态要好）",
    "今天宜存钱，宜记账，宜省钱",
]

HEALTH_TEXTS = [
    "今天精神饱满，适合运动出汗",
    "注意颈椎，久坐记得起来活动",
    "睡眠质量不错，继续保持好习惯",
    "今天容易上火，多喝水少吃辣",
    "心情愉悦是最好的保健品",
    "适合户外活动，晒晒太阳补补钙",
    "小心感冒，昼夜温差大注意保暖",
    "今天宜早睡，别再熬夜刷手机了",
    "肠胃敏感，少吃生冷食物",
    "深呼吸，放松肩膀，你已经很棒了",
]

ADVICE_TEXTS = [
    "今天宜：微笑 / 忌：抱怨",
    "今天宜：主动 / 忌：犹豫",
    "今天宜：独处 / 忌：八卦",
    "今天宜：尝试 / 忌：固执",
    "今天宜：分享 / 忌：独吞",
    "今天宜：倾听 / 忌：打断",
    "今天宜：放松 / 忌：焦虑",
    "今天宜：表达 / 忌：沉默",
    "今天宜：感恩 / 忌：攀比",
    "今天宜：勇敢 / 忌：退缩",
]

RATING_REASONS = [
    "星象显示今日能量集中在你的星座",
    "月亮与你的守护星形成有利相位",
    "水星逆行阴影期，宜稳不宜动",
    "木星赐福，好运自然来",
    "金星高照，魅力值拉满的一天",
    "土星提醒你脚踏实地更靠谱",
    "火星给你加满了行动力燃料",
    "天王星带来意想不到的惊喜",
    "海王星让你今天格外有艺术感",
    "冥王星暗示着一次蜕变的机会",
]

# ========================
# UI 引用
# ========================
root = None
canvas = None
lbl_title = None
lbl_result = None
lbl_detail = None
lbl_advice = None
lbl_stars = None
zodiac_btns = []
theme_btns = []
all_widgets = []
current_sign = None

# ========================
# 工具函数
# ========================
def get_text_color(hex_str):
    h = hex_str.lstrip("#")
    try:
        r, g, b = [int(h[i:i+2], 16) for i in (0, 2, 4)]
    except:
        return "#FFFFFF"
    bright = 0.299*r + 0.587*g + 0.114*b
    return "#FFFFFF" if bright < 140 else "#212121"

def get_star_sign(month, day):
    """根据月日判断星座"""
    if (month == 3 and day >= 21) or (month == 4 and day <= 19):
        return "白羊座"
    elif (month == 4 and day >= 20) or (month == 5 and day <= 20):
        return "金牛座"
    elif (month == 5 and day >= 21) or (month == 6 and day <= 20):
        return "双子座"
    elif (month == 6 and day >= 21) or (month == 7 and day <= 22):
        return "巨蟹座"
    elif (month == 7 and day >= 23) or (month == 8 and day <= 22):
        return "狮子座"
    elif (month == 8 and day >= 23) or (month == 9 and day <= 22):
        return "处女座"
    elif (month == 9 and day >= 23) or (month == 10 and day <= 22):
        return "天秤座"
    elif (month == 10 and day >= 23) or (month == 11 and day <= 21):
        return "天蝎座"
    elif (month == 11 and day >= 22) or (month == 12 and day <= 21):
        return "射手座"
    elif (month == 12 and day >= 22) or (month == 1 and day <= 19):
        return "摩羯座"
    elif (month == 1 and day >= 20) or (month == 2 and day <= 18):
        return "水瓶座"
    else:
        return "双鱼座"

def get_sign_data(name):
    for z in ZODIAC:
        if z["name"] == name:
            return z
    return ZODIAC[0]

def gen_rating():
    """生成 1-5 星的评分"""
    # 加权随机，3-4星概率更高
    weights = [1, 3, 5, 4, 2]
    stars = random.choices(range(1, 6), weights=weights)[0]
    return stars

def stars_display(n):
    return "★" * n + "☆" * (5 - n)

# ========================
# 核心：生成运势
# ========================
def generate_horoscope(sign_name):
    """为指定星座生成今日运势"""
    sign = get_sign_data(sign_name)
    
    # 用星座名+日期做种子，保证同一天结果一致
    today = datetime.now().strftime("%Y-%m-%d")
    seed_str = f"{sign_name}-{today}"
    random.seed(hash(seed_str) % (2**32))
    
    love_s = gen_rating()
    career_s = gen_rating()
    wealth_s = gen_rating()
    health_s = gen_rating()
    overall = round((love_s + career_s + wealth_s + health_s) / 4, 1)
    
    result = {
        "sign": sign,
        "date": today,
        "overall_stars": overall,
        "love": {"stars": love_s, "text": random.choice(LOVE_TEXTS)},
        "career": {"stars": career_s, "text": random.choice(CAREER_TEXTS)},
        "wealth": {"stars": wealth_s, "text": random.choice(WEALTH_TEXTS)},
        "health": {"stars": health_s, "text": random.choice(HEALTH_TEXTS)},
        "advice": random.choice(ADVICE_TEXTS),
        "reason": random.choice(RATING_REASONS),
        "lucky_color": random.choice(LUCKY_COLORS),
        "lucky_num": random.choice(LUCKY_NUMS),
        "lucky_item": random.choice(LUCKY_ITEMS),
    }
    
    # 恢复随机种子
    random.seed()
    return result

# ========================
# 显示运势
# ========================
def show_horoscope(sign_name):
    global current_sign
    current_sign = sign_name
    
    data = generate_horoscope(sign_name)
    t = THEMES[cur_theme]
    
    # 清除画布
    canvas.delete("all")
    
    # 背景
    canvas.create_rectangle(0, 0, WIDTH, HEIGHT - 160, fill=t["card"], outline="")
    
    # 星座标题
    sign = data["sign"]
    title_y = 20
    canvas.create_text(WIDTH // 2, title_y, text=f"{sign['icon']} {sign['name']}",
                        font=("Comic Sans MS", 22, "bold"), fill=t["fg"])
    canvas.create_text(WIDTH // 2, title_y + 28, text=f"{sign['date']} | {sign['element']}象 | 守护星: {sign['ruler']}",
                        font=("Comic Sans MS", 9), fill=t["accent"])
    
    # 整体运势
    oy = 65
    canvas.create_text(20, oy, text="📊 今日总评", font=("Comic Sans MS", 11, "bold"),
                        fill=t["accent"], anchor="w")
    canvas.create_text(WIDTH // 2, oy + 22, text=f"{stars_display(int(data['overall_stars']))}  {data['overall_stars']}/5.0",
                        font=("Comic Sans MS", 16, "bold"), fill=t["star"])
    canvas.create_text(WIDTH // 2, oy + 42, text=data["reason"],
                        font=("Comic Sans MS", 8), fill=t["fg"])
    
    # 四维评分
    cats = [
        ("💕 爱情", data["love"]),
        ("💼 事业", data["career"]),
        ("💰 财富", data["wealth"]),
        ("💪 健康", data["health"]),
    ]
    cy = 140
    cw = (WIDTH - 60) // 2
    for i, (label, d) in enumerate(cats):
        cx = 20 + (i % 2) * (cw + 20)
        ry = cy + (i // 2) * 55
        canvas.create_text(cx, ry, text=label, font=("Comic Sans MS", 10, "bold"),
                            fill=t["fg"], anchor="w")
        canvas.create_text(cx + 80, ry, text=stars_display(d["stars"]),
                            font=("", 11), fill=t["star"], anchor="w")
        # 文字（截断适应宽度）
        txt = d["text"]
        if len(txt) > 22:
            txt = txt[:22] + "..."
        canvas.create_text(cx, ry + 16, text=txt, font=("Comic Sans MS", 8),
                            fill=t["fg"], anchor="w")
    
    # 幸运物
    ly = 260
    canvas.create_rectangle(15, ly, WIDTH - 15, ly + 50, fill=t["panel"], outline=t["accent"], width=1)
    canvas.create_text(25, ly + 12, text="🍀 幸运播报", font=("Comic Sans MS", 10, "bold"),
                        fill=t["accent"], anchor="w")
    canvas.create_text(25, ly + 30, text=f"颜色: {data['lucky_color']}  数字: {data['lucky_num']}  物品: {data['lucky_item']}",
                        font=("Comic Sans MS", 9), fill=t["fg"], anchor="w")
    
    # 今日宜忌
    ay = 325
    canvas.create_rectangle(15, ay, WIDTH - 15, ay + 35, fill=t["panel"], outline=t["accent"], width=1)
    canvas.create_text(25, ay + 12, text="📝 今日指南", font=("Comic Sans MS", 10, "bold"),
                        fill=t["accent"], anchor="w")
    canvas.create_text(25, ay + 28, text=data["advice"],
                        font=("Comic Sans MS", 9), fill=t["fg"], anchor="w")
    
    # 底部提示
    canvas.create_text(WIDTH // 2, HEIGHT - 175, text="✨ 星座运势仅供娱乐参考 ✨",
                        font=("Comic Sans MS", 8, "italic"), fill=t["accent"])
    
    # 更新按钮状态
    for btn, name in zodiac_btns:
        if name == sign_name:
            btn.config(relief="sunken", bd=3)
        else:
            btn.config(relief="raised", bd=1)
    
    log_msg(f"🔮 已生成 {sign['name']} 今日运势")

def show_my_horoscope():
    """根据今天日期自动判断星座"""
    today = datetime.now()
    sign_name = get_star_sign(today.month, today.day)
    show_horoscope(sign_name)
    log_msg(f"🎯 今天是 {today.month}月{today.day}日 → {sign_name}")

def random_all():
    """随机看一个星座运势"""
    z = random.choice(ZODIAC)
    show_horoscope(z["name"])

# ========================
# 换肤
# ========================
def apply_theme(name):
    global cur_theme
    cur_theme = name
    t = THEMES[name]
    
    root.config(bg=t["bg"])
    for w in all_widgets:
        try:
            w.config(bg=t["bg"], fg=t["fg"])
        except:
            pass
    
    for btn in theme_btns:
        btn.config(bg=t["btn"], fg="white")
    
    if canvas:
        canvas.config(background=t["card"])
    
    # 重绘当前星座
    if current_sign:
        show_horoscope(current_sign)
    else:
        # 画个欢迎界面
        canvas.delete("all")
        canvas.create_text(WIDTH // 2, HEIGHT // 2 - 60, text="🔮 星座运势 🔮",
                            font=("Comic Sans MS", 28, "bold"), fill=t["fg"])
        canvas.create_text(WIDTH // 2, HEIGHT // 2 - 20, text="选择你的星座，查看今日运势~",
                            font=("Comic Sans MS", 11), fill=t["accent"])
        canvas.create_text(WIDTH // 2, HEIGHT // 2 + 10, text="✨ 仅供娱乐参考 ✨",
                            font=("Comic Sans MS", 9, "italic"), fill=t["fg"])
        # 装饰星星
        import math
        for i in range(12):
            angle = i * 30 * math.pi / 180
            sx = WIDTH // 2 + 120 * math.cos(angle)
            sy = HEIGHT // 2 - 60 + 50 * math.sin(angle)
            canvas.create_text(sx, sy, text="✦", font=("", 8), fill=t["star"])

# ========================
# 日志
# ========================
log_lines = []
def log_msg(msg):
    global log_lines
    ts = datetime.now().strftime("%H:%M:%S")
    log_lines.append(f"[{ts}] {msg}")
    if len(log_lines) > 30:
        log_lines.pop(0)
    if lbl_log:
        lbl_log.config(state="normal")
        lbl_log.delete("1.0", "end")
        for line in log_lines[-5:]:
            lbl_log.insert("end", line + "\n")
        lbl_log.see("end")
        lbl_log.config(state="disabled")

lbl_log = None

# ========================
# 配对测试
# ========================
def compatibility_test():
    """两个星座配对指数"""
    z1 = random.choice(ZODIAC)
    z2 = random.choice(ZODIAC)
    while z1 == z2:
        z2 = random.choice(ZODIAC)
    
    # 同元素 +20，互补元素 +10
    elem_pair = {"火": "火", "土": "土", "风": "风", "水": "水"}
    comp_elem = {"火": "风", "风": "火", "土": "水", "水": "土"}
    
    score = random.randint(40, 95)
    if z1["element"] == z2["element"]:
        score = min(99, score + 15)
    elif comp_elem.get(z1["element"]) == z2["element"]:
        score = min(99, score + 8)
    
    verdict = "天生一对" if score >= 85 else ("非常合拍" if score >= 70 else ("还不错" if score >= 55 else "需要磨合"))
    
    dlg = tk.Toplevel(root)
    dlg.title("💕 星座配对")
    dlg.geometry("400x280")
    dlg.transient(root)
    t = THEMES[cur_theme]
    dlg.config(bg=t["bg"])
    
    tk.Label(dlg, text="💕 星座配对测试 💕", font=("Comic Sans MS", 14, "bold"),
             bg=t["bg"], fg=t["fg"]).pack(pady=10)
    
    tk.Label(dlg, text=f"{z1['icon']} {z1['name']}  ❤️  {z2['icon']} {z2['name']}",
             font=("Comic Sans MS", 16), bg=t["bg"], fg=t["accent"]).pack(pady=5)
    
    # 进度条
    bar_frame = tk.Frame(dlg, bg=t["bg"])
    bar_frame.pack(pady=10)
    tk.Label(bar_frame, text="配对指数:", font=("Comic Sans MS", 11),
             bg=t["bg"], fg=t["fg"]).pack(side="left")
    
    bar = tk.Canvas(bar_frame, width=200, height=20, bg=t["panel"], highlightthickness=1)
    bar.pack(side="left", padx=5)
    bar.create_rectangle(2, 2, 2 + score * 2, 18, fill=t["accent"], outline="")
    bar.create_text(100, 10, text=f"{score}%", font=("Comic Sans MS", 9, "bold"), fill="white")
    
    tk.Label(dlg, text=f"💬 评价: {verdict}", font=("Comic Sans MS", 12, "bold"),
             bg=t["bg"], fg=t["accent"]).pack(pady=5)
    
    comments = [
        "你们在一起的时候，空气都是甜的~",
        "吵吵闹闹才是真感情！",
        "默契度不错，多沟通会更好",
        "性格互补，在一起很有趣",
        "细水长流，感情会越来越好",
    ]
    tk.Label(dlg, text=random.choice(comments), font=("Comic Sans MS", 9),
             bg=t["bg"], fg=t["fg"], wraplength=350).pack(pady=5)
    
    tk.Button(dlg, text="再测一次", command=lambda: [dlg.destroy(), compatibility_test()],
              bg=t["accent"], fg="white", font=("Comic Sans MS", 10)).pack(pady=5)
    tk.Button(dlg, text="关闭", command=dlg.destroy).pack()

# ========================
# 构建界面
# ========================
def build_ui():
    global root, canvas, lbl_log
    
    root = tk.Tk()
    root.title("🔮 星座运势小程序 · 娱乐版")
    root.geometry(f"{WIDTH}x{HEIGHT}")
    root.resizable(False, False)
    
    # ====== 顶部栏 ======
    top = tk.Frame(root)
    top.pack(fill="x", pady=3)
    
    tk.Label(top, text="🔮 星座运势", font=("Comic Sans MS", 13, "bold")).pack(side="left", padx=10)
    
    tk.Button(top, text="🎯 我的星座", font=("Comic Sans MS", 9),
              bg="#E91E63", fg="white", command=show_my_horoscope).pack(side="left", padx=3)
    tk.Button(top, text="🎲 随机一个", font=("Comic Sans MS", 9),
              bg="#9C27B0", fg="white", command=random_all).pack(side="left", padx=3)
    tk.Button(top, text="💕 配对测试", font=("Comic Sans MS", 9),
              bg="#FF5722", fg="white", command=compatibility_test).pack(side="left", padx=3)
    
    # ====== 主题栏 ======
    theme_bar = tk.Frame(root)
    theme_bar.pack(fill="x", pady=1)
    tk.Label(theme_bar, text="🎨 ", font=("", 8)).pack(side="left", padx=3)
    for name in THEMES:
        btn = tk.Button(theme_bar, text=name, font=("Comic Sans MS", 7, "bold"),
                         relief="raised", bd=1, padx=3,
                         command=lambda n=name: apply_theme(n))
        btn.pack(side="left", padx=1)
        theme_btns.append(btn)
    
    # ====== 星座选择栏 ======
    sign_bar = tk.Frame(root)
    sign_bar.pack(fill="x", pady=2)
    
    # 分两行排列12星座
    row1 = tk.Frame(sign_bar)
    row1.pack(fill="x")
    row2 = tk.Frame(sign_bar)
    row2.pack(fill="x")
    
    for i, z in enumerate(ZODIAC):
        parent = row1 if i < 6 else row2
        btn = tk.Button(parent, text=f"{z['icon']} {z['name']}",
                         font=("Comic Sans MS", 8),
                         relief="raised", bd=1,
                         command=lambda n=z["name"]: show_horoscope(n))
        btn.pack(side="left", padx=1, pady=1)
        zodiac_btns.append((btn, z["name"]))
    
    # ====== 画布（运势展示区）======
    canvas_frame = tk.Frame(root)
    canvas_frame.pack(fill="both", expand=True, padx=5, pady=3)
    
    canvas = tk.Canvas(canvas_frame, width=WIDTH - 20, height=HEIGHT - 200,
                        highlightthickness=0)
    canvas.pack(fill="both", expand=True)
    
    # ====== 底部日志 ======
    log_frame = tk.Frame(root)
    log_frame.pack(fill="x", side="bottom", pady=1)
    
    lbl_log = tk.Text(log_frame, font=("Consolas", 7), height=3, state="disabled")
    lbl_log.pack(fill="both", expand=True, padx=5)
    
    all_widgets.extend([top, theme_bar, sign_bar, row1, row2,
                        canvas_frame, log_frame])
    
    # 收集星座按钮的widget引用
    for btn, _ in zodiac_btns:
        all_widgets.append(btn)

# ========================
# 初始化
# ========================
def init():
    build_ui()
    apply_theme("💜 梦幻紫")
    log_msg("🔮 星座运势小程序已就绪")
    log_msg("💡 点「我的星座」自动识别，或选择星座查看")
    random.seed()  # 确保随机性

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