/* StrataSnap prototype — shared UI primitives + icon set. Babel/JSX.
   Exposes components on window for the other scripts. */

/* Iconography — StrataSnap uses simple rounded outline icons for actions plus
   branded blueprint-style icons for signature product surfaces. Inlined rather
   than CDN so they render in every context incl. screenshots + standalone export. */
const I = {
  back:     <path d="M15 6l-6 6 6 6" />,
  chevron:  <path d="M9 6l6 6-6 6" />,
  chevronR: <path d="M9 6l6 6-6 6" />,
  down:     <path d="M6 9l6 6 6-6" />,
  plus:     <path d="M12 5v14M5 12h14" />,
  check:    <path d="M5 12l5 5L20 7" />,
  pin:      <g><circle cx="12" cy="11" r="3" /><path d="M17.7 16.7L13.4 21a2 2 0 0 1-2.8 0l-4.3-4.3a8 8 0 1 1 11.4 0z" /></g>,
  camera:   <g><path d="M5 7h2l1.5-2h7L17 7h2a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V9a2 2 0 0 1 2-2z" /><circle cx="12" cy="13" r="3" /></g>,
  mic:      <g><rect x="9" y="3" width="6" height="11" rx="3" /><path d="M5 11a7 7 0 0 0 14 0M12 18v3M8 21h8" /></g>,
  stop:     <rect x="7" y="7" width="10" height="10" rx="1.5" />,
  image:    <g><rect x="3" y="5" width="18" height="14" rx="2" /><circle cx="8.5" cy="9.5" r="1.2" /><path d="M3 16l4-4 5 5M14 14l2-2 5 5" /></g>,
  lock:     <g><rect x="5" y="11" width="14" height="10" rx="2" /><circle cx="12" cy="16" r="1" /><path d="M8 11V7a4 4 0 0 1 8 0v4" /></g>,
  eye:      <g><circle cx="12" cy="12" r="2" /><path d="M21 12c-2.4 4-5.4 6-9 6s-6.6-2-9-6c2.4-4 5.4-6 9-6s6.6 2 9 6z" /></g>,
  alert:    <g><path d="M12 9v4M12 17h.01M10.2 4.2l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.8-2.8l-8-14a2 2 0 0 0-3.6 0z" /></g>,
  info:     <g><circle cx="12" cy="12" r="9" /><path d="M12 11v5M12 8h.01" /></g>,
  drop:     <path d="M7.5 13.3L12 4l4.5 9.3a5 5 0 1 1-9 0z" />,
  bolt:     <path d="M13 3l-1 7h5l-6 11 1-7H7z" />,
  door:     <g><path d="M5 21h14M6 21V5a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v16" /><circle cx="14" cy="12" r=".8" /></g>,
  warn:     <g><path d="M12 9v4M12 17h.01M10.2 4.2l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.8-2.8l-8-14a2 2 0 0 0-3.6 0z" /></g>,
  elevator: <g><rect x="5" y="3" width="14" height="18" rx="2" /><path d="M10 9l2-2 2 2M10 15l2 2 2-2" /></g>,
  trash:    <g><path d="M4 7h16M10 11v6M14 11v6M5 7l1 13a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2l1-13M9 7V4a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v3" /></g>,
  tree:     <g><path d="M12 21v-6" /><path d="M12 15a5 5 0 0 0 5-5 4 4 0 0 0-1.4-3 4.6 4.6 0 0 0-7.2 0A4 4 0 0 0 7 10a5 5 0 0 0 5 5z" /></g>,
  dots:     <g><circle cx="5" cy="12" r="1.3" /><circle cx="12" cy="12" r="1.3" /><circle cx="19" cy="12" r="1.3" /></g>,
  clock:    <g><circle cx="12" cy="12" r="9" /><path d="M12 7v5l3 2" /></g>,
  user:     <g><circle cx="12" cy="8" r="4" /><path d="M5 20c0-3.3 3-5 7-5s7 1.7 7 5" /></g>,
  building: <g><path d="M4 21V5a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v16M4 21h16M8 7h.01M12 7h.01M8 11h.01M12 11h.01M10 21v-4a2 2 0 0 1 4 0v4M16 9h2a2 2 0 0 1 2 2v10" /></g>,
  list:     <g><path d="M9 6h11M9 12h11M9 18h11" /><circle cx="5" cy="6" r=".6" /><circle cx="5" cy="12" r=".6" /><circle cx="5" cy="18" r=".6" /></g>,
  message:  <path d="M8 9h8M8 13h6M18 4a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2h-6l-4 4v-4H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2z" />,
  home:     <path d="M5 12l-2 0 9-9 9 9-2 0M5 12v7a1 1 0 0 0 1 1h3v-5a2 2 0 0 1 4 0v5h3a1 1 0 0 0 1-1v-7" />,
  download: <path d="M4 17v2a1 1 0 0 0 1 1h14a1 1 0 0 0 1-1v-2M7 11l5 5 5-5M12 4v12" />,
  printer:  <g><path d="M6 9V4h12v5M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2" /><rect x="6" y="14" width="12" height="7" rx="1" /><path d="M8 17h8" /></g>,
  files:    <g><path d="M8 7V5a2 2 0 0 1 2-2h6l4 4v10a2 2 0 0 1-2 2h-2" /><path d="M16 3v5h5" /><rect x="4" y="7" width="12" height="14" rx="2" /><path d="M7 12h6M7 16h6" /></g>,
  layoutList:<g><rect x="4" y="5" width="16" height="14" rx="2" /><path d="M8 9h8M8 13h8M8 17h5" /><circle cx="6.5" cy="9" r=".35" /><circle cx="6.5" cy="13" r=".35" /><circle cx="6.5" cy="17" r=".35" /></g>,
  shieldCheck:<g><path d="M12 3l7 3v5c0 5-3.1 8.4-7 10-3.9-1.6-7-5-7-10V6z" /><path d="M9 12l2 2 4-5" /></g>,
  x:        <path d="M18 6L6 18M6 6l12 12" />,
  send:     <path d="M10 14l11-11M21 3l-6.5 18a.55.55 0 0 1-1 0L10 14l-7-3.5a.55.55 0 0 1 0-1z" />,
  calendar: <g><rect x="4" y="5" width="16" height="16" rx="2" /><path d="M16 3v4M8 3v4M4 11h16M11 15h1v3" /></g>,
  refresh:  <path d="M14 8V6a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h7a2 2 0 0 0 2-2v-2M9 12h12l-3-3M18 15l3-3" />,
  qr:       <g><rect x="4" y="4" width="6" height="6" rx="1" /><rect x="14" y="4" width="6" height="6" rx="1" /><rect x="4" y="14" width="6" height="6" rx="1" /><path d="M14 14h3v3M20 14v.01M17 20v.01M20 17v3" /></g>,
  scale:    <g><path d="M12 3v18M7 7l-3.5 6a3.5 3.5 0 0 0 7 0L7 7zM17 7l-3.5 6a3.5 3.5 0 0 0 7 0L17 7zM5 7h14" /></g>,
  spark:    <path d="M12 3l1.9 5.6L19 10l-5.1 1.4L12 17l-1.9-5.6L5 10l5.1-1.4z" />,
  search:   <g><circle cx="11" cy="11" r="7" /><path d="M21 21l-4.3-4.3" /></g>,
  logout:   <path d="M14 8V6a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h7a2 2 0 0 0 2-2v-2M9 12h12M18 9l3 3-3 3" />,
  cog:      <g><circle cx="12" cy="12" r="3" /><path d="M12 3.5l1.4 2.3 2.6-.6.6 2.6 2.3 1.4-1.3 2.3 1.3 2.3-2.3 1.4-.6 2.6-2.6-.6L12 20.5l-1.4-2.3-2.6.6-.6-2.6L5.1 14.8l1.3-2.3-1.3-2.3 2.3-1.4.6-2.6 2.6.6z" /></g>,
  ssInbox:  <g><rect x="5" y="6" width="14" height="12" rx="2.5" /><path d="M8 10h8M8 13h6" /><circle cx="18" cy="7" r="2.2" fill="currentColor" stroke="none" /></g>,
  ssMap:    <g><path d="M5 7h14v11H5z" /><path d="M10 7v11M14 7v11M5 12.5h14" opacity=".55" /><path d="M12 9.2c-2 0-3.6 1.6-3.6 3.6 0 2.7 3.6 6 3.6 6s3.6-3.3 3.6-6c0-2-1.6-3.6-3.6-3.6z" fill="currentColor" stroke="none" /><circle cx="12" cy="12.8" r="1.1" fill="#fff" stroke="none" /></g>,
  ssPoster: <g><rect x="7" y="4" width="10" height="15" rx="2" /><path d="M10 8h1M13 8h1M10 11h4M10 14h2M14 14h.01M12 19v2M9 21h6" /></g>,
  ssCase:   <g><path d="M7 4h8l4 4v11a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2z" /><path d="M15 4v4h4M8 12h8M8 15h8M8 18h5" /><circle cx="8" cy="8" r="1.2" fill="currentColor" stroke="none" /></g>,
  ssUpdate: <g><path d="M5 7a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2h-5l-5 4v-4H7a2 2 0 0 1-2-2z" /><path d="M9 9h6M9 12h4" /><circle cx="18" cy="6" r="2.1" fill="currentColor" stroke="none" /></g>,
  ssPrivate:<g><rect x="5" y="10" width="14" height="10" rx="2" /><path d="M8 10V7a4 4 0 0 1 8 0v3" /><circle cx="12" cy="15" r="1.1" fill="currentColor" stroke="none" /><path d="M12 16v1.5" /></g>,
};

function Icon({ name, size = 22, stroke = 1.5, fill = false, style, className }) {
  const g = I[name] || I.dots;
  return (
    <svg className={className} 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}>
      {g}
    </svg>
  );
}

function StatusBar({ dark }) {
  return (
    <div className={'statusbar' + (dark ? ' on-dark' : '')}>
      <span>9:41</span>
      <span className="dots">
        <svg width="17" height="11" viewBox="0 0 18 12" fill="currentColor"><rect x="0" y="7" width="3" height="5" rx="1" /><rect x="5" y="4" width="3" height="8" rx="1" /><rect x="10" y="1.5" width="3" height="10.5" rx="1" /><rect x="15" y="0" width="3" height="12" rx="1" opacity=".4" /></svg>
        <svg width="22" height="11" viewBox="0 0 24 12" fill="none"><rect x="1" y="1" width="20" height="10" rx="2.5" stroke="currentColor" strokeWidth="1.1" opacity=".5" /><rect x="2.5" y="2.5" width="14" height="7" rx="1" fill="currentColor" /><rect x="22" y="4" width="1.5" height="4" rx="1" fill="currentColor" opacity=".5" /></svg>
      </span>
    </div>
  );
}

const HomeInd = ({ dark }) => <div className={'home-ind' + (dark ? ' on-dark' : '')} />;

function Btn({ variant = 'acc', children, onClick, disabled, type, style, className = '' }) {
  return (
    <button type={type || 'button'} disabled={disabled} onClick={onClick} style={style}
      className={`btn btn-${variant} ${className}`}>{children}</button>
  );
}

function StatusDot({ status, big, short }) {
  const meta = (window.SS.STATUS[status] || { tone: 'blue' });
  const label = (short === false) ? status : (meta.short || status);
  return <span className={'stt t-' + meta.tone + (big ? ' big' : '')}><span className="dot" />{label}</span>;
}
const toneVar = (status) => 'var(--st-' + ((window.SS.STATUS[status] || {}).tone || 'blue') + ')';

function CatIcon({ id, size = 20 }) { return <Icon name={window.SS.catIcon(id)} size={size} stroke={1.7} />; }

function Avatar({ name }) {
  const initials = (name || '?').split(/\s+/).map((w) => w[0]).slice(0, 2).join('').toUpperCase();
  return <span className="av">{initials}</span>;
}

function Field({ label, optional, children }) {
  return (
    <div className="field">
      <label>{label}{optional && <span className="opt-note"> · optional</span>}</label>
      {children}
    </div>
  );
}

function Note({ variant, icon = 'info', title, children }) {
  return (
    <div className={'note' + (variant ? ' ' + variant : '')}>
      <Icon name={icon} size={18} />
      <div>{title && <span className="h">{title}</span>}{children}</div>
    </div>
  );
}

function Sheet({ title, onClose, children, footer }) {
  return (
    <div className="sheet-backdrop" onClick={onClose}>
      <div className="sheet" onClick={(e) => e.stopPropagation()}>
        <div className="grip" />
        <div className="sh-head">
          <h3>{title}</h3>
          <button className="iconbtn" onClick={onClose} aria-label="Close"><Icon name="x" size={18} /></button>
        </div>
        <div className="sh-body">{children}</div>
        {footer && <div className="sh-foot">{footer}</div>}
      </div>
    </div>
  );
}

function Toast({ children, icon = 'check' }) {
  return <div className="toast"><Icon name={icon} size={18} /><span className="flex1">{children}</span></div>;
}

// faux photo tile (placeholder image content)
// Realistic issue-photo thumbnails — deterministic canvas render seeded by the
// issue type, cached as data URLs. Reads as a real camera photo at thumb size.
const _imgCache = {};
const _imgPAL = {
  plumbing:   ['#5a6b78', '#33414c', '#9aabb4'],
  electrical: ['#2f3340', '#1a1d25', '#e0b25c'],
  door:       ['#7e6c54', '#473a2b', '#ad9673'],
  structural: ['#8b8576', '#564f42', '#b8b09d'],
  elevator:   ['#6a717a', '#3a414a', '#9ca3ab'],
  cleanliness:['#5f6b57', '#3a4433', '#889179'],
  grounds:    ['#536b3f', '#324124', '#829c66'],
  _default:   ['#69707a', '#3e434b', '#9aa1a9'],
};
function _palFor(seed) {
  const map = { leak: 'plumbing', plumbing: 'plumbing', door: 'door', stair: 'structural',
    structural: 'structural', electrical: 'electrical', elevator: 'elevator',
    cleanliness: 'cleanliness', grounds: 'grounds', other: '_default', default: '_default' };
  return _imgPAL[map[seed] || seed] || _imgPAL._default;
}
function _hash(s) { let h = 2166136261; for (let i = 0; i < s.length; i++) { h ^= s.charCodeAt(i); h = Math.imul(h, 16777619); } return h >>> 0; }
function _rng(seed) { let x = seed >>> 0 || 1; return () => { x ^= x << 13; x ^= x >>> 17; x ^= x << 5; x >>>= 0; return x / 4294967296; }; }
function issuePhoto(seed, i) {
  const key = (seed || 'default') + '~' + (i || 0);
  if (_imgCache[key]) return _imgCache[key];
  const W = 240, H = 180, cv = document.createElement('canvas'); cv.width = W; cv.height = H;
  const ctx = cv.getContext('2d'); const pal = _palFor(seed); const rnd = _rng(_hash(key));
  const g = ctx.createLinearGradient(0, 0, W, H); g.addColorStop(0, pal[1]); g.addColorStop(1, pal[0]);
  ctx.fillStyle = g; ctx.fillRect(0, 0, W, H);
  for (let b = 0; b < 6; b++) {
    const x = rnd() * W, y = rnd() * H, r = 35 + rnd() * 95, col = [pal[0], pal[1], pal[2]][b % 3];
    const rg = ctx.createRadialGradient(x, y, 0, x, y, r); rg.addColorStop(0, col); rg.addColorStop(1, 'rgba(0,0,0,0)');
    ctx.globalAlpha = 0.45; ctx.fillStyle = rg; ctx.beginPath(); ctx.arc(x, y, r, 0, 7); ctx.fill();
  }
  ctx.globalAlpha = 1;
  const hx = W * (0.28 + rnd() * 0.44), hy = H * (0.22 + rnd() * 0.34);
  const hg = ctx.createRadialGradient(hx, hy, 0, hx, hy, 80); hg.addColorStop(0, 'rgba(255,255,255,.20)'); hg.addColorStop(1, 'rgba(255,255,255,0)');
  ctx.fillStyle = hg; ctx.fillRect(0, 0, W, H);
  for (let n = 0; n < 850; n++) { const v = rnd() > 0.5 ? 255 : 0; ctx.fillStyle = 'rgba(' + v + ',' + v + ',' + v + ',' + (rnd() * 0.08) + ')'; ctx.fillRect(rnd() * W, rnd() * H, 1, 1); }
  const vg = ctx.createRadialGradient(W / 2, H / 2, H * 0.32, W / 2, H / 2, H * 0.82); vg.addColorStop(0, 'rgba(0,0,0,0)'); vg.addColorStop(1, 'rgba(0,0,0,.34)');
  ctx.fillStyle = vg; ctx.fillRect(0, 0, W, H);
  const url = cv.toDataURL('image/jpeg', 0.72); _imgCache[key] = url; return url;
}
function IssuePhoto({ seed, i, className, style, alt }) {
  const src = typeof seed === 'string' && seed.indexOf('data:image/') === 0 ? seed :
    seed && typeof seed === 'object' && seed.url ? seed.url :
    seed && typeof seed === 'object' && seed.dataUrl ? seed.dataUrl : null;
  if (src) return <img className={className} src={src} alt={alt || 'Issue photo'} style={style} />;
  return <img className={className} src={issuePhoto(seed, i)} alt={alt || 'Issue photo'} style={style} />;
}

// photo tile — now renders a realistic generated photo
function PhotoThumb({ kind, cat, label, i }) {
  return (
    <div style={{ aspectRatio: '4/3', borderRadius: 11, overflow: 'hidden', position: 'relative' }}>
      <img src={issuePhoto(cat || kind || 'default', i)} alt="Issue photo" style={{ width: '100%', height: '100%', objectFit: 'cover', display: 'block' }} />
      {label && <span style={{ fontSize: 11, fontWeight: 600, position: 'absolute', left: 9, bottom: 8, color: '#fff', textShadow: '0 1px 4px rgba(0,0,0,.6)', zIndex: 1 }}>{label}</span>}
    </div>
  );
}

function QRGraphic({ value = 'SS', size = 160, fg = '#0A0A08', bg = '#FFFFFF', quiet = 2 }) {
  const qrFactory = window.qrcode;
  if (typeof qrFactory === 'function') {
    try {
      const qr = qrFactory(0, 'M');
      qr.addData(String(value || 'SS'));
      qr.make();
      const N = qr.getModuleCount();
      const margin = Math.max(4, Number(quiet) || 0);
      const tot = N + margin * 2;
      const cells = [];
      for (let r = 0; r < N; r++) for (let c = 0; c < N; c++) {
        if (qr.isDark(r, c)) cells.push(<rect key={r + '-' + c} x={c + margin} y={r + margin} width="1" height="1" fill={fg} />);
      }
      return (
        <svg width={size} height={size} viewBox={`0 0 ${tot} ${tot}`} shapeRendering="crispEdges" style={{ display: 'block' }} aria-label="Scannable QR code">
          <rect width={tot} height={tot} fill={bg} />
          {cells}
        </svg>
      );
    } catch (err) {}
  }

  // Fallback shown only if the QR generator script fails to load.
  const N = 25;
  let h = 2166136261;
  for (let i = 0; i < value.length; i++) { h ^= value.charCodeAt(i); h = Math.imul(h, 16777619); }
  const rand = (i) => { let x = Math.imul(h ^ (i * 2654435761), 2246822519); x ^= x >>> 15; return ((x >>> 0) % 1000) / 1000; };
  const finder = (cx, cy) => (r, c) => {
    const dr = Math.abs(r - cy), dc = Math.abs(c - cx);
    const d = Math.max(dr, dc);
    if (cx - 3 <= c && c <= cx + 3 && cy - 3 <= r && r <= cy + 3) return d === 3 || d === 1;
    return null;
  };
  const fs = [finder(3, 3), finder(N - 4, 3), finder(3, N - 4)];
  const cells = [];
  for (let r = 0; r < N; r++) for (let c = 0; c < N; c++) {
    let on = null;
    for (const f of fs) { const v = f(r, c); if (v !== null) { on = v; break; } }
    if (on === null) on = rand(r * N + c) > 0.55;
    if (on) cells.push(<rect key={r + '-' + c} x={c + quiet} y={r + quiet} width="1" height="1" fill={fg} />);
  }
  const tot = N + quiet * 2;
  return (
    <svg width={size} height={size} viewBox={`0 0 ${tot} ${tot}`} shapeRendering="crispEdges" style={{ display: 'block' }}>
      <rect width={tot} height={tot} fill={bg} />
      {cells}
    </svg>
  );
}

// StrataSnap logo — wordmark "Strata"(ink) "Snap"(royal-blue) + signature
// L-tick at the upper-right of "Snap". Echoes the Strata Match mark (no icon,
// corner tick) in StrataSnap's own royal-blue accent.
function Logo({ tone = 'light', size = 22 }) {
  return (
    <span className={'wordmark wm-' + tone} style={{ fontSize: size }}>
      <span className="wm-text">Strata<span className="wm-snap">Snap<span className="wm-tick" aria-hidden="true"></span></span></span>
    </span>
  );
}

Object.assign(window, { Icon, StatusBar, HomeInd, Btn, StatusDot, toneVar, CatIcon, Avatar, Field, Note, Sheet, Toast, PhotoThumb, IssuePhoto, issuePhoto, QRGraphic, Logo });
