"""
星座运势小程序（娱乐向）
功能：
  1. 选择或输入星座，查看今日综合运势
  2. 随机生成：综合指数、幸运色、幸运数字、幸运物、签文
  3. 切换查看「爱情 / 事业 / 财运」分项运势
  4. 星座性格简介
数据均为内置模拟，仅供娱乐，不具备任何占卜/预测效力。
"""

import random
import datetime
import tkinter as tk
from tkinter import ttk, messagebox


# ------------------------- 静态数据（娱乐用） -------------------------
ZODIAC_INFO = {
    "白羊座": ("03-21", "04-19", "热情直率、行动力强的开拓者，敢爱敢恨。"),
    "金牛座": ("04-20", "05-20", "稳重务实、注重质感，对喜欢的事物极其专一。"),
    "双子座": ("05-21", "06-21", "机智灵活、好奇心旺盛，擅长沟通与变化。"),
    "巨蟹座": ("06-22", "07-22", "温柔顾家、情感细腻，内心有坚硬的壳。"),
    "狮子座": ("07-23", "08-22", "自信大气、富有领导力，喜欢被关注。"),
    "处女座": ("08-23", "09-22", "细致完美、逻辑清晰，善于分析与整理。"),
    "天秤座": ("09-23", "10-23", "优雅平衡、追求和谐，审美在线。"),
    "天蝎座": ("10-24", "11-22", "深沉专注、洞察力强，爱恨分明。"),
    "射手座": ("11-23", "12-21", "自由乐观、热爱冒险，永远在路上。"),
    "摩羯座": ("12-22", "01-19", "自律务实、目标导向，沉默的努力者。"),
    "水瓶座": ("01-20", "02-18", "独立创新、思维跳脱，特立独行。"),
    "双鱼座": ("02-19", "03-20", "浪漫温柔、富有想象力，共情力满分。"),
}

# 运势文案库
FORTUNE_TEXTS = {
    "综合": [
        "整体节奏平稳，适合把注意力放在自己身上，做点让心情变好的小事。",
        "今天灵感在线，很多拖延的事迎来转机，把握住突然冒出的点子。",
        "运势起伏不大，宜静不宜动，低调处理人际关系会更轻松。",
        "贵人运不错，身边有人愿意拉你一把，记得大方表达感谢。",
        "精力旺盛的一天，适合开启新计划，把想法落到实处。",
    ],
    "爱情": [
        "单身的人可能在对视的瞬间心跳加速；有伴的适合聊聊未来。",
        "感情需要一点空间，别把控制当成关心，松弛感更迷人。",
        "旧人旧事可能被提起，放下执念才能迎来新的可能。",
        "适合制造小惊喜，一句真诚的夸奖胜过千言万语。",
        "沟通容易出现偏差，重要的事当面说清楚，别靠猜。",
    ],
    "事业": [
        "工作效率很高，复杂任务也能拆解清楚，适合推进关键节点。",
        "团队合作是关键词，适当示弱比硬扛更能赢得尊重。",
        "思路开阔但容易分心，先完成再完美，避免拖延。",
        "可能迎来新的机会或任务，提前准备才能稳稳接住。",
        "节奏偏慢，适合复盘整理，把过去的经验沉淀下来。",
    ],
    "财运": [
        "正财稳定，偏财谨慎，冲动下单前先冷静三分钟。",
        "有小小的进账机会，但大额支出要量力而行。",
        "适合做财务规划，梳理账单比盲目投资更靠谱。",
        "可能有意外支出，预留一部分应急资金更安心。",
        "理财运势平稳，稳健为主，别被高收益冲昏头脑。",
    ],
}

LUCKY_COLORS = ["蜜桃橙", "雾霾蓝", "奶油白", "薄荷绿", "葡萄紫", "焦糖棕", "樱花粉", "星空黑"]
LUCKY_NUMBERS = [3, 7, 9, 12, 18, 22, 27, 33, 41, 88]
LUCKY_ITEMS = ["四叶草", "星空项链", "一杯热拿铁", "水晶", "旧书信", "薄荷糖", "幸运硬币", "向日葵"]
ADVICE = [
    "今天的你值得被温柔以待，先照顾好自己。",
    "别想太多，顺其自然反而会有惊喜。",
    "勇敢表达，你的想法比想象中更有分量。",
    "适当休息不是偷懒，是给好运充电。",
    "把注意力拉回当下，答案就在眼前。",
]


def get_zodiac_by_date(date: datetime.date):
    """根据日期判断当日对应的星座（按开始日期）"""
    md = date.strftime("%m-%d")
    # 按起始日期排序，找到最后一个 <= 今日 的星座
    ordered = sorted(ZODIAC_INFO.items(), key=lambda kv: kv[1][0])
    result = ordered[0][0]
    for name, (start, end, desc) in ordered:
        if start <= md:
            result = name
        else:
            break
    # 摩羯座跨年（12-22 ~ 01-19）单独处理
    if md >= "12-22" or md <= "01-19":
        return "摩羯座"
    return result


# ----------------------------- 主界面 -----------------------------
class HoroscopeApp:
    SIGN_LABEL = "✨ 星座运势"

    def __init__(self, root):
        self.root = root
        self.root.title("星座运势小程序 · 娱乐版")
        self.root.geometry("560x680")
        self.root.minsize(520, 620)
        self.root.configure(bg="#1a1230")

        self.current_sign = tk.StringVar(value="白羊座")
        self.current_tab = tk.StringVar(value="综合")

        self._build_ui()
        self.refresh()

    def _build_ui(self):
        # 顶部标题
        top = tk.Frame(self.root, bg="#2b1d4e", height=70)
        top.pack(fill="x")
        top.pack_propagate(False)
        tk.Label(top, text="🔮  星座运势小程序", font=("Microsoft YaHei", 22, "bold"),
                 fg="#f6e6ff", bg="#2b1d4e").pack(pady=18)

        # 星座选择区
        select_frame = tk.Frame(self.root, bg="#1a1230")
        select_frame.pack(fill="x", padx=24, pady=(18, 6))

        tk.Label(select_frame, text="选择你的星座：", font=("Microsoft YaHei", 11),
                 fg="#d4c2f0", bg="#1a1230").pack(side="left")

        names = list(ZODIAC_INFO.keys())
        combo = ttk.Combobox(select_frame, textvariable=self.current_sign, values=names,
                              font=("Microsoft YaHei", 11), state="readonly", width=12)
        combo.pack(side="left", padx=(8, 8))

        tk.Button(select_frame, text="🎲 随机一个", font=("Microsoft YaHei", 9),
                  bg="#6c4bc0", fg="white", relief="flat", padx=10, cursor="hand2",
                  command=self._random_sign).pack(side="left")

        # 日期自动识别
        auto_frame = tk.Frame(self.root, bg="#1a1230")
        auto_frame.pack(fill="x", padx=24, pady=(0, 8))
        self.auto_var = tk.BooleanVar(value=False)
        cb = tk.Checkbutton(auto_frame, text="按今天的日期自动识别星座",
                             variable=self.auto_var, font=("Microsoft YaHei", 9),
                             fg="#a99bd0", bg="#1a1230", selectcolor="#2b1d4e",
                             activebackground="#1a1230", command=self.refresh)
        cb.pack(side="left")

        # 选项卡（综合/爱情/事业/财运）
        tab_frame = tk.Frame(self.root, bg="#1a1230")
        tab_frame.pack(fill="x", padx=24)
        tabs = [("综合", "综合"), ("💕 爱情", "爱情"), ("💼 事业", "事业"), ("💰 财运", "财运")]
        for text, value in tabs:
            btn = tk.Radiobutton(tab_frame, text=text, variable=self.current_tab, value=value,
                                 font=("Microsoft YaHei", 10, "bold"), fg="#e8dcff", bg="#2b1d4e",
                                 selectcolor="#6c4bc0", activebackground="#2b1d4e",
                                 activeforeground="#ffffff", indicatoron=False, padx=12, pady=5,
                                 cursor="hand2", command=self._render_detail)
            btn.pack(side="left", padx=3)

        # 运势卡片
        self.card = tk.Frame(self.root, bg="#ffffff", relief="flat")
        self.card.pack(fill="both", expand=True, padx=24, pady=14)

        # 底部提示
        tk.Label(self.root, text="本程序仅供娱乐，运势内容由程序随机生成，不具备任何预测效力 ❤️",
                 font=("Microsoft YaHei", 8), fg="#7a6cad", bg="#1a1230", wraplength=500).pack(pady=(0, 10))

    def _random_sign(self):
        names = list(ZODIAC_INFO.keys())
        self.current_sign.set(random.choice(names))
        self.refresh()

    def _build_fortune(self, sign):
        """为指定星座构建当日运势数据（带种子保证同一天同一星座结果稳定）"""
        today = datetime.date.today().isoformat()
        seed_key = f"{today}-{sign}"
        # 用字符串哈希做种子，保证当天结果稳定、不同星座不同
        random.seed(abs(hash(seed_key)) % (10 ** 8))

        score = random.randint(60, 98)
        detail = {tab: random.choice(FORTUNE_TEXTS[tab]) for tab in FORTUNE_TEXTS}
        return {
            "score": score,
            "color": random.choice(LUCKY_COLORS),
            "number": random.choice(LUCKY_NUMBERS),
            "item": random.choice(LUCKY_ITEMS),
            "advice": random.choice(ADVICE),
            "detail": detail,
        }

    def refresh(self):
        """整体刷新（星座改变时）"""
        if self.auto_var.get():
            self.current_sign.set(get_zodiac_by_date(datetime.date.today()))

        sign = self.current_sign.get()
        if sign not in ZODIAC_INFO:
            return

        # 更新卡片头部（星座信息）
        for w in self.card.winfo_children():
            w.destroy()

        self.fortune = self._build_fortune(sign)
        start, end, desc = ZODIAC_INFO[sign]

        head = tk.Frame(self.card, bg="#f3eeff")
        head.pack(fill="x")
        tk.Label(head, text=sign, font=("Microsoft YaHei", 22, "bold"),
                 fg="#4a2f9e", bg="#f3eeff").pack(anchor="w", padx=18, pady=(14, 0))
        tk.Label(head, text=f"{start} ~ {end}   ·   {desc}",
                 font=("Microsoft YaHei", 9), fg="#8a7bb5", bg="#f3eeff",
                 wraplength=460, justify="left").pack(anchor="w", padx=18, pady=(2, 12))

        self._render_detail()

    def _render_detail(self):
        """重新渲染运势正文（切换 tab 时，不重建头部）"""
        # 保留头部（第一个子组件），清除其余
        children = self.card.winfo_children()
        if children:
            head = children[0]
            for w in children[1:]:
                w.destroy()
        else:
            return

        sign = self.current_sign.get()
        tab = self.current_tab.get()
        f = self.fortune

        body = tk.Frame(self.card, bg="white")
        body.pack(fill="both", expand=True, padx=18, pady=(0, 16))

        # 综合指数（仅综合 tab 显示幸运信息）
        if tab == "综合":
            score_frame = tk.Frame(body, bg="white")
            score_frame.pack(fill="x", pady=(10, 4))
            tk.Label(score_frame, text="综合指数", font=("Microsoft YaHei", 11, "bold"),
                     fg="#4a2f9e", bg="white").pack(side="left")
            tk.Label(score_frame, text=f"{f['score']} 分",
                     font=("Microsoft YaHei", 16, "bold"), fg="#ff6b6b", bg="white").pack(side="right")

            # 简易进度条
            bar_bg = tk.Frame(body, bg="#eee8fa", height=12)
            bar_bg.pack(fill="x", pady=(0, 12))
            bar_fill = tk.Frame(bar_bg, bg="#7c5bd6", height=12, width=int(360 * f['score'] / 100))
            bar_fill.pack(side="left")

            # 幸运信息网格
            luck_frame = tk.Frame(body, bg="#faf8ff", relief="flat")
            luck_frame.pack(fill="x", pady=(4, 12), ipady=8)
            self._luck_row(luck_frame, "🎨 幸运色", f["color"])
            self._luck_row(luck_frame, "🔢 幸运数字", str(f["number"]))
            self._luck_row(luck_frame, "🎁 幸运物", f["item"])

            # 今日签文
            tk.Label(body, text="今日签文", font=("Microsoft YaHei", 11, "bold"),
                     fg="#4a2f9e", bg="white").pack(anchor="w", pady=(4, 4))
            tk.Label(body, text=f"「 {f['advice']} 」", font=("Microsoft YaHei", 11),
                     fg="#5a4a8a", bg="white", wraplength=440, justify="left").pack(anchor="w")

        # 分项运势文案
        tk.Label(body, text=f"{tab}运势", font=("Microsoft YaHei", 11, "bold"),
                 fg="#4a2f9e", bg="white").pack(anchor="w", pady=(12 if tab != "综合" else 6, 6))
        tk.Label(body, text=f["detail"][tab], font=("Microsoft YaHei", 11),
                 fg="#444444", bg="white", wraplength=440, justify="left").pack(anchor="w")

        today = datetime.date.today().strftime("%Y-%m-%d")
        tk.Label(body, text=f"更新日期：{today}", font=("Microsoft YaHei", 8), fg="#bbbbbb",
                 bg="white").pack(anchor="e", pady=(14, 0))

    def _luck_row(self, parent, label, value):
        row = tk.Frame(parent, bg="#faf8ff")
        row.pack(fill="x", padx=14, pady=4)
        tk.Label(row, text=label, font=("Microsoft YaHei", 10), fg="#8a7bb5", bg="#faf8ff").pack(side="left")
        tk.Label(row, text=value, font=("Microsoft YaHei", 10, "bold"), fg="#4a2f9e", bg="#faf8ff").pack(side="right")


def main():
    root = tk.Tk()
    HoroscopeApp(root)
    root.mainloop()


if __name__ == "__main__":
    main()
