import tkinter as tk
import random
import datetime
import calendar
from dataclasses import dataclass, field
from typing import List, Dict, Tuple, Optional
from enum import Enum

class ElementType(Enum):FIRE=1;EARTH=2;AIR=3;WATER=4
class LuckLevel(Enum):GREAT=5;GOOD=4;NORMAL=3;BAD=2;WORSE=1
@dataclass
class LuckyItems:number:int;color:str;direction:str;time:str;item:str
@dataclass
class ConstellationData:name:str;date_range:str;element:ElementType;ruler:str;lucky:LuckyItems;traits:List[str];desc:str
@dataclass
class FortuneResult:constellation:str;date:str;overall:LuckLevel;love:LuckLevel;career:LuckLevel;health:LuckLevel;wealth:LuckLevel;summary:str;advice:str;lucky:LuckyItems;score:int=0
class ConstellationDB:
    def __init__(self):self.c={};self.sum={};self.adv=[];self._init()
    def _init(self):
        d=[("白羊座","3.21-4.19",ElementType.FIRE,"火星",1,"红","东","早","头盔"),("金牛座","4.20-5.20",ElementType.EARTH,"金星",6,"绿","东南","下午","金币"),("双子座","5.21-6.21",ElementType.AIR,"水星",5,"黄","西","午","书"),("巨蟹座","6.22-7.22",ElementType.WATER,"月亮",2,"银","北","夜","贝壳"),("狮子座","7.23-8.22",ElementType.FIRE,"太阳",8,"金","南","正午","皇冠"),("处女座","8.23-9.22",ElementType.EARTH,"水星",4,"灰","西南","傍晚","羽毛"),("天秤座","9.23-10.23",ElementType.AIR,"金星",7,"蓝","西北","黄昏","天平"),("天蝎座","10.24-11.22",ElementType.WATER,"冥王星",9,"紫","东北","深夜","宝石"),("射手座","11.23-12.21",ElementType.FIRE,"木星",3,"橙","南","午后","弓箭"),("摩羯座","12.22-1.19",ElementType.EARTH,"土星",10,"褐","西南","凌晨","石块"),("水瓶座","1.20-2.18",ElementType.AIR,"天王星",11,"天蓝","北","清晨","水滴"),("双鱼座","2.19-3.20",ElementType.WATER,"海王星",12,"海蓝","东","黎明","海螺")]
        t={"白羊座":["热情","冲动","勇敢"],"金牛座":["稳重","固执","务实"],"双子座":["灵活","善变","好奇"],"巨蟹座":["温柔","敏感","顾家"],"狮子座":["自信","霸气","慷慨"],"处女座":["细致","挑剔","完美"],"天秤座":["优雅","犹豫","公正"],"天蝎座":["神秘","执着","深沉"],"射手座":["自由","乐观","冒险"],"摩羯座":["坚韧","保守","责任"],"水瓶座":["独立","创新","博爱"],"双鱼座":["浪漫","梦幻","同情"]}
        desc={"白羊座":"火象先锋","金牛座":"大地守护","双子座":"风中信使","巨蟹座":"月之儿女","狮子座":"烈日王者","处女座":"理性分析","天秤座":"美感裁判","天蝎座":"深渊守望","射手座":"自由弓箭","摩羯座":"时间雕刻","水瓶座":"未来先知","双鱼座":"海洋梦境"}
        for n,dr,et,r,nu,co,di,ti,it in d:self.c[n]=ConstellationData(n,dr,et,r,LuckyItems(nu,co,di,ti,it),t[n],desc[n])
        self.sum={LuckLevel.GREAT:["大吉之日","星光璀璨","万事顺遂"],LuckLevel.GOOD:["运势平稳","贵人相助","心情愉悦"],LuckLevel.NORMAL:["平淡是真","安稳度日","适宜整理"],LuckLevel.BAD:["稍有波折","谨慎行事","心态调节"],LuckLevel.WORSE:["诸事不宜","小人暗藏","静心反思"]}
        self.adv=["保持微笑","静思冥想","主动沟通","注重细节","相信直觉","劳逸结合","乐于助人","坚持初心"]
    def get(self,n):return self.c.get(n)
    def names(self):return list(self.c.keys())
class FortuneEngine:
    def __init__(self,db):self.db=db
    def _seed(self,c,s=""):d=datetime.date.today();random.seed(f"{d.year}{d.month}{d.day}{c}{s}")
    def _level(self):w={LuckLevel.GREAT:10,LuckLevel.GOOD:25,LuckLevel.NORMAL:40,LuckLevel.BAD:20,LuckLevel.WORSE:5};return random.choices(list(w.keys()),weights=list(w.values()),k=1)[0]
    def _score(self,r):m={LuckLevel.GREAT:100,LuckLevel.GOOD:80,LuckLevel.NORMAL:60,LuckLevel.BAD:40,LuckLevel.WORSE:20};return int(sum(m[getattr(r,x)] for x in ["overall","love","career","health","wealth"])/5)
    def daily(self,n):
        self._seed(n,"d");c=self.db.get(n);l=self._level()
        r=FortuneResult(n,datetime.date.today().strftime("%Y%m%d"),self._level(),self._level(),self._level(),self._level(),self._level(),random.choice(self.db.sum[l]),random.choice(self.db.adv),c.lucky)
        r.score=self._score(r);return r
    def weekly(self,n):
        self._seed(n,"w");t=["上升","平稳","波动","下滑","回暖"];f=["感情","事业","财运","健康"];return f"本周{t[random.randint(0,4)]}，关注{f[random.randint(0,3)]}，建议：{random.choice(self.db.adv)}"
    def monthly(self,n):
        self._seed(n,"m");d=datetime.date.today();dim=calendar.monthrange(d.year,d.month)[1];return f"{d.month}月{dim}天，基调{random.choice(['积累','突破','沉淀'])}，上旬{random.choice(['细节','沟通'])}，下旬{random.choice(['总结','规划'])}"
    def match(self,a,b):
        self._seed(a+b,"m");c1=self.db.get(a);c2=self.db.get(b);same=c1.element==c2.element;sc=random.randint(75,98) if same else random.randint(40,85)
        lv="天生一对" if sc>=85 else "默契搭档" if sc>=70 else "需要磨合" if sc>=50 else "欢喜冤家" if sc>=30 else "谨慎交往"
        return f"{a}({c1.element.name})♥{b}({c2.element.name})\n指数:{sc}/100\n评价:{lv}\n解析:{'同象相融' if same else '性格互补'}"
class App:
    def __init__(self,r):self.r=r;self.db=ConstellationDB();self.eg=FortuneEngine(self.db);self.cv=tk.StringVar();self._ui()
    def _ui(self):
        self.r.title("046.星座运势");self.r.geometry("640x720");self.r.configure(bg="#f0f0f0")
        tk.Label(self.r,text="✨ 星座运势小程序",font=("微软雅黑",20,"bold"),bg="#f0f0f0").pack(pady=10)
        lf=tk.LabelFrame(self.r,text="选择星座",bg="#f0f0f0");lf.pack(padx=15,pady=5,fill=tk.X)
        gf=tk.Frame(lf,bg="#f0f0f0");gf.pack(pady=8)
        for i,n in enumerate(self.db.names()):tk.Radiobutton(gf,text=n,variable=self.cv,value=n,bg="#f0f0f0").grid(row=i//4,column=i%4,padx=10,pady=3,sticky="w")
        bf=tk.Frame(self.r,bg="#f0f0f0");bf.pack(pady=10)
        tk.Button(bf,text="今日运势",width=12,command=self._d,bg="#5C6BC0",fg="white").pack(side=tk.LEFT,padx=4)
        tk.Button(bf,text="本周运势",width=12,command=self._w,bg="#43A047",fg="white").pack(side=tk.LEFT,padx=4)
        tk.Button(bf,text="本月运势",width=12,command=self._m,bg="#FB8C00",fg="white").pack(side=tk.LEFT,padx=4)
        tk.Button(bf,text="星座配对",width=12,command=self._mp,bg="#E53935",fg="white").pack(side=tk.LEFT,padx=4)
        rf=tk.LabelFrame(self.r,text="运势结果",bg="#f0f0f0");rf.pack(padx=15,pady=10,fill=tk.BOTH,expand=True)
        self.rt=tk.Text(rf,font=("Consolas",10),height=26,relief=tk.FLAT);self.rt.pack(fill=tk.BOTH,expand=True,padx=10,pady=10)
        bot=tk.Frame(self.r,bg="#f0f0f0");bot.pack(pady=8)
        tk.Button(bot,text="重置",width=10,command=self._rst,bg="#9E9E9E",fg="white").pack(side=tk.LEFT,padx=8)
        tk.Button(bot,text="退出",width=10,command=self.r.quit,bg="#607D8B",fg="white").pack(side=tk.LEFT,padx=8)
        self._rst()
    def _d(self):
        if not self.cv.get():self._msg("请选择星座");return
        r=self.eg.daily(self.cv.get());self._render(r)
    def _w(self):
        if not self.cv.get():self._msg("请选择星座");return
        self._msg(self.eg.weekly(self.cv.get()))
    def _m(self):
        if not self.cv.get():self._msg("请选择星座");return
        self._msg(self.eg.monthly(self.cv.get()))
    def _mp(self):
        if not self.cv.get():self._msg("请选择星座");return
        others=[x for x in self.db.names() if x!=self.cv.get()];self._msg(self.eg.match(self.cv.get(),random.choice(others)))
    def _render(self,r):
        self.rt.config(state=tk.NORMAL);self.rt.delete("1.0",tk.END)
        txt=f"╔══════════════════════════════╗\n║ 星座：{r.constellation:<8s} 日期：{r.date}\n║ 评分：{r.score:>3d}/100\n╠══════════════════════════════╣\n║ 综合：{r.overall.name:<4s} 爱情：{r.love.name:<4s}\n║ 事业：{r.career.name:<4s} 健康：{r.health.name:<4s}\n║ 财运：{r.wealth.name:<4s}\n╠══════════════════════════════╣\n║ 简评：{r.summary}\n╠══════════════════════════════╣\n║ 幸运数字：{r.lucky.number}\n║ 幸运颜色：{r.lucky.color}\n║ 幸运方位：{r.lucky.direction}\n║ 幸运时段：{r.lucky.time}\n║ 幸运物品：{r.lucky.item}\n╠══════════════════════════════╣\n║ 建议：{r.advice}\n╚══════════════════════════════╝"
        self.rt.insert("1.0",txt);self.rt.config(state=tk.DISABLED)
    def _msg(self,t):
        self.rt.config(state=tk.NORMAL);self.rt.delete("1.0",tk.END);self.rt.insert("1.0",t);self.rt.config(state=tk.DISABLED)
    def _rst(self):
        self.cv.set("");self._msg("请选择星座并点击功能按钮\n\n说明：本程序仅供娱乐")
if __name__=="__main__":
    rt=tk.Tk();App(rt);rt.mainloop()