// components.jsx — shared UI components
const { useState, useEffect, useMemo, useRef, useCallback } = React;
const t = DOPO.I18N.it;

// ─── Icons ──────────────────────────────────────────────────────────────────
function Icon({ name, size = 18, color = 'currentColor', strokeWidth = 1.6, style: extraStyle }) {
  const s = { width: size, height: size, display: 'inline-block', flexShrink: 0, ...extraStyle };
  const props = { width: size, height: size, viewBox: '0 0 24 24', fill: 'none', stroke: color, strokeWidth, strokeLinecap: 'round', strokeLinejoin: 'round', style: s };

  const paths = {
    home: <><path d="M3 9.5L12 3l9 6.5V20a1 1 0 01-1 1H4a1 1 0 01-1-1V9.5z"/><path d="M9 21V12h6v9"/></>,
    inventory: <><rect x="3" y="3" width="7" height="7" rx="1"/><rect x="14" y="3" width="7" height="7" rx="1"/><rect x="3" y="14" width="7" height="7" rx="1"/><rect x="14" y="14" width="7" height="7" rx="1"/></>,
    memories: <><path d="M20.84 4.61a5.5 5.5 0 00-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 00-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 000-7.78z"/></>,
    circle: <><path d="M17 21v-2a4 4 0 00-4-4H5a4 4 0 00-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 00-3-3.87"/><path d="M16 3.13a4 4 0 010 7.75"/></>,
    bequests: <><path d="M20 12V22H4V12"/><path d="M22 7H2v5h20V7z"/><path d="M12 22V7"/><path d="M12 7H7.5a2.5 2.5 0 010-5C11 2 12 7 12 7z"/><path d="M12 7h4.5a2.5 2.5 0 000-5C13 2 12 7 12 7z"/></>,
    profile: <><path d="M20 21v-2a4 4 0 00-4-4H8a4 4 0 00-4 4v2"/><circle cx="12" cy="7" r="4"/></>,
    search: <><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></>,
    plus: <><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></>,
    arrow_right: <><line x1="5" y1="12" x2="19" y2="12"/><polyline points="12 5 19 12 12 19"/></>,
    close: <><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></>,
    check: <><polyline points="20 6 9 17 4 12"/></>,
    chevron_right: <><polyline points="9 18 15 12 9 6"/></>,
    chevron_down: <><polyline points="6 9 12 15 18 9"/></>,
    dot_menu: <><circle cx="12" cy="5" r="1" fill={color}/><circle cx="12" cy="12" r="1" fill={color}/><circle cx="12" cy="19" r="1" fill={color}/></>,
    filter: <><polygon points="22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3"/></>,
    letter: <><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"/></>,
    audio: <><path d="M3 18v-6a9 9 0 0118 0v6"/><path d="M21 19a2 2 0 01-2 2h-1a2 2 0 01-2-2v-3a2 2 0 012-2h3zM3 19a2 2 0 002 2h1a2 2 0 002-2v-3a2 2 0 00-2-2H3z"/></>,
    photo: <><rect x="3" y="3" width="18" height="18" rx="2" ry="2"/><circle cx="8.5" cy="8.5" r="1.5"/><polyline points="21 15 16 10 5 21"/></>,
    video: <><polygon points="23 7 16 12 23 17 23 7"/><rect x="1" y="5" width="15" height="14" rx="2" ry="2"/></>,
    doc: <><path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/><polyline points="10 9 9 9 8 9"/></>,
    service: <><rect x="2" y="3" width="20" height="14" rx="2" ry="2"/><line x1="8" y1="21" x2="16" y2="21"/><line x1="12" y1="17" x2="12" y2="21"/></>,
    shield: <><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></>,
    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"/></>,
    lock: <><rect x="3" y="11" width="18" height="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0110 0v4"/></>,
    clock: <><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></>,
    oblio: <><polyline points="3 6 5 6 21 6"/><path d="M19 6v14a2 2 0 01-2 2H7a2 2 0 01-2-2V6m3 0V4a1 1 0 011-1h4a1 1 0 011 1v2"/></>,
    eye_off: <><path d="M17.94 17.94A10.07 10.07 0 0112 20c-7 0-11-8-11-8a18.45 18.45 0 015.06-5.94M9.9 4.24A9.12 9.12 0 0112 4c7 0 11 8 11 8a18.5 18.5 0 01-2.16 3.19m-6.72-1.07a3 3 0 11-4.24-4.24"/><line x1="1" y1="1" x2="23" y2="23"/></>,
    people: <><path d="M17 21v-2a4 4 0 00-4-4H5a4 4 0 00-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 00-3-3.87"/><path d="M16 3.13a4 4 0 010 7.75"/></>,
    tag: <><path d="M20.59 13.41l-7.17 7.17a2 2 0 01-2.83 0L2 12V2h10l8.59 8.59a2 2 0 010 2.82z"/><line x1="7" y1="7" x2="7.01" y2="7"/></>,
    sparkle: <><path d="M12 3L9.5 9.5 3 12l6.5 2.5L12 21l2.5-6.5L21 12l-6.5-2.5L12 3z"/></>,
    bell: <><path d="M18 8A6 6 0 006 8c0 7-3 9-3 9h18s-3-2-3-9"/><path d="M13.73 21a2 2 0 01-3.46 0"/></>,
    settings: <><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 00.33 1.82l.06.06a2 2 0 010 2.83 2 2 0 01-2.83 0l-.06-.06a1.65 1.65 0 00-1.82-.33 1.65 1.65 0 00-1 1.51V21a2 2 0 01-4 0v-.09A1.65 1.65 0 009 19.4a1.65 1.65 0 00-1.82.33l-.06.06a2 2 0 01-2.83 0 2 2 0 010-2.83l.06-.06A1.65 1.65 0 004.68 15a1.65 1.65 0 00-1.51-1H3a2 2 0 010-4h.09A1.65 1.65 0 004.6 9a1.65 1.65 0 00-.33-1.82l-.06-.06a2 2 0 010-2.83 2 2 0 012.83 0l.06.06A1.65 1.65 0 009 4.68a1.65 1.65 0 001-1.51V3a2 2 0 014 0v.09a1.65 1.65 0 001 1.51 1.65 1.65 0 001.82-.33l.06-.06a2 2 0 012.83 0 2 2 0 010 2.83l-.06.06A1.65 1.65 0 0019.4 9a1.65 1.65 0 001.51 1H21a2 2 0 010 4h-.09a1.65 1.65 0 00-1.51 1z"/></>,
    edit: <><path d="M11 4H4a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 013 3L12 15l-4 1 1-4 9.5-9.5z"/></>,
    trash: <><polyline points="3 6 5 6 21 6"/><path d="M19 6v14a2 2 0 01-2 2H7a2 2 0 01-2-2V6m3 0V4a1 1 0 011-1h4a1 1 0 011 1v2"/></>,
    heart: <><path d="M20.84 4.61a5.5 5.5 0 00-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 00-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 000-7.78z"/></>,
    gift: <><polyline points="20 12 20 22 4 22 4 12"/><rect x="2" y="7" width="20" height="5"/><line x1="12" y1="22" x2="12" y2="7"/><path d="M12 7H7.5a2.5 2.5 0 010-5C11 2 12 7 12 7z"/><path d="M12 7h4.5a2.5 2.5 0 000-5C13 2 12 7 12 7z"/></>,
    alert: <><path d="M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></>,
    key: <><path d="M21 2l-2 2m-7.61 7.61a5.5 5.5 0 11-7.778 7.778 5.5 5.5 0 017.777-7.777zm0 0L15.5 7.5m0 0l3 3L22 7l-3-3m-3.5 3.5L19 4"/></>,
    book: <><path d="M4 19.5A2.5 2.5 0 016.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 014 19.5v-15A2.5 2.5 0 016.5 2z"/></>,
  };

  return (
    <svg {...props}>
      {paths[name] || <circle cx="12" cy="12" r="10"/>}
    </svg>
  );
}

// ─── Monogram ────────────────────────────────────────────────────────────────
function Monogram({ initials, color, size = 'md', style: extraStyle = {} }) {
  const cls = size === 'sm' ? 'mono mono-sm' : size === 'lg' ? 'mono mono-lg' : size === 'xl' ? 'mono mono-xl' : 'mono';
  return (
    <div className={cls} style={{ background: color, ...extraStyle }}>
      {initials}
    </div>
  );
}

// ─── MonoStack ───────────────────────────────────────────────────────────────
function MonoStack({ ids, people, max = 3 }) {
  const shown = ids.slice(0, max);
  const rest = ids.length - max;
  const pMap = Object.fromEntries((people || DOPO.SEED.people).map(p => [p.id, p]));
  return (
    <div className="mono-stack">
      {shown.map(id => {
        const p = pMap[id];
        if (!p) return null;
        return <Monogram key={id} initials={p.initials} color={p.color} size="sm" />;
      })}
      {rest > 0 && (
        <div className="mono mono-sm" style={{ background: 'var(--gr-400)' }}>+{rest}</div>
      )}
    </div>
  );
}

// ─── DestinyPill ─────────────────────────────────────────────────────────────
function DestinyPill({ destiny, onClick }) {
  const labels = {
    people: 'Persone',
    oblio: 'Oblio',
    hidden: 'Nascosto',
    null: t.common.not_set,
    undefined: t.common.not_set,
  };
  const label = labels[destiny] || t.common.not_set;
  const d = destiny || 'none';
  return (
    <span
      className="destiny"
      data-d={d}
      style={{ cursor: onClick ? 'pointer' : 'default' }}
      onClick={onClick}
    >
      {label}
    </span>
  );
}

// ─── ServiceBadge ────────────────────────────────────────────────────────────
function ServiceBadge({ icon, color, size = 36 }) {
  return (
    <div style={{
      width: size,
      height: size,
      borderRadius: 8,
      background: color || 'var(--gr-700)',
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center',
      color: '#fff',
      fontWeight: 700,
      fontSize: size * 0.42,
      flexShrink: 0,
      fontFamily: 'var(--f-mono)',
      letterSpacing: '-0.02em',
    }}>
      {icon}
    </div>
  );
}

// ─── StatCell ────────────────────────────────────────────────────────────────
function StatCell({ num, label, accent = false }) {
  return (
    <div className="stat-cell">
      <div className="stat-num" style={accent ? { color: 'var(--accent)' } : {}}>
        {num}
      </div>
      <div className="stat-label">{label}</div>
    </div>
  );
}

// ─── Sidebar ─────────────────────────────────────────────────────────────────
function Sidebar({ route, setRoute, data }) {
  const nav = t.nav;
  const seed = data || DOPO.SEED;
  const unassigned = seed.services.filter(s => !s.destiny).length + seed.assets.filter(a => !a.destiny).length;

  const links = [
    { id: 'home', label: nav.home, icon: 'home' },
    { id: 'inventory', label: nav.inventory, icon: 'inventory', count: seed.services.length + seed.assets.length },
    { id: 'memories', label: nav.memories, icon: 'memories', count: seed.memories.length },
    { id: 'circle', label: nav.circle, icon: 'circle', count: seed.people.length },
    { id: 'bequests', label: nav.bequests, icon: 'bequests', count: seed.bequests.length },
    { id: 'profile', label: nav.profile, icon: 'profile' },
  ];

  const progress = seed.profileProgress || 62;

  return (
    <aside className="sidebar">
      {/* Logo */}
      <div className="sidebar-logo">
        dopo<span>.me</span>
      </div>

      {/* Nav */}
      <nav className="sidebar-nav">
        {links.map(link => (
          <div
            key={link.id}
            className={`nav-link${route === link.id ? ' active' : ''}`}
            onClick={() => setRoute(link.id)}
          >
            <Icon name={link.icon} size={17} />
            {link.label}
            {link.count !== undefined && (
              <span className="nav-count">{link.count}</span>
            )}
            {link.id === 'inventory' && unassigned > 0 && (
              <span className="nav-badge">{unassigned}</span>
            )}
          </div>
        ))}
      </nav>

      {/* Progress card */}
      <div className="sidebar-progress">
        <div className="row" style={{ marginBottom: 8 }}>
          <span style={{ fontSize: 12, fontWeight: 500, color: 'var(--ink)', flex: 1 }}>
            {t.home.plan_title}
          </span>
          <span style={{ fontSize: 12, color: 'var(--ink-muted)' }}>
            {progress}%
          </span>
        </div>
        <div className="progress">
          <div style={{ width: `${progress}%` }} />
        </div>
        <div style={{ fontSize: 11, color: 'var(--ink-muted)', marginTop: 8 }}>
          {t.home.plan_complete}
        </div>
      </div>

      {/* User */}
      <div className="sidebar-user" onClick={() => setRoute('profile')}>
        <Monogram initials={seed.user.initials} color={seed.user.color} />
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontSize: 13, fontWeight: 500, color: 'var(--ink)', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
            {seed.user.name}
          </div>
          <div style={{ fontSize: 11, color: 'var(--ink-muted)', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
            {seed.user.email}
          </div>
        </div>
      </div>
    </aside>
  );
}

// ─── PageHeader ──────────────────────────────────────────────────────────────
function PageHeader({ eyebrow, title, subtitle, actions, serif = true }) {
  return (
    <div style={{ marginBottom: 36 }}>
      {eyebrow && <div className="t-eyebrow" style={{ marginBottom: 8 }}>{eyebrow}</div>}
      <div className="row" style={{ alignItems: 'flex-end', marginBottom: subtitle ? 10 : 0 }}>
        <h1
          className={serif ? 't-h1' : ''}
          style={{
            fontSize: 38,
            margin: 0,
            flex: 1,
            fontFamily: serif ? 'var(--f-serif)' : 'var(--f-sans)',
            fontStyle: serif ? 'italic' : 'normal',
            fontWeight: serif ? 400 : 600,
            color: 'var(--ink)',
            letterSpacing: '-0.01em',
            lineHeight: 1.1,
          }}
        >
          {title}
        </h1>
        {actions && <div className="row">{actions}</div>}
      </div>
      {subtitle && (
        <p style={{ fontSize: 15, color: 'var(--ink-muted)', margin: 0, lineHeight: 1.5, maxWidth: 560 }}>
          {subtitle}
        </p>
      )}
    </div>
  );
}

// ─── SectionHeader ───────────────────────────────────────────────────────────
function SectionHeader({ title, action }) {
  return (
    <div className="section-head">
      <div className="section-title">{title}</div>
      {action}
    </div>
  );
}

// Export all to window
Object.assign(window, {
  Icon,
  Monogram,
  MonoStack,
  DestinyPill,
  ServiceBadge,
  StatCell,
  Sidebar,
  PageHeader,
  SectionHeader,
});
