// DiveDex — UI primitives + bottom nav + top bar

function Logo({ size = 28, mark = true, word = true, gold = false, name = 'DiveDex' }) {
  const accent = gold ? '#D7B46A' : '#82ECFF';
  const accent2 = gold ? '#FBE6A6' : '#31D7FF';
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
      {mark && (
        <svg width={size} height={size} viewBox="0 0 40 40" style={{ filter: `drop-shadow(0 2px 10px ${accent}55)` }}>
          <defs>
            <linearGradient id={`lg-${gold ? 'g' : 'a'}`} x1="0" y1="0" x2="40" y2="40">
              <stop offset="0" stopColor={accent2}/>
              <stop offset="1" stopColor={accent}/>
            </linearGradient>
          </defs>
          <circle cx="20" cy="20" r="18" fill="none" stroke={`url(#lg-${gold ? 'g' : 'a'})`} strokeWidth="1.4" opacity="0.7"/>
          <circle cx="20" cy="20" r="12" fill="none" stroke={`url(#lg-${gold ? 'g' : 'a'})`} strokeWidth="1.4" opacity="0.5"/>
          <path d="M8 24 Q 18 14 32 22 Q 26 26 18 24 Q 14 22 8 24 Z" fill={`url(#lg-${gold ? 'g' : 'a'})`}/>
          <circle cx="20" cy="20" r="1.6" fill={accent2}/>
        </svg>
      )}
      {word && (
        <span style={{ fontFamily: 'Space Grotesk', fontWeight: 700, fontSize: size * 0.62, letterSpacing: '-0.03em', color: '#EAF5FF' }}>
          Dive<span style={{ color: accent }}>Dex</span>
        </span>
      )}
    </div>
  );
}

function SonarRing({ size = 220, pulses = 3 }) {
  return (
    <div style={{ position: 'relative', width: size, height: size, display: 'grid', placeItems: 'center' }}>
      {Array.from({ length: pulses }).map((_, i) => (
        <div key={i} className={`dd-sonar-ring delay-${i}`} style={{ animationDelay: `${i * (3.2 / pulses)}s` }}/>
      ))}
      <div style={{ width: '38%', height: '38%', borderRadius: '50%', background: 'radial-gradient(circle at 30% 30%, #82ECFF, #1FB6E6 60%, #0a3552)', boxShadow: '0 0 28px rgba(49,215,255,0.6)', position: 'relative' }}>
        <div style={{ position:'absolute', inset: '14%', borderRadius:'50%', border:'1px solid rgba(255,255,255,0.25)'}}/>
      </div>
    </div>
  );
}

function GlassCard({ children, style = {}, strong = false, onClick, accent }) {
  return (
    <div onClick={onClick} className={`dd-glass ${strong ? 'dd-glass-strong' : ''}`} style={{
      position: 'relative', padding: 14, ...style,
      ...(accent ? { boxShadow: `inset 0 0 0 1px ${accent}33, 0 8px 24px -10px ${accent}55` } : {}),
      cursor: onClick ? 'pointer' : 'default',
    }}>{children}</div>
  );
}

function Chip({ children, variant = 'default', icon, style }) {
  const cls = {
    default: 'dd-chip', aqua: 'dd-chip dd-chip-aqua', gold: 'dd-chip dd-chip-gold',
    coral: 'dd-chip dd-chip-coral', foam: 'dd-chip dd-chip-foam',
  }[variant];
  return <span className={cls} style={style}>{icon}<span>{children}</span></span>;
}

function XPBar({ value, max, color = 'var(--aqua)', height = 8, label, sub, animate = true }) {
  const pct = Math.min(100, (value / max) * 100);
  return (
    <div style={{ width: '100%' }}>
      {(label || sub) && (
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 6 }}>
          <span style={{ fontSize: 12, color: 'var(--ink-2)', fontWeight: 600 }}>{label}</span>
          <span className="dd-num" style={{ fontSize: 11, color: 'var(--ink-3)' }}>{sub}</span>
        </div>
      )}
      <div style={{ height, borderRadius: 999, background: 'rgba(255,255,255,0.06)', overflow: 'hidden', border: '1px solid rgba(255,255,255,0.04)' }}>
        <div className={animate ? 'dd-xpfill' : ''} style={{
          width: `${pct}%`, height: '100%', borderRadius: 999,
          background: `linear-gradient(90deg, ${color}99, ${color})`,
          boxShadow: `0 0 12px ${color}88`,
        }}/>
      </div>
    </div>
  );
}

function RarityRing({ rarity, size = 86, children }) {
  const isMythic = rarity === 'mythic';
  return (
    <div className={`dd-rarity-${rarity}`} style={{
      width: size, height: size, position: 'relative',
      display: 'grid', placeItems: 'center',
    }}>
      <div style={{
        position: 'absolute', inset: 0, borderRadius: '50%',
        background: isMythic
          ? 'conic-gradient(from 0deg, #82ECFF, #63FFD2, #D7B46A, #FF7A6B, #8B7BFF, #82ECFF)'
          : `radial-gradient(circle at 50% 50%, var(--r-color) 0%, var(--r-color) 40%, transparent 70%)`,
        opacity: isMythic ? 0.85 : 0.3,
        filter: isMythic ? 'blur(0px)' : 'blur(6px)',
      }}/>
      <div style={{
        position: 'absolute', inset: 0, borderRadius: '50%',
        border: `1.5px solid var(--r-color)`,
        boxShadow: `0 0 14px var(--r-glow)`,
      }}/>
      <div style={{ position: 'relative', display: 'grid', placeItems: 'center', width: '74%', height: '74%', borderRadius: '50%', background: 'radial-gradient(circle at 50% 30%, #103048, #050B14)' }}>
        {children}
      </div>
    </div>
  );
}

// Bottom navigation — 5 tabs
function BottomNav({ tab, onTab }) {
  const items = [
    { id: 'levels', label: 'Levels', icon: <NavIcon kind="levels"/> },
    { id: 'log', label: 'Log', icon: <NavIcon kind="log"/> },
    { id: 'dex', label: 'Dex', icon: <NavIcon kind="dex"/> },
    { id: 'team', label: 'Team', icon: <NavIcon kind="team"/> },
    { id: 'memories', label: 'Memories', icon: <NavIcon kind="memories"/> },
    { id: 'gear', label: 'Gear', icon: <NavIcon kind="gear"/> },
  ];
  return (
    <div style={{
      position: 'absolute', left: 12, right: 12, zIndex: 5,
      bottom: 'max(12px, env(safe-area-inset-bottom, 0px))',
      padding: 6, borderRadius: 28,
      background: 'linear-gradient(180deg, rgba(8,22,38,0.85), rgba(5,11,20,0.95))',
      border: '1px solid rgba(130,236,255,0.10)',
      backdropFilter: 'blur(22px) saturate(160%)',
      boxShadow: '0 14px 30px -10px rgba(0,0,0,0.6), inset 0 1px 0 rgba(255,255,255,0.04)',
    }}>
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(6, 1fr)', gap: 2 }}>
        {items.map(it => {
          const active = tab === it.id;
          return (
            <button key={it.id} onClick={() => onTab(it.id)} className="dd-btn" style={{
              background: 'transparent', padding: '8px 4px 6px', borderRadius: 22,
              display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 3,
              color: active ? '#82ECFF' : 'var(--ink-3)',
              position: 'relative',
            }}>
              {active && <div style={{ position: 'absolute', inset: 2, borderRadius: 20, background: 'linear-gradient(180deg, rgba(49,215,255,0.18), rgba(49,215,255,0.06))', border: '1px solid rgba(49,215,255,0.25)', boxShadow: '0 0 14px rgba(49,215,255,0.25) inset' }}/>}
              <div style={{ position: 'relative', height: 22, display:'grid', placeItems:'center' }}>{it.icon}</div>
              <span style={{ position: 'relative', fontSize: 10.5, fontWeight: 600, letterSpacing: '0.01em' }}>{it.label}</span>
            </button>
          );
        })}
      </div>
    </div>
  );
}

function NavIcon({ kind }) {
  const s = { width: 22, height: 22, fill: 'none', stroke: 'currentColor', strokeWidth: 1.8, strokeLinecap: 'round', strokeLinejoin: 'round' };
  if (kind === 'levels') return <svg {...s} viewBox="0 0 24 24"><path d="M3 7l9-4 9 4-9 4-9-4z"/><path d="M3 12l9 4 9-4"/><path d="M3 17l9 4 9-4"/></svg>;
  if (kind === 'log') return <svg {...s} viewBox="0 0 24 24"><circle cx="12" cy="12" r="9"/><path d="M12 8v8M8 12h8"/></svg>;
  if (kind === 'dex') return <svg {...s} viewBox="0 0 24 24"><rect x="3" y="4" width="18" height="16" rx="3"/><path d="M3 10h18M9 4v16"/></svg>;
  if (kind === 'team') return <svg {...s} viewBox="0 0 24 24"><circle cx="9" cy="9" r="3"/><circle cx="17" cy="11" r="2.4"/><path d="M3 19c0-3 3-5 6-5s6 2 6 5"/><path d="M14 19c.4-2.4 2-4 4-4s3 1 3 3"/></svg>;
  if (kind === 'memories') return <svg {...s} viewBox="0 0 24 24"><rect x="3" y="5" width="18" height="14" rx="2.5"/><circle cx="9" cy="11" r="2"/><path d="M3 17l5-4 4 3 4-5 5 5"/></svg>;
  if (kind === 'gear') return <svg {...s} viewBox="0 0 24 24"><path d="M12 3l1.8 3.5L18 4l-1 4 3.5 1.8L17 12l3.5 2.2L17 16l1 4-4.2-2.5L12 21l-1.8-3.5L6 20l1-4-3.5-1.8L7 12 3.5 9.8 7 8 6 4l4.2 2.5z"/><circle cx="12" cy="12" r="3"/></svg>;
}

function TopBar({ title, sub, left, right, scroll = 0 }) {
  // Always-on blurred backdrop so scrolling content doesn't bleed visibly
  // through the sticky header. The `scroll` prop is no longer required —
  // kept for back-compat with any caller still passing it.
  //
  // The TopBar owns the device safe-area-inset-top: its background extends
  // all the way to the top of the viewport (under the iOS Dynamic Island /
  // notch), and its internal top padding is `14 + safe-area-inset-top` so
  // the title sits *below* the status bar. Sticky `top: 0` then keeps it
  // pinned to the very top of the scrollport, with no double-padding from
  // the scroll container. In a browser tab or on desktop the env value
  // resolves to 0 so this collapses to a normal 14px top padding.
  return (
    <div style={{
      position: 'sticky', top: 0, zIndex: 6,
      padding: '14px 18px 12px',
      paddingTop: 'calc(14px + env(safe-area-inset-top, 0px))',
      background: 'linear-gradient(180deg, rgba(5,11,20,0.88), rgba(5,11,20,0.62))',
      backdropFilter: 'blur(14px) saturate(140%)',
      WebkitBackdropFilter: 'blur(14px) saturate(140%)',
      borderBottom: '1px solid rgba(130,236,255,0.08)',
      display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12,
    }}>
      <div style={{ width: 36, display: 'flex', alignItems: 'center' }}>{left}</div>
      <div style={{ flex: 1, minWidth: 0, textAlign: 'center' }}>
        <div className="dd-h2" style={{ fontSize: 16, color: '#EAF5FF', lineHeight: 1.1 }}>{title}</div>
        {sub && <div style={{ fontSize: 11, color: 'var(--ink-3)', marginTop: 2 }}>{sub}</div>}
      </div>
      <div style={{ width: 36, display: 'flex', alignItems: 'center', justifyContent: 'flex-end' }}>{right}</div>
    </div>
  );
}

function IconBtn({ children, onClick }) {
  return (
    <button onClick={onClick} className="dd-btn" style={{
      width: 36, height: 36, borderRadius: 18,
      background: 'rgba(255,255,255,0.05)', color: 'var(--ink)',
      border: '1px solid rgba(130,236,255,0.12)',
      display: 'grid', placeItems: 'center',
    }}>{children}</button>
  );
}

function ProgressDots({ step, total }) {
  return (
    <div style={{ display: 'flex', gap: 4 }}>
      {Array.from({ length: total }).map((_, i) => (
        <div key={i} style={{
          width: i === step ? 18 : 6, height: 6, borderRadius: 3,
          background: i <= step ? '#31D7FF' : 'rgba(255,255,255,0.12)',
          transition: 'width 0.25s',
        }}/>
      ))}
    </div>
  );
}

function RarityFrame({ rarity, children, style }) {
  return (
    <div className={`dd-rarity-${rarity}`} style={{ position: 'relative', borderRadius: 16, ...style }}>
      <div style={{
        position: 'absolute', inset: 0, borderRadius: 16,
        background: rarity === 'mythic' ? 'conic-gradient(from 0deg, #82ECFF, #63FFD2, #D7B46A, #FF7A6B, #8B7BFF, #82ECFF)' : 'transparent',
        padding: 1.2, opacity: rarity === 'mythic' ? 1 : 0,
      }}/>
      <div style={{
        position: 'relative', borderRadius: 16, padding: 12,
        background: 'linear-gradient(180deg, rgba(16,30,46,0.92), rgba(7,18,30,0.95))',
        border: rarity === 'mythic' ? '0' : `1px solid var(--r-color)`,
        boxShadow: rarity === 'legendary' || rarity === 'mythic'
          ? `0 8px 26px -10px var(--r-glow), inset 0 1px 0 rgba(255,255,255,0.06)`
          : `0 4px 14px -8px var(--r-glow), inset 0 1px 0 rgba(255,255,255,0.04)`,
      }}>{children}</div>
    </div>
  );
}

function StatCell({ label, value, unit, color = '#EAF5FF', mono = true }) {
  return (
    <div>
      <div style={{ fontSize: 10.5, color: 'var(--ink-3)', letterSpacing: '0.08em', textTransform: 'uppercase', fontWeight: 600 }}>{label}</div>
      <div style={{ marginTop: 4, color, display: 'flex', alignItems: 'baseline', gap: 3 }}>
        <span className={mono ? 'dd-num' : ''} style={{ fontSize: 20, fontWeight: 600, fontFamily: mono ? 'JetBrains Mono' : 'Space Grotesk' }}>{value}</span>
        {unit && <span style={{ fontSize: 11, color: 'var(--ink-3)' }}>{unit}</span>}
      </div>
    </div>
  );
}

function Avatar({ name, color, size = 28 }) {
  return (
    <div style={{
      width: size, height: size, borderRadius: '50%',
      background: `linear-gradient(140deg, ${color}, #0B2A44)`,
      border: `1px solid ${color}`,
      boxShadow: `0 0 12px ${color}55`,
      display: 'grid', placeItems: 'center',
      fontSize: size * 0.4, fontWeight: 700, color: '#fff',
      fontFamily: 'Space Grotesk', letterSpacing: '-0.02em',
    }}>{name[0]}</div>
  );
}

function PhotoBlock({ ratio = '4 / 3', label = 'photo', style = {}, tint = 'rgba(49,215,255,0.06)' }) {
  return (
    <div style={{
      width: '100%', aspectRatio: ratio, borderRadius: 14,
      background: `${tint}, repeating-linear-gradient(135deg, rgba(255,255,255,0.04) 0 2px, transparent 2px 8px)`,
      backgroundColor: tint,
      backgroundImage: 'repeating-linear-gradient(135deg, rgba(255,255,255,0.04) 0 2px, transparent 2px 8px), radial-gradient(60% 50% at 30% 30%, rgba(49,215,255,0.15), transparent 70%)',
      border: '1px dashed rgba(130,236,255,0.18)',
      display: 'grid', placeItems: 'center',
      fontFamily: 'JetBrains Mono', fontSize: 10, color: 'var(--ink-3)', letterSpacing: '0.08em',
      textTransform: 'uppercase',
      ...style,
    }}>{label}</div>
  );
}

// DiveSiteMap — stylized regional chart with dive-site pins.
//
// Props:
//   region:    region key (e.g. 'japan') — picks the bounding box + label
//   sites:     [{ name, lat, lng, highlight?: bool }] — markers to render
//   height:    pixel height of the rendered map (default 200)
//   onSiteTap: optional click handler invoked with the tapped site name
//
// The silhouette is hand-drawn for vibe (it's not survey-accurate); the
// markers project real lat/lng into the same coordinate space so the
// relative positions of dive sites are correct.
function DiveSiteMap({ region, sites, height = 200, onSiteTap }) {
  const bounds = (window.DD_STATE && window.DD_STATE.REGION_MAP_BOUNDS && window.DD_STATE.REGION_MAP_BOUNDS[region]) || null;
  if (!bounds || !sites || sites.length === 0) return null;

  const VBW = 200, VBH = 250;
  const project = (lat, lng) => {
    const x = ((lng - bounds.minLng) / (bounds.maxLng - bounds.minLng)) * VBW;
    const y = VBH - ((lat - bounds.minLat) / (bounds.maxLat - bounds.minLat)) * VBH;
    return [x, y];
  };
  // Clamp markers to viewBox with a small inset so they never sit on the edge.
  const inset = 10;
  const clamp = (v, lo, hi) => Math.max(lo, Math.min(hi, v));
  const projected = sites.map(s => {
    const [x, y] = project(s.lat, s.lng);
    return { ...s, x: clamp(x, inset, VBW - inset), y: clamp(y, inset, VBH - inset) };
  });

  // Coastline silhouettes — one per region. They're decorative; if a region
  // doesn't have one yet, we fall back to "no land", which still looks fine
  // because the markers carry the meaning.
  const LAND_PATHS = {
    'japan':
      'M8,8 L192,8 L192,55 Q180,75 170,90 Q162,110 158,140 Q150,175 130,200 ' +
      'Q100,225 65,220 Q38,215 30,190 Q22,160 28,140 Q35,125 22,110 ' +
      'Q12,98 18,80 Q25,65 22,45 Q20,28 8,18 Z',
  };
  const land = LAND_PATHS[region];

  return (
    <div style={{ position: 'relative', width: '100%', height,
      borderRadius: 16, overflow: 'hidden',
      background: 'radial-gradient(120% 90% at 30% 20%, rgba(49,215,255,0.18), rgba(11,42,68,0.7) 55%, rgba(5,11,20,0.95))',
      border: '1px solid rgba(130,236,255,0.16)',
      boxShadow: 'inset 0 0 24px rgba(0,0,0,0.4)',
    }}>
      <svg viewBox={`0 0 ${VBW} ${VBH}`} preserveAspectRatio="xMidYMid meet"
           style={{ position: 'absolute', inset: 0, width: '100%', height: '100%' }}>
        <defs>
          <pattern id="dd-map-grid" width="20" height="20" patternUnits="userSpaceOnUse">
            <path d="M 20 0 L 0 0 0 20" fill="none" stroke="rgba(130,236,255,0.08)" strokeWidth="0.5"/>
          </pattern>
          <radialGradient id="dd-map-pin-glow" cx="50%" cy="50%" r="50%">
            <stop offset="0%" stopColor="rgba(130,236,255,0.55)"/>
            <stop offset="100%" stopColor="rgba(130,236,255,0)"/>
          </radialGradient>
          <radialGradient id="dd-map-pin-hot" cx="50%" cy="50%" r="50%">
            <stop offset="0%" stopColor="rgba(215,180,106,0.7)"/>
            <stop offset="100%" stopColor="rgba(215,180,106,0)"/>
          </radialGradient>
        </defs>
        {/* Faint navigational grid */}
        <rect x="0" y="0" width={VBW} height={VBH} fill="url(#dd-map-grid)"/>
        {/* Land silhouette */}
        {land && (
          <path d={land}
            fill="rgba(20,52,86,0.55)"
            stroke="rgba(130,236,255,0.30)"
            strokeWidth="1.2"
            strokeLinejoin="round"
          />
        )}
        {/* Compass rose */}
        <g transform={`translate(${VBW - 26},22)`}>
          <circle r="10" fill="rgba(5,11,20,0.55)" stroke="rgba(130,236,255,0.30)" strokeWidth="0.7"/>
          <path d="M0,-7 L1.6,0 L0,7 L-1.6,0 Z" fill="rgba(130,236,255,0.85)"/>
          <text x="0" y="-12" textAnchor="middle" fontSize="6" fill="rgba(130,236,255,0.7)" fontFamily="JetBrains Mono">N</text>
        </g>
        {/* Markers */}
        {projected.map((s, i) => {
          const c = s.highlight ? '#D7B46A' : '#82ECFF';
          const glow = s.highlight ? 'url(#dd-map-pin-hot)' : 'url(#dd-map-pin-glow)';
          return (
            <g key={s.name + '-' + i}
               style={onSiteTap ? { cursor: 'pointer' } : null}
               onClick={onSiteTap ? () => onSiteTap(s.name) : undefined}>
              <circle cx={s.x} cy={s.y} r="14" fill={glow}/>
              <circle cx={s.x} cy={s.y} r="4.5" fill={c} stroke="rgba(5,11,20,0.95)" strokeWidth="1.2"/>
              {s.highlight && (
                <circle cx={s.x} cy={s.y} r="9" fill="none" stroke={c} strokeWidth="0.8" opacity="0.6">
                  <animate attributeName="r" values="6;14;6" dur="2.6s" repeatCount="indefinite"/>
                  <animate attributeName="opacity" values="0.6;0;0.6" dur="2.6s" repeatCount="indefinite"/>
                </circle>
              )}
            </g>
          );
        })}
      </svg>
      {/* Label strip */}
      <div style={{
        position: 'absolute', left: 10, bottom: 8, right: 10,
        display: 'flex', justifyContent: 'space-between', alignItems: 'baseline',
        fontSize: 10, color: 'var(--ink-3)', letterSpacing: '0.1em', textTransform: 'uppercase',
        fontFamily: 'JetBrains Mono',
        textShadow: '0 1px 4px rgba(0,0,0,0.6)',
        pointerEvents: 'none',
      }}>
        <span>{bounds.label}</span>
        <span>{sites.length} {sites.length === 1 ? 'site' : 'sites'}</span>
      </div>
    </div>
  );
}

// Resolve a site name -> { name, lat, lng } using SEED_DIVE_SITE_GEO, or null.
function resolveDiveSiteGeo(name) {
  if (!name) return null;
  const geo = (window.DD_STATE && window.DD_STATE.SEED_DIVE_SITE_GEO) || {};
  const hit = geo[name];
  if (!hit) return null;
  return { name, lat: hit.lat, lng: hit.lng, region: hit.region };
}

Object.assign(window, {
  Logo, SonarRing, GlassCard, Chip, XPBar, RarityRing, BottomNav, NavIcon,
  TopBar, IconBtn, ProgressDots, RarityFrame, StatCell, Avatar, PhotoBlock,
  DiveSiteMap, resolveDiveSiteGeo,
});
