/* ============================================================
   Nuad Now — Booking flow, My Bookings, Survey, Ranking  (JSX)
   ============================================================ */

function Stepper({step, labels}){
  return (
    <div className="stepper">
      {labels.map((s,i)=>(
        <div key={i} className="step">
          <div className={`step ${i<step?'done':''} ${i===step?'active':''}`} style={{display:'flex',alignItems:'center',gap:10}}>
            <div className="num">{i<step? <Icon name="check" size={18}/> : i+1}</div>
            <div className="lbl hide-sm">{s}</div>
          </div>
          {i<labels.length-1 && <div className={`bar ${i<step?'done':''}`} style={i<step?{background:'var(--sage)'}:null}></div>}
        </div>
      ))}
    </div>
  );
}

function GuideBubble({children}){
  return (
    <div className="row" style={{gap:14, alignItems:'center'}}>
      <Mascot w={64} bob={false} style={{filter:'drop-shadow(0 6px 8px rgba(74,43,34,.18))'}}/>
      <Bubble tail="tail-l" lead style={{flex:1}}>{children}</Bubble>
    </div>
  );
}

/* ============================================================
   BOOKING FLOW
   ============================================================ */
function BookingFlow({bookings, allBookings, onConfirm, onExit, draft, setDraft}){
  const [step,setStep]=React.useState(0);
  const d=draft;
  const set=(patch)=> setDraft({...d, ...patch});
  const canNext=[ !!d.dateKey, !!d.slot, true ][step];
  const next=()=> step<2 ? setStep(step+1) : onConfirm(d);
  const back=()=> step>0 ? setStep(step-1) : onExit();

  return (
    <div className="fade-in">
      <div className="row" style={{justifyContent:'space-between', marginBottom:6}}>
        <h1 style={{fontSize:'1.7rem'}}>{t('book_title')}</h1>
        <button className="btn ghost sm" onClick={onExit}><Icon name="x" size={18}/> {t('book_exit')}</button>
      </div>
      <Stepper step={step} labels={[t('book_step1'),t('book_step2'),t('book_step3')]}/>
      <div style={{maxWidth:840, margin:'0 auto'}}>
        {step===0 && <StepDate d={d} set={set} bookings={bookings} allBookings={allBookings}/>}
        {step===1 && <StepTime d={d} set={set} bookings={bookings} allBookings={allBookings}/>}
        {step===2 && <StepConfirm d={d}/>}
        <div className="row" style={{justifyContent:'space-between', marginTop:26}}>
          <button className="btn secondary" onClick={back}>
            <Icon name="chevL" size={18}/> {step===0 ? t('book_to_home') : t('back')}
          </button>
          <button className="btn lg" disabled={!canNext} onClick={next}>
            {step===2 ? <>{t('book_confirm')} <Icon name="check" size={20}/></> : <>{t('next')} <Icon name="chevR" size={20}/></>}
          </button>
        </div>
      </div>
    </div>
  );
}

function StepDate({d, set, bookings, allBookings}){
  const lang = window.NN_LANG||'th';
  const groups={};
  NN.openDays().forEach(day=>{ const mk=NN.monthKey(day.key); (groups[mk]=groups[mk]||[]).push(day); });
  return (
    <div>
      <GuideBubble>{t('book_guide1')}</GuideBubble>
      <div className="card pad" style={{marginTop:16}}>
        {Object.entries(groups).map(([mk,days])=>{
          const mi=Number(mk.split('-')[1])-1;
          const yr = Number(mk.split('-')[0]);
          const monthLabel = lang==='en'
            ? `${window.EN_MON_FULL[mi]} ${yr}`
            : `${NN.TH_MON_FULL[mi]} ${yr+543}`;
          return (
            <div key={mk} style={{marginBottom:18}}>
              <div className="row" style={{gap:8, marginBottom:10}}>
                <Icon name="calendar" size={18} style={{color:'var(--accent)'}}/>
                <b style={{fontFamily:'var(--font-display)'}}>{monthLabel}</b>
              </div>
              <div style={{display:'flex', gap:10, flexWrap:'wrap'}}>
                {days.map(day=>{
                  const st=NN.dateState(day.key, bookings, allBookings);
                  const free=NN.dayBookable(day.key, bookings, allBookings);
                  const sel=d.dateKey===day.key;
                  const labels={full:t('date_full'), month:t('date_month'), past:t('date_past'), passed:t('date_passed'), closed:t('date_closed'), ok:`${t('date_ok')} ${free}`};
                  return (
                    <button key={day.key}
                      className={`datecard ${sel?'sel':''} ${day.offset===0?'today':''} ${st.selectable?'':'dim'}`}
                      onClick={()=> st.selectable && set({dateKey:day.key, slot:null})}
                      disabled={!st.selectable} style={{width:96}}>
                      <div className="dow">{day.offset===0 ? t('today') : NN.dowLabel(day.date)}</div>
                      <div className="dnum">{day.dnum}</div>
                      <div className="mon">{lang==='en' ? window.EN_MON[day.date.getMonth()] : day.mon}</div>
                      <div className="st" style={{fontSize:'.66rem', marginTop:4, fontFamily:'var(--font-display)', fontWeight:600,
                        color: sel?'#fff':(st.reason==='ok'?'var(--sage-600)':'var(--bad)')}}>
                        {labels[st.reason]||''}
                      </div>
                    </button>
                  );
                })}
              </div>
            </div>
          );
        })}
        <p className="muted" style={{fontSize:'.85rem', margin:0}}>
          <Icon name="lock" size={13} style={{display:'inline', verticalAlign:'-2px', marginRight:4}}/>
          {t('date_rule')}
        </p>
      </div>
    </div>
  );
}

function StepTime({d, set, bookings, allBookings}){
  return (
    <div>
      <GuideBubble>{t('book_guide2')}</GuideBubble>
      <div className="card pad" style={{marginTop:16}}>
        <div className="row" style={{gap:8, marginBottom:16}}>
          <Icon name="calendar" size={20} style={{color:'var(--accent)'}}/>
          <b style={{fontFamily:'var(--font-display)'}}>{NN.fmtDateLong(d.dateKey)}</b>
        </div>
        <div className="grid cols-2" style={{gap:14}}>
          {NN.SLOTS.map(s=>{
            const free=NN.freeCount(d.dateKey, s.id, bookings, allBookings);
            const state=NN.slotState(d.dateKey, s.id, bookings, allBookings);
            const disabled=state!=='open';
            const sel=d.slot===s.id;
            const sub={
              open:`${t('slot_left')} ${free} ${t('slot_from')} ${NN.CAPACITY} ${t('slot_q')}`,
              full:t('slot_full'),
              passed:t('slot_passed')
            }[state];
            return (
              <button key={s.id} className={`slot ${sel?'sel':''} ${disabled?'full':''}`}
                onClick={()=> !disabled && set({slot:s.id})} disabled={disabled} style={{padding:'20px 12px'}}>
                <span className="tm" style={{fontSize:'1.5rem'}}>{s.start}–{s.end}</span>
                <span className="st" style={{fontSize:'.85rem', marginTop:4}}>{sub}</span>
              </button>
            );
          })}
        </div>
        <p className="muted" style={{fontSize:'.85rem', marginTop:14, marginBottom:0}}>{t('slot_rule')}</p>
      </div>
    </div>
  );
}

function StepConfirm({d}){
  const s=NN.SERVICE;
  const lang=window.NN_LANG||'th';
  const timeStr = NN.slotLabel(d.slot) + (lang==='en' ? '' : ' น.');
  return (
    <div className="fade-in">
      <GuideBubble>{t('book_guide3')}</GuideBubble>
      <div className="card pad-lg" style={{marginTop:16, position:'relative', overflow:'hidden'}}>
        <div style={{maxWidth:'72%'}}>
          <div className="row" style={{gap:14, marginBottom:8}}>
            <SvcTok/>
            <div>
              <h2 style={{fontSize:'1.5rem'}}>{t('bk_service')}</h2>
              <span className="chip ghost"><Icon name="clock" size={14}/> {s.min} {t('min')}</span>
            </div>
          </div>
          <hr className="hr"/>
          <div className="kv"><span className="k"><Icon name="calendar" size={16} style={{display:'inline',verticalAlign:'-3px',marginRight:6}}/>{t('cf_date')}</span><span className="v">{NN.fmtDateLong(d.dateKey)}</span></div>
          <div className="kv"><span className="k"><Icon name="clock" size={16} style={{display:'inline',verticalAlign:'-3px',marginRight:6}}/>{t('cf_time')}</span><span className="v">{timeStr}</span></div>
          <div className="kv"><span className="k"><Icon name="user" size={16} style={{display:'inline',verticalAlign:'-3px',marginRight:6}}/>{t('cf_therapist')}</span><span className="v">{t('cf_auto')}</span></div>
          <div className="kv"><span className="k"><Icon name="pin" size={16} style={{display:'inline',verticalAlign:'-3px',marginRight:6}}/>{t('cf_location')}</span><span className="v">{t('cf_room')}</span></div>
          <div className="card flat pad" style={{marginTop:14, background:'var(--gold-100)', borderColor:'var(--gold-600)', display:'flex', alignItems:'center', gap:10}}>
            <span style={{color:'var(--gold-600)'}}><Icon name="star" size={20}/></span>
            <span style={{fontSize:'.92rem'}}>{t('cf_pts_note')} <b>5 {t('pts')}</b> {lang==='en' ? 'and +5 pts for completing the survey!' : 'และตอบแบบสอบถามหลังนวดรับอีก 5 แต้ม!'}</span>
          </div>
        </div>
        <Mascot w={140} style={{position:'absolute', right:-4, bottom:-12}}/>
      </div>
    </div>
  );
}

/* ============================================================
   MY BOOKINGS
   ============================================================ */
function MyBookings({bookings, onCancel, onSurvey, onBook}){
  const [tab,setTab]=React.useState('up');
  const up=bookings.filter(b=>b.status==='confirmed' && !NN.isPast(b.dateKey)).sort((a,b)=>(a.dateKey+a.slot).localeCompare(b.dateKey+b.slot));
  const past=bookings.filter(b=>b.status==='done').sort((a,b)=>(b.dateKey+b.slot).localeCompare(a.dateKey+a.slot));
  const list=tab==='up'?up:past;
  return (
    <div className="fade-in">
      <div className="row" style={{justifyContent:'space-between', marginBottom:18, flexWrap:'wrap', gap:12}}>
        <h1 style={{fontSize:'1.7rem'}}>{t('mine_title')}</h1>
        <button className="btn" onClick={onBook}><Icon name="plus" size={18}/> {t('book_new')}</button>
      </div>
      <div className="row" style={{gap:8, marginBottom:18}}>
        <button className={`chip ${tab==='up'?'plum':'ghost'}`} style={{cursor:'pointer', fontSize:'.95rem', padding:'.5em 1.1em'}} onClick={()=>setTab('up')}>{t('mine_tab_up')} ({up.length})</button>
        <button className={`chip ${tab==='past'?'plum':'ghost'}`} style={{cursor:'pointer', fontSize:'.95rem', padding:'.5em 1.1em'}} onClick={()=>setTab('past')}>{t('mine_tab_past')} ({past.length})</button>
      </div>
      {list.length===0
        ? <div className="card pad-lg center">
            <Mascot w={130} style={{display:'block', margin:'0 auto'}}/>
            <h3 style={{marginTop:8}}>{tab==='up' ? t('mine_empty_up') : t('mine_empty_pa')}</h3>
            <p className="muted">{tab==='up' ? t('mine_empty_up2') : t('mine_empty_pa2')}</p>
            {tab==='up' && <button className="btn" style={{marginTop:8}} onClick={onBook}><Icon name="plus" size={18}/> {t('mine_book_now')}</button>}
          </div>
        : <div style={{display:'flex', flexDirection:'column', gap:14}}>
            {list.map(b=> <BookingCard key={b.id} b={b} onCancel={onCancel} onSurvey={onSurvey}/>)}
          </div>}
    </div>
  );
}

/* ============================================================
   RANKING
   ============================================================ */
/* Gender avatar — falls back to letter if image missing */
function GenderAvatar({gender, name, size=40, style={}}){
  const [err,setErr]=React.useState(false);
  if(gender && gender!=='other' && !err){
    return <img src={`assets/avatar-${gender}.webp`} alt={gender}
      style={{width:size,height:size,borderRadius:'50%',objectFit:'cover',border:'2.5px solid var(--ink)',flexShrink:0,...style}}
      onError={()=>setErr(true)}/>;
  }
  return (
    <div className="avatar" style={{width:size,height:size,fontSize:size>44?'1.3rem':'1rem',...style}}>
      {(name||'?').slice(0,1)}
    </div>
  );
}

function Ranking({pointState, points, lbData}){
  // lbData = from Supabase; fall back to in-memory if not provided
  const lb = lbData || NN.leaderboard(pointState);
  const me=lb.find(r=>r.me);
  const bd=NN.pointsBreakdown(pointState);
  const medal=['var(--gold)','#B9B3A7','#C98A5B'];
  const fullName=(r)=>`${r.thai_firstname||r.english_firstname||''} ${r.thai_lastname||r.english_lastname||''}`.trim() || r.name;
  const rules=[
    {ic:'sun',    t:t('rk_rule1'), p:'+1', got:bd.login},
    {ic:'cal_plus',t:t('rk_rule2'), p:'+5', got:bd.book},
    {ic:'star',   t:t('rk_rule3'), p:'+5', got:bd.survey},
    {ic:'heart',  t:t('rk_rule4'), p:'+1', got:bd.like},
  ];
  return (
    <div className="fade-in">
      <div className="row" style={{gap:10, marginBottom:6}}>
        <span style={{color:'var(--gold-600)'}}><Icon name="trophy" size={26}/></span>
        <h1 style={{fontSize:'1.7rem'}}>{t('rk_title')}</h1>
      </div>
      <p className="muted" style={{marginTop:0, marginBottom:18}}>{t('rk_sub')}</p>

      <div className="grid cols-3 podium" style={{marginBottom:18, alignItems:'end'}}>
        {[1,0,2].map(rankIdx=>{
          const r=lb[rankIdx]; if(!r) return <div key={rankIdx}></div>;
          const place=rankIdx+1;
          const big=place===1;
          return (
            <div key={r.id} className="card pad" style={{textAlign:'center', borderColor:medal[rankIdx],
              background:r.me?'var(--accent-50)':'var(--paper)', transform:big?'translateY(-8px)':'none'}}>
              <div style={{position:'relative', width:big?72:58, height:big?72:58, margin:'0 auto 8px'}}>
                <GenderAvatar gender={r.gender} name={r.name} size={big?72:58}
                  style={{background:r.me?'var(--accent)':medal[rankIdx]}}/>
                <div style={{position:'absolute', bottom:-6, right:-6, color:medal[rankIdx]}}><Icon name="medal" size={big?26:22}/></div>
              </div>
              <div style={{fontFamily:'var(--font-display)', fontWeight:700, fontSize:big?'1.15rem':'1rem'}}>{r.name}{r.me?' '+t('rk_you'):''}</div>
              <div className="muted" style={{fontSize:'.78rem'}}>{fullName(r)}</div>
              <div style={{fontFamily:'var(--font-display)', fontWeight:800, fontSize:big?'1.8rem':'1.5rem', color:'var(--gold-600)', marginTop:6}}>{r.pts}</div>
              <div className="muted" style={{fontSize:'.74rem'}}>{t('rk_pts')} · {t('rk_rank')} {place}</div>
            </div>
          );
        })}
      </div>

      <div className="card pad">
        {lb.map(r=>(
          <div key={r.id} className="row" style={{gap:14, padding:'12px 4px', borderBottom:r.rank<lb.length?'2px solid var(--cream-200)':'none',
            background:r.me?'var(--accent-50)':'transparent', borderRadius:r.me?'var(--r-md)':0, paddingLeft:r.me?12:4, paddingRight:r.me?12:4}}>
            <div style={{width:30, textAlign:'center', fontFamily:'var(--font-display)', fontWeight:800, fontSize:'1.1rem',
              color:r.rank<=3?'var(--gold-600)':'var(--ink-300)'}}>{r.rank}</div>
            <GenderAvatar gender={r.gender} name={r.name} size={40}
              style={{background:r.me?'var(--accent)':'var(--cream-200)', color:r.me?'#fff':'var(--ink-500)'}}/>
            <div style={{flex:1, minWidth:0}}>
              <div style={{fontFamily:'var(--font-display)', fontWeight:600}}>{r.name}{r.me?' '+t('rk_you'):''}</div>
              <div className="muted" style={{fontSize:'.8rem'}}>{fullName(r)}</div>
            </div>
            <div className="chip gold"><Icon name="star" size={13}/> {r.pts}</div>
          </div>
        ))}
      </div>

      <div className="card pad" style={{marginTop:16}}>
        <div className="row" style={{gap:10, marginBottom:14}}>
          <Mascot w={56} bob={false}/>
          <div>
            <b style={{fontFamily:'var(--font-display)', fontSize:'1.15rem'}}>{t('rk_how')}</b>
            <div className="muted" style={{fontSize:'.85rem'}}>{t('rk_how_sub')}</div>
          </div>
        </div>
        <div className="grid cols-2" style={{gap:10}}>
          {rules.map((r,i)=>(
            <div key={i} className="card flat" style={{display:'flex', alignItems:'center', gap:12, padding:'12px 14px'}}>
              <span style={{color:'var(--accent)', flex:'0 0 auto'}}><Icon name={r.ic} size={22}/></span>
              <div style={{flex:1, minWidth:0}}>
                <div style={{fontFamily:'var(--font-display)', fontWeight:600, fontSize:'.95rem'}}>{r.t}</div>
                <div className="muted" style={{fontSize:'.78rem'}}>{t('rk_earned')} {r.got} {t('rk_pts')}</div>
              </div>
              <span className="chip gold" style={{flex:'0 0 auto'}}>{r.p}</span>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { GenderAvatar, Stepper, GuideBubble, BookingFlow, StepDate, StepTime, StepConfirm, MyBookings, Ranking });
