/* global React */
const { useState, useEffect, useRef, useMemo } = React;

// ---------- Icons ----------
function Heart({ size = 18, color = '#E51937' }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill={color} aria-hidden="true">
      <path d="M12 21s-7.5-4.6-9.6-9.3C1.1 8.3 3.4 4.5 7.2 4.5c2 0 3.6 1.1 4.8 2.8 1.2-1.7 2.8-2.8 4.8-2.8 3.8 0 6.1 3.8 4.8 7.2C19.5 16.4 12 21 12 21z" />
    </svg>
  );
}
function ArrowRight({ size = 18 }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round" className="arrow" aria-hidden="true">
      <line x1="5" y1="12" x2="19" y2="12"/><polyline points="13 6 19 12 13 18"/>
    </svg>
  );
}
function ArrowLeft({ size = 16 }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
      <line x1="19" y1="12" x2="5" y2="12"/><polyline points="11 18 5 12 11 6"/>
    </svg>
  );
}
function Check({ size = 12 }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
      <polyline points="20 6 9 17 4 12"/>
    </svg>
  );
}
function GateIcon({ kind, size = 22 }) {
  const stroke = 'currentColor';
  const props = { width: size, height: size, viewBox: '0 0 24 24', fill: 'none', stroke, strokeWidth: 1.7, strokeLinecap: 'round', strokeLinejoin: 'round' };
  if (kind === 'calendar') return <svg {...props}><rect x="3" y="5" width="18" height="16" rx="2"/><path d="M3 10h18"/><path d="M8 3v4M16 3v4"/></svg>;
  if (kind === 'jet' || kind === 'plane') return <svg {...props}><path d="M2 14l9-2 4-9 2 1-2 9 8 4-1 2-9-2-3 5h-2l1-6-6-2v-2z"/></svg>;
  if (kind === 'palm')     return <svg {...props}><path d="M12 22V10"/><path d="M12 10c-1-3-4-5-7-4 1 3 4 5 7 4z"/><path d="M12 10c1-3 4-5 7-4-1 3-4 5-7 4z"/><path d="M12 10c-2-2-2-5 0-7 2 2 2 5 0 7z"/></svg>;
  if (kind === 'spark')    return <svg {...props}><path d="M12 3v4M12 17v4M3 12h4M17 12h4"/><path d="M5.6 5.6l2.8 2.8M15.6 15.6l2.8 2.8M5.6 18.4l2.8-2.8M15.6 8.4l2.8-2.8"/></svg>;
  return null;
}
function PrizeIcon({ kind, size = 18 }) {
  const props = { width: size, height: size, viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', strokeWidth: 1.8, strokeLinecap: 'round', strokeLinejoin: 'round' };
  if (kind === 'points') return <svg {...props}><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></svg>;
  if (kind === 'ticket') return <svg {...props}><path d="M3 9a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v2a2 2 0 0 0 0 4v2a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-2a2 2 0 0 0 0-4V9z"/><path d="M14 7v10"/></svg>;
  if (kind === 'gift')   return <svg {...props}><rect x="3" y="8" width="18" height="13" rx="2"/><path d="M3 12h18M12 8v13M7.5 8a2.5 2.5 0 1 1 0-5C13 3 12 8 12 8s-1-5 4.5-5a2.5 2.5 0 1 1 0 5"/></svg>;
  return null;
}

// ---------- Top bar ----------
function TopBar({ progress, stepLabel, intent }) {
  const intentLabel = {
    trip: 'Upcoming trip',
    frequent: 'Frequent flyer',
    vacation: 'Vacation planning',
    just: 'Just here'
  }[intent] || '';
  return (
    <header className="sw-bar">
      <div className="sw-bar-left">
        <div className="sw-mark"><span className="dot">A</span> Ape <span style={{color:'var(--sw-ink-3)'}}>×</span> <span style={{color:'var(--sw-blue)'}}>Southwest</span></div>
        <div className="sw-divider"></div>
        <span className="sw-pill"><span className="blink"></span> Live demo</span>
      </div>
      <div className="sw-bar-right">
        {intentLabel && <span className="sw-tenant"><b>{intentLabel}</b></span>}
        <div className="sw-progressbar"><span style={{width: `${Math.round((progress||0)*100)}%`}} /></div>
        <span className="sw-step">{stepLabel}</span>
      </div>
    </header>
  );
}

// ---------- Question chrome ----------
function QuestionChrome({ kicker, title, sub, children, onBack, onNext, onSkip, nextLabel = 'Continue', nextDisabled, hideBack }) {
  return (
    <section className="sw-screen">
      <div className="sw-kicker">{kicker}</div>
      <h2 className="sw-q-title" dangerouslySetInnerHTML={{__html: title}} />
      {sub && <p className="sw-q-sub">{sub}</p>}
      <div className="sw-q-body">{children}</div>
      <div className="sw-q-nav">
        {!hideBack ? (
          <button className="sw-q-back" onClick={onBack}><ArrowLeft /> Back</button>
        ) : <span/>}
        <div style={{display:'flex', gap:10, alignItems:'center'}}>
          {onSkip && (
            <button className="sw-q-skip" onClick={onSkip}>Skip this question →</button>
          )}
          {onNext && (
            <button className="sw-btn" onClick={onNext} disabled={nextDisabled}>
              {nextLabel} <ArrowRight />
            </button>
          )}
        </div>
      </div>
    </section>
  );
}

// ---------- Pills (single-select) ----------
function PillSelect({ options, value, onChange }) {
  return (
    <div className="sw-pills">
      {options.map(o => (
        <button
          key={o.id}
          className={`sw-pill-opt ${value === o.id ? 'active' : ''}`}
          onClick={() => onChange(o.id)}>
          {o.label}
        </button>
      ))}
    </div>
  );
}

// ---------- Pills (multi-select) ----------
function MultiPills({ options, value = [], onChange }) {
  const toggle = id => {
    if (value.includes(id)) onChange(value.filter(v => v !== id));
    else onChange([...value, id]);
  };
  return (
    <div className="sw-pills">
      {options.map(o => {
        const active = value.includes(o.id);
        return (
          <button
            key={o.id}
            className={`sw-pill-opt ${active ? 'active' : ''}`}
            onClick={() => toggle(o.id)}>
            <span className="check">{active && <Check />}</span>
            {o.label}
          </button>
        );
      })}
    </div>
  );
}

// ---------- Slider (business/leisure) ----------
function SliderInput({ value = 50, onChange, leftLabel, rightLabel }) {
  const v = value;
  const readout = v === 50 ? 'Even split — 50 / 50'
    : v < 50 ? `${100 - v}% leisure · ${v}% business`
    : `${v}% business · ${100 - v}% leisure`;
  return (
    <div className="sw-slider-wrap">
      <div className="sw-slider-readout">{readout}</div>
      <input
        type="range" min="0" max="100" step="5" value={v}
        className="sw-slider"
        style={{'--pct': v + '%'}}
        onChange={e => onChange(parseInt(e.target.value, 10))}
      />
      <div className="sw-slider-labels"><span>{leftLabel}</span><span>{rightLabel}</span></div>
    </div>
  );
}

// ---------- Autocomplete (single + multi) ----------
function Autocomplete({ value, onChange, suggestions, placeholder }) {
  const [q, setQ] = useState(value || '');
  const [focus, setFocus] = useState(false);
  const matches = useMemo(() => {
    if (!q || q === value) return [];
    return suggestions.filter(s => s.toLowerCase().includes(q.toLowerCase())).slice(0, 8);
  }, [q, suggestions, value]);
  return (
    <div className="sw-input-wrap">
      <input
        className="sw-input"
        placeholder={placeholder}
        value={q}
        onChange={e => { setQ(e.target.value); onChange(''); }}
        onFocus={() => setFocus(true)}
        onBlur={() => setTimeout(() => setFocus(false), 160)}
      />
      {focus && matches.length > 0 && (
        <div className="sw-suggestions">
          {matches.map(s => (
            <button key={s} className="sw-suggestion" onMouseDown={(e) => { e.preventDefault(); setQ(s); onChange(s); }}>
              {s}
            </button>
          ))}
        </div>
      )}
    </div>
  );
}

function MultiAutocomplete({ value = [], onChange, suggestions, placeholder, max = 3 }) {
  const [q, setQ] = useState('');
  const [focus, setFocus] = useState(false);
  const matches = useMemo(() => {
    if (!q) return [];
    return suggestions.filter(s => !value.includes(s) && s.toLowerCase().includes(q.toLowerCase())).slice(0, 6);
  }, [q, suggestions, value]);
  const add = (s) => { if (value.length < max) onChange([...value, s]); setQ(''); };
  const remove = (s) => onChange(value.filter(v => v !== s));
  return (
    <div className="sw-input-wrap">
      {value.length > 0 && (
        <div className="sw-chosen-list">
          {value.map(v => <span key={v} className="sw-chip">{v} <button onClick={() => remove(v)} aria-label={`Remove ${v}`}>×</button></span>)}
        </div>
      )}
      {value.length < max && (
        <input
          className="sw-input"
          placeholder={`${placeholder} (${value.length}/${max})`}
          value={q}
          onChange={e => setQ(e.target.value)}
          onFocus={() => setFocus(true)}
          onBlur={() => setTimeout(() => setFocus(false), 160)}
        />
      )}
      {focus && matches.length > 0 && (
        <div className="sw-suggestions">
          {matches.map(s => (
            <button key={s} className="sw-suggestion" onMouseDown={(e) => { e.preventDefault(); add(s); }}>
              {s}
            </button>
          ))}
        </div>
      )}
    </div>
  );
}

// ---------- Open text ----------
function OpenText({ value = '', onChange, placeholder }) {
  return (
    <textarea
      className="sw-input"
      style={{minHeight: 110, resize: 'vertical'}}
      value={value}
      placeholder={placeholder}
      onChange={e => onChange(e.target.value)}
    />
  );
}

Object.assign(window, {
  Heart, ArrowRight, ArrowLeft, Check, GateIcon, PrizeIcon,
  TopBar, QuestionChrome,
  PillSelect, MultiPills, SliderInput, Autocomplete, MultiAutocomplete, OpenText
});
