/* ============================================================
   Shipstar landing — embedded calculator + offer band + claim modal
   Pure client-side ESTIMATES. Rate assumptions in CONST block.
   ============================================================ */
const { useState:useStateLC, useEffect:useEffectLC, useRef:useRefLC } = React;

/* ---- editable rate assumptions (estimates) ---- */
const RATES = {
  freightPerKg: { air_express:7.5, air_economy:5.0 },   // $/kg
  seaPerCbm: 220,            // $/CBM (LCL), min 1 CBM
  fclFlat: 4200,             // $/40ft container
  volumetricDivisor: 5000,   // cm³ → kg
  lastMile: { East:6.5, Central:5.4, West:4.6 },         // $/order base
  lastMilePerKg: 0.9,
  mpf: 0.003464,             // merchandise processing fee
  hmf: 0.00125,              // harbor maintenance (sea only)
  duty: { 'Ceramics & home':0.06, 'Apparel & textiles':0.12, 'Beauty & cosmetics':0.03,
          'Food & beverage':0.05, 'Electronics':0.0, 'Furniture':0.04, 'Other':0.05 },
  // savings model
  diy: { lease:4500, staff:6000, software:400, brokerRetainer:800, setup:15000, carrierPerOrder:9.2 },
  plans: { Starter:{ perOrder:5.4, storagePerUnit:0.42 }, Growth:{ perOrder:4.3, storagePerUnit:0.34 }, Scale:{ perOrder:3.6, storagePerUnit:0.28 } },
};

/* tween a number from previous → new value */
function useTween(target, dur=440){
  const [v,setV] = useStateLC(target); const prev = useRefLC(target);
  useEffectLC(()=>{
    const reduce = matchMedia('(prefers-reduced-motion:reduce)').matches;
    const from = prev.current, to = target; prev.current = target;
    if(reduce || from===to){ setV(to); return; }
    const t0 = Date.now();
    const id = setInterval(()=>{
      const p = Math.min(1,(Date.now()-t0)/dur); const e = 1-Math.pow(1-p,3);
      setV(from+(to-from)*e); if(p>=1) clearInterval(id);
    }, 1000/60);
    return ()=>clearInterval(id);
  },[target]);
  return v;
}
const money = (n,d=0)=>'$'+Number(n).toLocaleString('en-US',{minimumFractionDigits:d,maximumFractionDigits:d});

function Slider({ label, value, min, max, step, onChange, fmt }){
  const pct = ((value-min)/(max-min))*100;
  return (
    <div style={{marginBottom:16}}>
      <div style={{display:'flex',justifyContent:'space-between',alignItems:'baseline',marginBottom:7}}>
        <span style={{fontSize:12.5,fontWeight:550,color:'var(--fg-2)'}}>{label}</span>
        <span style={{fontFamily:'var(--font-tight)',fontWeight:700,fontSize:14,fontVariantNumeric:'tabular-nums'}}>{fmt?fmt(value):value}</span>
      </div>
      <input type="range" min={min} max={max} step={step} value={value} onChange={e=>onChange(+e.target.value)}
        className="lc-range" style={{background:`linear-gradient(90deg,var(--brand) ${pct}%,var(--bg-2) ${pct}%)`}} />
    </div>
  );
}

/* ============ The calculator (two modes) ============ */
function SavingsCalculator(){
  const [mode,setMode] = useStateLC('savings');
  return (
    <div className="lc-card" id="calculator">
      <div className="lc-modes">
        <button className={mode==='savings'?'on':''} onClick={()=>setMode('savings')}>My savings</button>
        <button className={mode==='shipping'?'on':''} onClick={()=>setMode('shipping')}>Shipping cost</button>
      </div>
      {mode==='savings' ? <SavingsMode /> : <ShippingMode />}
      <div className="lc-foot">
        <span className="lc-estimate">Estimates — final pricing confirmed at quote.</span>
        <Button variant="brand" iconRight="arrowR" onClick={()=>{ location.hash='#offer'; toast('Let\u2019s get you a quote','green'); }}>Get my exact quote</Button>
      </div>
    </div>
  );
}

function SavingsMode(){
  const [vol,setVol] = useStateLC(1200);
  const [upo,setUpo] = useStateLC(2);
  const [plan,setPlan] = useStateLC('Growth');
  const [open,setOpen] = useStateLC(false);
  const d = RATES.diy, p = RATES.plans[plan];

  const diyFixed = d.lease + d.staff + d.software + d.brokerRetainer;
  const diyMonthly = diyFixed + vol*d.carrierPerOrder + d.setup/12;       // amortize setup over yr1
  const ssMonthly = vol*p.perOrder + vol*upo*p.storagePerUnit*2.0;         // per-order + storage
  const save = Math.max(0, diyMonthly - ssMonthly);
  const annual = save*12;

  const tDiy = useTween(diyMonthly), tSs = useTween(ssMonthly), tSave = useTween(save), tAnnual = useTween(annual);

  // 12-month cumulative paths
  const W=520,H=170, months=12;
  const diyCum = i=> d.setup + diyMonthly*(i+1);
  const ssCum  = i=> ssMonthly*(i+1);
  const maxY = diyCum(months-1)*1.05;
  const px = i=> (i/(months-1))*W;
  const py = v=> H-6-(v/maxY)*(H-16);
  const path = (fn)=> Array.from({length:months}).map((_,i)=>(i?'L':'M')+px(i).toFixed(1)+' '+py(fn(i)).toFixed(1)).join(' ');

  return (
    <div>
      <div className="lc-grid">
        <div>
          <Slider label="Monthly orders" value={vol} min={100} max={8000} step={50} onChange={setVol} fmt={v=>v.toLocaleString()} />
          <Slider label="Avg units / order" value={upo} min={1} max={8} step={1} onChange={setUpo} />
          <div style={{marginTop:4}}>
            <div style={{fontSize:12.5,fontWeight:550,color:'var(--fg-2)',marginBottom:7}}>Shipstar plan</div>
            <div className="lc-seg">
              {['Starter','Growth','Scale'].map(pl=>(
                <button key={pl} className={plan===pl?'on':''} onClick={()=>setPlan(pl)}>{pl}</button>))}
            </div>
          </div>
          <button className="lc-how" onClick={()=>setOpen(o=>!o)}>
            <Icon name={open?'x':'info'} size={13} /> How we calculate this
          </button>
          {open &&
            <div className="lc-assume">
              DIY assumes US warehouse {money(d.lease)}/mo · staff {money(d.staff)}/mo · software {money(d.software)}/mo ·
              customs broker {money(d.brokerRetainer)}/mo · carrier {money(d.carrierPerOrder,2)}/order (no volume discount) ·
              one-time setup {money(d.setup)}. Shipstar {plan}: {money(p.perOrder,2)}/order + storage {money(p.storagePerUnit,2)}/unit.
            </div>}
        </div>

        <div className="lc-out">
          <div className="lc-save">
            <div className="lc-save-lbl">You'd save</div>
            <div className="lc-save-num">{money(tSave)}<span>/mo</span></div>
            <div className="lc-save-yr">{money(tAnnual)} a year</div>
          </div>
          <div className="lc-compare">
            <div className="lc-cmp"><span>Doing it yourself</span><b>{money(tDiy)}<i>/mo</i></b></div>
            <div className="lc-cmp ss"><span>With Shipstar</span><b>{money(tSs)}<i>/mo</i></b></div>
          </div>
        </div>
      </div>

      <div className="lc-chart">
        <div className="lc-chart-head">
          <span>12-month cumulative cost</span>
          <span className="lc-legend"><i className="diy" />Do it yourself <i className="ss" />Shipstar</span>
        </div>
        <svg viewBox={`0 0 ${W} ${H}`} width="100%" height={H} preserveAspectRatio="none" aria-hidden="true">
          <path d={path(diyCum)+` L ${W} ${H} L 0 ${H} Z`} fill="rgba(200,54,47,.06)" />
          <path className="lc-line" d={path(diyCum)} fill="none" stroke="var(--red)" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round" />
          <path className="lc-line" d={path(ssCum)} fill="none" stroke="var(--green)" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round" />
        </svg>
        <div className="lc-take">You'd save ~<b>{money(annual)}</b>/year and skip <b>{money(d.setup)}</b> in upfront setup.</div>
      </div>
    </div>
  );
}

function ShippingMode(){
  const [wt,setWt] = useStateLC(0.8);
  const [units,setUnits] = useStateLC(1200);
  const [L,setL]=useStateLC(20),[Wd,setWd]=useStateLC(15),[Hd,setHd]=useStateLC(10);
  const [shipMode,setShipMode] = useStateLC('air_economy');
  const [zone,setZone] = useStateLC('West');
  const [cat,setCat] = useStateLC('Ceramics & home');
  const [open,setOpen] = useStateLC(false);

  const vol = (L*Wd*Hd)/RATES.volumetricDivisor;
  const billW = Math.max(wt, vol);
  let freightUnit;
  if(shipMode==='sea_lcl') freightUnit = (RATES.seaPerCbm * (L*Wd*Hd/1e6));
  else if(shipMode==='sea_fcl') freightUnit = RATES.fclFlat/Math.max(units,1);
  else freightUnit = billW * RATES.freightPerKg[shipMode];
  const price = 28; // assumed customs value/unit
  const dutyUnit = price * (RATES.duty[cat]||0);
  const isSea = shipMode.startsWith('sea');
  const feesUnit = price*RATES.mpf + (isSea?price*RATES.hmf:0);
  const lastMile = RATES.lastMile[zone] + billW*RATES.lastMilePerKg;
  const landed = freightUnit + dutyUnit + feesUnit + lastMile;

  const tLanded=useTween(landed), tMonth=useTween(landed*units);
  const parts=[['Freight',freightUnit,'var(--brand)'],['Duty',dutyUnit,'var(--amber)'],['Fulfillment',lastMile,'var(--blue)'],['Fees',feesUnit,'var(--fg-3)']];
  const sum=parts.reduce((a,b)=>a+b[1],0)||1;

  return (
    <div>
      <div className="lc-grid">
        <div>
          <Slider label="Weight / unit" value={wt} min={0.1} max={20} step={0.1} onChange={setWt} fmt={v=>v.toFixed(1)+' kg'} />
          <Slider label="Units / month" value={units} min={50} max={10000} step={50} onChange={setUnits} fmt={v=>v.toLocaleString()} />
          <div style={{display:'flex',gap:8,marginBottom:14}}>
            {[['L',L,setL],['W',Wd,setWd],['H',Hd,setHd]].map(([lb,val,set])=>(
              <div key={lb} style={{flex:1}}>
                <div style={{fontSize:11,color:'var(--fg-3)',marginBottom:4,fontWeight:600}}>{lb} (cm)</div>
                <input className="inp" type="number" value={val} onChange={e=>set(+e.target.value||0)} style={{height:34,padding:'0 9px'}} />
              </div>))}
          </div>
          <div className="lc-seg" style={{marginBottom:12}}>
            {[['air_express','Air exp'],['air_economy','Air eco'],['sea_lcl','Sea LCL'],['sea_fcl','Sea FCL']].map(([k,l])=>(
              <button key={k} className={shipMode===k?'on':''} onClick={()=>setShipMode(k)}>{l}</button>))}
          </div>
          <div style={{display:'flex',gap:8}}>
            <select className="inp" value={zone} onChange={e=>setZone(e.target.value)} style={{height:38}}>
              {['East','Central','West'].map(z=><option key={z}>{z}</option>)}
            </select>
            <select className="inp" value={cat} onChange={e=>setCat(e.target.value)} style={{height:38}}>
              {Object.keys(RATES.duty).map(c=><option key={c}>{c}</option>)}
            </select>
          </div>
          <button className="lc-how" onClick={()=>setOpen(o=>!o)}><Icon name={open?'x':'info'} size={13} /> How we calculate this</button>
          {open && <div className="lc-assume">Billed on the greater of actual vs volumetric weight (L·W·H/5000). MPF ~0.3464%, HMF ~0.125% (sea only). Duty by HS category. Last-mile varies by US/CA zone + weight.</div>}
        </div>

        <div className="lc-out">
          <div className="lc-save">
            <div className="lc-save-lbl">All-in landed / unit</div>
            <div className="lc-save-num">{money(tLanded,2)}</div>
            <div className="lc-save-yr">{money(tMonth)} / month · {units.toLocaleString()} units</div>
          </div>
          <div className="lc-bar">
            {parts.map((p,i)=><div key={i} style={{width:(p[1]/sum*100)+'%',background:p[2]}} title={p[0]} />)}
          </div>
          <div className="lc-bar-key">
            {parts.map((p,i)=><span key={i}><i style={{background:p[2]}} />{p[0]} {money(p[1],2)}</span>)}
          </div>
        </div>
      </div>
    </div>
  );
}

/* ============ Offer band + claim modal ============ */
function OfferBand(){
  const [struck,setStruck] = useStateLC(false);
  const [claim,setClaim] = useStateLC(false);
  const ref = useRefLC(null);
  useEffectLC(()=>{
    const el = ref.current; if(!el) return;
    const io = new IntersectionObserver(es=>{ if(es[0].isIntersecting){ setStruck(true); io.disconnect(); } },{threshold:0.4});
    io.observe(el); return ()=>io.disconnect();
  },[]);
  return (
    <div className="offer-band" id="offer" ref={ref}>
      <div className="offer-inner">
        <div className="offer-eyebrow">Limited — new sellers</div>
        <h2 className="offer-h">Your first year on Growth is on us.</h2>
        <p className="offer-sub">Growth normally costs $1,200/year. New Shipstar sellers get <b>12 months free</b> — full fulfillment dashboard, analytics, and priority onboarding.</p>
        <div className="offer-price">
          <span className={'offer-old'+(struck?' struck':'')}>$1,200<i className="strike" /></span>
          <Icon name="arrowR" size={20} style={{color:'var(--brand-deep)'}} />
          <span className="offer-new">$0<small>year one</small></span>
        </div>
        <Button variant="brand" size="lg" onClick={()=>setClaim(true)}>Claim your free year</Button>
        <div className="offer-fine">New sellers only. Applies to the Growth plan. Standard per-order fulfillment &amp; shipping rates apply.</div>
        <div className="offer-spots"><span className="dot" /> 38 spots claimed this month</div>
      </div>
      {claim && <ClaimModal onClose={()=>setClaim(false)} />}
    </div>
  );
}

function ClaimModal({ onClose }){  const [brand,setBrand]=useStateLC(''); const [email,setEmail]=useStateLC('');
  const [busy,setBusy]=useStateLC(false); const [done,setDone]=useStateLC(false);
  const submit=()=>{ if(!brand||!email) return; setBusy(true); setTimeout(()=>{ setBusy(false); setDone(true); },900); };
  return (
    <Modal size="sm" onClose={onClose} icon={done?'check':'bolt'} iconTone={done?'green':'brand'}
      eyebrow="Growth · year one free" title={done?"You're in 🎉":'Claim your free year'}
      subtitle={done?null:'Tell us where to set it up. Takes 30 seconds.'}
      footer={done
        ? <Button variant="primary" block onClick={onClose}>Done</Button>
        : <><Button variant="ghost" onClick={onClose}>Cancel</Button><Button variant="brand" loading={busy} onClick={submit}>Claim free year</Button></>}>
      {done
        ? <div style={{textAlign:'center',padding:'4px 0'}}>
            <div style={{fontSize:14,color:'var(--fg-2)',lineHeight:1.5}}>Year 1 free on <b>Growth</b> is applied for <b>{brand}</b>. We'll email setup steps to {email} and map your US &amp; Canada launch on your onboarding call.</div>
          </div>
        : <>
            <Field label="Brand name"><input className="inp" value={brand} onChange={e=>setBrand(e.target.value)} placeholder="e.g. Saigon Ceramics Co." /></Field>
            <Field label="Work email" hint="We'll send your setup link here."><input className="inp" type="email" value={email} onChange={e=>setEmail(e.target.value)} placeholder="you@brand.vn" /></Field>
          </>}
    </Modal>
  );
}

Object.assign(window, { SavingsCalculator, OfferBand, ClaimModal, OfferBanner });

/* ---- compact dismissible in-app banner version (for seller dashboard top) ---- */
function OfferBanner({ onDismiss }){
  const [claim,setClaim] = useStateLC(false);
  const [gone,setGone] = useStateLC(false);
  if(gone) return null;
  return (
    <div className="offer-banner">
      <span className="ob-ic"><Icon name="bolt" size={16} /></span>
      <div className="ob-txt"><b>Your first year on Growth is free.</b> <span>Normally $1,200/yr — applied on your onboarding call.</span></div>
      <Button variant="brand" size="sm" onClick={()=>setClaim(true)}>Claim</Button>
      <button className="ob-x" onClick={()=>{ setGone(true); onDismiss&&onDismiss(); }} aria-label="Dismiss"><Icon name="x" size={15} /></button>
      {claim && <ClaimModal onClose={()=>setClaim(false)} />}
    </div>
  );
}
Object.assign(window, { OfferBanner });
