// ============================================
// USA Swimming Time Standards & Badge System
// Age-13 transition flow
// ============================================

// USA Swimming Motivational Time Standards (sample, SCY)
// Tiers: B → BB → A → AA → AAA → AAAA → Junior National → National
// Faster = better. A time qualifies for a tier if it's ≤ that tier's cut.
const TIME_STANDARDS = {
  // Format: gender-ageGroup-event: { tier: secondsCut }
  // Girls 11-12
  "F-11-12-50FR-SCY":   { B: 32.69, BB: 30.69, A: 28.79, AA: 27.49, AAA: 26.49, AAAA: 25.69 },
  "F-11-12-100FR-SCY":  { B: 71.39, BB: 66.99, A: 62.99, AA: 60.19, AAA: 57.99, AAAA: 56.29 },
  "F-11-12-50FL-SCY":   { B: 35.99, BB: 33.49, A: 31.39, AA: 29.89, AAA: 28.79, AAAA: 27.89 },
  "F-11-12-100BK-SCY":  { B: 78.99, BB: 74.49, A: 70.39, AA: 67.29, AAA: 64.99, AAAA: 63.09 },
  // Girls 13-14
  "F-13-14-50FR-SCY":   { B: 30.49, BB: 28.69, A: 27.09, AA: 25.99, AAA: 25.09, AAAA: 24.39 },
  "F-13-14-100FR-SCY":  { B: 66.59, BB: 62.69, A: 59.09, AA: 56.59, AAA: 54.59, AAAA: 53.09 },
  "F-13-14-200IM-SCY":  { B: 156.39, BB: 146.79, A: 138.39, AA: 132.49, AAA: 127.69, AAAA: 123.99 },
  // Boys 13-14
  "M-13-14-100FR-SCY":  { B: 61.79, BB: 58.29, A: 54.99, AA: 52.59, AAA: 50.79, AAAA: 49.29 },
  "M-13-14-200IM-SCY":  { B: 144.49, BB: 135.59, A: 127.79, AA: 122.39, AAA: 117.99, AAAA: 114.59 },
};

const TIER_ORDER = ["B", "BB", "A", "AA", "AAA", "AAAA", "JR_NAT", "NAT"];

const TIER_DEF = {
  B:      { label: "B",     color: "#9CA3AF", text: "white",    desc: "Beginner standard" },
  BB:     { label: "BB",    color: "#6B7280", text: "white",    desc: "Improving" },
  A:      { label: "A",     color: "#0099CC", text: "white",    desc: "A-time" },
  AA:     { label: "AA",    color: "#007A8A", text: "white",    desc: "Solid age-group" },
  AAA:    { label: "AAA",   color: "#00C9A7", text: "#04284f",  desc: "Strong age-group" },
  AAAA:   { label: "AAAA",  color: "#D4A017", text: "white",    desc: "Top of age group" },
  JR_NAT: { label: "Jr Nat",color: "#7C3AED", text: "white",    desc: "Junior National cut" },
  NAT:    { label: "Nat",   color: "#003366", text: "white",    desc: "National cut" },
};

// Returns the highest tier earned (or null), and progress toward next
function evaluateStandard(timeSec, key) {
  const std = TIME_STANDARDS[key];
  if (!std || !timeSec) return null;
  // Determine highest tier achieved (lowest cut your time is ≤)
  const tiers = ["B", "BB", "A", "AA", "AAA", "AAAA"];
  let earned = null;
  for (const t of tiers) {
    if (timeSec <= std[t]) earned = t;
  }
  // Next tier and gap
  const idx = earned ? tiers.indexOf(earned) : -1;
  const next = tiers[idx + 1];
  const nextCut = next ? std[next] : null;
  const gap = nextCut ? (timeSec - nextCut).toFixed(2) : null;
  return { earned, next, gap, std };
}

// Single badge chip
function StandardBadge({ tier, size = "md" }) {
  if (!tier || !TIER_DEF[tier]) return null;
  const t = TIER_DEF[tier];
  const sz = size === "sm" ? { h: 20, font: 10, pad: "0 8px" } : size === "lg" ? { h: 36, font: 14, pad: "0 16px" } : { h: 26, font: 12, pad: "0 12px" };
  return (
    <span title={t.desc} style={{
      display: "inline-flex", alignItems: "center", gap: 4,
      height: sz.h, padding: sz.pad,
      background: t.color, color: t.text,
      borderRadius: 999, fontFamily: "var(--f-mono)",
      fontWeight: 700, fontSize: sz.font, letterSpacing: 0.5,
      boxShadow: tier === "AAAA" || tier === "JR_NAT" || tier === "NAT" ? "0 0 0 2px rgba(255,255,255,0.5), 0 2px 6px rgba(0,0,0,0.15)" : "none",
    }}>
      {tier === "AAAA" && "★ "}{tier === "JR_NAT" && "◆ "}{tier === "NAT" && "● "}
      {t.label}
    </span>
  );
}

// Visual ladder showing all tiers and which the swimmer has hit
function StandardsLadder({ time, stdKey, dense }) {
  const ev = evaluateStandard(time, stdKey);
  if (!ev) return <div className="t-caption">No standard registered for this event.</div>;
  const tiers = ["B", "BB", "A", "AA", "AAA", "AAAA"];
  const earnedIdx = ev.earned ? tiers.indexOf(ev.earned) : -1;
  return (
    <div className="col" style={{ gap: 6 }}>
      <div className="row" style={{ gap: dense ? 4 : 6, flexWrap: "wrap" }}>
        {tiers.map((t, i) => {
          const hit = i <= earnedIdx;
          const isNext = i === earnedIdx + 1;
          const def = TIER_DEF[t];
          return (
            <div key={t} style={{
              flex: 1, minWidth: dense ? 36 : 48,
              padding: "8px 6px", borderRadius: 8, textAlign: "center",
              background: hit ? def.color : "white",
              color: hit ? def.text : isNext ? def.color : "var(--gray-400)",
              border: hit ? "none" : isNext ? `1.5px dashed ${def.color}` : "1px solid var(--gray-200)",
              fontFamily: "var(--f-mono)", fontWeight: 700, fontSize: dense ? 10 : 12,
              position: "relative",
              transition: "all 240ms",
            }}>
              {hit && <Icon name="check" size={10} color={def.text} style={{ position: "absolute", top: 4, right: 4 }}/>}
              {def.label}
              {!dense && <div style={{ fontSize: 9, opacity: 0.7, marginTop: 2, fontFamily: "var(--f-body)", fontWeight: 500 }}>{ev.std[t]?.toFixed(2)}</div>}
            </div>
          );
        })}
      </div>
      {ev.next && !dense && (
        <div className="t-caption" style={{ textAlign: "center", marginTop: 4 }}>
          {ev.gap > 0 ? <>Drop <strong style={{ color: TIER_DEF[ev.next].color }}>{ev.gap}s</strong> to earn <StandardBadge tier={ev.next} size="sm"/></> : "Top tier!"}
        </div>
      )}
    </div>
  );
}

// Badge collection grid (used on swimmer profile, parent view, etc)
function BadgeCollection({ swimmer }) {
  // Demo: each swimmer has a set of earned best-times → derive their highest tier per event
  const records = swimmer || [
    { event: "100m Free",  time: "1:07.42", sec: 67.42, std: "F-13-14-100FR-SCY", date: "May 14" },
    { event: "50m Free",   time: "0:27.42", sec: 27.42, std: "F-13-14-50FR-SCY",  date: "Mar 22" },
    { event: "200m IM",    time: "2:24.18", sec: 144.18, std: "F-13-14-200IM-SCY", date: "Apr 10" },
    { event: "50m Fly",    time: "0:32.41", sec: 32.41, std: "F-11-12-50FL-SCY",   date: "Apr 18", pb: true },
    { event: "100m Back",  time: "1:09.20", sec: 69.20, std: "F-11-12-100BK-SCY",  date: "Mar 8" },
  ];
  return (
    <div className="col" style={{ gap: 10 }}>
      {records.map((r, i) => {
        const ev = evaluateStandard(r.sec, r.std);
        return (
          <div key={i} className="row" style={{ padding: 14, background: "var(--gray-50)", borderRadius: 10, gap: 12, alignItems: "center" }}>
            <div style={{ flex: 1, minWidth: 0 }}>
              <div className="row" style={{ gap: 8, marginBottom: 4 }}>
                <span style={{ fontWeight: 700, fontSize: 14 }}>{r.event}</span>
                {r.pb && <Pill tone="amber">NEW PB</Pill>}
              </div>
              <div className="row" style={{ gap: 8 }}>
                <span className="t-mono-sm" style={{ fontWeight: 700, fontSize: 16, color: "var(--navy)" }}>{r.time}</span>
                <span className="t-caption">{r.date}</span>
              </div>
              <div style={{ marginTop: 10 }}>
                <StandardsLadder time={r.sec} stdKey={r.std} dense/>
              </div>
            </div>
            <div style={{ minWidth: 70, textAlign: "center" }}>
              {ev?.earned ? (
                <>
                  <StandardBadge tier={ev.earned} size="lg"/>
                  {ev.next && <div className="t-caption" style={{ marginTop: 6 }}>-{ev.gap}s to {TIER_DEF[ev.next].label}</div>}
                </>
              ) : (
                <Pill>No standard</Pill>
              )}
            </div>
          </div>
        );
      })}
    </div>
  );
}

// Summary of all earned tiers for a swimmer — counts per tier
function BadgeSummary({ counts }) {
  const def = counts || { B: 0, BB: 1, A: 2, AA: 1, AAA: 1, AAAA: 0 };
  return (
    <div className="row" style={{ gap: 6, flexWrap: "wrap" }}>
      {["B","BB","A","AA","AAA","AAAA"].map(t => (
        <div key={t} className="row" style={{ gap: 6, padding: "6px 10px", background: "white", borderRadius: 999, border: "1px solid var(--gray-200)" }}>
          <StandardBadge tier={t} size="sm"/>
          <span className="t-mono-sm" style={{ fontWeight: 700 }}>×{def[t] || 0}</span>
        </div>
      ))}
    </div>
  );
}

// ============================================
// Age-13 Account Transition Flow
// ============================================

// Children data on parent account
const CHILDREN = [
  { id: "mia",    name: "Mia Tanaka",  age: 7,  birthday: "Apr 3, 2018",   level: 3, color: "#0099CC", attendance: 95, gender: "F",
    program: "Learn-to-Swim", club: "Marina Bay AC", coach: "Coach Maria", weekly: 2, monthly: 185,
    nextClass: "Today 11:00 · Stingrays L3", competing: false, lastPB: null,
    badges: { B: 0, BB: 0, A: 0, AA: 0, AAA: 0, AAAA: 0 } },
  { id: "kai",    name: "Kai Tanaka",  age: 12, birthday: "Aug 22, 2013",  level: 7, color: "#F97316", attendance: 88, gender: "M",
    program: "Pre-Competitive", club: "Marina Bay AC", coach: "Coach Maria", weekly: 5, monthly: 320,
    nextClass: "Tomorrow 16:30 · Sharks Pre-Comp", competing: true,
    lastPB: { event: "100m Free", time: "1:08.21", date: "May 5", std: "M-13-14-100FR-SCY", sec: 68.21 },
    badges: { B: 4, BB: 3, A: 1, AA: 0, AAA: 0, AAAA: 0 } },
  { id: "sophie", name: "Sophie Chen", age: 13, birthday: "May 18, 2013",  level: 8, color: "#00C9A7", attendance: 100, gender: "F",
    program: "Competitive Senior", club: "Marina Bay AC", coach: "Coach Maria", weekly: 8, monthly: 450,
    nextClass: "Today 16:30 · Sharks Pre-Comp", competing: true, readyToTransition: true,
    lastPB: { event: "100m Free", time: "1:00.42", date: "May 14", std: "F-13-14-100FR-SCY", sec: 60.42 },
    badges: { B: 5, BB: 5, A: 4, AA: 3, AAA: 1, AAAA: 0 } },
];

function ChildAgeBadge({ child }) {
  if (child.age >= 13) {
    return <Pill tone={child.readyToTransition ? "amber" : "aqua"}>
      <Icon name="star" size={11}/>
      {child.readyToTransition ? "Ready: own account" : "Independent account"}
    </Pill>;
  }
  const monthsUntil13 = (13 - child.age) * 12;
  if (monthsUntil13 <= 6) return <Pill tone="amber">{monthsUntil13}mo to age 13</Pill>;
  return <Pill tone="mint">Age {child.age} · supervised</Pill>;
}

function TransitionFlow({ child, onClose, onComplete, toast }) {
  const [step, setStep] = useState(0);
  const [childEmail, setChildEmail] = useState("");
  const [permissions, setPermissions] = useState({
    fullProfile: true,
    parentVisibility: true,
    parentPayments: true,
    coachMessages: true,
  });

  const steps = ["Confirm", "Child email", "Permissions", "Review"];

  return (
    <Sheet open={true} onClose={onClose} title={null} large>
      <div className="between" style={{ marginBottom: 8 }}>
        <Pill tone="amber">Account transition</Pill>
        <div className="t-caption">Step {step + 1} of {steps.length}</div>
      </div>

      <div className="row" style={{ gap: 6, marginBottom: 20 }}>
        {steps.map((s, i) => (
          <div key={s} style={{ flex: 1, height: 6, borderRadius: 999, background: i <= step ? "var(--aqua)" : "var(--gray-200)", transition: "background 220ms" }}/>
        ))}
      </div>

      {step === 0 && (
        <div>
          <div className="row" style={{ gap: 16, padding: "8px 0 24px", borderBottom: "1px solid var(--gray-200)", marginBottom: 20 }}>
            <Avatar name={child.name} color={child.color} size="lg"/>
            <div style={{ flex: 1 }}>
              <div className="t-h1">{child.name}</div>
              <div className="muted">Turning 13 · {child.birthday}</div>
              <StandardBadge tier="AA" size="sm"/>
            </div>
          </div>
          <div className="t-h2" style={{ marginBottom: 8 }}>It's time for an independent account</div>
          <div className="muted" style={{ marginBottom: 16, fontSize: 14, lineHeight: 1.55 }}>
            At age 13, AquaFlow moves swimmer profiles off the parent account onto their own log-in. {child.name} keeps every PB, badge, class history and assigned workout — only the log-in and notification preferences move.
          </div>
          <div className="col" style={{ gap: 8 }}>
            {[
              { icon: "check", label: "Everything transfers", body: "PBs, time-standard badges, level progress, attendance, assigned workouts, achievements." },
              { icon: "lock", label: "Stays linked to you", body: "You keep visibility, billing control and coach messaging — until you choose to unlink." },
              { icon: "star", label: "Independence, age-appropriate", body: "Direct coach chat, own profile photo, push notifications on their device." },
            ].map((b, i) => (
              <div key={i} className="row" style={{ gap: 12, padding: 12, background: "var(--gray-50)", borderRadius: 10 }}>
                <div style={{ width: 32, height: 32, borderRadius: 8, background: "var(--mint-50)", display: "flex", alignItems: "center", justifyContent: "center" }}>
                  <Icon name={b.icon} size={16} color="var(--mint)"/>
                </div>
                <div style={{ flex: 1 }}>
                  <div style={{ fontWeight: 600, fontSize: 13 }}>{b.label}</div>
                  <div className="t-caption">{b.body}</div>
                </div>
              </div>
            ))}
          </div>
        </div>
      )}

      {step === 1 && (
        <div>
          <div className="t-h2" style={{ marginBottom: 8 }}>{child.name}'s email</div>
          <div className="muted" style={{ marginBottom: 18 }}>We'll send a sign-in link directly to {child.name}. You'll co-sign on the next step.</div>
          <div className="col" style={{ gap: 14 }}>
            <div className="field">
              <label>Child's email address</label>
              <input className="input" type="email" value={childEmail} onChange={e => setChildEmail(e.target.value)} placeholder="sophie@example.com" autoFocus/>
              <div className="t-caption">Must be a working email {child.name} can access independently.</div>
            </div>
            <div style={{ background: "var(--amber-50)", padding: 14, borderRadius: 10, borderLeft: "3px solid var(--amber)" }}>
              <div className="row" style={{ gap: 10, alignItems: "flex-start" }}>
                <Icon name="info" size={16} color="var(--amber)"/>
                <div>
                  <div style={{ fontWeight: 600, fontSize: 13, color: "#7a4a06" }}>COPPA & local minor protections</div>
                  <div style={{ fontSize: 12, color: "#92590a", marginTop: 4 }}>For users 13+ we still apply parental controls until {child.name} turns 18, in line with USA Swimming SafeSport guidance. You can review or revoke at any time.</div>
                </div>
              </div>
            </div>
          </div>
        </div>
      )}

      {step === 2 && (
        <div>
          <div className="t-h2" style={{ marginBottom: 8 }}>What can {child.name} do alone?</div>
          <div className="muted" style={{ marginBottom: 18 }}>Toggle parental controls for the new account. You can change these later.</div>
          <div className="col" style={{ gap: 6 }}>
            {[
              { id: "fullProfile",     label: "Edit own profile photo & display name", on: permissions.fullProfile },
              { id: "parentVisibility", label: "You can view all sessions, splits and meets", on: permissions.parentVisibility },
              { id: "parentPayments",  label: "Billing & club dues stay on your account", on: permissions.parentPayments },
              { id: "coachMessages",   label: "Direct coach messaging (you're CC'd by default)", on: permissions.coachMessages },
            ].map(t => (
              <div key={t.id} className="between" style={{ padding: 12, background: "var(--gray-50)", borderRadius: 10 }}>
                <div style={{ fontWeight: 600, fontSize: 13 }}>{t.label}</div>
                <Toggle on={t.on} onChange={v => setPermissions({ ...permissions, [t.id]: v })}/>
              </div>
            ))}
          </div>
        </div>
      )}

      {step === 3 && (
        <div>
          <div className="t-h2" style={{ marginBottom: 8 }}>Ready to send</div>
          <div className="muted" style={{ marginBottom: 18 }}>{child.name} will receive an email to verify and complete setup.</div>
          <div className="col" style={{ gap: 8 }}>
            <Row k="Account" v={`${child.name} — independent swimmer`}/>
            <Row k="Email" v={childEmail || "—"}/>
            <Row k="Linked to" v="Hiroshi Tanaka (you)"/>
            <Row k="Parent visibility" v={permissions.parentVisibility ? "Full access" : "Summary only"}/>
            <Row k="Billing" v="Stays on your account"/>
            <Row k="Coach messages" v={permissions.coachMessages ? "Direct + you CC'd" : "Through you only"}/>
          </div>
          <div style={{ marginTop: 18, padding: 14, background: "var(--mint-50)", borderRadius: 10, borderLeft: "3px solid var(--mint)" }}>
            <div className="row" style={{ gap: 10 }}>
              <Icon name="check-circle" size={18} color="var(--mint)"/>
              <div>
                <div style={{ fontWeight: 700, fontSize: 13, color: "#046855" }}>Everything {child.name} earned travels with the account</div>
                <div style={{ fontSize: 12, color: "#04866d", marginTop: 4 }}>5 time-standard badges, 18 personal records, 184 sessions, Level 8 status — all preserved.</div>
              </div>
            </div>
          </div>
        </div>
      )}

      <div className="row" style={{ marginTop: 24, gap: 10 }}>
        {step > 0 && <Button variant="ghost" onClick={() => setStep(step - 1)}>Back</Button>}
        <div style={{ flex: 1 }}/>
        <Button variant="ghost" onClick={onClose}>Cancel</Button>
        <Button variant="primary" onClick={() => {
          if (step < 3) {
            if (step === 1 && !childEmail) { toast({ message: "Please enter an email", tone: "error" }); return; }
            setStep(step + 1);
          } else {
            toast({ message: `Invitation sent to ${child.name}` });
            onComplete?.();
          }
        }}>{step < 3 ? "Continue" : "Send invitation"}<Icon name="chev-right" size={14}/></Button>
      </div>
    </Sheet>
  );
}

function Row({ k, v }) {
  return (
    <div className="between" style={{ padding: "10px 12px", background: "var(--gray-50)", borderRadius: 8 }}>
      <span className="t-caption">{k}</span>
      <span style={{ fontWeight: 600, fontSize: 13 }}>{v}</span>
    </div>
  );
}

Object.assign(window, { TIME_STANDARDS, TIER_DEF, evaluateStandard, StandardBadge, StandardsLadder, BadgeCollection, BadgeSummary, CHILDREN, ChildAgeBadge, TransitionFlow });

// ============================================
// Competitive Skill Map — for swimmers past Learn-to-Swim
// ============================================
// Replaces the Level Ladder for swimmers in Pre-Comp / Competitive / Senior squads.
// Stroke-by-stroke technical mastery + competition tier ladder.

const COMP_STROKES = [
  { id: "free", name: "Freestyle", icon: "wave", color: "var(--aqua)" },
  { id: "back", name: "Backstroke", icon: "swimmer", color: "var(--teal)" },
  { id: "breast", name: "Breaststroke", icon: "wave", color: "var(--c-openwater)" },
  { id: "fly", name: "Butterfly", icon: "wave", color: "var(--c-competitive)" },
  { id: "im", name: "Individual Medley", icon: "ladder", color: "var(--c-parent)" },
];

const COMP_PHASES = {
  free: [
    "Legal stroke — DQ-clean",
    "6-beat kick consistency",
    "Bilateral breathing every 3",
    "Streamline 5m off start",
    "Underwater dolphin to 12m",
    "Flip-turn contact < 0.9s",
    "Race-pace 100 split",
    "Negative-split 200",
    "Distance per stroke (DPS) target",
  ],
  back: [
    "Legal stroke (head still, no DQ)",
    "Streamline kick to 12m",
    "Hip rotation drill mastery",
    "Backstroke ledge start",
    "Flag-to-flag awareness",
    "Backstroke flip turn — single arm",
    "Sub-5s 15m off start",
    "Race-pace 100 split",
  ],
  breast: [
    "Legal pull (no scull)",
    "Symmetric kick (whip)",
    "Pullout — one fly kick legal",
    "Streamline + glide phase",
    "Underwater pullout to 10m",
    "Two-hand touch turn",
    "Race-pace 100 split",
    "200 strategy: build 50s",
  ],
  fly: [
    "Legal stroke + 2-kick rhythm",
    "Streamline off walls",
    "Hip-driven undulation",
    "Underwater dolphin to 12m",
    "Two-hand touch turn",
    "Breath-every-2 endurance",
    "Race-pace 100 split",
    "Late-race fly form (last 25)",
  ],
  im: [
    "Legal transitions (all 4)",
    "200 IM under cut",
    "400 IM aerobic base",
    "Fly→back transition cleanliness",
    "Back→breast crossover turn",
    "Breast→free transition speed",
    "Race-pace IM splits balanced",
  ],
};

// Competitive tier ladder (USA Swimming-aligned)
const COMP_TIERS = [
  { id: "novice",   label: "Novice",          desc: "First competitive year, learning meets",      color: "var(--gray-400)" },
  { id: "club",     label: "Club Swimmer",    desc: "Registered, racing local meets",              color: "var(--aqua)" },
  { id: "ageGroup", label: "Age Group",       desc: "Regular meets, B–A standards",                color: "var(--mint)" },
  { id: "regional", label: "Regional",        desc: "Sectionals / Regional qualifier (AA–AAA)",    color: "var(--teal)" },
  { id: "senior",   label: "Senior Squad",    desc: "State + Senior cuts, year-round high-volume", color: "var(--c-competitive)" },
  { id: "jrNat",    label: "Junior National", desc: "Jr Nat qualifier · 6+ training sessions/wk",  color: "var(--c-parent)" },
  { id: "national", label: "National",        desc: "Senior National cut · sponsored athlete",     color: "var(--navy)" },
];

function CompetitiveSkillMap({ swimmer = {}, tier = "regional" }) {
  const [activeStroke, setActiveStroke] = useState("free");
  // Generate per-stroke progress (deterministic by stroke id length so it's stable per render)
  const progress = {
    free:   { mastered: 6, total: COMP_PHASES.free.length },
    back:   { mastered: 5, total: COMP_PHASES.back.length },
    breast: { mastered: 4, total: COMP_PHASES.breast.length },
    fly:    { mastered: 4, total: COMP_PHASES.fly.length },
    im:     { mastered: 3, total: COMP_PHASES.im.length },
  };
  const tierIdx = COMP_TIERS.findIndex(t => t.id === tier);

  return (
    <div className="col" style={{ gap: 20 }}>
      {/* Competition tier ladder */}
      <div>
        <div className="t-h3" style={{ marginBottom: 12 }}>Competition tier</div>
        <div style={{ display: "grid", gridTemplateColumns: `repeat(${COMP_TIERS.length}, 1fr)`, gap: 4 }}>
          {COMP_TIERS.map((t, i) => {
            const passed = i < tierIdx;
            const current = i === tierIdx;
            const future = i > tierIdx;
            return (
              <div key={t.id} title={t.desc} style={{
                padding: "8px 4px",
                textAlign: "center",
                background: passed || current ? t.color : "white",
                color: passed || current ? "white" : "var(--gray-500)",
                border: future ? "1px solid var(--gray-200)" : "none",
                borderRadius: 6,
                fontSize: 11, fontWeight: 700,
                position: "relative",
              }}>
                {passed && <Icon name="check" size={10} color="white" style={{ position: "absolute", top: 3, right: 3 }}/>}
                <div style={{ fontSize: 9, opacity: 0.7, letterSpacing: 0.5, textTransform: "uppercase" }}>Tier {i + 1}</div>
                <div>{t.label}</div>
              </div>
            );
          })}
        </div>
        <div style={{ marginTop: 10, padding: 12, background: "var(--sky)", borderRadius: 8, borderLeft: `3px solid ${COMP_TIERS[tierIdx].color}` }}>
          <div className="row" style={{ gap: 8 }}>
            <Icon name="info" size={14} color={COMP_TIERS[tierIdx].color}/>
            <span style={{ fontSize: 13, fontWeight: 600 }}>Currently: {COMP_TIERS[tierIdx].label}</span>
          </div>
          <div style={{ fontSize: 12, color: "var(--gray-600)", marginTop: 4 }}>{COMP_TIERS[tierIdx].desc}</div>
          {tierIdx < COMP_TIERS.length - 1 && (
            <div style={{ fontSize: 12, color: "var(--gray-700)", marginTop: 6 }}>
              <strong>Next:</strong> {COMP_TIERS[tierIdx + 1].label} — {COMP_TIERS[tierIdx + 1].desc}
            </div>
          )}
        </div>
      </div>

      {/* Per-stroke mastery */}
      <div>
        <div className="between" style={{ marginBottom: 12 }}>
          <div className="t-h3">Stroke technical mastery</div>
          <Pill>Coach-assessed</Pill>
        </div>

        {/* Stroke picker — radial summary */}
        <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(120px, 1fr))", gap: 8, marginBottom: 16 }}>
          {COMP_STROKES.map(s => {
            const p = progress[s.id];
            const pct = (p.mastered / p.total) * 100;
            const active = activeStroke === s.id;
            return (
              <button key={s.id} onClick={() => setActiveStroke(s.id)} className="card" style={{
                padding: 14, textAlign: "left", cursor: "pointer",
                borderTop: `3px solid ${s.color}`,
                background: active ? "var(--sky)" : "white",
                boxShadow: active ? "var(--sh-8)" : "var(--sh-2)",
                transition: "all 160ms",
              }}>
                <div className="row" style={{ gap: 8 }}>
                  <Icon name={s.icon} size={16} color={s.color}/>
                  <span style={{ fontWeight: 700, fontSize: 12 }}>{s.name}</span>
                </div>
                <div className="t-mono-stat" style={{ fontSize: 22, color: s.color, marginTop: 6 }}>{p.mastered}<span style={{ fontSize: 12, color: "var(--gray-500)" }}>/{p.total}</span></div>
                <ProgressBar pct={pct} color={s.color} height={4}/>
              </button>
            );
          })}
        </div>

        {/* Detailed phase list for active stroke */}
        <Card style={{ background: "var(--gray-50)", boxShadow: "none", border: "1px solid var(--gray-200)" }}>
          <div className="row" style={{ marginBottom: 12, gap: 10 }}>
            <Icon name={COMP_STROKES.find(x => x.id === activeStroke).icon} size={20} color={COMP_STROKES.find(x => x.id === activeStroke).color}/>
            <div className="t-h3">{COMP_STROKES.find(x => x.id === activeStroke).name} — phase mastery</div>
          </div>
          <div className="col" style={{ gap: 6 }}>
            {COMP_PHASES[activeStroke].map((skill, i) => {
              const masteredCount = progress[activeStroke].mastered;
              const state = i < masteredCount ? "mastered" : i === masteredCount ? "progress" : "not";
              const tone = state === "mastered" ? "var(--mint)" : state === "progress" ? "var(--aqua)" : "var(--gray-300)";
              return (
                <div key={skill} className="row" style={{ padding: 10, background: "white", borderRadius: 8, borderLeft: `3px solid ${tone}`, gap: 12 }}>
                  <div style={{ width: 24, height: 24, borderRadius: "50%", background: tone, display: "flex", alignItems: "center", justifyContent: "center", color: state === "not" ? "var(--gray-500)" : "white", flexShrink: 0 }}>
                    {state === "mastered" ? <Icon name="check" size={12}/> : state === "progress" ? <div style={{ width: 8, height: 8, background: "white", borderRadius: "50%" }}/> : <Icon name="dot" size={8}/>}
                  </div>
                  <span style={{ fontWeight: 600, fontSize: 13, flex: 1 }}>{skill}</span>
                  <Pill tone={state === "mastered" ? "mint" : state === "progress" ? "aqua" : "default"}>{state === "mastered" ? "Mastered" : state === "progress" ? "In progress" : "Working on"}</Pill>
                </div>
              );
            })}
          </div>
        </Card>
      </div>

      {/* Race events list */}
      <div>
        <div className="t-h3" style={{ marginBottom: 12 }}>Race events tracked</div>
        <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(140px, 1fr))", gap: 6 }}>
          {[
            { event: "50 FR", tier: "AA" },
            { event: "100 FR", tier: "AAA" },
            { event: "200 FR", tier: "AA" },
            { event: "400 FR", tier: "A" },
            { event: "100 BK", tier: "A" },
            { event: "200 IM", tier: "AA" },
            { event: "100 FL", tier: "B" },
            { event: "100 BR", tier: "BB" },
          ].map(r => (
            <div key={r.event} style={{ padding: 10, background: "var(--gray-50)", borderRadius: 8, textAlign: "center" }}>
              <div className="t-mono-sm" style={{ fontWeight: 700, fontSize: 13 }}>{r.event}</div>
              <div style={{ marginTop: 6 }}><StandardBadge tier={r.tier} size="sm"/></div>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

// Smart wrapper — picks the right ladder based on swimmer context.
function SwimmerProgressMap({ swimmer, level, competitive, tier, progress }) {
  // If swimmer is in a competitive program, show CompetitiveSkillMap
  const isCompetitive = competitive ?? (swimmer?.competing || (level && level >= 7));
  if (isCompetitive) {
    return <CompetitiveSkillMap swimmer={swimmer} tier={tier || (level >= 8 ? "senior" : "regional")}/>;
  }
  return <LevelLadder current={level ?? 3} progress={progress ?? 0.6}/>;
}

Object.assign(window, { CompetitiveSkillMap, COMP_TIERS, SwimmerProgressMap });
