// Pocket Marshal — shared: icons, avatar, theme builder, helpers

// Brand palette — navy + fire on warm white
const PM_NAVY = '#0d1f38';      // primary — darkest navy
const PM_CRIMSON = '#8c1c0e';   // deep fire — fails/alerts only
const PM_FLAME = '#d44a18';     // bold flame — warm action accent
const PM_HIGHLIGHT = '#f08030'; // bright orange — highlights/indicators
const PM_SURFACE = '#fff8f0';   // warm white
// Legacy/support tones
const PM_BLUE = '#3470c4';      // Marshal's pocket blue (mascot)
const PM_BLUE_DEEP = '#2a5da6';
const PM_INK = '#0d1f38';
const PM_RED = PM_CRIMSON;
const PM_EMBER = PM_FLAME;
const PM_EMBER_DARK = '#b03c12';
const PM_AMBER = '#f5a623';
const PM_AMBER_DARK = '#9a6a0c';
const PM_BG = PM_SURFACE;
const PM_LINE = '#eadfd0';
const PM_MUTED = '#675f55';

// ---------- Icons (24x24 stroke) ----------
function PMIcon({ children, size = 24, stroke = 2, style }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none"
      stroke="currentColor" strokeWidth={stroke} strokeLinecap="round" strokeLinejoin="round"
      style={{ flexShrink: 0, ...style }}>{children}</svg>
  );
}
function IconChat(p) { return <PMIcon {...p}><path d="M21 12a8.5 8.5 0 0 1-8.5 8.5c-1.5 0-2.9-.36-4.1-1L3 21l1.6-4.6A8.5 8.5 0 1 1 21 12z" /></PMIcon>; }
function IconHistory(p) { return <PMIcon {...p}><circle cx="12" cy="12" r="9" /><path d="M12 7v5l3.2 2" /></PMIcon>; }
function IconBook(p) { return <PMIcon {...p}><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20V3H6.5A2.5 2.5 0 0 0 4 5.5v14z" /><path d="M4 19.5A2.5 2.5 0 0 0 6.5 22H20v-5" /></PMIcon>; }
function IconGear(p) { return <PMIcon {...p}><circle cx="12" cy="12" r="3.2" /><path d="M19.4 15a1.7 1.7 0 0 0 .34 1.87l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.7 1.7 0 0 0-1.87-.34 1.7 1.7 0 0 0-1.03 1.56V21a2 2 0 1 1-4 0v-.09A1.7 1.7 0 0 0 9 19.35a1.7 1.7 0 0 0-1.87.34l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06A1.7 1.7 0 0 0 4.65 15a1.7 1.7 0 0 0-1.56-1.03H3a2 2 0 1 1 0-4h.09A1.7 1.7 0 0 0 4.65 9a1.7 1.7 0 0 0-.34-1.87l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06A1.7 1.7 0 0 0 9 4.65h.01A1.7 1.7 0 0 0 10.04 3.1V3a2 2 0 1 1 4 0v.09c0 .68.4 1.3 1.03 1.56.6.26 1.3.13 1.87-.34l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06A1.7 1.7 0 0 0 19.35 9v.01c.26.62.88 1.03 1.56 1.03H21a2 2 0 1 1 0 4h-.09c-.68 0-1.3.4-1.56 1.03z" /></PMIcon>; }
function IconCamera(p) { return <PMIcon {...p}><path d="M3 8a2 2 0 0 1 2-2h2l1.5-2.2A1.5 1.5 0 0 1 9.8 3h4.4a1.5 1.5 0 0 1 1.3.8L17 6h2a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8z" /><circle cx="12" cy="13" r="3.5" /></PMIcon>; }
function IconSend(p) { return <PMIcon {...p}><path d="M12 19V5" /><path d="M5.5 11.5 12 5l6.5 6.5" /></PMIcon>; }
function IconChevron(p) { return <PMIcon {...p}><path d="M9 6l6 6-6 6" /></PMIcon>; }
function IconSearch(p) { return <PMIcon {...p}><circle cx="11" cy="11" r="7" /><path d="m20 20-3.8-3.8" /></PMIcon>; }
function IconPlusChat(p) { return <PMIcon {...p}><path d="M12 8v8M8 12h8" /><circle cx="12" cy="12" r="9.2" /></PMIcon>; }
function IconTrash(p) { return <PMIcon {...p}><path d="M4 7h16M10 11v6M14 11v6M6 7l1 13a1.6 1.6 0 0 0 1.6 1.4h6.8A1.6 1.6 0 0 0 17 20l1-13M9 7V5a1.5 1.5 0 0 1 1.5-1.5h3A1.5 1.5 0 0 1 15 5v2" /></PMIcon>; }
function IconX(p) { return <PMIcon {...p}><path d="M6 6l12 12M18 6 6 18" /></PMIcon>; }
function IconSun(p) { return <PMIcon {...p}><circle cx="12" cy="12" r="4" /><path d="M12 2v2.4M12 19.6V22M2 12h2.4M19.6 12H22M4.9 4.9l1.7 1.7M17.4 17.4l1.7 1.7M19.1 4.9l-1.7 1.7M6.6 17.4l-1.7 1.7" /></PMIcon>; }
function IconMoon(p) { return <PMIcon {...p}><path d="M20.6 14.3A8.6 8.6 0 0 1 9.7 3.4a8.6 8.6 0 1 0 10.9 10.9z" /></PMIcon>; }
function IconDoor(p) { return <PMIcon {...p}><path d="M4 21h16M6 21V4.5A1.5 1.5 0 0 1 7.5 3h9A1.5 1.5 0 0 1 18 4.5V21" /><path d="M14.5 12.5h.01" strokeWidth="2.8" /></PMIcon>; }
function IconDroplet(p) { return <PMIcon {...p}><path d="M12 2.7s6.5 7 6.5 11.3a6.5 6.5 0 0 1-13 0C5.5 9.7 12 2.7 12 2.7z" /></PMIcon>; }
function IconExtinguisher(p) { return <PMIcon {...p}><path d="M9.5 8.5h5a1 1 0 0 1 1 1V20a1.5 1.5 0 0 1-1.5 1.5h-4A1.5 1.5 0 0 1 8.5 20V9.5a1 1 0 0 1 1-1z" /><path d="M12 8.5V6M12 6h4.5M12 6 8 4M10.5 12.5h3" /></PMIcon>; }
function IconBolt(p) { return <PMIcon {...p}><path d="M13 2 4.5 13.5H11L9.8 22 19.5 9.8H13L13 2z" /></PMIcon>; }
function IconCheck(p) { return <PMIcon {...p}><path d="M4.5 12.5 10 18 19.5 6.5" /></PMIcon>; }
function IconBell(p) { return <PMIcon {...p}><path d="M18 8.4a6 6 0 1 0-12 0c0 6.2-2.4 7.6-2.4 7.6h16.8S18 14.6 18 8.4z" /><path d="M10 19.5a2.2 2.2 0 0 0 4 0" /></PMIcon>; }
function IconHood(p) { return <PMIcon {...p}><path d="M4 13h16l-3-6.5a2 2 0 0 0-1.8-1.2H8.8A2 2 0 0 0 7 6.5L4 13z" /><path d="M4 13v2.5h16V13M9 19v2M12 19v2.5M15 19v2" /></PMIcon>; }
function IconBuilding(p) { return <PMIcon {...p}><path d="M4 21h16M6 21V5a1.5 1.5 0 0 1 1.5-1.5h9A1.5 1.5 0 0 1 18 5v16" /><path d="M9.5 7h.01M14.5 7h.01M9.5 11h.01M14.5 11h.01M10 21v-4h4v4" /></PMIcon>; }
function IconRoute(p) { return <PMIcon {...p}><circle cx="6" cy="19" r="2.6" /><circle cx="18" cy="5" r="2.6" /><path d="M8.6 19H15a3.5 3.5 0 0 0 0-7H9a3.5 3.5 0 0 1 0-7h6.4" /></PMIcon>; }
function IconPhone(p) { return <PMIcon {...p}><path d="M5.2 3h2.9a1 1 0 0 1 .95.68l1.2 3.6a1 1 0 0 1-.36 1.12l-1.9 1.43a13.4 13.4 0 0 0 5.18 5.18l1.43-1.9a1 1 0 0 1 1.12-.36l3.6 1.2a1 1 0 0 1 .68.95v2.9A2.2 2.2 0 0 1 17.8 20 16.8 16.8 0 0 1 4 6.2 2.2 2.2 0 0 1 5.2 3z" /></PMIcon>; }
function IconMic(p) { return <PMIcon {...p}><rect x="9" y="2.8" width="6" height="11.2" rx="3" /><path d="M5.5 11.5a6.5 6.5 0 0 0 13 0M12 18v3.2M8.8 21.2h6.4" /></PMIcon>; }
function IconCopy(p) { return <PMIcon {...p}><rect x="8.5" y="8.5" width="12" height="12" rx="2.4" /><path d="M15.5 5.5H5.8a2 2 0 0 0-2 2v9.7" /></PMIcon>; }
function IconThumbUp(p) { return <PMIcon {...p}><path d="M7 21V10.5l4.2-7a1.6 1.6 0 0 1 2.9 1.2L13.3 9h4.9a2 2 0 0 1 2 2.4l-1.4 7A2 2 0 0 1 16.8 20H7z" /><rect x="2.8" y="10.5" width="4.2" height="10.5" rx="1.2" /></PMIcon>; }
function IconThumbDown(p) { return <PMIcon {...p}><path d="M7 3v10.5l4.2 7a1.6 1.6 0 0 0 2.9-1.2L13.3 15h4.9a2 2 0 0 0 2-2.4l-1.4-7A2 2 0 0 0 16.8 4H7z" /><rect x="2.8" y="3" width="4.2" height="10.5" rx="1.2" /></PMIcon>; }
function IconCompass(p) { return <PMIcon {...p}><circle cx="12" cy="12" r="9.2" /><path d="m15.5 8.5-2 5-5 2 2-5 5-2z" /></PMIcon>; }
function IconShieldCheck(p) { return <PMIcon {...p}><path d="M12 2.5 19.3 5.2v5.9c0 4.7-3.1 8.2-7.3 10.1C7.8 19.3 4.7 15.8 4.7 11.1V5.2L12 2.5z" /><path d="m8.8 11.8 2.3 2.3 4.1-4.6" /></PMIcon>; }
function IconScroll(p) { return <PMIcon {...p}><path d="M7 3h11a2 2 0 0 1 2 2v2h-4" /><path d="M16 21H6.5A2.5 2.5 0 0 1 4 18.5V5a2 2 0 0 1 2-2h.5A1.5 1.5 0 0 1 8 4.5V18a2 2 0 0 0 2 2h6z" /><path d="M16 21a2 2 0 0 0 2-2V5" /><path d="M11 8h4M11 12h4" /></PMIcon>; }

// ---------- Marshal avatar ----------
// styles: 'mascot' (the Pocket Marshal character), 'badge', 'monogram', 'none'
function MarshalAvatar({ styleKind = 'badge', size = 40, pocket, float = false }) {
  if (styleKind === 'none') return null;
  if (styleKind === 'mascot') {
    const variant = pocket || window.__pmPocketColor || 'blue';
    return (
      <div aria-hidden="true" style={{ width: size, height: size, flexShrink: 0, position: 'relative' }}>
        <img src={`assets/marshal-${variant}.png`} alt="" style={{
          width: '100%', height: '100%', objectFit: 'contain', display: 'block',
          animation: float ? 'pm-float 3.4s ease-in-out infinite' : 'none',
        }} />
        {float && (
          <div style={{
            position: 'absolute', left: '20%', right: '20%', bottom: -Math.max(6, size * 0.1),
            height: Math.max(4, size * 0.08), borderRadius: '50%',
            background: 'rgba(8,14,24,0.32)', filter: 'blur(1.5px)',
            animation: 'pm-float-shadow 3.4s ease-in-out infinite',
          }}></div>
        )}
      </div>
    );
  }
  if (styleKind === 'monogram') {
    return (
      <div aria-hidden="true" style={{
        width: size, height: size, borderRadius: '50%', background: PM_AMBER,
        display: 'grid', placeItems: 'center', flexShrink: 0,
        color: PM_NAVY, fontWeight: 800, fontSize: size * 0.5, letterSpacing: '-0.02em',
        fontFamily: 'inherit',
      }}>M</div>
    );
  }
  // badge: navy disc, amber shield with star
  return (
    <div aria-hidden="true" style={{
      width: size, height: size, borderRadius: '50%', background: PM_NAVY,
      display: 'grid', placeItems: 'center', flexShrink: 0,
    }}>
      <svg width={size * 0.62} height={size * 0.62} viewBox="0 0 24 24" fill="none">
        <path d="M12 2.2 19.6 5v6.1c0 4.9-3.2 8.5-7.6 10.5C7.6 19.6 4.4 16 4.4 11.1V5L12 2.2z"
          stroke={PM_AMBER} strokeWidth="1.9" strokeLinejoin="round" />
        <path d="m12 7.2 1.25 2.53 2.8.41-2.03 1.97.48 2.78L12 13.58l-2.5 1.31.48-2.78-2.03-1.97 2.8-.41L12 7.2z"
          fill={PM_AMBER} />
      </svg>
    </div>
  );
}

// ---------- Theme ----------
// mode: 'light' (warm white) | 'dark' (deep navy)
function pmBuildTheme(t) {
  const dark = t.mode === 'dark';
  const shared = {
    navy: PM_NAVY, crimson: PM_CRIMSON, flame: PM_FLAME, highlight: PM_HIGHLIGHT, surface: PM_SURFACE,
    blue: PM_BLUE, amber: PM_AMBER,
  };
  if (!dark) {
    return { ...shared, dark: false,
      bg: PM_SURFACE, paper: '#ffffff', ink: PM_NAVY, muted: PM_MUTED, line: PM_LINE,
      cardEdge: 'rgba(13,31,56,0.07)',
      navySoft: '#edf0f6', emberSoft: '#fce7da', amberSoft: '#fdf1d8',
      red: PM_CRIMSON, ember: PM_FLAME, emberDark: '#b03c12', amberDark: '#9a6a0c',
      citeBorder: '#f0d3b8',
      bannerBg: '#fce7da', bannerInk: '#8c2e10',
      dangerInk: '#8c1c0e', dangerEdge: '#e8b9ae',
      userBubble: PM_NAVY, userInk: PM_SURFACE,
      headerBg: '#ffffff', headerInk: PM_NAVY, headerSub: PM_MUTED,
      cta: PM_NAVY, ctaInk: PM_SURFACE,
      chipIcon: '#b03c12', chipBorder: PM_LINE,
      navActive: PM_NAVY, navIndicator: PM_FLAME,
      heroAccent: PM_NAVY, focusRing: PM_FLAME,
    };
  }
  return { ...shared, dark: true,
    bg: '#0a1626', paper: '#13233e', ink: '#f4efe6', muted: '#8fa0ba', line: '#26395c',
    cardEdge: 'rgba(255,248,240,0.07)',
    navySoft: '#1b3050', emberSoft: '#33231a', amberSoft: '#352a12',
    red: '#e8705c', ember: PM_HIGHLIGHT, emberDark: PM_HIGHLIGHT, amberDark: '#f0b03f',
    citeBorder: '#54391f',
    bannerBg: '#2c1f12', bannerInk: '#f0b285',
    dangerInk: '#ff9a86', dangerEdge: '#643026',
    userBubble: '#27466e', userInk: '#fff8f0',
    headerBg: '#0f1d33', headerInk: '#f4efe6', headerSub: '#8fa0ba',
    cta: PM_FLAME, ctaInk: '#fff8f0',
    chipIcon: PM_HIGHLIGHT, chipBorder: '#26395c',
    navActive: PM_HIGHLIGHT, navIndicator: PM_HIGHLIGHT,
    heroAccent: PM_HIGHLIGHT, focusRing: PM_HIGHLIGHT,
  };
}

const PM_FONTS = {
  system: { label: 'System — SF Pro', stack: "-apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Segoe UI', system-ui, sans-serif" },
  humanist: { label: 'Public Sans', stack: "'Public Sans', system-ui, sans-serif" },
  rounded: { label: 'Nunito', stack: "'Nunito', system-ui, sans-serif" },
  grotesque: { label: 'Archivo', stack: "'Archivo', system-ui, sans-serif" },
};

// ---------- Lightweight message formatting ----------
// Supports **bold**, "- " bullets, and [[NFPA 101 §7.10.1.2]] citation pills.
function pmRenderInline(text, theme, keyBase) {
  const parts = [];
  let rest = text, i = 0;
  const pattern = /(\*\*[^*]+\*\*|\[\[[^\]]+\]\])/;
  while (rest.length) {
    const m = rest.match(pattern);
    if (!m) { parts.push(rest); break; }
    if (m.index > 0) parts.push(rest.slice(0, m.index));
    const tok = m[0];
    if (tok.startsWith('**')) {
      parts.push(<strong key={keyBase + '-b' + i} style={{ fontWeight: 800 }}>{tok.slice(2, -2)}</strong>);
    } else {
      parts.push(
        <span key={keyBase + '-c' + i} style={{
          display: 'inline-block', background: theme.amberSoft, color: theme.amberDark,
          border: `1px solid ${theme.citeBorder || '#ecd095'}`, borderRadius: 6, padding: '0 0.4em',
          fontWeight: 700, fontSize: '0.88em', whiteSpace: 'nowrap', verticalAlign: 'baseline',
        }}>{tok.slice(2, -2)}</span>
      );
    }
    rest = rest.slice(m.index + tok.length);
    i++;
  }
  return parts;
}

function PMRichText({ text, theme }) {
  const lines = String(text || '').split('\n');
  const blocks = [];
  let bullets = null;
  lines.forEach((ln, idx) => {
    const trimmed = ln.trim();
    if (/^[-•] /.test(trimmed)) {
      if (!bullets) { bullets = []; blocks.push(bullets); }
      bullets.push(trimmed.replace(/^[-•] /, ''));
    } else {
      bullets = null;
      if (trimmed) blocks.push(trimmed);
    }
  });
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: '0.55em' }}>
      {blocks.map((b, i) => Array.isArray(b) ? (
        <ul key={i} style={{ margin: 0, paddingLeft: '1.2em', display: 'flex', flexDirection: 'column', gap: '0.3em' }}>
          {b.map((item, j) => <li key={j} style={{ lineHeight: 1.45 }}>{pmRenderInline(item, theme, i + '-' + j)}</li>)}
        </ul>
      ) : (
        <p key={i} style={{ margin: 0, lineHeight: 1.5 }}>{pmRenderInline(b, theme, 'p' + i)}</p>
      ))}
    </div>
  );
}

// ---------- Image helper: downscale a File to dataURL ----------
// Always re-encodes to JPEG so the AI vision pipeline gets a format it can read
// (raw camera formats like HEIC would otherwise pass through and fail silently).
async function pmFileToThumb(file, maxDim = 900) {
  const dataUrl = await new Promise((res, rej) => {
    const r = new FileReader();
    r.onload = () => res(r.result); r.onerror = rej;
    r.readAsDataURL(file);
  });
  const img = await new Promise((res, rej) => {
    const im = new Image();
    im.onload = () => res(im); im.onerror = () => rej(new Error('unsupported-format'));
    im.src = dataUrl;
  });
  if (!img.width || !img.height) throw new Error('unsupported-format');
  const scale = Math.min(1, maxDim / Math.max(img.width, img.height));
  const c = document.createElement('canvas');
  c.width = Math.max(1, Math.round(img.width * scale));
  c.height = Math.max(1, Math.round(img.height * scale));
  const ctx = c.getContext('2d');
  ctx.fillStyle = '#ffffff';
  ctx.fillRect(0, 0, c.width, c.height);
  ctx.drawImage(img, 0, 0, c.width, c.height);
  return c.toDataURL('image/jpeg', 0.85);
}

function pmTimeAgo(ts) {
  const d = Date.now() - ts;
  const min = Math.round(d / 60000);
  if (min < 1) return 'Just now';
  if (min < 60) return min + ' min ago';
  const h = Math.round(min / 60);
  if (h < 24) return h + (h === 1 ? ' hour ago' : ' hours ago');
  const days = Math.round(h / 24);
  if (days === 1) return 'Yesterday';
  return new Date(ts).toLocaleDateString(undefined, { month: 'short', day: 'numeric' });
}

Object.assign(window, {
  PM_NAVY, PM_CRIMSON, PM_FLAME, PM_HIGHLIGHT, PM_SURFACE,
  PM_BLUE, PM_BLUE_DEEP, PM_INK, PM_RED, PM_EMBER, PM_EMBER_DARK, PM_AMBER, PM_AMBER_DARK, PM_FONTS,
  PMIcon, IconChat, IconHistory, IconBook, IconGear, IconCamera, IconSend, IconChevron,
  IconSearch, IconPlusChat, IconTrash, IconX, IconSun, IconMoon, IconDoor, IconDroplet,
  IconExtinguisher, IconBolt, IconCheck, IconBell, IconHood, IconBuilding, IconPhone, IconMic,
  IconCompass, IconShieldCheck, IconScroll, IconRoute, IconThumbUp, IconThumbDown, IconCopy,
  MarshalAvatar, pmBuildTheme, PMRichText, pmRenderInline, pmFileToThumb, pmTimeAgo,
});
