/* global React, IconRefresh, IconCalendar, IconStar, Chip, SourceBadge, shortWhen */
// Analítica (agendas por fuente vía UTM, costo por agendada/asistencia,
// show-rate, embudo, desempeño por closer) + lista de próximas llamadas.

const { useState: _us, useMemo: _um } = React;

function fmtMoney(n) {
  return "$" + Math.round(n).toLocaleString("en-US");
}

// Presets de periodo para la barra de fecha de la analítica
const ANALYTICS_PERIODS = [
  { id: "7d", label: "7 días", days: 7 },
  { id: "14d", label: "14 días", days: 14 },
  { id: "30d", label: "30 días", days: 30 },
  { id: "90d", label: "90 días", days: 90 },
];
function presetRange(days) {
  const t = new Date(); t.setHours(0, 0, 0, 0);
  return { from: new Date(t.getTime() - days * 86400000), to: t };
}
function _sameDayV(a, b) { return a && b && a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate(); }
function matchAnalyticsPeriod(range) {
  if (!range || !range.from || !range.to) return null;
  for (const p of ANALYTICS_PERIODS) { const r = presetRange(p.days); if (_sameDayV(range.from, r.from) && _sameDayV(range.to, r.to)) return p.id; }
  return null;
}

// ---- Sparkline ---------------------------------------------------
function Sparkline({ data, w = 280, h = 60, accent }) {
  const max = Math.max(...data), min = Math.min(...data), r = max - min || 1;
  const step = w / (data.length - 1);
  const pts = data.map((d, i) => [i * step, h - 6 - ((d - min) / r) * (h - 16)]);
  const path = pts.map((p, i) => (i === 0 ? "M" : "L") + p[0].toFixed(1) + " " + p[1].toFixed(1)).join(" ");
  const area = path + ` L${w} ${h} L0 ${h} Z`;
  return (
    <svg width={w} height={h} viewBox={`0 0 ${w} ${h}`}>
      <path d={area} fill={accent} opacity="0.12"/>
      <path d={path} stroke={accent} strokeWidth="1.8" fill="none"/>
      {pts.map((p, i) => <circle key={i} cx={p[0]} cy={p[1]} r={i === pts.length - 1 ? 3 : 1.5} fill={accent}/>)}
    </svg>);
}

function Donut({ items, size = 150, hole = 0.64 }) {
  const total = items.reduce((s, x) => s + x.v, 0) || 1;
  let a = -Math.PI / 2;
  const r = size / 2, inner = r * hole;
  return (
    <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`}>
      {items.map((it, i) => {
        const frac = it.v / total, a2 = a + frac * Math.PI * 2, large = frac > 0.5 ? 1 : 0;
        const x1 = r + r * Math.cos(a), y1 = r + r * Math.sin(a);
        const x2 = r + r * Math.cos(a2), y2 = r + r * Math.sin(a2);
        const x3 = r + inner * Math.cos(a2), y3 = r + inner * Math.sin(a2);
        const x4 = r + inner * Math.cos(a), y4 = r + inner * Math.sin(a);
        const d = `M${x1} ${y1} A${r} ${r} 0 ${large} 1 ${x2} ${y2} L${x3} ${y3} A${inner} ${inner} 0 ${large} 0 ${x4} ${y4} Z`;
        a = a2;
        return <path key={i} d={d} fill={it.color}/>;
      })}
    </svg>);
}

function AnalyticsView({ calls, allCalls, accent, isAdmin, closers, adSpend, onEditSpend, canEditSpend, filters, setFilters }) {
  const { SOURCES, PAID_SOURCES, BOOKINGS_14D } = window.REVOLVR_DATA;
  const TOTAL_SPEND = adSpend.directa + adSpend.reconocimiento;

  // Filtro por fecha (sobre la fecha de agendado / createdAt)
  const range = filters && filters.dateRange;
  const inRange = (c) => {
    if (!range || (!range.from && !range.to)) return true;
    const d = c.createdAt;
    if (range.from && d < range.from) return false;
    if (range.to) { const end = new Date(range.to); end.setHours(23, 59, 59, 999); if (d > end) return false; }
    return true;
  };
  const fc = calls.filter(inRange);
  const fAll = (allCalls || calls).filter(inRange);

  // --- Métricas del alcance visible (las del closer, o las que mira el admin)
  const m = _um(() => {
    const total = fc.length;
    const shows = fc.filter((c) => c.status === "asistio").length;
    const noshows = fc.filter((c) => c.status === "noshow").length;
    const won = fc.filter((c) => c.stage === "ganada").length;
    const proposalPlus = fc.filter((c) => ["propuesta", "ganada", "perdida"].includes(c.stage)).length;

    const bySource = {};
    Object.keys(SOURCES).forEach((k) => bySource[k] = { count: 0, shows: 0 });
    fc.forEach((c) => {
      const k = c.utm.source;
      if (!bySource[k]) bySource[k] = { count: 0, shows: 0 };
      bySource[k].count++;
      if (c.status === "asistio") bySource[k].shows++;
    });
    const sourceRows = Object.entries(bySource)
      .map(([k, v]) => ({ k, ...v, label: SOURCES[k]?.label || k, color: SOURCES[k]?.color || "#94a3b8", paid: PAID_SOURCES.includes(k) }))
      .filter((r) => r.count > 0)
      .sort((a, b) => b.count - a.count);

    return {
      total, shows, noshows, won, proposalPlus, sourceRows,
      showRate: total ? Math.round((shows / total) * 100) : 0,
      noShowRate: total ? Math.round((noshows / total) * 100) : 0,
      closeRate: total ? Math.round((won / total) * 100) : 0,
    };
  }, [fc, TOTAL_SPEND]);

  // --- Métricas de TODA la operación (solo admin: costos + operación global)
  const g = _um(() => {
    const src = fAll;
    const total = src.length;
    const shows = src.filter((c) => c.status === "asistio").length;
    const noshows = src.filter((c) => c.status === "noshow").length;
    const wonCalls = src.filter((c) => c.stage === "ganada");
    const won = wonCalls.length;
    const adsAgendas = src.filter((c) => PAID_SOURCES.includes(c.utm.source)).length;
    const organicAgendas = total - adsAgendas;
    let facturado = 0, cobrado = 0;
    wonCalls.forEach((c) => {
      if (!c.sale) return;
      facturado += Number(c.sale.total || 0);
      cobrado += c.sale.tipo === "total" ? Number(c.sale.total || 0) : Number(c.sale.pagado || 0);
    });
    return {
      total, shows, noshows, won, adsAgendas, organicAgendas,
      facturado, cobrado, pendiente: Math.max(0, facturado - cobrado),
      showRate: total ? Math.round((shows / total) * 100) : 0,
      closeRate: total ? Math.round((won / total) * 100) : 0,
      costLlamadaTotal: total ? TOTAL_SPEND / total : 0,
      costLlamadaVSL: adsAgendas ? adSpend.directa / adsAgendas : 0,
      cplOrganico: organicAgendas ? adSpend.reconocimiento / organicAgendas : 0,
      costPorShow: shows ? TOTAL_SPEND / shows : 0,
      cac: won ? TOTAL_SPEND / won : 0,
      roas: TOTAL_SPEND ? facturado / TOTAL_SPEND : 0,
    };
  }, [fAll, TOTAL_SPEND, adSpend.directa]);

  const maxSource = Math.max(1, ...m.sourceRows.map((r) => r.count));
  const donutItems = m.sourceRows.map((r) => ({ v: r.count, color: r.color }));

  const closerRows = _um(() => {
    if (!isAdmin) return [];
    const src = fAll;
    return closers.map((cl) => {
      const cc = src.filter((c) => c.closerId === cl.id);
      const shows = cc.filter((c) => c.status === "asistio").length;
      const won = cc.filter((c) => c.stage === "ganada").length;
      return { ...cl, bookings: cc.length, shows, won,
        showRate: cc.length ? Math.round(shows / cc.length * 100) : 0,
        closeRate: cc.length ? Math.round(won / cc.length * 100) : 0 };
    }).sort((a, b) => b.bookings - a.bookings);
  }, [fAll, isAdmin, closers]);

  const funnel = [
    { label: "Agendadas", value: m.total },
    { label: "Asistieron", value: m.shows },
    { label: "En propuesta+", value: m.proposalPlus },
    { label: "Cerradas", value: m.won },
  ];
  const fMax = Math.max(1, ...funnel.map((f) => f.value));

  return (
    <div className="analytics">
      {setFilters &&
        <div className="analytics-periodbar" style={{ gridColumn: "span 12" }}>
          <span className="period-lbl">Periodo:</span>
          {ANALYTICS_PERIODS.map((p) => {
            const active = matchAnalyticsPeriod(range) === p.id;
            return <Chip key={p.id} active={active} onClick={() => setFilters({ ...filters, dateRange: active ? null : presetRange(p.days) })}>{p.label}</Chip>;
          })}
          <DateRangeFilter value={range} onChange={(r) => setFilters({ ...filters, dateRange: r })}/>
          <span style={{ marginLeft: "auto", fontSize: 11.5, color: "var(--text-3)" }}>{fc.length} de {calls.length} agendas en el periodo</span>
        </div>}

      {/* Inversión en ads — horizontal, debajo del periodo (SOLO admin) */}
      {isAdmin &&
        <div className="chart-card" style={{ gridColumn: "span 12" }}>
          <SpendEditor adSpend={adSpend} onEditSpend={onEditSpend} canEdit={canEditSpend} total={TOTAL_SPEND}/>
        </div>}

      {/* Facturación y adquisición (SOLO admin) — arriba de las métricas */}
      {isAdmin &&
        <div className="chart-card" style={{ gridColumn: "span 12" }}>
          <h3>Facturación y adquisición <small>· {g.won} clientes cerrados</small></h3>
          <div className="ops-summary fact">
            <div className="ops-stat"><div className="n">{fmtMoney(g.facturado)}</div><div className="l">Total facturado</div></div>
            <div className="ops-stat"><div className="n">{fmtMoney(g.cobrado)}</div><div className="l">Total cobrado</div></div>
            <div className="ops-stat"><div className="n">{fmtMoney(g.pendiente)}</div><div className="l">Saldo pendiente</div></div>
            <div className="ops-stat hi"><div className="n">{fmtMoney(g.cac)}</div><div className="l">CAC (costo por cliente)</div></div>
            <div className="ops-stat hi"><div className="n">{g.roas.toFixed(1)}<small>x</small></div><div className="l">ROAS (facturado / ads)</div></div>
          </div>
        </div>}

      {/* Métricas operativas del alcance visible (closer y admin) */}
      <MetricCard span={3} lbl="Llamadas agendadas" val={m.total} sub={`${m.shows} asistieron`} dir="up"/>
      <MetricCard span={3} lbl="Tasa de asistencia" val={m.showRate} suffix="%" sub={`${m.noShowRate}% no-show`} dir={m.showRate >= 50 ? "up" : "down"}/>
      <MetricCard span={3} lbl="% de cierre" val={m.closeRate} suffix="%" sub={`${m.won} cerradas`} dir="up"/>
      <MetricCard span={3} lbl="Cerradas ganadas" val={m.won} sub={`de ${m.total} agendas`} dir="up"/>

      {/* Costos por llamada (SOLO admin) */}
      {isAdmin &&
        <div className="chart-card" style={{ gridColumn: "span 12" }}>
          <h3>Costos por llamada <small>· toda la operación · según inversión en ads</small></h3>
          <div className="cpl-cards four">
            <div className="cpl-card">
              <div className="l">Costo por llamada TOTAL</div>
              <div className="v">{fmtMoney(g.costLlamadaTotal)}</div>
              <div className="d">(VSL + reconocimiento) / {g.total} agendas</div>
            </div>
            <div className="cpl-card" data-accent="paid">
              <div className="l">Costo por llamada VSL</div>
              <div className="v">{fmtMoney(g.costLlamadaVSL)}</div>
              <div className="d">inversión VSL / {g.adsAgendas} agenda{g.adsAgendas === 1 ? "" : "s"} de Facebook ads</div>
            </div>
            <div className="cpl-card" data-accent="organic">
              <div className="l">Costo por lead orgánico</div>
              <div className="v">{fmtMoney(g.cplOrganico)}</div>
              <div className="d">inversión en reconocimiento / {g.organicAgendas} agenda{g.organicAgendas === 1 ? "" : "s"} orgánica{g.organicAgendas === 1 ? "" : "s"}</div>
            </div>
            <div className="cpl-card">
              <div className="l">Costo por asistencia</div>
              <div className="v">{fmtMoney(g.costPorShow)}</div>
              <div className="d">inversión total / {g.shows} asistencia{g.shows === 1 ? "" : "s"} (shows)</div>
            </div>
          </div>
        </div>}

      {/* Operación global de closers (admin) — debajo de Facturación */}
      {isAdmin &&
        <div className="chart-card" style={{ gridColumn: "span 12" }}>
          <h3>Operación de closers <small>· {g.total} llamadas · {closerRows.length} closers</small></h3>
          <div className="ops-summary">
            <div className="ops-stat"><div className="n">{g.total}</div><div className="l">Agendadas (equipo)</div></div>
            <div className="ops-stat"><div className="n">{g.shows}</div><div className="l">Asistieron (equipo)</div></div>
            <div className="ops-stat"><div className="n">{g.won}</div><div className="l">Cerradas (equipo)</div></div>
            <div className="ops-stat hi"><div className="n">{g.showRate}<small>%</small></div><div className="l">% asistencia global</div></div>
            <div className="ops-stat hi"><div className="n">{g.closeRate}<small>%</small></div><div className="l">% cierre global</div></div>
          </div>
          <div className="closer-perf">
            {closerRows.map((r) => (
              <div key={r.id} className="cp-row">
                <div className="rv-avatar sm" style={{ background: r.color }}>{r.initials}</div>
                <div className="cp-name">{r.name}</div>
                <div className="cp-stats">
                  <div className="cp-stat"><div className="n">{r.bookings}</div><div className="l">agendadas</div></div>
                  <div className="cp-stat"><div className="n">{r.shows}</div><div className="l">asistieron</div></div>
                  <div className="cp-stat"><div className="n">{r.won}</div><div className="l">cerradas</div></div>
                  <div className="cp-stat"><div className="n">{r.showRate}%</div><div className="l">show rate</div></div>
                  <div className="cp-stat hi"><div className="n">{r.closeRate}%</div><div className="l">% cierre</div></div>
                </div>
              </div>
            ))}
          </div>
        </div>}

      {/* Agendas por fuente */}
      <div className="chart-card" style={{ gridColumn: "span 8" }}>
        <h3>Agendas por fuente <small>· según UTM de Calendly</small></h3>
        <div className="src-bars">
          {m.sourceRows.map((r) => (
            <div key={r.k} className="src-row">
              <div className="src-name"><span className="dot" style={{ background: r.color }}/>{r.label}{r.paid && <span className="paid-tag">ads</span>}</div>
              <div className="src-track"><div className="src-fill" style={{ width: (r.count / maxSource * 100) + "%", background: r.color }}/></div>
              <div className="src-val">{r.count} <small>· {r.shows} shows</small></div>
            </div>
          ))}
        </div>
      </div>

      {/* Donut de mezcla */}
      <div className="chart-card" style={{ gridColumn: "span 4" }}>
        <h3>Mezcla de fuentes</h3>
        <div style={{ display: "flex", alignItems: "center", gap: 14 }}>
          <Donut items={donutItems} size={132}/>
          <div style={{ display: "flex", flexDirection: "column", gap: 7, flex: 1 }}>
            {m.sourceRows.map((r) => (
              <div key={r.k} style={{ display: "flex", alignItems: "center", gap: 8, fontSize: 12 }}>
                <span style={{ width: 8, height: 8, borderRadius: 2, background: r.color }}/>
                <span style={{ flex: 1 }}>{r.label}</span>
                <span style={{ color: "var(--text-2)", fontWeight: 600, fontVariantNumeric: "tabular-nums" }}>
                  {Math.round(r.count / (m.total || 1) * 100)}%
                </span>
              </div>
            ))}
          </div>
        </div>
      </div>

      {/* Tendencia */}
      <div className="chart-card" style={{ gridColumn: "span 7" }}>
        <h3>Agendas · últimos 14 días <span style={{ marginLeft: "auto", fontSize: 11, color: "var(--text-3)", display: "inline-flex", alignItems: "center", gap: 5 }}><IconRefresh size={10}/> sincronizado con Calendly</span></h3>
        <Sparkline data={BOOKINGS_14D} w={560} h={120} accent={accent}/>
        <div style={{ display: "flex", justifyContent: "space-between", marginTop: 6, fontSize: 10.5, color: "var(--text-3)", fontVariantNumeric: "tabular-nums" }}>
          <span>hace 14 d</span><span>hace 7 d</span><span>hoy</span>
        </div>
      </div>

      {/* Embudo */}
      <div className="chart-card" style={{ gridColumn: "span 5" }}>
        <h3>Embudo de llamadas</h3>
        <div className="funnel">
          {funnel.map((f, i) => (
            <div className="funnel-row" key={i}>
              <span style={{ fontSize: 12, color: "var(--text-2)" }}>{f.label}</span>
              <div className="funnel-bar"><div className="fill" style={{ width: (f.value / fMax * 100) + "%" }}>{f.value}</div></div>
              <span className="pct">{Math.round(f.value / (funnel[0].value || 1) * 100)}%</span>
            </div>
          ))}
        </div>
      </div>
    </div>);
}

function SpendEditor({ adSpend, onEditSpend, canEdit, total }) {
  const { useState: _sue } = React;
  const [local, setLocal] = _sue({ directa: adSpend.directa, reconocimiento: adSpend.reconocimiento });

  // Sincronizar si el padre cambia por fuera
  React.useEffect(() => { setLocal({ directa: adSpend.directa, reconocimiento: adSpend.reconocimiento }); }, [adSpend.directa, adSpend.reconocimiento]);

  const handleChange = (k, val) => setLocal((l) => ({ ...l, [k]: val }));
  const handleBlur = (k) => {
    const num = Math.max(0, Number(local[k]) || 0);
    setLocal((l) => ({ ...l, [k]: num }));
    onEditSpend({ ...adSpend, [k]: num });
  };

  return (
    <div className="spend-editor-h">
      <div className="seh-head">Inversión en ads {canEdit ? <span className="se-edit">editable</span> : <span className="se-edit ro">solo lectura</span>}</div>
      <div className="seh-fields">
        {["directa", "reconocimiento"].map((k) => (
          <div key={k} className="se-field">
            <div className="se-label">
              {k === "directa" ? "Agenda directa" : "Reconocimiento"}
              <span className="se-hint">{k === "directa" ? "anuncio → VSL" : "promo orgánico"}</span>
            </div>
            <div className="se-input">
              <span className="se-cur">$</span>
              <input type="number" min="0" step="50" value={local[k]} disabled={!canEdit}
                onChange={(e) => handleChange(k, e.target.value)}
                onBlur={() => handleBlur(k)}/>
            </div>
          </div>
        ))}
        <div className="seh-total"><span>Total invertido</span><strong>{fmtMoney(total)}</strong></div>
      </div>
    </div>);
}

function MetricCard({ span, lbl, val, suffix, sub, dir }) {
  return (
    <div className="metric-card" style={{ gridColumn: "span " + span }}>
      <div className="lbl">{lbl}</div>
      <div className="val">{val}{suffix && <small style={{ fontSize: 18 }}>{suffix}</small>}</div>
      {sub && <div className="delta" data-dir={dir || "flat"}>{dir === "up" ? "↑ " : dir === "down" ? "↓ " : ""}{sub}</div>}
    </div>);
}

// ============ Próximas llamadas =================================
function CallsView({ calls, closers, onOpen }) {
  const { CALL_STATUS } = window.REVOLVR_DATA;
  const now = new Date();
  const upcoming = calls
    .filter((c) => c.scheduledAt instanceof Date && c.scheduledAt >= new Date(now.getFullYear(), now.getMonth(), now.getDate()))
    .filter((c) => c.status !== "cancelada")
    .sort((a, b) => a.scheduledAt - b.scheduledAt);

  const groups = [];
  upcoming.forEach((c) => {
    const key = c.scheduledAt.toDateString();
    let g = groups.find((x) => x.key === key);
    if (!g) { g = { key, when: c.scheduledAt, items: [] }; groups.push(g); }
    g.items.push(c);
  });

  const today = new Date();
  const tomorrow = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 1);
  const sameDay = (a, b) => a.toDateString() === b.toDateString();
  const dayLabel = (d) => sameDay(d, today) ? "Hoy" : sameDay(d, tomorrow) ? "Mañana" : d.toLocaleDateString("es-ES", { weekday: "long", day: "numeric", month: "long" });
  const timeLabel = (d) => d.toLocaleTimeString("es-ES", { hour: "2-digit", minute: "2-digit", hour12: false });

  return (
    <div className="calls-wrap">
      <div className="calls-head">
        <div>
          <h2 className="calls-title">Próximas llamadas</h2>
          <div className="calls-sub">{upcoming.length} agendadas desde hoy</div>
        </div>
      </div>

      {upcoming.length === 0 ?
        <div className="calls-empty">
          <IconCalendar size={28}/>
          <div className="t">Sin llamadas próximas</div>
          <div className="d">Las nuevas citas de Calendly aparecerán aquí automáticamente.</div>
        </div> :
        <div className="calls-groups">
          {groups.map((g) =>
            <div key={g.key} className="calls-group">
              <div className="calls-day">
                <span className="day-label">{dayLabel(g.when)}</span>
                <span className="day-count">{g.items.length} llamada{g.items.length === 1 ? "" : "s"}</span>
              </div>
              {g.items.map((c) => {
                const closer = closers.find((x) => x.id === c.closerId);
                const st = CALL_STATUS[c.status] || {};
                const initials = c.name.split(" ").map((s) => s[0]).slice(0, 2).join("");
                return (
                  <div key={c.id} className="call-card" onClick={() => onOpen(c.id)}>
                    <div className="call-time">
                      <div className="t-hh">{timeLabel(c.scheduledAt)}</div>
                      <div className="t-dur">{c.duration} min</div>
                    </div>
                    <div className="rv-avatar" style={{ background: closer ? closer.color : "var(--accent)", width: 36, height: 36, fontSize: 13 }}>{initials}</div>
                    <div className="call-meta">
                      <div className="call-name">{c.name}<span className="call-status" style={{ "--st": st.color }}><span className="d"/>{st.label}</span></div>
                      <div className="call-biz">{c.eventType} · {c.form.industria}</div>
                      <div className="call-msg">"{c.form.objetivo}"</div>
                    </div>
                    <div className="call-side">
                      {closer && <span className="call-acct">{closer.name}</span>}
                      <div className="call-actions" onClick={(e) => e.stopPropagation()}>
                        <button className="crm-btn" data-variant="ghost" onClick={() => onOpen(c.id)}>Ver ficha</button>
                        <button className="crm-btn" data-variant="primary">Unirse</button>
                      </div>
                    </div>
                  </div>);
              })}
            </div>)}
        </div>}
    </div>);
}

// ============ Integraciones (solo admin) =======================
function IntegracionesView({ closers, pushToast }) {
  const [apiKeyVisible, setApiKeyVisible] = _us(false);
  const [closerActivo, setCloserActivo] = _us(
    () => Object.fromEntries(closers.map((c) => [c.id, true]))
  );

  const WEBHOOK_URL = "https://gcbbosnfrpygymbnwayt.supabase.co/functions/v1/webhook-inbound";
  const API_KEY = "rvlr_25447f6c3a37733f19c12c163130f4c3cdd251eea7624089";

  const copyToClipboard = (text, label) => {
    if (navigator.clipboard && navigator.clipboard.writeText) {
      navigator.clipboard.writeText(text).catch(() => {});
    }
    if (pushToast) pushToast(label + " copiado al portapapeles");
    else alert(label + " copiado");
  };

  const closersActivos = closers.filter((c) => closerActivo[c.id]);

  const FIELDS = [
    { key: "name",          label: "Nombre completo",               group: "Lead",       req: true  },
    { key: "email",         label: "Email",                         group: "Lead",       req: true  },
    { key: "phone",         label: "Teléfono",                      group: "Lead",       req: false },
    { key: "location",      label: "Ciudad / País",                 group: "Lead",       req: false },
    { key: "timezone",      label: "Zona horaria",                  group: "Lead",       req: false },
    { key: "event_type",    label: "Tipo de evento",                group: "Llamada",    req: false },
    { key: "duration",      label: "Duración (minutos)",            group: "Llamada",    req: false },
    { key: "scheduled_at",  label: "Fecha y hora",                  group: "Llamada",    req: true  },
    { key: "meeting_link",  label: "Link de reunión",               group: "Llamada",    req: false },
    { key: "value",         label: "Valor estimado (USD)",          group: "Negocio",    req: false },
    { key: "utm_source",    label: "UTM Source",                    group: "Marketing",  req: false },
    { key: "utm_medium",    label: "UTM Medium",                    group: "Marketing",  req: false },
    { key: "utm_campaign",  label: "UTM Campaign",                  group: "Marketing",  req: false },
    { key: "form.NOMBRE",   label: "Campo dinámico del formulario", group: "Formulario", req: false },
  ];

  return (
    <div className="integraciones-wrap">

      {/* ── BLOQUE 1: Webhook ── */}
      <div className="integ-card">
        <div className="integ-card-header">
          <div className="integ-card-title">Webhook de entrada</div>
          <div className="integ-card-desc">
            Usa esta URL y API Key en n8n para enviar leads al CRM automáticamente
          </div>
        </div>

        <div className="integ-field-group">
          <div className="integ-field">
            <label>URL del Webhook</label>
            <div className="integ-input-row">
              <input readOnly value={WEBHOOK_URL} className="integ-input"/>
              <button className="crm-btn" data-variant="ghost"
                onClick={() => copyToClipboard(WEBHOOK_URL, "URL")}>
                Copiar
              </button>
            </div>
          </div>

          <div className="integ-field">
            <label>API Key</label>
            <div className="integ-input-row">
              <input readOnly
                value={apiKeyVisible ? API_KEY : "••••••••••••••••••••••••••••••••••••••••"}
                className="integ-input mono"/>
              <button className="crm-btn" data-variant="ghost"
                onClick={() => setApiKeyVisible((v) => !v)}>
                {apiKeyVisible ? "Ocultar" : "Revelar"}
              </button>
              <button className="crm-btn" data-variant="ghost"
                onClick={() => copyToClipboard(API_KEY, "API Key")}>
                Copiar
              </button>
            </div>
          </div>
        </div>
      </div>

      {/* ── BLOQUE 2: Variables disponibles ── */}
      <div className="integ-card">
        <div className="integ-card-header">
          <div className="integ-card-title">Campos disponibles para n8n</div>
          <div className="integ-card-desc">
            Usa estas claves exactas en el nodo Set de n8n para mapear
            los datos de Calendly al CRM
          </div>
        </div>

        <table className="integ-table">
          <thead>
            <tr>
              <th>Clave</th>
              <th>Etiqueta</th>
              <th>Grupo</th>
              <th>Requerido</th>
            </tr>
          </thead>
          <tbody>
            {FIELDS.map((f) => (
              <tr key={f.key}>
                <td><code className="integ-code">{f.key}</code></td>
                <td>{f.label}</td>
                <td><span className="integ-group-badge">{f.group}</span></td>
                <td>
                  {f.req
                    ? <span className="integ-badge req">Sí</span>
                    : <span className="integ-badge opt">No</span>}
                </td>
              </tr>
            ))}
          </tbody>
        </table>

        <div className="integ-footnote">
          💡 Los campos <code>form.*</code> son dinámicos. Ejemplo:{" "}
          <code>form.facturacion</code>, <code>form.equipo</code>,{" "}
          <code>form.industria</code>. Tú defines el nombre en n8n
          y el CRM los muestra tal como llegan. El closer se asigna
          automáticamente — no necesitas enviarlo desde n8n.
        </div>
      </div>

      {/* ── BLOQUE 3: Asignación round-robin ── */}
      <div className="integ-card">
        <div className="integ-card-header">
          <div className="integ-card-title">Asignación automática de llamadas</div>
          <div className="integ-card-desc">
            Las llamadas entran en rotación entre los closers activos.
            Desactiva un closer para excluirlo de la rotación.
          </div>
        </div>

        <div className="integ-closer-list">
          {closers.map((c) => {
            const activo = closerActivo[c.id];
            const orden = closersActivos.findIndex((x) => x.id === c.id);
            return (
              <div key={c.id} className="integ-closer-row" data-inactive={!activo}>
                <div className="rv-avatar sm" style={{ background: c.color }}>
                  {c.initials}
                </div>
                <div className="integ-closer-name">{c.name}</div>
                {activo && orden >= 0 &&
                  <span className="integ-orden-badge">{orden + 1}°</span>}
                <label className="integ-toggle">
                  <input type="checkbox" checked={activo}
                    onChange={() => setCloserActivo((s) => ({ ...s, [c.id]: !s[c.id] }))}/>
                  <span className="integ-toggle-track"/>
                </label>
              </div>
            );
          })}
        </div>

        <div className="integ-info-box">
          Rotación activa: {closersActivos.map((c) => c.name.split(" ")[0]).join(" → ") || "Ningún closer activo"}
          {closersActivos.length > 0 && " → (vuelve al primero)"}
        </div>
      </div>

      {/* ── BLOQUE 4: Logs ── */}
      <div className="integ-card">
        <div className="integ-card-header" style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start" }}>
          <div>
            <div className="integ-card-title">Actividad reciente</div>
            <div className="integ-card-desc">Últimos leads recibidos desde n8n</div>
          </div>
          <button className="crm-btn" data-variant="ghost">Actualizar</button>
        </div>

        <div className="integ-empty">
          <IconCalendar size={24}/>
          <div className="t">Sin actividad todavía</div>
          <div className="d">
            Los eventos aparecerán aquí cuando n8n envíe el primer lead
          </div>
        </div>
      </div>

    </div>
  );
}

Object.assign(window, { AnalyticsView, CallsView, IntegracionesView });
