/* Day Trip Planner — shared UI primitives, icons, illustrations, frame */

// ─────────────────────────────────────────────────────────────
// Icons — simple consistent line set (24×24, stroke 1.8)
// ─────────────────────────────────────────────────────────────
function Icon({ name, size = 22, stroke = 1.8, fill = false, style }) {
  const p = {
    pin:     <><path d="M12 21c4.5-5 7-8 7-11a7 7 0 1 0-14 0c0 3 2.5 6 7 11Z"/><circle cx="12" cy="10" r="2.6"/></>,
    crosshair: <><circle cx="12" cy="12" r="7"/><path d="M12 2v3M12 19v3M2 12h3M19 12h3"/></>,
    clock:   <><circle cx="12" cy="12" r="8.5"/><path d="M12 7.5V12l3 2"/></>,
    fork:    <><path d="M7 3v7a2 2 0 0 0 4 0V3M9 10v11"/><path d="M16 3c-1.5 0-2.5 1.5-2.5 4S15 11 16 11s2.5-1.5 2.5-4S17.5 3 16 3Zm0 8v10"/></>,
    hike:    <><path d="M4 20l4-9 3 3 2-5 3 5 4 6\"/><circle cx="14" cy="4.5" r="1.7"/></>,
    bag:     <><path d="M5 8h14l-1 12H6L5 8Z\"/><path d="M9 8V6a3 3 0 0 1 6 0v2\"/></>,
    museum:  <><path d="M3 9l9-5 9 5\"/><path d="M5 9v8M10 9v8M14 9v8M19 9v8\"/><path d="M3 20h18\"/></>,
    beer:    <><rect x="5" y="7" width="9" height="13" rx="2"/><path d="M14 10h3a2 2 0 0 1 2 2v3a2 2 0 0 1-2 2h-3\"/><path d="M7 4.5c1-1 2 0 2.5-.5\"/></>,
    kid:     <><circle cx="12" cy="7" r="3"/><path d="M6 21v-2a6 6 0 0 1 12 0v2\"/></>,
    scenic:  <><path d="M3 18l5-7 4 5 3-4 6 6\"/><circle cx="17" cy="6.5" r="2\"/><rect x="2.5" y="4" width="19" height="16" rx="2.5\"/></>,
    star:    <><path d="M12 3.5l2.4 5.1 5.6.7-4.1 3.9 1.1 5.6L12 16.9 7 18.8l1.1-5.6L4 9.3l5.6-.7L12 3.5Z\"/></>,
    car:     <><path d="M4 13l1.5-4.5A2 2 0 0 1 7.4 7h9.2a2 2 0 0 1 1.9 1.5L20 13\"/><path d="M3 13h18v4a1 1 0 0 1-1 1h-1.5a1 1 0 0 1-1-1v-1H6.5v1a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1v-4Z\"/><path d="M6.5 15.5h.01M17.5 15.5h.01\"/></>,
    dollar:  <><path d="M12 3v18\"/><path d="M16 7.5c0-1.7-1.8-2.8-4-2.8s-4 1-4 2.8 1.8 2.5 4 2.9 4 1.2 4 3-1.8 2.9-4 2.9-4-1.1-4-2.9\"/></>,
    users:   <><circle cx="9" cy="8" r="3"/><path d="M3 20v-1.5A4.5 4.5 0 0 1 7.5 14h3A4.5 4.5 0 0 1 15 18.5V20\"/><path d="M16 5.2a3 3 0 0 1 0 5.6M21 20v-1.5a4.5 4.5 0 0 0-3-4.2\"/></>,
    chevR:   <><path d="M9 5l7 7-7 7\"/></>,
    chevD:   <><path d="M5 9l7 7 7-7\"/></>,
    chevL:   <><path d="M15 5l-7 7 7 7\"/></>,
    plus:    <><path d="M12 5v14M5 12h14\"/></>,
    check:   <><path d="M4 12.5l5 5L20 6.5\"/></>,
    swap:    <><path d="M4 8h13l-3-3M20 16H7l3 3\"/></>,
    map:     <><path d="M9 4L4 6v14l5-2 6 2 5-2V4l-5 2-6-2Z\"/><path d="M9 4v14M15 6v14\"/></>,
    heart:   <><path d="M12 20s-7-4.4-7-9.5A3.8 3.8 0 0 1 12 7a3.8 3.8 0 0 1 7-2.5C19 10.6 12 20 12 20Z\"/></>,
    sparkle: <><path d="M12 3l1.6 5.4L19 10l-5.4 1.6L12 17l-1.6-5.4L5 10l5.4-1.6L12 3Z\"/></>,
    reroll:  <><path d="M4 10a8 8 0 0 1 14-4l2 2M20 14a8 8 0 0 1-14 4l-2-2\"/><path d="M19 3v5h-5M5 21v-5h5\"/></>,
    x:       <><path d="M6 6l12 12M18 6L6 18\"/></>,
    trash:   <><path d="M5 7h14M9 7V5h6v2M7 7l1 13h8l1-13\"/></>,
    arrowUp: <><path d="M12 19V5M6 11l6-6 6 6\"/></>,
    arrowR:  <><path d="M5 12h14M13 6l6 6-6 6\"/></>,
    open:    <><path d="M14 5h5v5M19 5l-8 8M11 5H6a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-5\"/></>,
    sun:     <><circle cx="12" cy="12" r="4.5\"/><path d="M12 2v2.5M12 19.5V22M2 12h2.5M19.5 12H22M5 5l1.8 1.8M17.2 17.2L19 19M19 5l-1.8 1.8M6.8 17.2 5 19\"/></>,
  }[name];
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill={fill ? 'currentColor' : 'none'}
      stroke={fill ? 'none' : 'currentColor'} strokeWidth={stroke} strokeLinecap="round"
      strokeLinejoin="round" style={style} aria-hidden="true">{p}</svg>
  );
}

const INTEREST_ICON = {
  Dining: 'fork', Hiking: 'hike', Shopping: 'bag', Museums: 'museum',
  Breweries: 'beer', 'Kid-friendly': 'kid', 'Scenic Drives': 'scenic', 'Quirky/Oddities': 'star',
};

// ─────────────────────────────────────────────────────────────
// Status bar
// ─────────────────────────────────────────────────────────────
function StatusBar({ theme = 'dark', floating = false, time = '9:41' }) {
  return (
    <div className={'statusbar ' + theme}
      style={floating ? { position: 'absolute', top: 0, left: 0, right: 0 } : null}>
      <span className="sb-time">{time}</span>
      <div className="sb-right">
        <svg className="sb-glyph" width="18" height="11" viewBox="0 0 18 11" fill="currentColor">
          <rect x="0" y="7" width="3" height="4" rx="0.6"/><rect x="4.5" y="4.8" width="3" height="6.2" rx="0.6"/>
          <rect x="9" y="2.5" width="3" height="8.5" rx="0.6"/><rect x="13.5" y="0" width="3" height="11" rx="0.6"/>
        </svg>
        <svg className="sb-glyph" width="16" height="11" viewBox="0 0 16 11" fill="currentColor">
          <path d="M8 2.8c2 0 3.9.8 5.3 2.2l1.1-1.1A9 9 0 0 0 8 1.2 9 9 0 0 0 1.6 3.9l1.1 1.1A7.4 7.4 0 0 1 8 2.8Z"/>
          <path d="M8 6.1c1.1 0 2.1.45 2.8 1.2l1.1-1.1A5.5 5.5 0 0 0 8 4.6a5.5 5.5 0 0 0-3.9 1.6l1.1 1.1A3.9 3.9 0 0 1 8 6.1Z"/>
          <circle cx="8" cy="9.4" r="1.3"/>
        </svg>
        <svg className="sb-glyph" width="26" height="12" viewBox="0 0 26 12">
          <rect x="0.5" y="0.5" width="22" height="11" rx="3" stroke="currentColor" strokeOpacity="0.4" fill="none"/>
          <rect x="2" y="2" width="17" height="8" rx="1.8" fill="currentColor"/>
          <path d="M24 4v4c.8-.3 1.4-1 1.4-2S24.8 4.3 24 4Z" fill="currentColor" fillOpacity="0.5"/>
        </svg>
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// Phone frame (interactive) + Board frame (overview)
// ─────────────────────────────────────────────────────────────
function PhoneFrame({ children, homeTheme = 'dark' }) {
  return (
    <div className="phone-bezel dtp">
      <div className="phone-screen">
        <div className="island" />
        {children}
        <div className={'home-ind ' + homeTheme} />
      </div>
    </div>
  );
}

function BoardFrame({ children, homeTheme = 'dark' }) {
  return (
    <div className="board-screen dtp">
      {children}
      <div className={'home-ind ' + homeTheme} style={{ position: 'absolute' }} />
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// Illustrations — winding road + compass (stylized, abstract)
// ─────────────────────────────────────────────────────────────
function RoadIllustration({ style }) {
  return (
    <svg viewBox="0 0 375 320" style={style} aria-hidden="true" preserveAspectRatio="xMidYMax meet">
      {/* soft hills */}
      <path d="M0 250 Q70 205 150 235 T375 220 V320 H0 Z" fill="var(--sage-soft)"/>
      <path d="M0 285 Q110 250 210 278 T375 268 V320 H0 Z" fill="var(--sage)" opacity="0.22"/>
      {/* sun */}
      <circle cx="288" cy="78" r="34" fill="var(--amber-soft)"/>
      <circle cx="288" cy="78" r="20" fill="var(--amber)" opacity="0.85"/>
      {/* winding road — two edges + dashed center */}
      <path d="M150 320 C150 250 230 235 215 175 C202 122 120 120 140 66 C152 33 205 30 230 8"
        fill="none" stroke="var(--ink)" strokeOpacity="0.12" strokeWidth="46" strokeLinecap="round"/>
      <path d="M150 320 C150 250 230 235 215 175 C202 122 120 120 140 66 C152 33 205 30 230 8"
        fill="none" stroke="var(--card)" strokeWidth="40" strokeLinecap="round"/>
      <path d="M150 320 C150 250 230 235 215 175 C202 122 120 120 140 66 C152 33 205 30 230 8"
        fill="none" stroke="var(--accent)" strokeOpacity="0.85" strokeWidth="3.4"
        strokeDasharray="2 16" strokeLinecap="round"/>
      {/* start pin */}
      <g transform="translate(150 304)">
        <circle r="12" fill="var(--accent)"/>
        <circle r="4.5" fill="#fff"/>
      </g>
      {/* destination flag */}
      <g transform="translate(230 8)">
        <circle r="9" fill="var(--sky)"/>
        <circle r="3.3" fill="#fff"/>
      </g>
    </svg>
  );
}

function Compass({ size = 132, spin = false, style }) {
  return (
    <svg width={size} height={size} viewBox="0 0 120 120" style={style} aria-hidden="true">
      <circle cx="60" cy="60" r="56" fill="var(--card)" />
      <circle cx="60" cy="60" r="56" fill="none" stroke="var(--line)" strokeWidth="1.5"/>
      <circle cx="60" cy="60" r="47" fill="none" stroke="var(--sand)" strokeWidth="2"/>
      {/* tick ring (rotates slowly) */}
      <g className={spin ? 'spin-rev' : ''} style={{ transformBox: 'fill-box', transformOrigin: 'center' }}>
        {Array.from({ length: 24 }).map((_, i) => (
          <rect key={i} x="59.2" y="9" width="1.6" height={i % 6 === 0 ? 9 : 5}
            rx="0.8" fill="var(--ink-3)" opacity={i % 6 === 0 ? 0.7 : 0.4}
            transform={`rotate(${i * 15} 60 60)`} />
        ))}
      </g>
      {/* needle (the spinner) */}
      <g className={spin ? 'spin' : ''} style={{ transformBox: 'fill-box', transformOrigin: 'center' }}>
        <path d="M60 22 L70 60 L60 56 L50 60 Z" fill="var(--accent)"/>
        <path d="M60 98 L70 60 L60 64 L50 60 Z" fill="var(--ink)" opacity="0.82"/>
      </g>
      <circle cx="60" cy="60" r="5.5" fill="var(--card)" stroke="var(--ink)" strokeWidth="2"/>
    </svg>
  );
}

// ─────────────────────────────────────────────────────────────
// Map preview — stylized minimal map with route + numbered pins
// ─────────────────────────────────────────────────────────────
function MapPreview({ height = 168, style, pins = 4, active = null }) {
  const pts = [[42, 120], [120, 78], [205, 116], [300, 58]];
  return (
    <div style={{ position: 'relative', height, overflow: 'hidden', background: 'var(--sage-soft)', ...style }}>
      <svg viewBox="0 0 340 168" width="100%" height="100%" preserveAspectRatio="xMidYMid slice" style={{ display: 'block' }}>
        <rect width="340" height="168" fill="var(--sage-soft)"/>
        {/* water */}
        <path d="M250 168 Q255 120 300 112 Q340 106 340 60 V168 Z" fill="var(--sky-soft)"/>
        <path d="M0 0 H120 Q150 40 110 70 Q70 95 95 168 H0 Z" fill="var(--sky-soft)" opacity="0.5"/>
        {/* parks */}
        <circle cx="60" cy="40" r="34" fill="var(--sage)" opacity="0.18"/>
        <circle cx="280" cy="140" r="40" fill="var(--sage)" opacity="0.16"/>
        {/* faint road grid */}
        <g stroke="var(--card)" strokeWidth="5" opacity="0.6" strokeLinecap="round">
          <path d="M-10 70 H360"/><path d="M-10 130 H360"/><path d="M90 -10 V178"/><path d="M230 -10 V178"/>
        </g>
        <g stroke="#fff" strokeWidth="2" opacity="0.5" strokeLinecap="round">
          <path d="M-10 100 H360"/><path d="M160 -10 V178"/>
        </g>
        {/* route */}
        <path d="M42 120 C80 96 96 70 120 78 C150 88 168 122 205 116 C250 108 262 70 300 58"
          fill="none" stroke="var(--accent)" strokeWidth="4.5" strokeLinecap="round"
          strokeDasharray="1 11" opacity="0.95"/>
        <path d="M42 120 C80 96 96 70 120 78 C150 88 168 122 205 116 C250 108 262 70 300 58"
          fill="none" stroke="var(--accent)" strokeWidth="1.6" opacity="0.4"/>
        {/* pins */}
        {pts.slice(0, pins).map((p, i) => (
          <g key={i} transform={`translate(${p[0]} ${p[1]})`}>
            <ellipse cx="0" cy="2" rx="9" ry="3.5" fill="rgba(43,38,32,0.16)"/>
            <path d="M0 2 C-9 -8 -9 -14 0 -19 C9 -14 9 -8 0 2Z"
              fill={active === i ? 'var(--sky)' : 'var(--accent)'} />
            <circle cx="0" cy="-12" r="6.2" fill="#fff"/>
            <text x="0" y="-9" textAnchor="middle" fontFamily="var(--font-display)"
              fontSize="9" fontWeight="700" fill={active === i ? 'var(--sky)' : 'var(--accent)'}>{i + 1}</text>
          </g>
        ))}
      </svg>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// Small building blocks
// ─────────────────────────────────────────────────────────────
function Placeholder({ label, tone, style, labelStyle, src }) {
  const [failed, setFailed] = React.useState(false);
  // reset the error state if the source changes (e.g. a stop is rerolled/swapped)
  React.useEffect(() => { setFailed(false); }, [src]);
  const showImg = src && !failed;
  return (
    <div className={'ph' + (tone ? ' ph-' + tone : '')} style={style}>
      {showImg && (
        <img className="ph-img" src={src} alt={label || ''} loading="lazy"
          onError={() => setFailed(true)} />
      )}
      {label && !showImg && <span className="ph-label" style={labelStyle}>{label}</span>}
    </div>
  );
}

function Tag({ children, tone }) {
  return <span className={'tag' + (tone ? ' tag-' + tone : '')}>{children}</span>;
}

function Stat({ k, children }) {
  return (
    <div className="stat">
      <span className="stat-k">{k}</span>
      <span className="stat-v">{children}</span>
    </div>
  );
}

function Button({ variant = 'primary', size, pill, children, icon, iconR, onClick, disabled, style }) {
  const cls = ['btn', 'btn-' + variant, size === 'sm' ? 'btn-sm' : '', pill ? 'btn-pill' : ''].join(' ');
  return (
    <button className={cls} onClick={onClick} disabled={disabled} style={style}>
      {icon && !iconR && <Icon name={icon} size={size === 'sm' ? 18 : 20} />}
      {children}
      {icon && iconR && <Icon name={icon} size={size === 'sm' ? 18 : 20} />}
    </button>
  );
}

function IconButton({ name, onClick, style, size = 20, label }) {
  return (
    <button className="icon-btn" onClick={onClick} style={style} aria-label={label}>
      <Icon name={name} size={size} />
    </button>
  );
}

Object.assign(window, {
  Icon, INTEREST_ICON, StatusBar, PhoneFrame, BoardFrame,
  RoadIllustration, Compass, MapPreview, Placeholder, Tag, Stat, Button, IconButton,
});
