/* ============================================================
   Speed Assessment App — live demo component
   Adapted from SpeedAssessmentApp_1772155208389.jsx:
   - Removed ES module syntax (no imports/exports)
   - React.useState instead of useState
   - Demo-friendly defaults (samplePrefill tweak)
   - VIP lock preserved
   ============================================================ */

const SA_VIP_CODE = "VIPSKOOL";
const SA_FREE_TESTS = ["sprint20m", "cmj"];
const SA_LOCKED_TESTS = ["flying30"];

const SA_SPORTS = {
  soccer:     { label: "Soccer / Football",         color: "#16a34a", glow: "#4ade80" },
  afl:        { label: "Australian Rules Football", color: "#1d4ed8", glow: "#60a5fa" },
  basketball: { label: "Basketball",                color: "#c2410c", glow: "#fb923c" },
  rugby:      { label: "Rugby Union / League",      color: "#9f1239", glow: "#fb7185" },
  athletics:  { label: "Track & Field / Sprinting", color: "#7c3aed", glow: "#c084fc" },
  netball:    { label: "Netball",                   color: "#0891b2", glow: "#22d3ee" },
  amfootball: { label: "American Football",         color: "#92400e", glow: "#fbbf24" },
  baseball:   { label: "Baseball / Softball",       color: "#166534", glow: "#86efac" },
  tennis:     { label: "Tennis",                    color: "#0e7490", glow: "#67e8f9" },
};

// Compact benchmark tables — a representative subset across ages for the demo
// (full dataset is in the production app; this preserves the gauge behaviour)
const SA_DATA_20M = {
  soccer:     { male:{14:[2.98,3.12,3.32,3.55],16:[2.88,3.00,3.18,3.42],17:[2.84,2.97,3.14,3.38],18:[2.82,2.94,3.10,3.34],20:[2.78,2.90,3.06,3.30],22:[2.76,2.88,3.04,3.28]}, female:{14:[3.22,3.38,3.56,3.82],16:[3.12,3.28,3.46,3.72],17:[3.10,3.26,3.44,3.70],18:[3.08,3.24,3.42,3.68],20:[3.06,3.22,3.40,3.66]}, note:"Nikolaidis et al. (2016) Biol Sport; Emmonds et al. (2020)" },
  afl:        { male:{14:[3.10,3.28,3.50,3.80],16:[2.98,3.12,3.35,3.62],17:[2.94,3.08,3.30,3.58],18:[2.91,3.05,3.26,3.55],20:[2.85,2.98,3.18,3.46],22:[2.82,2.95,3.12,3.40]}, female:null, note:"Haycraft et al. (2017); AFL Draft Combine (Pyne et al. 2005)" },
  basketball: { male:{14:[3.08,3.24,3.44,3.70],16:[2.90,3.06,3.24,3.50],17:[2.85,2.99,3.18,3.44],18:[2.82,2.96,3.14,3.40],20:[2.78,2.92,3.10,3.36],22:[2.75,2.89,3.06,3.32]}, female:{14:[3.22,3.40,3.60,3.86],16:[3.10,3.27,3.46,3.72],17:[3.06,3.23,3.42,3.68],18:[3.04,3.20,3.39,3.65],20:[3.02,3.18,3.37,3.62]}, note:"Ben Abdelkrim et al. (2010) JSCR; Drinkwater et al. (2008) IJSPP" },
  rugby:      { male:{14:[3.00,3.16,3.34,3.60],16:[2.86,3.01,3.18,3.44],17:[2.80,2.95,3.12,3.38],18:[2.76,2.91,3.07,3.33],20:[2.72,2.86,3.02,3.28],22:[2.68,2.82,2.98,3.24]}, female:{14:[3.18,3.35,3.55,3.82],16:[3.07,3.24,3.42,3.69],17:[3.03,3.20,3.38,3.65],18:[3.00,3.16,3.35,3.61],20:[2.96,3.12,3.30,3.56]}, note:"Gabbett et al. (2007); Baker & Newton (2008)" },
  athletics:  { male:{14:[2.72,2.86,3.04,3.30],16:[2.60,2.74,2.90,3.16],17:[2.56,2.70,2.86,3.12],18:[2.52,2.66,2.82,3.08],20:[2.48,2.62,2.77,3.03],22:[2.46,2.60,2.75,3.01]}, female:{14:[2.86,3.02,3.20,3.46],16:[2.78,2.92,3.10,3.36],17:[2.76,2.90,3.07,3.33],18:[2.74,2.88,3.05,3.31],20:[2.70,2.84,3.01,3.27]}, note:"Haugen et al. (2019); Holmberg (2015)" },
  netball:    { male:null, female:{14:[3.55,3.74,3.96,4.22],16:[3.42,3.60,3.82,4.08],17:[3.38,3.56,3.77,4.03],18:[3.34,3.52,3.73,3.98],20:[3.28,3.46,3.67,3.92]}, note:"Thomas et al. (2017); Sinclair et al. (2020)" },
  amfootball: { male:{14:[3.32,3.50,3.72,4.00],16:[3.16,3.34,3.55,3.82],17:[3.10,3.28,3.48,3.75],18:[3.05,3.22,3.42,3.68],20:[2.96,3.12,3.32,3.58],22:[2.90,3.06,3.25,3.51]}, female:{14:[3.52,3.72,3.94,4.22],16:[3.38,3.58,3.80,4.08],17:[3.32,3.52,3.74,4.01],18:[3.28,3.47,3.69,3.96]}, note:"McKay et al. (2020); NFL Combine data" },
  baseball:   { male:{14:[3.40,3.58,3.78,4.05],16:[3.25,3.42,3.62,3.88],17:[3.18,3.35,3.55,3.80],18:[3.12,3.29,3.48,3.74],20:[3.03,3.20,3.38,3.64],22:[2.97,3.13,3.31,3.57]}, female:{14:[3.55,3.74,3.96,4.22],16:[3.42,3.61,3.82,4.08],17:[3.37,3.56,3.77,4.02],18:[3.33,3.52,3.73,3.98]}, note:"Hoffman et al. (2009); MLB Statcast" },
  tennis:     { male:{14:[3.04,3.20,3.38,3.64],16:[2.92,3.07,3.24,3.50],17:[2.88,3.03,3.20,3.46],18:[2.85,3.00,3.17,3.43],20:[2.81,2.95,3.12,3.38]}, female:{14:[3.20,3.38,3.58,3.85],16:[3.09,3.26,3.46,3.72],17:[3.06,3.23,3.42,3.68],18:[3.04,3.21,3.40,3.66]}, note:"Lambrich & Muehlbauer (2022); Ulbricht et al. (2016)" },
};

const SA_DATA_F30 = {
  soccer:     { male:{16:[3.28,3.46,3.65,3.92],17:[3.22,3.40,3.58,3.85],18:[3.18,3.35,3.54,3.80],20:[3.12,3.28,3.47,3.72]}, female:{16:[3.50,3.70,3.92,4.20],17:[3.46,3.65,3.87,4.15],18:[3.42,3.61,3.83,4.10]}, note:"Haugen et al. (2014); Portes et al. (2023)" },
  afl:        { male:{16:[3.22,3.38,3.58,3.84],17:[3.16,3.32,3.52,3.78],18:[3.12,3.28,3.47,3.73],20:[3.05,3.20,3.39,3.65]}, female:null, note:"Pyne et al. (2005); AFL Draft Combine" },
  basketball: { male:{16:[3.28,3.45,3.65,3.92],17:[3.22,3.38,3.58,3.84],18:[3.18,3.34,3.53,3.79],20:[3.10,3.26,3.45,3.71]}, female:{16:[3.48,3.68,3.90,4.18],17:[3.44,3.63,3.85,4.12],18:[3.40,3.59,3.80,4.08]}, note:"Drinkwater et al. (2008); Ostojic et al. (2006)" },
  rugby:      { male:{16:[3.14,3.32,3.53,3.80],17:[3.08,3.26,3.46,3.73],18:[3.02,3.20,3.40,3.66],20:[2.95,3.12,3.32,3.58]}, female:{16:[3.35,3.55,3.78,4.06],17:[3.30,3.50,3.72,4.00],18:[3.26,3.45,3.67,3.94]}, note:"Gabbett et al. (2007); Baker & Newton (2008)" },
  athletics:  { male:{16:[2.96,3.13,3.32,3.60],17:[2.90,3.07,3.26,3.53],18:[2.84,3.01,3.19,3.46],20:[2.76,2.92,3.10,3.37]}, female:{16:[3.14,3.34,3.56,3.84],17:[3.08,3.27,3.48,3.76],18:[3.04,3.22,3.43,3.70]}, note:"Haugen et al. (2019); Mackala & Mero (2013)" },
  netball:    { male:null, female:{16:[3.42,3.60,3.82,4.08],17:[3.38,3.56,3.77,4.03],18:[3.34,3.52,3.73,3.98]}, note:"Thomas et al. (2017); Sinclair et al. (2020)" },
  amfootball: { male:{16:[3.16,3.34,3.55,3.82],17:[3.10,3.28,3.48,3.75],18:[3.05,3.22,3.42,3.68],20:[2.96,3.12,3.32,3.58]}, female:{16:[3.38,3.58,3.80,4.08],17:[3.32,3.52,3.74,4.01],18:[3.28,3.47,3.69,3.96]}, note:"McKay et al. (2020); Clark et al. (2019)" },
  baseball:   { male:{16:[3.25,3.42,3.62,3.88],17:[3.18,3.35,3.55,3.80],18:[3.12,3.29,3.48,3.74],20:[3.03,3.20,3.38,3.64]}, female:{16:[3.42,3.61,3.82,4.08],17:[3.37,3.56,3.77,4.02],18:[3.33,3.52,3.73,3.98]}, note:"Hoffman et al. (2009); Mangine et al. (2013)" },
  tennis:     { male:{16:[3.24,3.42,3.62,3.90],17:[3.18,3.36,3.56,3.83],18:[3.14,3.32,3.51,3.78],20:[3.08,3.25,3.44,3.71]}, female:{16:[3.42,3.61,3.82,4.10],17:[3.38,3.57,3.78,4.05],18:[3.35,3.54,3.75,4.01]}, note:"Lambrich & Muehlbauer (2022); Ulbricht et al. (2016)" },
};

const SA_DATA_CMJ = {
  soccer:     { male:{14:[43,37,31,24],16:[48,41,35,28],17:[50,43,37,29],18:[52,45,38,30],20:[54,47,40,32]}, female:{14:[32,27,22,17],16:[35,30,25,19],17:[36,31,26,20],18:[37,32,27,21]}, note:"VALD ForceDecks; Nikolaidis et al. (2016)" },
  afl:        { male:{14:[45,38,31,24],16:[51,43,36,28],17:[53,45,38,30],18:[55,47,40,31],20:[58,50,42,33]}, female:null, note:"AFL Draft Combine; Mooney et al. (2011)" },
  basketball: { male:{14:[44,37,30,23],16:[50,43,36,28],17:[53,45,38,30],18:[55,47,40,31],20:[58,50,43,34]}, female:{14:[30,25,20,15],16:[35,29,24,18],17:[37,31,26,20],18:[38,32,27,21]}, note:"Ben Abdelkrim et al. (2010); Ziv & Lidor (2010)" },
  rugby:      { male:{16:[49,41,34,27],17:[52,44,37,29],18:[54,46,39,31],20:[58,50,43,34]}, female:{16:[32,26,21,16],17:[33,27,22,17],18:[34,28,23,18]}, note:"Argus et al. (2012); Baker & Newton (2008)" },
  athletics:  { male:{14:[46,39,32,25],16:[54,46,39,31],17:[57,49,42,33],18:[60,52,44,35],20:[63,55,47,37]}, female:{14:[34,28,23,17],16:[39,33,27,21],17:[41,35,29,22],18:[43,36,30,23]}, note:"Markovic et al. (2004); Haugen et al. (2019)" },
  netball:    { male:null, female:{14:[30,25,20,15],16:[34,28,23,18],17:[36,30,25,19],18:[38,32,26,20]}, note:"Thomas et al. (2017); Forster et al. (2022)" },
  amfootball: { male:{14:[52,43,35,26],16:[59,49,40,30],17:[62,52,43,32],18:[65,54,45,34],20:[70,59,49,37]}, female:{14:[32,26,21,16],16:[36,30,25,18],17:[38,31,26,19],18:[39,33,27,20]}, note:"McKay et al. (2020); Frank et al. (2023)" },
  baseball:   { male:{14:[48,40,33,26],16:[54,46,38,30],17:[57,49,41,32],18:[60,52,44,34],20:[65,56,47,37]}, female:{14:[30,25,20,15],16:[35,29,24,18],17:[37,31,26,19],18:[38,32,27,20]}, note:"Hoffman et al. (2009); Mangine et al. (2013)" },
  tennis:     { male:{14:[34,28,22,16],16:[42,35,28,21],17:[45,38,31,23],18:[48,40,33,25],20:[52,44,36,27]}, female:{14:[27,21,17,12],16:[31,25,20,14],17:[33,27,22,15],18:[34,28,23,16]}, note:"Lambrich & Muehlbauer (2022); Kramer et al. (2016)" },
};

const SA_LEVELS = ["Elite / Professional","Semi-Pro / State","Academy / Dev","Recreational"];
const SA_LEVEL_COLORS = ["#22c55e","#84cc16","#eab308","#ef4444"];
const SA_LEVEL_SHORT = ["Elite","Semi-Pro","Academy","Rec"];
const SA_RATING_MSGS = [
  { emoji:"🏆", text:"Top ~2% of players at this age & sport" },
  { emoji:"⚡", text:"Top 20% — competitive semi-professional level" },
  { emoji:"📈", text:"Solid development level — targeted training can elevate this" },
  { emoji:"🎯", text:"Recreational level — structured coaching recommended" },
  { emoji:"💪", text:"Below recreational — focused training strongly recommended" },
];

const SA_TEST_CONFIG = {
  sprint20m: { label:"20m Sprint",    emoji:"🏃", unit:"s",   isSprint:true,  placeholder:"e.g. 2.95", step:"0.01", hint:"Standing start, timing gates. Lower = faster." },
  flying30:  { label:"Flying 30m",    emoji:"⚡", unit:"s",   isSprint:true,  placeholder:"e.g. 3.15", step:"0.01", hint:"30m rolling run-up. Lower = faster." },
  cmj:       { label:"Vertical Jump", emoji:"🦘", unit:" cm", isSprint:false, placeholder:"e.g. 45",   step:"1",    hint:"Countermovement jump, hands on hips. Higher = better." },
};

function saGetDataset(t) {
  if (t === "sprint20m") return SA_DATA_20M;
  if (t === "flying30")  return SA_DATA_F30;
  return SA_DATA_CMJ;
}
function saClosestAge(ageData, age) {
  const ages = Object.keys(ageData).map(Number).sort((a,b)=>a-b);
  return ages.reduce((p,c)=>Math.abs(c-age)<Math.abs(p-age)?c:p, ages[0]);
}
function saGetRating(val, bm, isSprint) {
  if (!bm || val === "" || val === null || val === undefined) return null;
  const v = parseFloat(val);
  for (let i=0;i<4;i++) {
    if (isSprint ? v<=bm[i] : v>=bm[i]) return i;
  }
  return 4;
}

function SAGaugeBar({ value, benchmarks, isSprint }) {
  if (value === "" || value === null || !benchmarks) return null;
  const lo = isSprint ? benchmarks[0]-0.15 : benchmarks[3]-8;
  const hi = isSprint ? benchmarks[3]+0.25 : benchmarks[0]+10;
  const pct = Math.max(0,Math.min(100, isSprint
    ? ((hi - parseFloat(value))/(hi-lo))*100
    : ((parseFloat(value)-lo)/(hi-lo))*100));
  const ticks = benchmarks.map(b => isSprint ? ((hi-b)/(hi-lo))*100 : ((b-lo)/(hi-lo))*100);
  return (
    <div style={{marginTop:10}}>
      <div style={{position:"relative",height:26,borderRadius:13,background:"linear-gradient(to right,#ef4444,#eab308,#84cc16,#22c55e)",boxShadow:"inset 0 2px 4px rgba(0,0,0,0.4)"}}>
        {ticks.map((t,i)=><div key={i} style={{position:"absolute",left:`${t}%`,top:0,bottom:0,width:2,background:"rgba(0,0,0,0.35)",transform:"translateX(-50%)"}}/>)}
        <div style={{position:"absolute",left:`${pct}%`,top:"50%",transform:"translate(-50%,-50%)",width:20,height:20,borderRadius:"50%",background:"#fff",border:"3px solid #111",boxShadow:`0 0 10px rgba(255,255,255,0.8)`,transition:"left 0.5s cubic-bezier(0.34,1.56,0.64,1)"}}/>
      </div>
      <div style={{display:"flex",justifyContent:"space-between",marginTop:6}}>
        {SA_LEVEL_SHORT.map((l,i)=><span key={i} style={{fontSize:9,color:SA_LEVEL_COLORS[i],fontWeight:700,textTransform:"uppercase"}}>{l}</span>)}
      </div>
    </div>
  );
}

function SABenchmarkTable({ benchmarks, value, isSprint, sport }) {
  const ri = saGetRating(value, benchmarks, isSprint);
  return (
    <div style={{background:"#111827",borderRadius:14,overflow:"hidden",border:`1px solid ${sport.color}33`,marginTop:16}}>
      <div style={{padding:"10px 16px",background:`${sport.color}22`,borderBottom:`1px solid ${sport.color}33`,fontSize:11,fontWeight:700,letterSpacing:2,color:sport.glow,textTransform:"uppercase"}}>
        {isSprint?"Sprint Benchmarks (seconds — lower is better)":"Jump Benchmarks (cm — higher is better)"}
      </div>
      {SA_LEVELS.map((lvl,i)=>(
        <div key={i} style={{display:"flex",justifyContent:"space-between",alignItems:"center",padding:"11px 16px",background:value!==""&&ri===i?`${SA_LEVEL_COLORS[i]}18`:"transparent",borderBottom:i<3?"1px solid #1f2937":"none"}}>
          <div style={{display:"flex",alignItems:"center",gap:10}}>
            <div style={{width:9,height:9,borderRadius:"50%",background:SA_LEVEL_COLORS[i],boxShadow:`0 0 5px ${SA_LEVEL_COLORS[i]}`}}/>
            <span style={{fontSize:13,color:"#e2e8f0",fontWeight:500}}>{lvl}</span>
          </div>
          <span style={{fontSize:16,fontFamily:"monospace",fontWeight:700,color:SA_LEVEL_COLORS[i]}}>
            {isSprint?`≤ ${benchmarks[i].toFixed(2)}s`:`≥ ${benchmarks[i]} cm`}
          </span>
        </div>
      ))}
    </div>
  );
}

function SAResultCard({ value, ratingIdx, isSprint, sport, age, gender }) {
  if (ratingIdx===null||value==="") return null;
  const dc = ratingIdx<4?SA_LEVEL_COLORS[ratingIdx]:"#9ca3af";
  const dl = ratingIdx<4?SA_LEVELS[ratingIdx]:"Below Recreational";
  const msg = SA_RATING_MSGS[Math.min(ratingIdx,4)];
  const unit = isSprint ? "s" : " cm";
  return (
    <div style={{marginTop:16,padding:"18px 20px",background:`linear-gradient(135deg,${dc}18,${dc}06)`,border:`2px solid ${dc}55`,borderRadius:16,textAlign:"center"}}>
      <div style={{fontSize:11,fontWeight:700,letterSpacing:2,color:"#64748b",textTransform:"uppercase"}}>Your Result</div>
      <div style={{fontSize:40,fontWeight:900,fontFamily:"monospace",color:dc,textShadow:`0 0 28px ${dc}`,margin:"6px 0"}}>
        {parseFloat(value).toFixed(isSprint?2:0)}{unit}
      </div>
      <div style={{fontSize:19,fontWeight:700,color:dc}}>{dl}</div>
      <div style={{fontSize:12,color:"#94a3b8",marginTop:5}}>for a {age}-year-old {gender} {sport.label} athlete</div>
      <div style={{marginTop:10,fontSize:13,fontWeight:600,color:dc}}>{msg.emoji} {msg.text}</div>
    </div>
  );
}

function SAVipLockOverlay({ sport, onUnlock, hint }) {
  const [code, setCode] = React.useState("");
  const [error, setError] = React.useState(false);
  const [shake, setShake] = React.useState(false);

  const handleSubmit = () => {
    if (code.trim().toUpperCase() === SA_VIP_CODE) {
      onUnlock();
    } else {
      setError(true);
      setShake(true);
      setTimeout(()=>setShake(false), 600);
    }
  };

  return (
    <div style={{position:"relative",borderRadius:16,overflow:"hidden",marginTop:20}}>
      <div style={{filter:"blur(6px)",opacity:0.35,pointerEvents:"none",padding:"20px",background:"#111827",borderRadius:16,border:`1px solid ${sport.color}33`}}>
        <div style={{height:14,background:"#334155",borderRadius:6,marginBottom:10,width:"60%"}}/>
        <div style={{height:50,background:"#1e293b",borderRadius:10,marginBottom:14}}/>
        <div style={{height:120,background:"#0f172a",borderRadius:12,marginBottom:10}}/>
        <div style={{height:26,background:"linear-gradient(to right,#ef4444,#eab308,#84cc16,#22c55e)",borderRadius:13}}/>
        <div style={{height:80,background:"#111827",borderRadius:14,marginTop:14}}/>
      </div>

      <div style={{position:"absolute",inset:0,display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",background:"rgba(10,10,15,0.82)",backdropFilter:"blur(2px)",borderRadius:16,padding:"28px 24px"}}>
        <div style={{fontSize:40,marginBottom:8}}>🔒</div>
        <div style={{fontSize:18,fontWeight:800,color:"#f1f5f9",marginBottom:4,textAlign:"center"}}>VIP Members Only</div>
        <div style={{fontSize:13,color:"#94a3b8",textAlign:"center",marginBottom:20,maxWidth:280,lineHeight:1.6}}>
          The Flying 30m Sprint benchmark is exclusive to VIP members. Join the Skool community to unlock full access.
        </div>

        <div style={{width:"100%",maxWidth:320,animation:shake?"sa-shake 0.5s ease":"none"}}>
          <style>{`@keyframes sa-shake{0%,100%{transform:translateX(0)}20%,60%{transform:translateX(-8px)}40%,80%{transform:translateX(8px)}}`}</style>
          <input
            type="text"
            placeholder={hint ? `Hint: try ${SA_VIP_CODE}` : "Enter VIP code"}
            value={code}
            onChange={e=>{setCode(e.target.value);setError(false);}}
            onKeyDown={e=>e.key==="Enter"&&handleSubmit()}
            style={{width:"100%",boxSizing:"border-box",padding:"12px 16px",borderRadius:10,background:"#1e293b",border:`2px solid ${error?"#ef4444":code?sport.color:"#334155"}`,color:"#f1f5f9",fontSize:16,fontFamily:"monospace",fontWeight:700,outline:"none",textAlign:"center",letterSpacing:3,textTransform:"uppercase",boxShadow:error?`0 0 16px #ef444455`:code?`0 0 16px ${sport.color}44`:"none",transition:"all 0.2s ease"}}
          />
          {error && <div style={{color:"#ef4444",fontSize:12,textAlign:"center",marginTop:6,fontWeight:600}}>❌ Incorrect code — please try again</div>}
        </div>

        <button onClick={handleSubmit} style={{marginTop:12,padding:"11px 32px",borderRadius:10,border:"none",cursor:"pointer",background:`linear-gradient(135deg,${sport.color},${sport.glow})`,color:"#fff",fontSize:14,fontWeight:700,boxShadow:`0 4px 20px ${sport.color}55`,transition:"all 0.2s ease"}}>
          Unlock Access
        </button>

        <div style={{marginTop:16,fontSize:11,color:"#475569",textAlign:"center",lineHeight:1.8}}>
          Not a VIP member yet?{" "}
          <span style={{color:sport.glow,fontWeight:700,cursor:"pointer"}}>
            Join the community →
          </span>
        </div>
      </div>
    </div>
  );
}

function SATestPanel({ testKey, sport, age, gender, isUnlocked, onUnlock, initialValue, hintCode }) {
  const [value, setValue] = React.useState(initialValue ?? "");
  const [showSrc, setShowSrc] = React.useState(false);
  // When initialValue changes (e.g. via tweak), reset
  React.useEffect(()=>{ setValue(initialValue ?? ""); }, [initialValue, testKey, sport, gender]);

  const cfg = SA_TEST_CONFIG[testKey];
  const isLocked = SA_LOCKED_TESTS.includes(testKey) && !isUnlocked;

  const dataset = saGetDataset(testKey);
  const sportData = dataset[sport];
  const genderData = sportData ? sportData[gender] : null;
  const noData = !genderData;
  const ca = genderData ? saClosestAge(genderData, age) : null;
  const benchmarks = ca ? genderData[ca] : null;
  const ratingIdx = benchmarks&&value!=="" ? saGetRating(value, benchmarks, cfg.isSprint) : null;
  const sportObj = SA_SPORTS[sport];

  if (isLocked) {
    return <SAVipLockOverlay sport={sportObj} onUnlock={onUnlock} hint={hintCode}/>;
  }

  return (
    <div>
      {noData && (
        <div style={{padding:"10px 14px",background:"#451a03",borderRadius:10,border:"1px solid #92400e",fontSize:12,color:"#fbbf24",marginBottom:14}}>
          ⚠ Normative data is limited for this gender/sport in the literature. Showing reference data only.
        </div>
      )}
      <label style={{fontSize:11,fontWeight:700,letterSpacing:2,color:"#64748b",textTransform:"uppercase"}}>
        {cfg.emoji} {cfg.label} {cfg.isSprint?"(seconds)":"(centimetres)"}
      </label>
      <input type="number" step={cfg.step} placeholder={cfg.placeholder} value={value} onChange={e=>setValue(e.target.value)}
        style={{width:"100%",boxSizing:"border-box",marginTop:8,padding:"13px 16px",borderRadius:12,background:"#1e293b",border:`2px solid ${value?sportObj.color:"#334155"}`,color:"#f1f5f9",fontSize:22,fontFamily:"monospace",fontWeight:700,outline:"none",boxShadow:value?`0 0 18px ${sportObj.color}33`:"none",transition:"all 0.2s ease"}}
      />
      <p style={{fontSize:11,color:"#64748b",margin:"6px 0 14px"}}>{cfg.hint}</p>

      {benchmarks && <SABenchmarkTable benchmarks={benchmarks} value={value} isSprint={cfg.isSprint} sport={sportObj}/>}

      {benchmarks && value!=="" && (
        <div style={{marginTop:14,padding:"14px 16px",background:"#111827",borderRadius:14,border:"1px solid #1f2937"}}>
          <div style={{fontSize:10,fontWeight:700,letterSpacing:2,color:"#4b5563",textTransform:"uppercase",marginBottom:8}}>Performance Range</div>
          <SAGaugeBar value={parseFloat(value)} benchmarks={benchmarks} isSprint={cfg.isSprint}/>
        </div>
      )}

      <SAResultCard value={value} ratingIdx={ratingIdx} isSprint={cfg.isSprint} sport={sportObj} age={ca||age} gender={gender}/>

      {benchmarks && (
        <>
          <button onClick={()=>setShowSrc(!showSrc)} style={{width:"100%",marginTop:14,padding:"10px",borderRadius:10,background:"#1e293b",border:"1px solid #334155",color:"#64748b",fontSize:12,fontWeight:600,cursor:"pointer",textAlign:"left"}}>
            {showSrc?"▼":"▶"} Research Sources & Methodology
          </button>
          {showSrc && (
            <div style={{marginTop:6,padding:"14px 16px",background:"#0f172a",borderRadius:10,border:"1px solid #1e293b",fontSize:12,color:"#64748b",lineHeight:1.8}}>
              <strong style={{color:"#94a3b8"}}>Primary Sources:</strong><br/>{sportData && sportData.note}
            </div>
          )}
        </>
      )}
    </div>
  );
}

const SA_SPORT_PAGES = [
  ["soccer","afl","basketball","rugby","athletics"],
  ["netball","amfootball","baseball","tennis"],
];

function SpeedAssessmentApp({ initialSport, samplePrefill, showVipHint, forceVipUnlock }) {
  const [sport, setSport] = React.useState(initialSport || "basketball");
  const [gender, setGender] = React.useState("male");
  const [age, setAge] = React.useState(17);
  const [activeTest, setActiveTest] = React.useState("sprint20m");
  const [sportPage, setSportPage] = React.useState(
    SA_SPORT_PAGES[0].includes(initialSport || "basketball") ? 0 : 1
  );
  const [vipUnlocked, setVipUnlocked] = React.useState(!!forceVipUnlock);

  // React to prop changes from the landing-page tweaks
  React.useEffect(()=>{
    if (initialSport && initialSport !== sport) {
      setSport(initialSport);
      setSportPage(SA_SPORT_PAGES[0].includes(initialSport) ? 0 : 1);
    }
  }, [initialSport]);
  React.useEffect(()=>{ if (forceVipUnlock) setVipUnlocked(true); }, [forceVipUnlock]);

  const currentSport = SA_SPORTS[sport];
  const currentPage = SA_SPORT_PAGES[sportPage];

  const handleSportPageSwitch = (p) => {
    setSportPage(p);
    if (!SA_SPORT_PAGES[p].includes(sport)) setSport(SA_SPORT_PAGES[p][0]);
  };

  // Sample pre-fill values per test (for social-proof tweak)
  const prefillValue = samplePrefill
    ? (activeTest === "sprint20m" ? "2.95" : activeTest === "flying30" ? "3.15" : "48")
    : "";

  return (
    <div style={{background:"#0a0a0f",fontFamily:"'DM Sans','Segoe UI',sans-serif",color:"#f1f5f9",paddingBottom:32,borderRadius:20,overflow:"hidden"}}>

      <div style={{background:"linear-gradient(135deg,#0a0a0f 0%,#0f172a 60%,#0a0a0f 100%)",borderBottom:`1px solid ${currentSport.color}33`,padding:"28px 24px 20px",textAlign:"center"}}>
        <div style={{fontSize:10,fontWeight:700,letterSpacing:3,color:currentSport.glow,textTransform:"uppercase",marginBottom:8}}>
          Speed & Power Assessment
        </div>
        <h3 style={{margin:0,fontSize:26,fontWeight:800,background:`linear-gradient(135deg,#fff 30%,${currentSport.glow})`,WebkitBackgroundClip:"text",WebkitTextFillColor:"transparent",lineHeight:1.2,fontFamily:"'DM Sans',sans-serif",textTransform:"none",letterSpacing:"normal"}}>
          Athletic Benchmark Tool
        </h3>
        <p style={{margin:"8px 0 0",fontSize:12,color:"#64748b"}}>
          9 Sports · Peer-reviewed normative data · Ages 12–30
        </p>

        {vipUnlocked && (
          <div style={{display:"inline-flex",alignItems:"center",gap:6,marginTop:10,padding:"4px 12px",background:"linear-gradient(135deg,#22c55e22,#4ade8022)",border:"1px solid #22c55e55",borderRadius:20}}>
            <span style={{fontSize:12}}>✅</span>
            <span style={{fontSize:11,fontWeight:700,color:"#4ade80",letterSpacing:1}}>VIP ACCESS UNLOCKED</span>
          </div>
        )}
      </div>

      <div style={{maxWidth:560,margin:"0 auto",padding:"0 20px"}}>

        <div style={{marginTop:24,display:"flex",gap:0,background:"#1e293b",borderRadius:10,padding:3}}>
          {[["⚽🏉🏀","Soccer · AFL · Basketball · Rugby · Athletics"],["🏐🏈⚾🎾","Netball · Am. Football · Baseball · Tennis"]].map(([icon,title],i)=>(
            <button key={i} onClick={()=>handleSportPageSwitch(i)} style={{flex:1,padding:"8px",borderRadius:8,border:"none",cursor:"pointer",background:sportPage===i?"#334155":"transparent",color:sportPage===i?"#f1f5f9":"#64748b",fontSize:10,fontWeight:600,transition:"all 0.2s ease",textAlign:"center"}}>
              <div style={{fontSize:14}}>{icon}</div>
              <div style={{fontSize:10,marginTop:2,color:sportPage===i?"#94a3b8":"#475569"}}>{title}</div>
            </button>
          ))}
        </div>

        <div style={{marginTop:14}}>
          <label style={{fontSize:10,fontWeight:700,letterSpacing:2,color:"#475569",textTransform:"uppercase"}}>Select Sport</label>
          <div style={{display:"grid",gridTemplateColumns:"1fr 1fr",gap:7,marginTop:8}}>
            {currentPage.map(key=>{
              const d=SA_SPORTS[key];
              return (
                <button key={key} onClick={()=>setSport(key)} style={{padding:"9px 12px",borderRadius:10,border:"none",cursor:"pointer",background:sport===key?d.color:"#1e293b",color:sport===key?"#fff":"#94a3b8",fontSize:11,fontWeight:600,textAlign:"left",boxShadow:sport===key?`0 0 16px ${d.color}55`:"none",transition:"all 0.2s ease",lineHeight:1.3}}>
                  {d.label}
                </button>
              );
            })}
          </div>
        </div>

        <div style={{marginTop:18}}>
          <label style={{fontSize:10,fontWeight:700,letterSpacing:2,color:"#475569",textTransform:"uppercase"}}>Gender</label>
          <div style={{display:"flex",gap:7,marginTop:8}}>
            {["male","female"].map(g=>(
              <button key={g} onClick={()=>setGender(g)} style={{flex:1,padding:"9px",borderRadius:10,border:"none",cursor:"pointer",background:gender===g?currentSport.color:"#1e293b",color:gender===g?"#fff":"#94a3b8",fontSize:13,fontWeight:600,textTransform:"capitalize",boxShadow:gender===g?`0 0 14px ${currentSport.color}55`:"none",transition:"all 0.2s ease"}}>
                {g}
              </button>
            ))}
          </div>
        </div>

        <div style={{marginTop:18}}>
          <label style={{fontSize:10,fontWeight:700,letterSpacing:2,color:"#475569",textTransform:"uppercase"}}>
            Age: <span style={{color:currentSport.glow,fontSize:18}}>{age}</span>
          </label>
          <input type="range" min={12} max={30} value={age} onChange={e=>setAge(Number(e.target.value))}
            style={{width:"100%",marginTop:8,accentColor:currentSport.color,cursor:"pointer"}}/>
          <div style={{display:"flex",justifyContent:"space-between",fontSize:11,color:"#475569"}}>
            <span>12</span><span>16</span><span>20</span><span>24</span><span>28</span><span>30</span>
          </div>
        </div>

        <div style={{marginTop:22,display:"flex",gap:0,background:"#1e293b",borderRadius:12,padding:4}}>
          {Object.entries(SA_TEST_CONFIG).map(([key,cfg])=>{
            const isLocked = SA_LOCKED_TESTS.includes(key) && !vipUnlocked;
            const isActive = activeTest===key;
            return (
              <button key={key} onClick={()=>setActiveTest(key)} style={{flex:1,padding:"9px 6px",borderRadius:10,border:"none",cursor:"pointer",background:isActive?currentSport.color:"transparent",color:isActive?"#fff":"#64748b",fontSize:11,fontWeight:700,boxShadow:isActive?`0 0 14px ${currentSport.color}66`:"none",transition:"all 0.2s ease",position:"relative"}}>
                <span>{cfg.emoji} {cfg.label}</span>
                {isLocked && (<span style={{position:"absolute",top:3,right:5,fontSize:9}}>🔒</span>)}
                {!isLocked && SA_LOCKED_TESTS.includes(key) && (<span style={{position:"absolute",top:3,right:5,fontSize:9,color:"#22c55e"}}>✓</span>)}
              </button>
            );
          })}
        </div>

        {SA_FREE_TESTS.includes(activeTest) && (
          <div style={{marginTop:8,display:"flex",alignItems:"center",gap:6}}>
            <div style={{padding:"2px 10px",background:"#14532d",border:"1px solid #22c55e55",borderRadius:20,fontSize:10,fontWeight:700,color:"#4ade80",letterSpacing:1}}>
              ✓ FREE ACCESS
            </div>
            <span style={{fontSize:11,color:"#475569"}}>Available to all users</span>
          </div>
        )}
        {SA_LOCKED_TESTS.includes(activeTest) && !vipUnlocked && (
          <div style={{marginTop:8,display:"flex",alignItems:"center",gap:6}}>
            <div style={{padding:"2px 10px",background:"#7c341230",border:"1px solid #fbbf2455",borderRadius:20,fontSize:10,fontWeight:700,color:"#fbbf24",letterSpacing:1}}>
              🔒 VIP ONLY
            </div>
            <span style={{fontSize:11,color:"#475569"}}>Requires VIP membership code</span>
          </div>
        )}

        <div style={{marginTop:16}}>
          <SATestPanel
            key={`${sport}-${gender}-${age}-${activeTest}-${samplePrefill?'p':'e'}`}
            testKey={activeTest}
            sport={sport}
            age={age}
            gender={gender}
            isUnlocked={vipUnlocked}
            onUnlock={()=>setVipUnlocked(true)}
            initialValue={prefillValue}
            hintCode={showVipHint}
          />
        </div>

        <p style={{textAlign:"center",marginTop:28,fontSize:11,color:"#64748b",lineHeight:1.6}}>
          For educational & coaching use only.<br/>
          Calibrated timing gates and force plates recommended for accurate measurement.
        </p>
      </div>
    </div>
  );
}

window.SpeedAssessmentApp = SpeedAssessmentApp;
