/* ============================================================================
   INBOX / SOCIAL AGENT — first version (local mock).
   Mounts into #inbox-react-root. All data flows through window.MissionState
   (no fetch, no WebSocket, no external calls). Suggested replies are
   handcrafted in the seed; copying uses the local clipboard API only.

   Wrapped in an IIFE: Babel standalone evaluates each <script type="text/babel">
   in the SAME top-level scope, so a bare `const { useState } = React` here
   would collide with the identical line in app.jsx and abort this whole file.
============================================================================ */
(function () {
const { useState, useEffect, useMemo } = React;

// -----------------------------------------------------------------------------
// Display labels (Spanish) for canonical enums kept in MissionState.
// -----------------------------------------------------------------------------
const INBOX_CATEGORY_LABELS = {
  urgent:      "Urgente",
  collab:      "Colaboración",
  opportunity: "Oportunidad",
  community:   "Comunidad",
  spam:        "Spam",
  later:       "Responder luego",
};
const INBOX_CATEGORY_ORDER = ["urgent", "collab", "opportunity", "community", "later", "spam"];
const INBOX_CATEGORY_TINTS = {
  urgent:      "#FF8A7A",
  collab:      "#7EE8FF",
  opportunity: "#FFD170",
  community:   "#4FE08A",
  spam:        "rgba(255,255,255,0.35)",
  later:       "#B78BFF",
};
const INBOX_PRIORITY_LABELS = { high: "Alta", medium: "Media", low: "Baja" };
const INBOX_PRIORITY_TINTS  = { high: "#FF8A7A", medium: "#FFD170", low: "rgba(255,255,255,0.45)" };
const INBOX_STATUS_LABELS   = {
  new:      "Nuevo",
  reviewed: "Revisado",
  pending:  "Pendiente",
  resolved: "Resuelto",
  ignored:  "Ignorado",
};
const PLATFORM_LABELS = {
  instagram: "Instagram",
  tiktok:    "TikTok",
  email:     "Email",
  web:       "Web",
  other:     "Otro",
};

// Re-render this view whenever MissionState mutates. Mirrors the same hook
// the Team Overview uses so any addInboxMessage / setInboxStatus / etc.
// triggers an immediate update.
function useInboxTick() {
  const [, force] = useState(0);
  useEffect(() => {
    const ms = window.MissionState;
    if (!ms || typeof ms.subscribe !== "function") return;
    const unsub = ms.subscribe(() => force(n => (n + 1) | 0));
    return unsub;
  }, []);
}

// Relative time, short form (e.g. "8m", "2h", "ayer", "3d"). Local-only.
function relativeTime(iso) {
  if (!iso) return "—";
  const t = Date.parse(iso);
  if (isNaN(t)) return "—";
  const diffSec = Math.max(0, Math.floor((Date.now() - t) / 1000));
  if (diffSec < 60)        return "ahora";
  if (diffSec < 3600)      return Math.floor(diffSec / 60)   + "m";
  if (diffSec < 86400)     return Math.floor(diffSec / 3600) + "h";
  if (diffSec < 86400 * 2) return "ayer";
  return Math.floor(diffSec / 86400) + "d";
}

// -----------------------------------------------------------------------------
// HEADER — anchors this view to JARVIS so it never reads as a generic inbox.
// -----------------------------------------------------------------------------
function InboxHeader() {
  return (
    <div className="ix-header">
      <div>
        <div className="ix-eyebrow">JARVIS · KAREN / SEÑALES SOCIALES</div>
        <div className="ix-title">Bandeja Operativa</div>
        <div className="ix-sub">KAREN clasifica señales simuladas de comunidad, colaboración y respuesta. Sin conexión real.</div>
      </div>
      <div className="ix-mode-tag">MODO LOCAL · MOCK</div>
    </div>
  );
}

// -----------------------------------------------------------------------------
// JARVIS SUMMARY STRIP — derived counters + one-line recommendation.
// -----------------------------------------------------------------------------
function SummaryStrip() {
  const ms = window.MissionState;
  const summary = (ms && ms.getInboxSummary) ? ms.getInboxSummary() : null;
  if (!summary) return null;

  // 4 ejecutivos. Comunidad y Spam siguen accesibles via filtros — no necesitan
  // chip aquí. "Sin revisar" sustituye al ruido bajando: es la métrica de
  // inbox-zero más útil para el operador.
  const chips = [
    { key: "urgent",      label: "Urgentes",       value: summary.urgent },
    { key: "collab",      label: "Colaboraciones", value: summary.collab },
    { key: "opportunity", label: "Oportunidades",  value: summary.opportunity },
    { key: "new",         label: "Sin revisar",    value: summary.totalNew },
  ];

  return (
    <div className="ix-summary">
      <div className="ix-summary-row">
        {chips.map(c => (
          <div key={c.key} className={"ix-sum-chip ix-sum-" + c.key}>
            <span className="ix-sum-label">{c.label}</span>
            <span className="ix-sum-value">{c.value}</span>
          </div>
        ))}
      </div>
      <div className="ix-summary-rec">
        <span className="ix-rec-icon">⌘</span>
        <span className="ix-rec-text">{summary.recommendation}</span>
      </div>
      <div className="ix-summary-note">
        Datos simulados para validar el flujo. Conexión real pendiente.
      </div>
    </div>
  );
}

// -----------------------------------------------------------------------------
// FILTERS — pills by category with counts. "Todos" clears the filter.
// -----------------------------------------------------------------------------
// Two-tier filters: primary group reads first, secondary group attenuated
// to the right after a thin divider. Same functionality, calmer hierarchy.
const FILTER_PRIMARY   = ["urgent", "collab", "opportunity"];
const FILTER_SECONDARY = ["community", "later", "spam"];

function CategoryFilters({ inbox, value, onChange }) {
  const counts = useMemo(() => {
    const m = { __all: inbox.length };
    INBOX_CATEGORY_ORDER.forEach(k => { m[k] = 0; });
    inbox.forEach(x => { if (m[x.category] !== undefined) m[x.category] += 1; });
    return m;
  }, [inbox]);

  const renderPill = (k, tier) => (
    <button
      key={k}
      type="button"
      className={"ix-filter ix-filter-" + k + " ix-filter-" + tier + (value === k ? " active" : "")}
      onClick={() => onChange(k)}
      style={{ "--ix-cat-tint": INBOX_CATEGORY_TINTS[k] }}
    >
      {INBOX_CATEGORY_LABELS[k]} <span className="ix-filter-count">{counts[k] || 0}</span>
    </button>
  );

  return (
    <div className="ix-filters">
      <button
        type="button"
        className={"ix-filter ix-filter-all" + (value === null ? " active" : "")}
        onClick={() => onChange(null)}
      >Todos <span className="ix-filter-count">{counts.__all}</span></button>

      {FILTER_PRIMARY.map(k => renderPill(k, "primary"))}

      <span className="ix-filter-divider" aria-hidden="true" />

      {FILTER_SECONDARY.map(k => renderPill(k, "secondary"))}
    </div>
  );
}

// -----------------------------------------------------------------------------
// MESSAGE LIST — left column. Selecting a row swaps the right detail.
// -----------------------------------------------------------------------------
function MessageList({ messages, selectedId, onSelect }) {
  if (!messages.length) {
    return (
      <div className="ix-list-empty">
        Sin mensajes en esta categoría.
      </div>
    );
  }
  // Compact row: ONE category chip + priority as a left border (via class) +
  // status as subtle dots / dim. Plataforma queda solo en el detalle.
  return (
    <ul className="ix-list">
      {messages.map(m => {
        const isMuted = m.category === "community" || m.category === "spam";
        const cls = "ix-row"
          + (selectedId === m.id ? " selected" : "")
          + (m.status === "new" ? " new" : "")
          + ((m.status === "ignored" || m.status === "resolved") ? " dim" : "")
          + " ix-row-prio-" + m.priority
          + " ix-row-cat-" + m.category
          + (isMuted ? " muted-cat" : "");
        return (
          <li key={m.id} className={cls} onClick={() => onSelect(m.id)}>
            <div className="ix-row-top">
              <div className="ix-row-sender">
                {(m.status === "pending" || m.status === "reviewed") && (
                  <span className={"ix-row-state-dot ix-row-state-" + m.status}
                        title={INBOX_STATUS_LABELS[m.status]} aria-hidden="true" />
                )}
                <span className="ix-row-name">{m.senderName}</span>
                {m.senderHandle && <span className="ix-row-handle">{m.senderHandle}</span>}
              </div>
              <span className="ix-row-time">{relativeTime(m.createdAt)}</span>
            </div>
            <div className="ix-row-preview">{m.preview}</div>
            <div className="ix-row-tags">
              <span className={"ix-tag ix-tag-cat ix-tag-cat-" + m.category}
                    style={{ "--ix-cat-tint": INBOX_CATEGORY_TINTS[m.category] }}>
                {INBOX_CATEGORY_LABELS[m.category]}
              </span>
            </div>
          </li>
        );
      })}
    </ul>
  );
}

// -----------------------------------------------------------------------------
// DETAIL — right column. Body, suggested reply, quick actions, manual selects.
// -----------------------------------------------------------------------------
function MessageDetail({ message }) {
  const [copied, setCopied] = useState(false);
  const [manualOpen, setManualOpen] = useState(false);
  if (!message) {
    return (
      <div className="ix-detail-empty">
        <div className="ix-detail-empty-title">Selecciona un mensaje</div>
        <div className="ix-detail-empty-sub">Elige una entrada en la bandeja para ver el detalle, la sugerencia de respuesta y las acciones rápidas.</div>
      </div>
    );
  }
  const ms = window.MissionState;

  // Quick actions — each is a single canonical mutation through MissionState.
  const markUrgent = () => {
    ms.setInboxCategory(message.id, "urgent");
    ms.setInboxPriority(message.id, "high");
  };
  const moveCollab     = () => ms.setInboxCategory(message.id, "collab");
  const respondLater   = () => { ms.setInboxCategory(message.id, "later"); ms.setInboxStatus(message.id, "pending"); };
  const ignore         = () => ms.setInboxStatus(message.id, "ignored");
  const markResolved   = () => ms.setInboxStatus(message.id, "resolved");
  const copySuggestion = async () => {
    if (!message.suggestedReply) return;
    try {
      // Local browser API — no network, no external call.
      await navigator.clipboard.writeText(message.suggestedReply);
      setCopied(true);
      setTimeout(() => setCopied(false), 1800);
    } catch (e) {
      console.warn("[Inbox] clipboard copy failed:", e && e.message);
    }
  };

  return (
    <div className="ix-detail">
      {/* Sender block */}
      <div className="ix-detail-head">
        <div>
          <div className="ix-detail-sender">{message.senderName}</div>
          <div className="ix-detail-meta">
            {message.senderHandle ? message.senderHandle + " · " : ""}
            {PLATFORM_LABELS[message.platform] || message.platform}
            {" · "}
            {relativeTime(message.createdAt)}
          </div>
        </div>
        <div className="ix-detail-tags">
          <span className={"ix-tag ix-tag-cat ix-tag-cat-" + message.category}
                style={{ "--ix-cat-tint": INBOX_CATEGORY_TINTS[message.category] }}>
            {INBOX_CATEGORY_LABELS[message.category]}
          </span>
          <span className={"ix-tag ix-tag-prio ix-tag-prio-" + message.priority}
                style={{ "--ix-prio-tint": INBOX_PRIORITY_TINTS[message.priority] }}>
            {INBOX_PRIORITY_LABELS[message.priority]}
          </span>
          <span className={"ix-tag ix-tag-status ix-tag-status-" + message.status}>
            {INBOX_STATUS_LABELS[message.status]}
          </span>
        </div>
      </div>

      {/* Body */}
      <div className="ix-section">
        <div className="ix-section-label">MENSAJE</div>
        <div className="ix-body">{message.body}</div>
      </div>

      {/* Suggested reply */}
      <div className="ix-section">
        <div className="ix-section-label">
          ⌘ SUGERENCIA DE RESPUESTA
          {message.suggestedReply && (
            <button type="button" className="ix-copy-btn" onClick={copySuggestion}>
              {copied ? "✓ Copiado" : "Copiar"}
            </button>
          )}
        </div>
        {message.suggestedReply
          ? <div className="ix-reply">{message.suggestedReply}</div>
          : <div className="ix-reply ix-reply-empty">Sin sugerencia para este mensaje.</div>}
      </div>

      {/* Quick actions */}
      <div className="ix-section">
        <div className="ix-section-label">ACCIONES RÁPIDAS</div>
        <div className="ix-actions">
          <button type="button" className="ix-action ix-act-urgent"   onClick={markUrgent}>⚠ Marcar urgente</button>
          <button type="button" className="ix-action ix-act-collab"   onClick={moveCollab}>🤝 Mover a colaboración</button>
          <button type="button" className="ix-action ix-act-later"    onClick={respondLater}>◷ Responder luego</button>
          <button type="button" className="ix-action ix-act-resolved" onClick={markResolved}>✓ Marcar resuelto</button>
          <button type="button" className="ix-action ix-act-ignore"   onClick={ignore}>× Ignorar</button>
        </div>
      </div>

      {/* Manual selectors — collapsible secondary, closed by default so it
          doesn't compete visually with primary actions. */}
      <div className={"ix-manual" + (manualOpen ? " open" : "")}>
        <button
          type="button"
          className="ix-manual-toggle"
          onClick={() => setManualOpen(o => !o)}
          aria-expanded={manualOpen}
        >
          <span className="ix-manual-caret">{manualOpen ? "▾" : "▸"}</span>
          <span>Ajustar manualmente</span>
          <span className="ix-manual-hint">categoría · prioridad · estado</span>
        </button>
        {manualOpen && (
          <div className="ix-manual-grid">
            <label className="ix-manual-row">
              <span>Categoría</span>
              <select value={message.category} onChange={(e) => ms.setInboxCategory(message.id, e.target.value)}>
                {INBOX_CATEGORY_ORDER.map(k => (
                  <option key={k} value={k}>{INBOX_CATEGORY_LABELS[k]}</option>
                ))}
              </select>
            </label>
            <label className="ix-manual-row">
              <span>Prioridad</span>
              <select value={message.priority} onChange={(e) => ms.setInboxPriority(message.id, e.target.value)}>
                {["high", "medium", "low"].map(k => (
                  <option key={k} value={k}>{INBOX_PRIORITY_LABELS[k]}</option>
                ))}
              </select>
            </label>
            <label className="ix-manual-row">
              <span>Estado</span>
              <select value={message.status} onChange={(e) => ms.setInboxStatus(message.id, e.target.value)}>
                {["new", "reviewed", "pending", "resolved", "ignored"].map(k => (
                  <option key={k} value={k}>{INBOX_STATUS_LABELS[k]}</option>
                ))}
              </select>
            </label>
          </div>
        )}
      </div>
    </div>
  );
}

// -----------------------------------------------------------------------------
// EXECUTIVE SUMMARY — 4 chips ejecutivos para el Nivel 1.
// "Pendientes" = mensajes que el operador todavía no decidió y SÍ merecen
// decisión (categorías que importan: urgent/collab/opportunity y status no
// terminal). Cero cambios en MissionState — derivado puro.
// -----------------------------------------------------------------------------
function ExecutiveSummary({ inbox, summary }) {
  const decisionable = inbox.filter(m =>
    (m.status === "new" || m.status === "pending") &&
    (m.category === "urgent" || m.category === "collab" || m.category === "opportunity")
  ).length;

  const chips = [
    { key: "urgent",      label: "Urgentes",       value: summary.urgent },
    { key: "collab",      label: "Colaboraciones", value: summary.collab },
    { key: "pending",     label: "Pendientes",     value: decisionable },
    { key: "new",         label: "Sin revisar",    value: summary.totalNew },
  ];

  return (
    <div className="ix-exec-summary">
      <div className="ix-exec-summary-row">
        {chips.map(c => (
          <div key={c.key} className={"ix-exec-chip ix-exec-chip-" + c.key}>
            <span className="ix-exec-chip-value">{c.value}</span>
            <span className="ix-exec-chip-label">{c.label}</span>
          </div>
        ))}
      </div>
      <div className="ix-summary-rec">
        <span className="ix-rec-icon">⌘</span>
        <span className="ix-rec-text">{summary.recommendation}</span>
      </div>
      <div className="ix-summary-note">
        Datos simulados para validar el flujo. Conexión real pendiente.
      </div>
    </div>
  );
}

// -----------------------------------------------------------------------------
// EXECUTIVE LIST — top 5 mensajes clave, ordenados por relevancia operativa.
// Sin filtros, sin ajuste manual, sin chips redundantes. Una fila = una
// decisión rápida.
// -----------------------------------------------------------------------------
function rankInboxRow(m) {
  // status terminal o spam queda fuera (filtrado antes de llamar)
  let score = 10;
  const isCollabOrOpp = m.category === "collab" || m.category === "opportunity";
  if (m.category === "urgent")                    score = 100;
  else if (m.priority === "high" && isCollabOrOpp) score = 80;
  else if (m.priority === "high" && m.category !== "spam" && m.category !== "community") score = 60;
  else if (isCollabOrOpp)                          score = 40;
  return score;
}

function ExecutiveList({ inbox, onView, onResolve, onPostpone }) {
  const items = useMemo(() => {
    return inbox
      .filter(m => m.status !== "resolved" && m.status !== "ignored" && m.category !== "spam")
      .map(m => ({ m: m, score: rankInboxRow(m) }))
      .sort((a, b) => {
        if (b.score !== a.score) return b.score - a.score;
        return String(b.m.createdAt || "").localeCompare(String(a.m.createdAt || ""));
      })
      .slice(0, 5)
      .map(x => x.m);
  }, [inbox]);

  if (!items.length) {
    return (
      <div className="ix-exec-list-card">
        <div className="ix-exec-list-head">
          <span className="ix-exec-list-title">MENSAJES CLAVE</span>
        </div>
        <div className="ix-exec-list-empty">
          Bandeja al día. JARVIS no detecta mensajes que requieran tu atención.
        </div>
      </div>
    );
  }

  return (
    <div className="ix-exec-list-card">
      <div className="ix-exec-list-head">
        <span className="ix-exec-list-title">MENSAJES CLAVE</span>
        <span className="ix-exec-list-meta">{items.length} de mayor relevancia</span>
      </div>
      <ul className="ix-exec-list">
        {items.map(m => (
          <li key={m.id} className={"ix-exec-row ix-row-prio-" + m.priority}>
            <div className="ix-exec-row-top">
              <span className="ix-exec-row-name">{m.senderName}</span>
              <span className={"ix-tag ix-tag-cat ix-tag-cat-" + m.category}
                    style={{ "--ix-cat-tint": INBOX_CATEGORY_TINTS[m.category] }}>
                {INBOX_CATEGORY_LABELS[m.category]}
              </span>
              <span className="ix-exec-row-time">{relativeTime(m.createdAt)}</span>
            </div>
            <div className="ix-exec-row-preview">{m.preview}</div>
            <div className="ix-exec-row-actions">
              <button type="button" className="ix-exec-action ix-exec-act-view"     onClick={() => onView(m.id)}>Ver</button>
              <button type="button" className="ix-exec-action ix-exec-act-resolve"  onClick={() => onResolve(m.id)}>Atendido</button>
              <button type="button" className="ix-exec-action ix-exec-act-postpone" onClick={() => onPostpone(m.id)}>Posponer</button>
            </div>
          </li>
        ))}
      </ul>
    </div>
  );
}

// -----------------------------------------------------------------------------
// FULL INBOX DRAWER — Nivel 2. Reutiliza los componentes completos existentes
// (Summary, Filters, List, Detail). Solo los envuelve en un overlay con botón
// de retorno al brief ejecutivo.
// -----------------------------------------------------------------------------
function FullInboxDrawer({ inbox, initialSelectedId, onClose }) {
  const sorted = useMemo(() => (
    inbox.slice().sort((a, b) =>
      String(b.createdAt || "").localeCompare(String(a.createdAt || ""))
    )
  ), [inbox]);

  const [filter, setFilter] = useState(null);
  const [selectedId, setSelectedId] = useState(initialSelectedId || null);

  useEffect(() => {
    if (selectedId == null && sorted.length > 0) setSelectedId(sorted[0].id);
  }, [sorted, selectedId]);

  useEffect(() => {
    const onKey = (e) => { if (e.key === "Escape") onClose(); };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [onClose]);

  const visible  = filter == null ? sorted : sorted.filter(m => m.category === filter);
  const selected = inbox.find(m => m.id === selectedId) || null;

  useEffect(() => {
    if (selectedId != null && !visible.find(m => m.id === selectedId) && visible.length > 0) {
      setSelectedId(visible[0].id);
    }
  }, [filter, visible, selectedId]);

  return (
    <div className="ix-fullscreen-overlay">
      <div className="ix-fullscreen-toolbar">
        <button type="button" className="ix-back-btn" onClick={onClose} aria-label="Volver al brief ejecutivo">
          ← Volver al brief
        </button>
        <span className="ix-fullscreen-title">BANDEJA COMPLETA</span>
      </div>
      <SummaryStrip />
      <CategoryFilters inbox={inbox} value={filter} onChange={setFilter} />
      <div className="ix-body-2col">
        <div className="ix-col-list">
          <MessageList messages={visible} selectedId={selectedId} onSelect={setSelectedId} />
        </div>
        <div className="ix-col-detail">
          <MessageDetail message={selected} />
        </div>
      </div>
    </div>
  );
}

// -----------------------------------------------------------------------------
// ROOT — Nivel 1 por defecto (vista ejecutiva). Drawer Nivel 2 a demanda.
// -----------------------------------------------------------------------------
function InboxApp() {
  useInboxTick();
  const ms = window.MissionState;
  const inbox   = (ms && ms.getInbox)         ? ms.getInbox()         : [];
  const summary = (ms && ms.getInboxSummary)  ? ms.getInboxSummary()  : null;

  // Drawer state — UI only, never persists. Reload always returns to brief.
  const [drawerOpen, setDrawerOpen]     = useState(false);
  const [drawerSelected, setDrawerSelected] = useState(null);

  const openFull = (preselectId) => {
    setDrawerSelected(preselectId || null);
    setDrawerOpen(true);
  };
  const closeFull = () => setDrawerOpen(false);

  // Executive-level actions — combinaciones de helpers ya existentes.
  const onView     = (id) => openFull(id);
  const onResolve  = (id) => ms && ms.setInboxStatus && ms.setInboxStatus(id, "resolved");
  const onPostpone = (id) => {
    if (!ms) return;
    ms.setInboxCategory(id, "later");
    ms.setInboxStatus(id, "pending");
  };

  return (
    <div className="ix-root">
      <div className="ix-bg-grid" aria-hidden="true" />
      <div className="ix-shell">
        <InboxHeader />

        {!drawerOpen && summary && (
          <>
            <ExecutiveSummary inbox={inbox} summary={summary} />
            <div className="ix-exec-list-wrap">
              <div className="ix-exec-list-toolbar">
                <button type="button" className="ix-open-full-btn" onClick={() => openFull(null)}>
                  Abrir bandeja completa ›
                </button>
              </div>
              <ExecutiveList
                inbox={inbox}
                onView={onView}
                onResolve={onResolve}
                onPostpone={onPostpone}
              />
            </div>
          </>
        )}

        {drawerOpen && (
          <FullInboxDrawer
            inbox={inbox}
            initialSelectedId={drawerSelected}
            onClose={closeFull}
          />
        )}
      </div>
    </div>
  );
}

const inboxMountEl = document.getElementById("inbox-react-root");
if (inboxMountEl) {
  const root = ReactDOM.createRoot(inboxMountEl);
  root.render(<InboxApp />);
}
})();
