/* ============ MAKI — Componentes UI compartidos ============ */
const { useState, useEffect, useRef, useMemo } = React;
const cv = (name) => `var(${name})`;

/* —— Iconos (stroke, estilo lucide) —— */
const ICONS = {
  inbox: "M22 12h-6l-2 3h-4l-2-3H2 M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z",
  board: "M3 3h7v9H3z M14 3h7v5h-7z M14 12h7v9h-7z M3 16h7v5H3z",
  chart: "M3 3v18h18 M7 16v-5 M12 16V8 M17 16v-9",
  users: "M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2 M9 11a4 4 0 1 0 0-8 4 4 0 0 0 0 8 M22 21v-2a4 4 0 0 0-3-3.87 M16 3.13a4 4 0 0 1 0 7.75",
  truck: "M14 18V6a1 1 0 0 0-1-1H2 M14 9h4l3 3v6h-2 M2 18h2 M10 18h2 M5.5 18a2.5 2.5 0 1 1-5 0 2.5 2.5 0 0 1 5 0z M19.5 18a2.5 2.5 0 1 1-5 0 2.5 2.5 0 0 1 5 0z",
  settings: "M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0z",
  search: "M11 19a8 8 0 1 0 0-16 8 8 0 0 0 0 16z M21 21l-4.3-4.3",
  bell: "M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9 M10.3 21a1.94 1.94 0 0 0 3.4 0",
  plus: "M12 5v14 M5 12h14",
  clock: "M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20z M12 6v6l4 2",
  check: "M20 6 9 17l-5-5",
  checkCheck: "m2 14 4 4 8-9 M14 18l1.5 1.5L22 12",
  chevR: "m9 18 6-6-6-6",
  chevL: "m15 18-6-6 6-6",
  chevD: "m6 9 6 6 6-6",
  x: "M18 6 6 18 M6 6l12 12",
  map: "M12 21s-6-5.7-6-10a6 6 0 0 1 12 0c0 4.3-6 10-6 10z M12 11a2 2 0 1 0 0-4 2 2 0 0 0 0 4z",
  whatsapp: "M3 21l1.65-3.8a9 9 0 1 1 3.4 2.9z M9 10a.5.5 0 0 0 1 0V9a.5.5 0 0 0-1 0v1a5 5 0 0 0 5 5h1a.5.5 0 0 0 0-1h-1a.5.5 0 0 0 0 1",
  globe: "M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20z M2 12h20 M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z",
  phone: "M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72c.13.96.36 1.9.7 2.81a2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45c.91.34 1.85.57 2.81.7A2 2 0 0 1 22 16.92z",
  mail: "M22 7l-10 6L2 7 M4 5h16a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V7a2 2 0 0 1 2-2z",
  moped: "M5 18a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5z M19 18a2 2 0 1 0 0-4 2 2 0 0 0 0 4z M5 15.5V11h4l3 4h5 M9 11l2-5h3l1 3 M16 16h2a3 3 0 0 0 0-6h-1",
  filter: "M22 3H2l8 9.46V19l4 2v-8.54z",
  dots: "M12 13a1 1 0 1 0 0-2 1 1 0 0 0 0 2z M19 13a1 1 0 1 0 0-2 1 1 0 0 0 0 2z M5 13a1 1 0 1 0 0-2 1 1 0 0 0 0 2z",
  send: "M22 2 11 13 M22 2l-7 20-4-9-9-4z",
  flame: "M8.5 14.5A2.5 2.5 0 0 0 11 12c0-1.38-.5-2-1-3-1.072-2.143-.224-4.054 2-6 .5 2.5 2 4.9 4 6.5 2 1.6 3 3.5 3 5.5a7 7 0 1 1-14 0c0-1.153.433-2.294 1-3a2.5 2.5 0 0 0 2.5 2.5z",
  store: "M3 9l1-5h16l1 5 M4 9v11a1 1 0 0 0 1 1h14a1 1 0 0 0 1-1V9 M3 9h18 M9 21v-6h6v6",
  pin: "M20 10c0 6-8 12-8 12s-8-6-8-12a8 8 0 0 1 16 0z M12 13a3 3 0 1 0 0-6 3 3 0 0 0 0 6z",
  user: "M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2 M12 11a4 4 0 1 0 0-8 4 4 0 0 0 0 8z",
  bag: "M6 2 3 6v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6l-3-4z M3 6h18 M16 10a4 4 0 0 1-8 0",
  repeat: "M17 2l4 4-4 4 M3 11V9a4 4 0 0 1 4-4h14 M7 22l-4-4 4-4 M21 13v2a4 4 0 0 1-4 4H3",
  zap: "M13 2 3 14h9l-1 8 10-12h-9z",
  alert: "m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3z M12 9v4 M12 17h.01",
  star: "M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01z",
  headphones: "M3 14h3a2 2 0 0 1 2 2v3a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-7a9 9 0 0 1 18 0v7a2 2 0 0 1-2 2h-1a2 2 0 0 1-2-2v-3a2 2 0 0 1 2-2h3",
  wifiOff: "M2 2l20 20 M8.5 16.5a5 5 0 0 1 7 0 M2 8.82a15 15 0 0 1 4.17-2.65 M10.66 5c4.01-.36 8.14.9 11.34 3.76 M16.85 11.25a10 10 0 0 1 2.22 1.68 M5 12.55a10 10 0 0 1 5.24-2.76",
  copy: "M9 9h10a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H9a2 2 0 0 1-2-2V11a2 2 0 0 1 2-2z M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1",
  card: "M3 5h18a1 1 0 0 1 1 1v12a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V6a1 1 0 0 1 1-1z M2 10h20",
  activity: "M22 12h-4l-3 9L9 3l-3 9H2",
  shield: "M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z",
  upload: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4 M17 8l-5-5-5 5 M12 3v12",
  message: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z",
  cash: "M2 7h20v10H2z M12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6z M6 10v.01 M18 14v.01",
  edit: "M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7 M18.5 2.5a2.12 2.12 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z",
  trash: "M3 6h18 M8 6V4h8v2 M19 6l-1 14H6L5 6 M10 11v6 M14 11v6",
  logout: "M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4 M16 17l5-5-5-5 M21 12H9",
  lock: "M19 11H5a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7a2 2 0 0 0-2-2z M7 11V7a5 5 0 0 1 10 0v4",
};

/* —— Alerta sonora (RF-2.1 · chat VIP entrante) —— */
function makiBeep(times = 2) {
  try {
    const AC = window.AudioContext || window.webkitAudioContext;
    const ac = new AC();
    for (let n = 0; n < times; n++) {
      const t0 = ac.currentTime + n * 0.26;
      const o = ac.createOscillator(), g = ac.createGain();
      o.connect(g); g.connect(ac.destination);
      o.type = "sine"; o.frequency.setValueAtTime(n ? 1040 : 820, t0);
      g.gain.setValueAtTime(0.0001, t0);
      g.gain.exponentialRampToValueAtTime(0.16, t0 + 0.02);
      g.gain.exponentialRampToValueAtTime(0.0001, t0 + 0.22);
      o.start(t0); o.stop(t0 + 0.24);
    }
  } catch (e) { /* sin audio disponible */ }
}

function Icon({ name, size = 18, color = "currentColor", stroke = 2, style, fill }) {
  const d = ICONS[name];
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill={fill || "none"}
      stroke={color} strokeWidth={stroke} strokeLinecap="round" strokeLinejoin="round"
      style={{ flexShrink: 0, ...style }}>
      {d.split(" M").map((seg, i) => <path key={i} d={(i ? "M" : "") + seg} />)}
    </svg>
  );
}

/* —— Logo Maki (hinomaru / salmón) —— */
function Logo({ size = 30 }) {
  return (
    <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
      <div style={{ position: "relative", width: size, height: size, flexShrink: 0 }}>
        <div style={{ position: "absolute", inset: 0, borderRadius: "50%", background: cv("--ink"), }} />
        <div style={{ position: "absolute", inset: size * 0.18, borderRadius: "50%", background: cv("--primary") }} />
        <div style={{ position: "absolute", inset: size * 0.40, borderRadius: "50%", background: cv("--primary-tint") }} />
      </div>
      <div style={{ lineHeight: 1 }}>
        <div style={{ fontWeight: 800, fontSize: size * 0.62, letterSpacing: "-0.02em", color: cv("--ink") }}>Maki</div>
      </div>
    </div>
  );
}

/* —— Pill de estado —— */
function StatusPill({ state, size = "md" }) {
  const st = MAKI.STATES.find(s => s.id === state);
  if (!st) return null;
  const pad = size === "sm" ? "3px 9px" : "4px 11px";
  const fs = size === "sm" ? 11.5 : 12.5;
  return (
    <span style={{
      display: "inline-flex", alignItems: "center", gap: 6, padding: pad,
      borderRadius: 99, background: cv(st.bg), color: cv(st.color),
      fontSize: fs, fontWeight: 700, whiteSpace: "nowrap",
    }}>
      <span style={{ width: 6, height: 6, borderRadius: "50%", background: cv(st.color) }} />
      {st.label}
    </span>
  );
}

/* —— Tag de canal —— */
function ChannelTag({ channel, compact }) {
  const ch = MAKI.CHANNELS[channel];
  if (!ch) return null;
  if (compact) {
    return (
      <span title={ch.label} style={{
        display: "inline-flex", alignItems: "center", justifyContent: "center",
        width: 24, height: 24, borderRadius: 7, background: cv(ch.bg), color: cv(ch.color),
      }}>
        <Icon name={ch.icon} size={14} stroke={2.2} />
      </span>
    );
  }
  return (
    <span style={{
      display: "inline-flex", alignItems: "center", gap: 6, padding: "3px 9px 3px 7px",
      borderRadius: 99, background: cv(ch.bg), color: cv(ch.color), fontSize: 12, fontWeight: 700,
    }}>
      <Icon name={ch.icon} size={13} stroke={2.2} /> {ch.label}
    </span>
  );
}

/* —— Avatar (iniciales) —— */
function Avatar({ name, size = 34, type }) {
  const initials = (name || "?").split(" ").slice(0, 2).map(w => w[0]).join("").toUpperCase();
  const hue = [...(name || "x")].reduce((a, c) => a + c.charCodeAt(0), 0) % 360;
  const isEmpresa = type === "empresa";
  return (
    <div style={{
      width: size, height: size, flexShrink: 0, borderRadius: isEmpresa ? size * 0.28 : "50%",
      background: `oklch(0.92 0.045 ${hue})`, color: `oklch(0.42 0.09 ${hue})`,
      display: "flex", alignItems: "center", justifyContent: "center",
      fontSize: size * 0.4, fontWeight: 700, letterSpacing: "-0.01em",
    }}>{initials}</div>
  );
}

/* —— Tag de cadena —— */
function ChainTag({ chainId, dot }) {
  const ch = MAKI.CHAINS.find(c => c.id === chainId);
  if (!ch) return null;
  return (
    <span style={{ display: "inline-flex", alignItems: "center", gap: 6, fontSize: 12.5, fontWeight: 600, color: cv("--ink-2") }}>
      <span style={{ width: 8, height: 8, borderRadius: 3, background: ch.color }} />
      {ch.name}
    </span>
  );
}

/* —— Chip SLA —— */
function SlaChip({ min }) {
  const overdue = min < 0;
  const urgent = min >= 0 && min <= 10;
  const bg = overdue ? cv("--st-cancelado-bg") : urgent ? cv("--st-preparacion-bg") : cv("--surface-2");
  const fg = overdue ? cv("--st-cancelado") : urgent ? cv("--st-preparacion") : cv("--ink-2");
  const txt = overdue ? `+${Math.abs(min)}m tarde` : `${min}m`;
  return (
    <span style={{
      display: "inline-flex", alignItems: "center", gap: 4, padding: "2px 8px", borderRadius: 99,
      background: bg, color: fg, fontSize: 11.5, fontWeight: 700,
    }}>
      <Icon name="clock" size={11} stroke={2.4} /> {txt}
    </span>
  );
}

/* —— Botón —— */
function Btn({ children, variant = "ghost", size = "md", icon, onClick, style, title }) {
  const [h, setH] = useState(false);
  const sizes = {
    sm: { padding: icon && !children ? 7 : "6px 11px", fontSize: 13, gap: 6 },
    md: { padding: icon && !children ? 9 : "9px 15px", fontSize: 13.5, gap: 7 },
  };
  const variants = {
    primary: { background: h ? cv("--primary-600") : cv("--primary"), color: "#fff", border: "1px solid transparent", boxShadow: "var(--sh-1)" },
    solid:   { background: h ? cv("--ink") : "#2A352F", color: "#fff", border: "1px solid transparent" },
    ghost:   { background: h ? cv("--surface-2") : "transparent", color: cv("--ink-2"), border: "1px solid transparent" },
    outline: { background: h ? cv("--surface-2") : cv("--surface"), color: cv("--ink"), border: `1px solid ${cv("--line-2")}` },
  };
  return (
    <button onClick={onClick} title={title}
      onMouseEnter={() => setH(true)} onMouseLeave={() => setH(false)}
      style={{
        display: "inline-flex", alignItems: "center", justifyContent: "center",
        ...sizes[size], ...variants[variant], borderRadius: 10, fontWeight: 650,
        cursor: "pointer", transition: "background .12s, transform .08s", whiteSpace: "nowrap",
        ...style,
      }}>
      {icon && <Icon name={icon} size={size === "sm" ? 15 : 16} stroke={2.1} />}
      {children}
    </button>
  );
}

/* —— Tag de segmento (Masaca · VIP / B2B / B2C) —— */
function SegmentTag({ segment, size = "md" }) {
  const s = MAKI.SEGMENTS[segment];
  if (!s) return null;
  const isVip = segment === "VIP";
  return (
    <span style={{
      display: "inline-flex", alignItems: "center", gap: 5,
      padding: size === "sm" ? "2px 8px" : "3px 10px", borderRadius: 99,
      background: cv(s.bg), color: cv(s.color),
      fontSize: size === "sm" ? 10.5 : 11.5, fontWeight: 800, letterSpacing: "0.02em", whiteSpace: "nowrap",
    }}>
      {isVip && <Icon name="star" size={size === "sm" ? 10 : 11} stroke={2.4} fill={cv(s.color)} />}
      {s.label}
    </span>
  );
}

Object.assign(window, { Icon, Logo, StatusPill, ChannelTag, Avatar, ChainTag, SlaChip, Btn, SegmentTag, makiBeep, cv });
