// Shared UI: Nav, Footer, Card primitives, Stars, Avatar etc.

const NAV = [
  { key: 'home', label: 'Home' },
  { key: 'operators', label: 'Operators' },
  { key: 'manufacturers', label: 'Manufacturers and Tools' },
  { key: 'designers', label: 'Designers' },
  { key: 'pricing', label: 'Pricing' },
  { key: 'blog', label: 'Journal' },
];

const Nav = ({ route, nav }) => {
  const section = route.page;
  return (
    <>
      <div className="announce">
        <span className="dot" />
        NEW · The 2026 State of the Drone Show Industry report is live
        <a onClick={() => nav({ page: 'blog-post', id: 'bp-01' })} style={{ marginLeft: 14, textDecoration: 'underline', cursor: 'pointer' }}>Read →</a>
      </div>
      <nav className="nav">
        <div className="container nav-inner">
          <a className="logo" onClick={() => nav({ page: 'home' })} style={{ cursor: 'pointer' }}>
            <LogoMark size={22} />
            <span>DroneShowCompanies</span>
          </a>
          <div className="nav-links">
            {NAV.slice(1).map(item => (
              <a key={item.key}
                 className={`nav-link ${matchNav(section, item.key) ? 'active' : ''}`}
                 onClick={() => nav({ page: item.key === 'operators' ? 'directory' : item.key === 'manufacturers' ? 'directory-mf' : item.key === 'designers' ? 'directory-ds' : item.key })}
                 style={{ cursor: 'pointer' }}>
                {item.label}
              </a>
            ))}
            {/* placeholder for matchNav */}
          </div>
          <div className="nav-spacer" />
          <div className="nav-right">
            <button className="btn btn-ghost btn-sm" onClick={() => nav({ page: 'operator-login' })}>Operator login</button>
            <button className="btn btn-primary btn-sm" onClick={() => nav({ page: 'rfp' })}>Post an RFP</button>
          </div>
        </div>
      </nav>
    </>
  );
};

function matchNav(section, key) {
  if (key === 'operators') return section === 'directory' || section === 'operator';
  if (key === 'manufacturers') return section === 'directory-mf' || section === 'manufacturer';
  if (key === 'designers') return section === 'directory-ds' || section === 'designer';
  if (key === 'blog') return section === 'blog' || section === 'blog-post';
  if (key === 'tools') return section === 'tools';
  return section === key;
}

const Footer = ({ nav }) => (
  <footer className="footer">
    <div className="container">
      <div style={{ display: 'grid', gridTemplateColumns: '1.2fr 1fr 1fr 1fr 1fr', gap: 32, marginBottom: 48 }}>
        <div>
          <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 14 }}>
            <LogoMark size={22} color="#fff" />
            <span style={{ color: '#fff', fontWeight: 600 }}>DroneShowCompanies</span>
          </div>
          <p style={{ fontSize: 13, lineHeight: 1.6, maxWidth: 280, color: 'oklch(74% 0.012 260)' }}>
            The complete directory of professional drone show companies, designers, and manufacturers. Independently operated.
          </p>
          <div style={{ marginTop: 20, display: 'flex', gap: 10, flexWrap: 'wrap' }}>
            <span className="chip" style={{ background: 'transparent', color: 'oklch(74% 0.012 260)', borderColor: 'oklch(30% 0.012 260)' }}>{window.__DSC_DATA?.operators?.length || 0} operators</span>
            <span className="chip" style={{ background: 'transparent', color: 'oklch(74% 0.012 260)', borderColor: 'oklch(30% 0.012 260)' }}>{window.__DSC_DATA?.manufacturers?.length || 0} mfrs</span>
          </div>
        </div>
        <div>
          <h5>Directory</h5>
          <ul>
            <li><a onClick={() => nav({ page: 'directory' })} style={{cursor:'pointer'}}>Operators</a></li>
            <li><a onClick={() => nav({ page: 'directory-mf' })} style={{cursor:'pointer'}}>Manufacturers</a></li>
            <li><a onClick={() => nav({ page: 'directory-ds' })} style={{cursor:'pointer'}}>Designers</a></li>
            <li><a onClick={() => nav({ page: 'rfp' })} style={{cursor:'pointer'}}>Post an RFP</a></li>
          </ul>
        </div>
        <div>
          <h5>For listings</h5>
          <ul>
            <li><a onClick={() => nav({ page: 'pricing' })} style={{cursor:'pointer'}}>Pricing</a></li>
            <li><a onClick={() => nav({ page: 'operator-login' })} style={{cursor:'pointer'}}>Operator login</a></li>
            <li><a>Claim your profile</a></li>
            <li><a>Advertiser program</a></li>
          </ul>
        </div>
        <div>
          <h5>Resources</h5>
          <ul>
            <li><a onClick={() => nav({ page: 'blog' })} style={{cursor:'pointer'}}>Journal</a></li>
            <li><a>Buyer's guide</a></li>
            <li><a>Pricing calculator</a></li>
            <li><a>FAA waiver help</a></li>
          </ul>
        </div>
        <div>
          <h5>Company</h5>
          <ul>
            <li><a>About</a></li>
            <li><a>Editorial standards</a></li>
            <li><a>Contact</a></li>
            <li><a>Press</a></li>
          </ul>
        </div>
      </div>
      <div className="footer-bottom">
        <span>© 2026 DroneShowCompanies, An independent industry directory</span>
        <span>v3.2 · Updated Apr 2026</span>
      </div>
    </div>
  </footer>
);

const Stars = ({ n = 5, filled = 5, size = 12 }) => (
  <span className="stars">
    {Array.from({ length: n }).map((_, i) => (
      <svg key={i} className={`star ${i < filled ? 'on' : ''}`} width={size} height={size} viewBox="0 0 24 24">
        <path d="M12 2l2.9 6.9 7.4.6-5.6 4.9 1.7 7.3L12 17.8 5.6 21.7l1.7-7.3L1.7 9.5l7.4-.6z" />
      </svg>
    ))}
  </span>
);

const Avatar = ({ name, size = 32, hex }) => {
  const initials = name.split(' ').map(s => s[0]).slice(0, 2).join('');
  return (
    <div style={{
      width: size, height: size, borderRadius: '50%',
      background: hex || 'var(--ink)',
      color: '#fff',
      display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
      fontFamily: 'var(--ff-mono)', fontSize: size * 0.38, fontWeight: 500, letterSpacing: 0,
      flexShrink: 0,
    }}>{initials.toUpperCase()}</div>
  );
};

const Tier = ({ tier }) => {
  const map = {
    Elite: { cls: 'amber', label: 'Elite' },
    Pro: { cls: 'accent', label: 'Pro' },
    Basic: { cls: '', label: 'Basic' },
    Sponsored: { cls: 'solid', label: 'Sponsored' }
  };
  const t = map[tier] || map.Basic;
  return <span className={`chip ${t.cls}`} style={{ fontSize: 10 }}><span className="sq" />{t.label}</span>;
};

const OperatorCard = ({ op, onClick, layout = 'grid' }) => {
  if (layout === 'list') {
    return (
      <div className="card hover-lift" onClick={onClick} style={{ cursor: 'pointer', padding: 0, display: 'flex', gap: 0 }}>
        <div style={{ width: 220, flexShrink: 0 }}>
          <DotFormation variant={['arc', 'ring', 'wave', 'triangle', 'star'][op.id.charCodeAt(op.id.length - 1) % 5]} color={op.hex} size="square" density={60} />
        </div>
        <div style={{ padding: 20, flex: 1, display: 'flex', flexDirection: 'column', gap: 8 }}>
          <div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', gap: 16 }}>
            <div>
              <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 4 }}>
                <h3 style={{ margin: 0, fontSize: 17, fontWeight: 600, letterSpacing: '-0.01em' }}>{op.name}</h3>
                {op.verified && <VerifiedIcon />}
                {op.skyrender && <SkyRenderBadge />}
              </div>
              <div className="mono muted" style={{ fontSize: 12 }}>{[op.city, op.fleet ? `${op.fleet.toLocaleString()} drones` : null, op.founded ? `est. ${op.founded}` : null].filter(Boolean).join(' · ')}</div>
            </div>
            {op.rating > 0 && (
              <div style={{ textAlign: 'right' }}>
                <div style={{ display: 'flex', alignItems: 'center', gap: 6, justifyContent: 'flex-end' }}>
                  <Stars filled={Math.round(op.rating)} />
                  <strong style={{ fontSize: 14 }}>{op.rating}</strong>
                </div>
              </div>
            )}
          </div>
          <p style={{ margin: '4px 0 8px', color: 'var(--ink-2)', fontSize: 14 }}>{op.headline}</p>
          <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap', marginTop: 'auto', alignItems: 'center' }}>
            {op.specialties.map(s => <span key={s} className="tag">{s}</span>)}
            <div style={{ marginLeft: 'auto' }}><ClaimButton entityType="operator" entity={op} /></div>
          </div>
        </div>
      </div>
    );
  }

  return (
    <div className="card hover-lift" onClick={onClick} style={{ cursor: 'pointer', overflow: 'hidden' }}>
      <DotFormation variant={['arc', 'ring', 'wave', 'triangle', 'star'][op.id.charCodeAt(op.id.length - 1) % 5]} color={op.hex || '#4a6fff'} density={70} label={op.fleet ? `${op.fleet} DRONES` : op.name.toUpperCase()} />
      <div style={{ padding: 'var(--density-pad)' }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 6 }}>
          <h3 style={{ margin: 0, fontSize: 16, fontWeight: 600, letterSpacing: '-0.01em' }}>{op.name}</h3>
          {op.verified && <VerifiedIcon />}
        </div>
        <div className="mono muted" style={{ fontSize: 11, marginBottom: 10 }}>{op.city}</div>
        <p style={{ margin: '0 0 12px', color: 'var(--ink-2)', fontSize: 13, lineHeight: 1.45 }}>{op.headline}</p>
        <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap', marginBottom: 12 }}>
          {op.specialties.slice(0, 2).map(s => <span key={s} className="tag">{s}</span>)}
          {op.specialties.length > 2 && <span className="tag">+{op.specialties.length - 2}</span>}
        </div>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', paddingTop: 12, borderTop: '1px solid var(--line)' }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
            {op.rating > 0 ? (
              <>
                <Stars filled={Math.round(op.rating)} size={11} />
                <span className="mono" style={{ fontSize: 11 }}>{op.rating}</span>
              </>
            ) : <span className="mono muted" style={{ fontSize: 11 }}>Unrated</span>}
          </div>
          <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
            {op.skyrender && <SkyRenderBadge />}
            <ClaimButton entityType="operator" entity={op} />
          </div>
        </div>
      </div>
    </div>
  );
};

const VerifiedIcon = () => (
  <svg width="14" height="14" viewBox="0 0 16 16" style={{ color: 'var(--accent)' }}>
    <path fill="currentColor" d="M8 0l1.6 1.6L12 1l.4 2.4L14.8 4l-.6 2.4L16 8l-1.8 1.6.6 2.4-2.4.6L12 15l-2.4-.4L8 16l-1.6-1.6L4 15l-.4-2.4L1.2 12l.6-2.4L0 8l1.8-1.6L1.2 4l2.4-.6L4 1l2.4.4z" />
    <path fill="#fff" d="M6.8 10.4L4.6 8.2l.8-.8 1.4 1.4 3.2-3.2.8.8z" />
  </svg>
);

const EmptyImage = ({ label, h = 200 }) => (
  <div className="strip" style={{ minHeight: h }}>[ {label} ]</div>
);

const SkyRenderBadge = () => (
  <span className="chip" title="Preview this operator's shows in AR via SkyRender"
    style={{ background: 'oklch(48% 0.18 295)', color: '#fff', border: 0, padding: '3px 8px', fontSize: 10, letterSpacing: '0.06em', textTransform: 'uppercase', display: 'inline-flex', alignItems: 'center', gap: 5 }}>
    <svg width="9" height="9" viewBox="0 0 10 10" fill="currentColor"><circle cx="5" cy="5" r="2.2" /><circle cx="5" cy="5" r="4.2" fill="none" stroke="currentColor" strokeWidth="0.7" /></svg>
    SkyRender
  </span>
);

// ClaimButton — small inline button; stops click propagation so it doesn't trigger parent card clicks
const ClaimButton = ({ entityType, entity, size = 'sm', variant = 'outline' }) => {
  const [open, setOpen] = React.useState(false);
  if (entity?.claimed) return null;
  const styles = variant === 'primary'
    ? { background: 'var(--ink)', color: 'var(--bg)', border: '1px solid var(--ink)' }
    : { background: 'var(--bg)', color: 'var(--ink)', border: '1px dashed var(--line-2)' };
  return (
    <>
      <button onClick={(e) => { e.stopPropagation(); setOpen(true); }}
        style={{ ...styles, borderRadius: 999, fontSize: size === 'sm' ? 11 : 13, padding: size === 'sm' ? '4px 10px' : '8px 14px', fontFamily: 'var(--ff-mono)', textTransform: 'uppercase', letterSpacing: '0.05em', cursor: 'pointer' }}>
        Claim this profile
      </button>
      {open && <ClaimModal entityType={entityType} entity={entity} onClose={() => setOpen(false)} />}
    </>
  );
};

const ClaimModal = ({ entityType, entity, onClose }) => {
  const [email, setEmail] = React.useState('');
  const [name, setName] = React.useState('');
  const [submitting, setSubmitting] = React.useState(false);
  const [done, setDone] = React.useState(false);
  const [err, setErr] = React.useState('');

  const submit = async (e) => {
    e.preventDefault();
    setErr(''); setSubmitting(true);
    try {
      const res = await fetch((window.__API_BASE||'') + '/api/claims', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ entityType, entityId: entity.id, slug: entity.slug, email, name }),
      });
      const data = await res.json();
      if (!res.ok) throw new Error(data.error || 'Request failed');
      setDone(true);
    } catch (ex) {
      setErr(ex.message);
    } finally {
      setSubmitting(false);
    }
  };

  return (
    <div onClick={onClose} style={{ position: 'fixed', inset: 0, background: 'rgba(0,0,0,0.5)', zIndex: 100, display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 20 }}>
      <div onClick={(e) => e.stopPropagation()} className="card" style={{ background: 'var(--bg)', maxWidth: 440, width: '100%', padding: 28, borderRadius: 8 }}>
        {done ? (
          <>
            <h3 style={{ margin: '0 0 8px', fontFamily: 'var(--ff-display)', fontWeight: 400, fontSize: 24 }}>Check your inbox</h3>
            <p style={{ color: 'var(--ink-2)', fontSize: 14, margin: '0 0 20px' }}>We sent a confirmation link to <strong>{email}</strong>. Click it to finish claiming <strong>{entity.name}</strong>.</p>
            <button className="btn btn-primary" onClick={onClose}>Close</button>
          </>
        ) : (
          <form onSubmit={submit}>
            <h3 style={{ margin: '0 0 6px', fontFamily: 'var(--ff-display)', fontWeight: 400, fontSize: 24 }}>Claim {entity.name}</h3>
            <p style={{ color: 'var(--ink-2)', fontSize: 13, margin: '0 0 18px' }}>Enter your company email. We'll send a confirmation link.</p>
            <label className="mono muted" style={{ fontSize: 11, textTransform: 'uppercase', letterSpacing: '0.05em' }}>Your name (optional)</label>
            <input className="input" value={name} onChange={(e) => setName(e.target.value)} placeholder="Full name" style={{ marginTop: 4, marginBottom: 14 }} />
            <label className="mono muted" style={{ fontSize: 11, textTransform: 'uppercase', letterSpacing: '0.05em' }}>Company email</label>
            <input className="input" type="email" required value={email} onChange={(e) => setEmail(e.target.value)} placeholder="you@company.com" style={{ marginTop: 4, marginBottom: 14 }} />
            {err && <div style={{ color: 'oklch(55% 0.2 25)', fontSize: 13, marginBottom: 12 }}>{err}</div>}
            <div style={{ display: 'flex', gap: 8, justifyContent: 'flex-end' }}>
              <button type="button" className="btn" onClick={onClose}>Cancel</button>
              <button type="submit" className="btn btn-primary" disabled={submitting}>{submitting ? 'Sending…' : 'Send confirmation'}</button>
            </div>
          </form>
        )}
      </div>
    </div>
  );
};

const ComingSoon = ({ nav, title = 'Coming soon', subtitle }) => (
  <div className="page">
    <div className="container-narrow" style={{ padding: '120px 32px 160px', textAlign: 'center' }}>
      <div className="eyebrow" style={{ marginBottom: 14 }}>Coming soon</div>
      <h1 style={{ fontFamily: 'var(--ff-display)', fontSize: 'clamp(40px, 5.5vw, 64px)', margin: '0 0 16px', letterSpacing: '-0.02em', fontWeight: 400 }}>{title}</h1>
      {subtitle && <p style={{ color: 'var(--ink-2)', fontSize: 17, lineHeight: 1.5, maxWidth: 540, margin: '0 auto 28px' }}>{subtitle}</p>}
      <button className="btn btn-primary" onClick={() => nav({ page: 'home' })}>Back to home</button>
    </div>
  </div>
);

Object.assign(window, { Nav, Footer, Stars, Avatar, Tier, OperatorCard, VerifiedIcon, EmptyImage, SkyRenderBadge, ClaimButton, ClaimModal, ComingSoon });
