/* 星命合参 — beautified SPA.
   Logic: window.ZiweiCore (verbatim from ZiweiStar.jsx).
   Visuals: window.DesignSystem_73ccbe components + CSS tokens only.
   Tweaks: persona voice · starfield density · rise animation. */

const {
  StarfieldBackground, Section, Card, Nav,
  Field, Input, Select, DateSelect, SegButton, TabButton, GoldButton, GhostButton,
  Bar, Tag, Quote, ZBadge, Pillar, DailyCard, Icon,
} = window.DesignSystem_73ccbe;
const Z = window.ZiweiCore;
const { useState, useMemo } = React;

/* 五行 → token 引用 */
const WX = { 木:"var(--wuxing-wood)", 火:"var(--wuxing-fire)", 土:"var(--wuxing-earth)", 金:"var(--wuxing-metal)", 水:"var(--wuxing-water)" };

const ZT = {
  h1:{fontFamily:"var(--font-display)",letterSpacing:"var(--tracking-wide)",fontSize:25,margin:0,color:"var(--gold-bright)"},
  sub:{fontSize:12,color:"var(--text-muted)",letterSpacing:"var(--tracking-display)",marginTop:6},
  note:{fontSize:12,color:"var(--text-muted)",lineHeight:1.7,margin:"6px 0 0"},
};

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "persona": "毒舌",
  "stars": 50,
  "riseAnim": true
}/*EDITMODE-END*/;

function Shell({stars,children}){return <StarfieldBackground stars={stars}><div style={{maxWidth:480,margin:"0 auto",minHeight:"100vh",position:"relative"}}>{children}</div></StarfieldBackground>;}
function Page({children,label}){return <div data-screen-label={label} style={{padding:"20px 16px 90px"}}>{children}</div>;}

function Header({p,onEdit,title}){return (<div style={{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:"var(--space-5)"}}>
  <div><div style={{fontFamily:"var(--font-display)",fontSize:13,color:"var(--gold-muted)",letterSpacing:"var(--tracking-display)"}}>{title||"本命"}</div>
    <div style={{fontSize:16,color:"var(--gold-bright)",marginTop:2}}>{p.name} <span style={{fontSize:12,color:"var(--text-muted)"}}>{p.gender} · {p.y}.{p.m}.{p.d} {p.sc}</span></div></div>
  {onEdit&&<GhostButton onClick={onEdit}>改档</GhostButton>}
</div>);}

function Onboard({stars,initial,onDone}){
  const [f,setF]=useState(initial||{name:"",gender:"女",y:1995,m:6,d:15,sc:"午时"});
  const submit=()=>{ onDone({...f,name:f.name.trim()||"命主"}); };
  return (<StarfieldBackground stars={stars}><div data-screen-label="立盘 Onboarding" style={{maxWidth:460,margin:"0 auto",padding:"60px 20px",position:"relative"}}>
    <div style={{textAlign:"center",marginBottom:30}}>
      <div style={{display:"flex",justifyContent:"center",gap:10,color:"var(--gold-muted)",marginBottom:8}}><Icon name="sun" size={18}></Icon><Icon name="star" size={18}></Icon><Icon name="moon" size={18}></Icon></div>
      <h1 style={ZT.h1}>星 命 合 参</h1><p style={ZT.sub}>西法星座 · 子平命理 · 果老星宗</p>
    </div>
    <Card>
      <Field label="姓名"><Input value={f.name} placeholder="选填" onChange={e=>setF({...f,name:e.target.value})}></Input></Field>
      <Field label="性别"><div style={{display:"flex",gap:8,marginTop:4}}>{["女","男"].map(g=><SegButton key={g} active={f.gender===g} onClick={()=>setF({...f,gender:g})}>{g}</SegButton>)}</div></Field>
      <DateSelect y={f.y} m={f.m} d={f.d} onChange={nf=>setF({...f,...nf})}></DateSelect>
      <Field label="时辰"><Select value={f.sc} onChange={e=>setF({...f,sc:e.target.value})} options={Z.SHICHEN.map(s=>s[0])} renderLabel={v=>{const s=Z.SHICHEN.find(x=>x[0]===v);return `${s[0]}（${s[2]}）`;}}></Select></Field>
      <GoldButton onClick={submit}>立 盘 入 命</GoldButton>
    </Card>
    <p style={{textAlign:"center",fontSize:11,color:"var(--text-disclaimer)",marginTop:20,lineHeight:1.7}}>性别用于大运顺逆 · 月柱按节气换月、年柱按立春换岁<br></br>节气为公式估算 · 仅供文化娱乐</p>
  </div></StarfieldBackground>);
}

function Daily({p,c,persona,setPersona}){
  const now=new Date();
  const dateStr=`${now.getFullYear()}-${now.getMonth()+1}-${now.getDate()}`;
  const dd=useMemo(()=>Z.computeDaily(p,c,dateStr),[p,c,dateStr]);
  const line=Z.PERSONA[persona].say(dd.theme);
  const shareText=`【星命合参·今日天机】${dateStr}\n${p.name}｜${dd.gz}日｜${dd.theme.t}（${dd.ss}）\n${line}${dd.tail}\n吉时${dd.jiShi}·幸运${dd.luckyWx}行(${dd.fang})·数字${dd.num}`;
  return <DailyCard date={dateStr} gz={dd.gz} themeTitle={dd.theme.t} score={dd.score}
    line={line} tail={dd.tail} jiShi={dd.jiShi} luckyWx={dd.luckyWx} fang={dd.fang} num={dd.num}
    yi={dd.yi} ji={dd.ji}
    personas={Object.entries(Z.PERSONA).map(([key,v])=>({key,name:v.name}))}
    persona={persona} onPersonaChange={setPersona} shareText={shareText}></DailyCard>;
}

function ChartPage({p,onEdit,persona,setPersona}){
  const c=useMemo(()=>Z.computeChart(p),[p]);
  return (<Page label="命盘 Chart">
    <Header p={p} onEdit={onEdit}></Header>
    <Daily p={p} c={c} persona={persona} setPersona={setPersona}></Daily>
    <Section d={0}><div style={{display:"flex",alignItems:"center",gap:16}}>
      <div style={{fontSize:50,color:"var(--gold-bright)",textShadow:"var(--glow-gold)"}}>{c.z[2]}</div>
      <div><div style={{fontSize:21,color:"var(--gold-bright)"}}>{c.z[0]} <span style={{fontSize:13,color:"var(--text-muted)"}}>属{c.sx}</span></div>
        <div style={{fontSize:12,fontFamily:"var(--font-display)",color:"var(--text-muted)",letterSpacing:"var(--tracking-display)"}}>{c.z[1]} · {c.z[3]}象</div>
        <div style={{fontSize:12.5,color:"var(--text-secondary)",marginTop:5,lineHeight:1.6}}>{Z.GUOLAO[c.z[0]]}</div></div>
    </div></Section>
    <Section d={0.08} title="四柱命盘">
      <div style={{display:"grid",gridTemplateColumns:"repeat(4,1fr)",gap:8}}>{c.pillars.map(q=>(
        <Pillar key={q.l} label={q.l+"柱"} gan={Z.GAN[q.gan]} zhi={Z.ZHI[q.zhi]}
          ganWx={Z.GAN_WX[q.gan]} zhiWx={Z.ZHI_WX[Z.ZHI[q.zhi]]} highlight={q.l==="日"}></Pillar>))}</div>
      <p style={{...ZT.note,marginTop:10}}>日主 <b style={{color:WX[c.dm.wx]}}>{Z.GAN[c.dm.gan]}（{c.dm.yy?"阳":"阴"}{c.dm.wx}）</b> 为命之本元。月柱依 <b style={{color:"var(--gold-bright)"}}>{c.monthZhi}月</b> 之节令而定。《子平真诠》以日干为我。</p>
    </Section>
    <Section d={0.16} title="五行旺衰">
      {c.sorted.map(it=><Bar key={it[0]} label={it[0]} v={it[1]} max={8} color={WX[it[0]]}></Bar>)}
      <p style={{...ZT.note,marginTop:8}}>{c.lack.length? <React.Fragment>命局缺 <b style={{color:"var(--gold-bright)"}}>{c.lack.join("、")}</b>，《渊海子平》《神峰通考》主张取缺者补之。</React.Fragment> : <React.Fragment>五行俱全，《三命通会》谓之「中和」，难得之福。</React.Fragment>}</p>
    </Section>
    <Section d={0.24} title="大运 · 每步十年">
      <div style={{fontSize:11.5,color:"var(--text-muted)",marginBottom:10}}>{c.forward?"顺行":"逆行"}排盘（{p.gender}命 · {c.yangYear?"阳":"阴"}年生）· 约 <b style={{color:"var(--gold-primary)"}}>{c.startAge}</b> 岁起运</div>
      <div style={{display:"flex",gap:6,overflowX:"auto",paddingBottom:4}}>{c.luck.map((u,i)=>(
        <Pillar key={i} compact label={u.age+"岁"} gan={Z.GAN[u.gan]} zhi={Z.ZHI[u.zhi]}
          ganWx={Z.GAN_WX[u.gan]} zhiWx={Z.ZHI_WX[Z.ZHI[u.zhi]]} sub={Z.shiShen(c.dm.gan,u.gan)}></Pillar>))}</div>
      <p style={{...ZT.note,marginTop:8}}>※ 起运岁按交节天数÷3 推算；节气为公式估算，或有 ±1 日。</p>
    </Section>
  </Page>);
}

function FortunePage({p}){
  const [sub,setSub]=useState("日");
  const c=useMemo(()=>Z.computeChart(p),[p]);
  const now=new Date();
  const periodKey=useMemo(()=>{
    if(sub==="日") return `${now.getFullYear()}-${now.getMonth()+1}-${now.getDate()}`;
    if(sub==="周"){const w=Math.ceil(((now-new Date(now.getFullYear(),0,1))/864e5+1)/7);return `${now.getFullYear()}W${w}`;}
    if(sub==="月") return `${now.getFullYear()}-${now.getMonth()+1}`;
    return `${now.getFullYear()}`;
  },[sub]);
  const f=useMemo(()=>{
    const r=Z.seedRand(`${p.name}${p.y}${p.m}${p.d}${p.sc}-${periodKey}`);
    const base=sub==="日"?65:sub==="周"?68:sub==="月"?70:72;
    const dim=()=>Math.floor(r()*24)+base;
    const fo={career:dim(),wealth:dim(),love:dim(),health:dim()};
    fo.total=Math.round((fo.career+fo.wealth+fo.love+fo.health)/4);
    const pick=a=>a[Math.floor(r()*a.length)];
    return {...fo,yi:[...new Set([pick(Z.YI),pick(Z.YI)])],ji:[...new Set([pick(Z.JI),pick(Z.JI)])],piyu:pick(Z.PIYU),num:Math.floor(r()*9)+1};
  },[periodKey,sub,p]);
  return (<Page label="运势 Fortune">
    <Header p={p} title="运势"></Header>
    <div style={{display:"flex",gap:6,marginBottom:12}}>{["日","周","月","年"].map(s=><TabButton key={s} active={sub===s} onClick={()=>setSub(s)}>{s}运</TabButton>)}</div>
    <Section d={0} title={`${sub}运 · ${periodKey}`}>
      <div style={{textAlign:"center",marginBottom:14}}><div style={{fontSize:44,fontWeight:900,color:"var(--gold-bright)",fontFamily:"var(--font-display)"}}>{f.total}</div><div style={{fontSize:12,color:"var(--text-muted)"}}>综合 · {f.total>=85?"大吉":f.total>=75?"吉":"平"}</div></div>
      {[["事业",f.career],["财运",f.wealth],["感情",f.love],["健康",f.health]].map(it=><Bar key={it[0]} label={it[0]} v={it[1]} max={100} gold w={34}></Bar>)}
      <div style={{display:"flex",gap:8,marginTop:14}}><Tag tone="good" title="宜">{f.yi.join(" · ")}</Tag><Tag tone="bad" title="忌">{f.ji.join(" · ")}</Tag></div>
      <div style={{display:"flex",gap:14,marginTop:12,fontSize:12,color:"var(--text-secondary)"}}>
        <span><Icon name="gem" size={12} inline color={WX[c.sorted[0][0]]}></Icon> 幸运色 <b style={{color:WX[c.sorted[0][0]]}}>{c.sorted[0][0]}行</b></span>
        <span><Icon name="sparkles" size={12} inline color="var(--gold-bright)"></Icon> 幸运数 <b style={{color:"var(--gold-bright)"}}>{f.num}</b></span></div>
      <Quote>{f.piyu}</Quote>
      <p style={ZT.note}>※《协纪辨方书》宜忌之论，吉凶在人事，娱乐参详。</p>
    </Section>
  </Page>);
}

function YearPage({p}){
  const c=useMemo(()=>Z.computeChart(p),[p]);
  const yr=new Date().getFullYear();
  const curAge=yr-p.y;
  const curStep=Math.floor((curAge-c.startAge)/10);
  const curLuck=curStep>=0&&curStep<c.luck.length?c.luck[curStep]:null;
  const data=useMemo(()=>[0,1,2].map(off=>{
    const Y=yr+off, yp=Z.yearPillar(Y), ss=Z.shiShen(c.dm.gan,yp.gan);
    const tg=Z.GAN_WX[yp.gan],dw=c.dm.wx;
    let rel="比和竞合"; if(Z.SHENG[tg]===dw)rel="生身得助";else if(Z.SHENG[dw]===tg)rel="泄气耗神";else if(Z.KE[tg]===dw)rel="受克需谨";else if(Z.KE[dw]===tg)rel="我克掌局";
    const r=Z.seedRand(`${p.name}${p.y}-ln-${Y}`);
    return {Y,yp,ss,rel,sx:Z.SX[Z.ZHI[yp.zhi]],score:Math.floor(r()*24)+68};
  }),[p]);
  return (<Page label="流年 Year">
    <Header p={p} title="流年"></Header>
    <Section d={0} title="当前所行大运">
      {curLuck? <div style={{display:"flex",alignItems:"center",gap:14}}>
        <Pillar gan={Z.GAN[curLuck.gan]} zhi={Z.ZHI[curLuck.zhi]} ganWx={Z.GAN_WX[curLuck.gan]} zhiWx={Z.ZHI_WX[Z.ZHI[curLuck.zhi]]} highlight style={{padding:"6px 12px"}}></Pillar>
        <div style={{flex:1,fontSize:12.5,color:"var(--text-secondary)",lineHeight:1.7}}>{curLuck.age}–{curLuck.age+9}岁行 <b style={{color:"var(--gold-primary)"}}>{Z.GAN[curLuck.gan]}{Z.ZHI[curLuck.zhi]}</b> 大运，引 <b style={{color:"var(--gold-bright)"}}>{Z.shiShen(c.dm.gan,curLuck.gan)}</b>。{Z.SS_DESC[Z.shiShen(c.dm.gan,curLuck.gan)]}，为此十年之主调。</div>
      </div> : <p style={ZT.note}>尚未起运（约 {c.startAge} 岁起运），此前行月柱童限，受原局与流年牵引为主。</p>}
    </Section>
    {data.map((x,i)=>(<Section key={x.Y} d={0.08+i*0.07} title={`${x.Y} 年 · ${Z.GAN[x.yp.gan]}${Z.ZHI[x.yp.zhi]}（${x.sx}年）`}>
      <div style={{display:"flex",alignItems:"center",gap:14}}>
        <div style={{textAlign:"center"}}><div style={{fontSize:34,fontWeight:900,color:"var(--gold-bright)",fontFamily:"var(--font-display)"}}>{x.score}</div><div style={{fontSize:10,color:"var(--text-muted)"}}>年运分</div></div>
        <div style={{flex:1,fontSize:12.5,color:"var(--text-secondary)",lineHeight:1.7}}>流年透 <b style={{color:"var(--gold-primary)"}}>{x.ss}</b>，对日主 <b style={{color:WX[c.dm.wx]}}>{Z.GAN[c.dm.gan]}</b> 为 <b style={{color:"var(--gold-bright)"}}>{x.rel}</b>。{Z.SS_DESC[x.ss]}。{Z.GAN[x.yp.gan]}{Z.ZHI[x.yp.zhi]}太岁当值。</div></div>
    </Section>))}
    <Section d={0.32} title="十神流转">
      <p style={{...ZT.note,lineHeight:1.8}}>《滴天髓》论命，重原局与岁运之生克制化。以日主 <b style={{color:WX[c.dm.wx]}}>{Z.GAN[c.dm.gan]}</b> 为我，大运管十年大势，流年主一岁吉凶，二者交叠定休咎。</p>
      <p style={ZT.note}>※ 流年取公历年干支，未严格依立春换岁。</p>
    </Section>
  </Page>);
}

function SynastryPage({p}){
  const [g,setG]=useState({name:"",gender:"男",y:1994,m:8,d:20,sc:"子时"});
  const [show,setShow]=useState(false);
  const me=useMemo(()=>Z.computeChart(p),[p]);
  const ta=useMemo(()=>(show?Z.computeChart({...g,name:g.name||"TA"}):null),[show,g]);
  const res=useMemo(()=>{
    if(!ta) return null;
    const i=Z.ZODIAC.indexOf(me.z),j=Z.ZODIAC.indexOf(ta.z);
    const diff=Math.min((i-j+12)%12,(j-i+12)%12);
    const aspect=({0:["同座",76],2:["六分相",86],4:["三分相",92],6:["对分相",71],3:["四分相",61],1:["半六分",66],5:["十二分相",64]})[diff]||["微相",70];
    const mw=me.dm.wx,tw=ta.dm.wx; let wxTxt="比和相亲",wxAdj=4;
    if(Z.SHENG[mw]===tw){wxTxt=`${mw}生${tw}，你护持对方`;wxAdj=8;}
    else if(Z.SHENG[tw]===mw){wxTxt=`${tw}生${mw}，对方滋养你`;wxAdj=8;}
    else if(Z.KE[mw]===tw){wxTxt=`${mw}克${tw}，你主导有张力`;wxAdj=-6;}
    else if(Z.KE[tw]===mw){wxTxt=`${tw}克${mw}，对方压制需磨合`;wxAdj=-6;}
    const zr=Z.zhiRelation(me.yearBranch, ta.yearBranch);
    const r=Z.seedRand(`${p.name}${p.y}+${g.name}${g.y}`);
    const base=aspect[1]+wxAdj;
    const dim=b=>Math.max(45,Math.min(98,b+Math.floor(r()*14)-5));
    const dims={爱情:dim(base),默契:dim(base+2),稳定:dim(base+wxAdj+zr.adj/2),激情:dim(aspect[1]),成长:dim(base+zr.adj/3)};
    const total=Math.round(Object.values(dims).reduce((a,b)=>a+b,0)/5);
    const ssM=Z.shiShen(me.dm.gan,ta.dm.gan);
    return {aspect,wxTxt,zr,dims,total,ssM};
  },[ta,g,p,me]);
  return (<Page label="合盘 Synastry">
    <Header p={p} title="双人合盘"></Header>
    <Section d={0} title="TA 的生辰">
      <Field label="姓名"><Input value={g.name} placeholder="对方姓名" onChange={e=>setG({...g,name:e.target.value})}></Input></Field>
      <Field label="性别"><div style={{display:"flex",gap:8,marginTop:4}}>{["女","男"].map(x=><SegButton key={x} active={g.gender===x} onClick={()=>setG({...g,gender:x})}>{x}</SegButton>)}</div></Field>
      <DateSelect y={g.y} m={g.m} d={g.d} onChange={nf=>setG({...g,...nf})}></DateSelect>
      <Field label="时辰"><Select value={g.sc} onChange={e=>setG({...g,sc:e.target.value})} options={Z.SHICHEN.map(s=>s[0])}></Select></Field>
      <GoldButton onClick={()=>setShow(true)}>合 盘 测 缘</GoldButton>
    </Section>
    {res&&(<React.Fragment>
      <Section d={0.05} title="缘分总评">
        <div style={{display:"flex",alignItems:"center",justifyContent:"center",gap:18,marginBottom:8}}>
          <ZBadge symbol={me.z[2]} name={p.name} label={me.z[0]}></ZBadge>
          <div style={{textAlign:"center"}}><div style={{fontSize:40,fontWeight:900,color:"var(--gold-bright)",fontFamily:"var(--font-display)"}}>{res.total}</div><Icon name="heart-handshake" size={16} color="var(--semantic-bad)"></Icon></div>
          <ZBadge symbol={ta.z[2]} name={g.name||"TA"} label={ta.z[0]}></ZBadge></div>
        <p style={ZT.note}>星座成 <b style={{color:"var(--gold-bright)"}}>{res.aspect[0]}</b>（{res.aspect[1]}分）；日主 {res.wxTxt}。</p>
      </Section>
      <Section d={0.1} title="生肖合婚">
        <div style={{display:"flex",alignItems:"center",gap:12}}>
          <div style={{textAlign:"center"}}><div style={{fontSize:26}}>{Z.SX[me.yearBranch]}</div><div style={{fontSize:10,color:"var(--text-muted)"}}>{p.name}</div></div>
          <div style={{flex:1,textAlign:"center",fontSize:13,color:res.zr.adj>0?"var(--semantic-good)":res.zr.adj<0?"var(--semantic-bad)":"var(--text-secondary)",fontWeight:600}}>{res.zr.txt}</div>
          <div style={{textAlign:"center"}}><div style={{fontSize:26}}>{Z.SX[ta.yearBranch]}</div><div style={{fontSize:10,color:"var(--text-muted)"}}>{g.name||"TA"}</div></div></div>
        <p style={{...ZT.note,marginTop:8}}>《三命通会》论婚配，重地支六合三合为吉、相冲相害为忌。</p>
      </Section>
      <Section d={0.16} title="五维相性">{Object.entries(res.dims).map(it=><Bar key={it[0]} label={it[0]} v={it[1]} max={100} gold w={34}></Bar>)}</Section>
      <Section d={0.22} title="子平断语">
        <p style={{...ZT.note,lineHeight:1.8}}>以你为日主，对方现 <b style={{color:"var(--gold-primary)"}}>{res.ssM}</b> 之象——{Z.SS_DESC[res.ssM]}。《渊海子平》论夫妻宫贵在五行调候、刚柔相济。{res.total>=82?"星合支合，相处如鱼得水。":res.total>=70?"有张力亦有吸引，磨合则久。":"差异较大，需各退一步，以诚相守。"}</p>
        <p style={ZT.note}>※ 合盘为简化模型（星座相位 + 日主十神 + 五行生克 + 生肖六合），非完整 synastry。</p>
      </Section>
    </React.Fragment>)}
  </Page>);
}

const PROFILE_KEY = "ziweistar.beautified.profile";
function loadProfile(){ try{ const s=localStorage.getItem(PROFILE_KEY); return s?JSON.parse(s):null; }catch(e){ return null; } }

function App(){
  const [t,setTweak]=useTweaks(TWEAK_DEFAULTS);
  const [profile,setProfileState]=useState(loadProfile);
  const [editing,setEditing]=useState(false);
  const [tab,setTab]=useState("chart");
  const persona = Z.PERSONA[t.persona] ? t.persona : "毒舌";
  const setPersona = k=>setTweak("persona",k);
  const saveProfile = p=>{ setProfileState(p); setEditing(false); try{ localStorage.setItem(PROFILE_KEY, JSON.stringify(p)); }catch(e){} };
  return (<React.Fragment>
    {!t.riseAnim && <style>{".rise{animation:none !important}"}</style>}
    {(!profile||editing)
      ? <Onboard stars={t.stars} initial={profile} onDone={saveProfile}></Onboard>
      : <Shell stars={t.stars}>
          {tab==="chart"&&<ChartPage p={profile} persona={persona} setPersona={setPersona} onEdit={()=>setEditing(true)}></ChartPage>}
          {tab==="fortune"&&<FortunePage p={profile}></FortunePage>}
          {tab==="year"&&<YearPage p={profile}></YearPage>}
          {tab==="synastry"&&<SynastryPage p={profile}></SynastryPage>}
          <Nav tab={tab} setTab={setTab}></Nav>
        </Shell>}
    <TweaksPanel title="Tweaks">
      <TweakSection label="批语口吻"></TweakSection>
      <TweakRadio label="星官人格" value={persona} options={["毒舌","仙姑","命师"]} onChange={setPersona}></TweakRadio>
      <TweakSection label="夜空氛围"></TweakSection>
      <TweakSlider label="星空密度" value={t.stars} min={0} max={150} step={10} onChange={v=>setTweak("stars",v)}></TweakSlider>
      <TweakToggle label="入场动画" value={t.riseAnim} onChange={v=>setTweak("riseAnim",v)}></TweakToggle>
    </TweaksPanel>
  </React.Fragment>);
}

ReactDOM.createRoot(document.getElementById("root")).render(<App></App>);
