﻿/* global React, LogoLockup, LogoMark */

// ============================================================
// XILROS UI components
// ============================================================

// -------- Buttons --------
function Button({ variant = 'primary', size = 'md', children, onClick, href, icon, iconRight, ...rest }) {
  const cls = `xb xb-${variant} xb-${size}`;
  const inner = (
    <>
      {icon ? <span className="xb-i" aria-hidden="true">{icon}</span> : null}
      <span>{children}</span>
      {iconRight ? <span className="xb-i" aria-hidden="true">{iconRight}</span> : null}
    </>
  );
  if (href) return <a className={cls} href={href} onClick={onClick} {...rest}>{inner}</a>;
  return <button className={cls} onClick={onClick} {...rest}>{inner}</button>;
}

// -------- Mono label / section eyebrow --------
function MonoLabel({ children, color, prefix = '/' }) {
  return (
    <span className="xs-mono" style={color ? { color } : null}>
      {prefix && <span style={{ opacity: 0.55, marginRight: 6 }}>{prefix}</span>}
      {children}
    </span>
  );
}

// -------- Inquiry pill (selectable, single or multi) --------
function InquiryPill({ label, active = false, onClick }) {
  return (
    <button
      type="button"
      className={'xs-pill ' + (active ? 'is-active' : '')}
      aria-pressed={active}
      onClick={onClick}
    >
      {label}
    </button>
  );
}

// -------- Contact form --------
function ContactForm({ categories, toEmail }) {
  const [subject, setSubject]   = React.useState(categories[0]);
  const [from, setFrom]         = React.useState('');
  const [message, setMessage]   = React.useState('');
  const [error, setError]       = React.useState('');

  const emailValid = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(from);
  const canSend = emailValid && message.trim().length > 0;

  function send(e) {
    e.preventDefault();
    if (!canSend) {
      setError(!emailValid ? 'Please enter a valid email.' : 'Please write a short message.');
      return;
    }
    setError('');
    const subj = encodeURIComponent(`[XILROS] ${subject}`);
    const body = encodeURIComponent(`${message}\n\nFrom: ${from}`);
    window.location.href = `mailto:${toEmail}?subject=${subj}&body=${body}`;
  }

  return (
    <form className="xs-form" onSubmit={send} noValidate>
      <div className="xs-form-row">
        <label className="xs-mono xs-form-label">/ inquiry type</label>
        <div className="xs-pillrow">
          {categories.map(c => (
            <InquiryPill
              key={c}
              label={c}
              active={subject === c}
              onClick={() => setSubject(c)}
            />
          ))}
        </div>
      </div>

      <div className="xs-form-row">
        <label className="xs-mono xs-form-label" htmlFor="xs-from">/ your email</label>
        <input
          id="xs-from"
          className="xs-input"
          type="email"
          inputMode="email"
          autoComplete="email"
          placeholder="you@example.com"
          value={from}
          onChange={e => setFrom(e.target.value)}
        />
      </div>

      <div className="xs-form-row">
        <label className="xs-mono xs-form-label" htmlFor="xs-msg">/ message</label>
        <textarea
          id="xs-msg"
          className="xs-input xs-textarea"
          rows={6}
          placeholder="A short description of the project, question, or idea."
          value={message}
          onChange={e => setMessage(e.target.value)}
        />
      </div>

      {error && <div className="xs-form-error">{error}</div>}

      <div className="xs-form-actions">
        <Button variant="primary" type="submit">Send message</Button>
        <Button variant="secondary" href={`mailto:${toEmail}`} icon={<SocialIcon name="mail" size={16}/>}>
          Email directly
        </Button>
      </div>
      <div className="xs-mono xs-form-hint">
        Send opens your email client with the message pre-filled. No data is stored by this site.
      </div>
    </form>
  );
}

// -------- Status pill --------
function StatusPill({ children, tone = 'accent' }) {
  return (
    <span className={`xs-status xs-status-${tone}`}>
      <span className="xs-status-dot" aria-hidden="true" />
      {children}
    </span>
  );
}

// -------- Header / nav --------
function Header({ route, onNav }) {
  const D = window.XILROS_DATA;
  const [open, setOpen] = React.useState(false);
  const go = (id) => { setOpen(false); onNav(id); };
  return (
    <header className="xs-header">
      <div className={'xs-nav ' + (open ? 'is-open' : '')}>
        <button className="xs-brand" onClick={() => go('home')} aria-label="XILROS home">
          <LogoLockup
            markSize={26}
            wordWidth={84}
            color="var(--color-logo-on-dark)"
            bg="var(--color-canvas-dark)"
          />
        </button>
        <nav className="xs-links">
          {D.nav.map(n => (
            <button
              key={n.id}
              onClick={() => onNav(n.id)}
              className={'xs-link ' + (route === n.id ? 'is-active' : '')}
            >
              {n.label}
            </button>
          ))}
        </nav>
        <div className="xs-cta">
          <Button variant="primary" size="sm" href={(window.XILROS_DATA.support || {}).url || '#'}>Support the Lab</Button>
        </div>
        <button
          className="xs-nav-toggle"
          aria-label={open ? 'Close menu' : 'Open menu'}
          aria-expanded={open}
          onClick={() => setOpen(!open)}
        >
          <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
            {open
              ? (<><line x1="6" y1="6" x2="18" y2="18"/><line x1="18" y1="6" x2="6" y2="18"/></>)
              : (<><line x1="4" y1="7" x2="20" y2="7"/><line x1="4" y1="12" x2="20" y2="12"/><line x1="4" y1="17" x2="20" y2="17"/></>)}
          </svg>
        </button>
      </div>
      {open && (
        <div className="xs-nav-sheet" role="menu">
          {D.nav.map(n => (
            <button
              key={n.id}
              role="menuitem"
              onClick={() => go(n.id)}
              className={'xs-nav-sheet-link ' + (route === n.id ? 'is-active' : '')}
            >
              {n.label}
            </button>
          ))}
          <a
            className="xs-nav-sheet-cta"
            href={(window.XILROS_DATA.support || {}).url || '#'}
            onClick={() => setOpen(false)}
          >
            Support the Lab
          </a>
        </div>
      )}
    </header>
  );
}

// -------- Footer --------
function Footer({ onNav }) {
  const D = window.XILROS_DATA;
  const year = new Date().getFullYear();
  return (
    <footer className="xs-footer">
      <div className="xs-footer-grid">
        <div className="xs-footer-brand">
          <LogoLockup
            markSize={32}
            wordWidth={100}
            color="var(--color-logo-on-dark)"
            bg="var(--color-surface-dark-3)"
          />
          <div className="xs-footer-tag">Mechatronics Engineering Studio</div>
        </div>
        <div>
          <div className="xs-footer-h">Site</div>
          <ul className="xs-footer-list">
            {D.nav.map(n => (
              <li key={n.id}>
                <button className="xs-footer-link" onClick={() => onNav(n.id)}>{n.label}</button>
              </li>
            ))}
          </ul>
        </div>
        <div>
          <div className="xs-footer-h">Channels</div>
          <ul className="xs-footer-list">
            {D.socials.filter(s => s.enabled && !s.personal).slice(0, 5).map(s => (
              <li key={s.id}><a className="xs-footer-link" href={s.url} {...(s.url && !s.url.startsWith('mailto:') ? {target: '_blank', rel: 'noopener noreferrer'} : {})}>{s.label} &#8599;</a></li>
            ))}
          </ul>
        </div>
        <div>
          <div className="xs-footer-h">Support</div>
          <ul className="xs-footer-list">
            <li><a className="xs-footer-link" href={(window.XILROS_DATA.support || {}).url || '#'} target="_blank" rel="noopener noreferrer">Support the Lab &#8599;</a></li>
            <li><a className="xs-footer-link" href={`mailto:${((window.XILROS_DATA.socials || []).find(s => s.id === 'email') || {}).handle || 'contact@xilros.com'}`}>{((window.XILROS_DATA.socials || []).find(s => s.id === 'email') || {}).handle || 'contact@xilros.com'}</a></li>
          </ul>
        </div>
      </div>
      <div className="xs-footer-bottom">
        <span>(C) {year} XILROS. All rights reserved.</span>
        <span className="xs-mono" style={{ opacity: 0.6 }}>/ build - 2026.05</span>
      </div>
    </footer>
  );
}

// -------- Project card --------
function ProjectCard({ p, onOpen }) {
  return (
    <article className="xs-project" onClick={() => onOpen && onOpen(p.id)}>
      <div className={'xs-project-media ' + (p.image ? 'has-image' : '')}>
        {p.image && <img className="xs-media-img" src={p.image} alt={p.imageAlt || p.title} loading="lazy" />}
      </div>
      <div className="xs-project-body">
        <div className="xs-project-meta">
          <span>{p.category}</span>
          <StatusPill>{p.status}</StatusPill>
        </div>
        <h3 className="xs-project-title">{p.title}</h3>
        <p className="xs-project-desc">{p.summary}</p>
        <div className="xs-tags">
          {p.tags.map(t => <span key={t} className="xs-tag">{t}</span>)}
        </div>
      </div>
    </article>
  );
}

function ProjectCardEmpty({ headline = 'More projects coming soon', sub = 'Build logs are posted as projects move from concept to working prototype.' }) {
  return (
    <div className="xs-project-empty">
      <div className="xs-project-empty-h">{headline}</div>
      <div className="xs-project-empty-s">{sub}</div>
    </div>
  );
}

// -------- Service card --------
function ServiceCard({ idx, title, desc }) {
  return (
    <div className="xs-service">
      <MonoLabel color="var(--color-primary-on-dark)">service - {String(idx + 1).padStart(2, '0')}</MonoLabel>
      <h3 className="xs-service-title">{title}</h3>
      <p className="xs-service-desc">{desc}</p>
    </div>
  );
}

// -------- Support card --------
function SupportCard({ wide = false }) {
  const support = (window.XILROS_DATA && window.XILROS_DATA.support) || {};
  if (support.enabled === false) return null;
  return (
    <div className={'xs-support ' + (wide ? 'is-wide' : '')}>
      <div className="xs-support-text">
        <MonoLabel color="var(--color-primary-on-dark)">support</MonoLabel>
        <h3 className="xs-support-title">Support the Lab</h3>
        <p className="xs-support-desc">Support future builds, open project releases, and development updates.</p>
      </div>
      <div className="xs-support-cta">
        <Button variant="primary" href={support.url || '#'} iconRight={<span>-&gt;</span>}>Support the Lab</Button>
      </div>
    </div>
  );
}

// -------- Lab card --------
function LabCard({ entry, homePreview = false }) {
  const [expanded, setExpanded] = React.useState(false);
  const isText = entry.mediaKind === 'text';
  const isYouTubeShort = entry.mediaKind === 'youtubeShort';
  const isYouTube = entry.mediaKind === 'youtube' || isYouTubeShort;
  const isSquare = entry.mediaKind === 'imageSquare' || entry.mediaKind === 'square';
  const externalLabel = isYouTubeShort ? 'Watch Short' : 'Watch';
  const isPreviewSquare = homePreview && !expanded && !isText;
  const mediaClass = [
    'xs-lab-media',
    entry.mediaKind === 'video' || isYouTube ? 'is-video' : '',
    isYouTubeShort ? 'is-short' : '',
    isSquare ? 'is-square' : '',
    homePreview ? 'is-home-preview' : '',
    isPreviewSquare ? 'is-preview-square' : '',
    !isYouTube && entry.mediaKind !== 'video' && !isSquare ? 'is-grid' : '',
  ].filter(Boolean).join(' ');

  return (
    <article className={'xs-lab ' + (isText ? 'is-text-only' : '') + (homePreview ? ' is-home-preview-card' : '')}>
      <header className="xs-lab-head">
        <MonoLabel color="var(--color-primary-on-dark)">{entry.kind}</MonoLabel>
        <span className="xs-lab-date">{entry.date}</span>
      </header>
      {!isText && (
        <div className={mediaClass}>
          {isYouTube && entry.youtubeId ? (
            <iframe
              width={isYouTubeShort ? '315' : '560'}
              height={isYouTubeShort ? '560' : '315'}
              src={`https://www.youtube.com/embed/${entry.youtubeId}?rel=0&modestbranding=1&playsinline=1`}
              title={entry.title}
              loading="lazy"
              allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
              referrerPolicy="strict-origin-when-cross-origin"
              allowFullScreen
            />
          ) : entry.mediaKind === 'video' && (
            <div className="xs-lab-play">
              <svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
                <path d="M8 5v14l11-7z"/>
              </svg>
              {entry.duration && <span className="xs-lab-dur">{entry.duration}</span>}
            </div>
          )}
          {isPreviewSquare && (
            <button
              className="xs-lab-expand"
              type="button"
              onClick={() => setExpanded(true)}
              aria-label={`Expand ${entry.title}`}
            >
              View clip
            </button>
          )}
        </div>
      )}
      <div className="xs-lab-body">
        <div className="xs-lab-title">{entry.title}</div>
        <p className="xs-lab-note">{entry.note}</p>
        <div className="xs-lab-foot">
          {entry.url && (
            <a className="xs-lab-link" href={entry.url} target="_blank" rel="noopener noreferrer">
              {externalLabel} &#8599;
            </a>
          )}
          <span className="xs-mono" style={{ opacity: 0.6 }}>/ project &middot; {entry.project}</span>
        </div>
      </div>
    </article>
  );
}

// -------- Social icons (Lucide SVG paths, inlined so they always render) --------
const SOCIAL_ICONS = {
  instagram: <><rect x="2" y="2" width="20" height="20" rx="5"/><path d="M16 11.37A4 4 0 1 1 12.63 8 4 4 0 0 1 16 11.37z"/><line x1="17.5" y1="6.5" x2="17.51" y2="6.5"/></>,
  youtube:   <><path d="M22.54 6.42a2.78 2.78 0 0 0-1.94-2C18.88 4 12 4 12 4s-6.88 0-8.6.46a2.78 2.78 0 0 0-1.94 2A29 29 0 0 0 1 11.75a29 29 0 0 0 .46 5.33A2.78 2.78 0 0 0 3.4 19c1.72.46 8.6.46 8.6.46s6.88 0 8.6-.46a2.78 2.78 0 0 0 1.94-2 29 29 0 0 0 .46-5.25 29 29 0 0 0-.46-5.33z"/><polygon points="9.75 15.02 15.5 11.75 9.75 8.48 9.75 15.02"/></>,
  facebook:  <path d="M18 2h-3a5 5 0 0 0-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 0 1 1-1h3z"/>,
  cube:      <><path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"/><polyline points="3.27 6.96 12 12.01 20.73 6.96"/><line x1="12" y1="22.08" x2="12" y2="12"/></>,
  github:    <path d="M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22"/>,
  linkedin:  <><path d="M16 8a6 6 0 0 1 6 6v7h-4v-7a2 2 0 0 0-4 0v7h-4v-7a6 6 0 0 1 6-6z"/><rect x="2" y="9" width="4" height="12"/><circle cx="4" cy="4" r="2"/></>,
  music:     <><path d="M9 18V5l12-2v13"/><circle cx="6" cy="18" r="3"/><circle cx="18" cy="16" r="3"/></>,
  mail:      <><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/><polyline points="22,6 12,13 2,6"/></>,
};

function SocialIcon({ name, size = 16 }) {
  const paths = SOCIAL_ICONS[name];
  return (
    <svg
      width={size} height={size} viewBox="0 0 24 24"
      fill="none" stroke="currentColor" strokeWidth="1.75"
      strokeLinecap="round" strokeLinejoin="round" aria-hidden="true"
    >
      {paths}
    </svg>
  );
}

function SocialGrid({ socials, compact = false }) {
  // Public grid: show only enabled, non-personal accounts.
  const items = socials.filter(s => s.enabled && !s.personal);
  return (
    <div className={'xs-social ' + (compact ? 'is-compact' : '')}>
      {items.map(s => (
        <a className="xs-social-link" key={s.id} href={s.url} {...(s.url && !s.url.startsWith('mailto:') ? {target: '_blank', rel: 'noopener noreferrer'} : {})}>
          <span className="xs-social-icon"><SocialIcon name={s.icon} /></span>
          <span className="xs-social-text">
            <span className="xs-social-label">{s.label}</span>
            <span className="xs-social-handle">{s.handle}</span>
          </span>
          <span className="xs-social-arrow" aria-hidden="true">&#8599;</span>
        </a>
      ))}
    </div>
  );
}

// -------- Section header --------
function SectionHead({ eyebrow, title, kicker, action }) {
  return (
    <header className="xs-sh">
      <div>
        {eyebrow && <MonoLabel color="var(--color-primary-on-dark)">{eyebrow}</MonoLabel>}
        <h2 className="xs-sh-title">{title}</h2>
        {kicker && <p className="xs-sh-kicker">{kicker}</p>}
      </div>
      {action && <div className="xs-sh-action">{action}</div>}
    </header>
  );
}

Object.assign(window, {
  Button, MonoLabel, StatusPill,
  Header, Footer,
  ProjectCard, ProjectCardEmpty,
  ServiceCard, SupportCard, LabCard,
  SocialIcon, SocialGrid,
  SectionHead, InquiryPill, ContactForm,
});
