// iceland-ui.jsx — Glacier theme + shared primitives. Exports to window.
const { useState, useEffect, useRef } = React;

// ── Theme ────────────────────────────────────────────────────
const GL = {
  bg: '#0B0C0F',
  surface: 'rgba(255,255,255,0.045)',
  surfaceSolid: '#15171C',
  line: 'rgba(255,255,255,0.10)',
  lineStrong: 'rgba(255,255,255,0.18)',
  text: '#F4F6F8',
  mut: 'rgba(244,246,248,0.62)',
  faint: 'rgba(244,246,248,0.4)',
  glacier: 'oklch(0.76 0.11 232)',
  glacierDim: 'oklch(0.76 0.11 232 / 0.16)',
  warn: 'oklch(0.78 0.13 60)',
  display: '"Anton", sans-serif',
  body: '"Archivo", sans-serif',
  mono: '"Space Mono", monospace',
};

// ── Striped photo placeholder ────────────────────────────────
function Ph({ label, hue = 220, h = 120, r = 0, src, style = {}, children }) {
  return (
    <div style={{
      height: h, borderRadius: r, position: 'relative', overflow: 'hidden', isolation: 'isolate',
      background: `linear-gradient(135deg, oklch(0.30 0.045 ${hue}), oklch(0.18 0.04 ${hue}))`, ...style,
    }}>
      <div style={{ position: 'absolute', inset: 0,
        background: 'repeating-linear-gradient(135deg, transparent 0 12px, rgba(255,255,255,0.04) 12px 13px)' }} />
      {src && (
        <img src={src} alt={label || ''} loading="lazy"
          onError={e => { e.currentTarget.style.display = 'none'; }}
          style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover', zIndex: 1 }} />
      )}
      {label && !src && (
        <div style={{ position: 'absolute', left: 12, bottom: 10, display: 'flex', alignItems: 'center', gap: 7, zIndex: 2 }}>
          <span style={{ fontFamily: GL.mono, fontSize: 8.5, letterSpacing: 1, color: 'rgba(255,255,255,0.6)',
            border: '1px solid rgba(255,255,255,0.5)', padding: '1px 4px', borderRadius: 2 }}>FOTO</span>
          <span style={{ fontFamily: GL.mono, fontSize: 10, color: 'rgba(255,255,255,0.66)', letterSpacing: 0.3 }}>{label}</span>
        </div>
      )}
      {children}
    </div>
  );
}

// ── Countdown ────────────────────────────────────────────────
function useCountdown(iso) {
  const [d, setD] = useState(null);
  useEffect(() => {
    const target = new Date(iso);
    const tick = () => {
      const ms = target - new Date();
      if (ms <= 0) { setD({ days: 0, hours: 0, live: true }); return; }
      setD({ days: Math.floor(ms / 86400000), hours: Math.floor((ms % 86400000) / 3600000) });
    };
    tick(); const id = setInterval(tick, 30000); return () => clearInterval(id);
  }, [iso]);
  return d;
}

// ── Small bits ───────────────────────────────────────────────
function Kicker({ children, color = GL.glacier, style = {} }) {
  return <div style={{ fontFamily: GL.mono, fontSize: 10.5, letterSpacing: 2, color, ...style }}>{children}</div>;
}

function KickBadge({ small }) {
  return (
    <span style={{ fontFamily: GL.mono, fontSize: small ? 8.5 : 9.5, fontWeight: 700, letterSpacing: 1,
      color: GL.bg, background: GL.glacier, padding: small ? '2px 5px' : '3px 7px', borderRadius: 3, whiteSpace: 'nowrap' }}>KICK</span>
  );
}

// Top bar for subviews
function TopBar({ title, onBack }) {
  return (
    <div style={{
      position: 'sticky', top: 0, zIndex: 30,
      display: 'flex', alignItems: 'center', gap: 12, padding: '14px 16px 12px',
      background: 'rgba(11,12,15,0.82)', backdropFilter: 'blur(16px)', WebkitBackdropFilter: 'blur(16px)',
      borderBottom: `1px solid ${GL.line}`,
    }}>
      <button onClick={onBack} style={{
        width: 38, height: 38, borderRadius: 11, flexShrink: 0, cursor: 'pointer',
        background: GL.surface, border: `1px solid ${GL.line}`, color: GL.text,
        display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 0,
      }}>
        <svg width="11" height="18" viewBox="0 0 11 18" fill="none"><path d="M9 1L2 9l7 8" stroke={GL.text} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/></svg>
      </button>
      <div style={{ fontFamily: GL.display, fontSize: 21, letterSpacing: 0.5, textTransform: 'uppercase', color: GL.text }}>{title}</div>
    </div>
  );
}

// Checklist row with localStorage persistence handled by parent
function CheckRow({ checked, onToggle, text, note, last }) {
  return (
    <button onClick={onToggle} style={{
      display: 'flex', gap: 13, alignItems: 'flex-start', width: '100%', textAlign: 'left',
      padding: '15px 4px', background: 'none', border: 'none', cursor: 'pointer',
      borderBottom: last ? 'none' : `1px solid ${GL.line}`,
    }}>
      <div style={{
        width: 24, height: 24, borderRadius: 7, flexShrink: 0, marginTop: 1,
        border: `1.5px solid ${checked ? GL.glacier : GL.lineStrong}`,
        background: checked ? GL.glacier : 'transparent',
        display: 'flex', alignItems: 'center', justifyContent: 'center', transition: 'all .15s',
      }}>
        {checked && <svg width="13" height="13" viewBox="0 0 13 13" fill="none"><path d="M2 7l3 3 6-7" stroke={GL.bg} strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"/></svg>}
      </div>
      <div style={{ flex: 1 }}>
        <div style={{ fontFamily: GL.body, fontWeight: 600, fontSize: 15.5, color: checked ? GL.faint : GL.text,
          textDecoration: checked ? 'line-through' : 'none', lineHeight: 1.25 }}>{text}</div>
        {note && <div style={{ fontFamily: GL.body, fontSize: 12.5, color: GL.mut, marginTop: 3, lineHeight: 1.35 }}>{note}</div>}
      </div>
    </button>
  );
}

function useStored(key, init) {
  const [v, setV] = useState(() => {
    try { const s = localStorage.getItem(key); return s ? JSON.parse(s) : init; } catch (e) { return init; }
  });
  useEffect(() => { try { localStorage.setItem(key, JSON.stringify(v)); } catch (e) {} }, [key, v]);
  return [v, setV];
}

// ── Shared map projection (SW-Iceland, km-accurate, padded to 0..100) ──
// Built once after the trip data arrives (see Root in iceland-auth.jsx), then read
// as the global `MAP` everywhere. Not computed at load — there's no data yet then.
function buildMAP() {
  const LON0 = -22.85, LAT1 = 64.46, COSLAT = 0.438;
  const pts = window.TRIP.pins.map(p => ({ ...p, kmx: (p.lon - LON0) * 111 * COSLAT, kmy: (LAT1 - p.lat) * 111 }));
  const maxx = Math.max(...pts.map(p => p.kmx)), maxy = Math.max(...pts.map(p => p.kmy)), pad = 11;
  const byId = {};
  pts.forEach(p => { p.x = pad + (p.kmx / maxx) * (100 - 2 * pad); p.y = pad + (p.kmy / maxy) * (100 - 2 * pad); byId[p.id] = p; });
  return { pts, byId, aspect: maxx / maxy };
}

// Small inline link: a map pin ("map") or an external-arrow ("ext") source link.
function PinLink({ href, kind = 'map', children }) {
  const icon = kind === 'ext'
    ? <svg width="11" height="11" viewBox="0 0 24 24" fill="none"><path d="M7 17L17 7M9 7h8v8" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"/></svg>
    : <svg width="11" height="11" viewBox="0 0 24 24" fill="none"><path d="M12 21s7-6.3 7-11a7 7 0 10-14 0c0 4.7 7 11 7 11z" stroke="currentColor" strokeWidth="2" strokeLinejoin="round"/><circle cx="12" cy="10" r="2.2" fill="currentColor"/></svg>;
  return (
    <a href={href} target="_blank" rel="noopener" style={{ display: 'inline-flex', alignItems: 'center', gap: 5,
      fontFamily: GL.mono, fontSize: 11, letterSpacing: 0.3, color: GL.glacier, textDecoration: 'none' }}>
      {icon}{children}
    </a>
  );
}

Object.assign(window, { GL, Ph, useCountdown, Kicker, KickBadge, TopBar, CheckRow, useStored, buildMAP, PinLink });
