// ── Informe de Gestión Comercial ── Admin only ──
const { useState, useEffect, useContext } = React;

const fmtUSD = v => "$" + Number(v||0).toLocaleString("en-US",{minimumFractionDigits:0,maximumFractionDigits:0});
const fmtPct = v => Number(v||0).toFixed(1)+"%";
const esc    = s => String(s||"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;");
const fmtHistDate = iso => { try { return new Date(iso).toLocaleDateString("es-PA",{day:"2-digit",month:"short",year:"numeric",hour:"2-digit",minute:"2-digit"}); } catch { return iso; } };

const LOGO = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAfwAAAHwCAYAAABDkN1oAAAACXBIWXMAAC4jAAAuIwF4pT92AAAQJElEQVR4nO3d0ZHbRrbH4cYtvcsZyBnYGUg3Ak8GYgjeDHozUAjcDMYZaDOwM7Az2BsB7oNhrW1pNOQQxGng/32PU2WefnDVrxoQeaZ5nhsAcGyvvvTHaZr6xucAAJ52nuf511s+YPrSDX+aJtd+ABjH/87z/PGWD/iflQ4CAAxM8AEggOADQADBB4AAgg8AAQQfAAIIPgAEEHwACCD4ABBA8AEggOADQADBB4AAgg8AAQQfAAIIPgAEEHwACCD4ABBA8AEggOADQADBB4AAgg8AAQQfAAIIPgAEEHwACCD4ABBA8AEgwKvqAyz+WX0AALjCu9ba2+pDXGOI4M/z3KvPAACXmqapt50F3yN9AAgg+AAQQPABIIDgA0AAwQeAAIIPAAEEHwACCD4ABBB8AAgg+AAQQPABIIDgA0AAwQeAAIIPAAEEHwACCD4ABBB8AAgg+AAQQPABIIDgA0AAwQeAAIIPAAEEHwACCD4ABBB8AAgg+AAQQPABIIDgA0AAwQeAAIIPAAEEHwACCD4ABBB8AAgg+AAQQPABIIDgA0AAwQeAAIIPAAEEHwACCD4ABBB8AAgg+AAQQPABIIDgA0AAwQeAAIIPAAEEHwACCD4ABBB8AAgg+AAQQPABIIDgA0AAwQeAAIIPAAEEHwACCD4ABBB8AAgg+AAQ4FX1AbjeNE0fW2tvNxz5z3me+4bzGEzB/3Oj+G2e52+rDwGttXettY+3fIAbPsDT3kzT9FB9CFiD4AN83Y/VB4A1CD7A172dpuld9SHgVoIP8LxefQC4leADPO/tNE3fVh8CbiH4AJfp1QeAWwg+wGXeu+WzZ4IPcLlefQB4KcEHuNz7aZq+qT4EvITgA1zH9/LZJcEHuM6PbvnskeADXOd1c8tnhwQf4Hqn6gPAtQQf4Hpvpmk6VR8CriH4AC/Tqw8A1xB8gJdxy2dXBB/g5U7VB4BLCT7Ay1mdy24IPsBtevUB4BKCD3Cbt9M0fV99CHiO4APczg/xMDzBB7id1bkMT/AB1tGrDwBfI/gA63DLZ2iCD7CeU/UB4Cmvqg8A8AX/aq2db/yMx/b7Zrst/ThN04d5nv+z8Vx4luADI/p1nuePt3zANE2PrbX36xznYn+szu0bz4VneaQPHFUvmusregxJ8IFDmuf51/b7q4GtvbZUhxEJPnBkPWwuPEnwgcNabvk/FYy2OpfhCD5wdB+K5nqXz1AEHzi05V/7/7tg9HdW5zISwQcS9LC58BnBBw5vueX/VjD6rVs+oxB8IEUvmmsqmgt/IfhAhHmez63mlm+pDkMQfCBJD5sLnwg+kOSxtfZ/BXPd8ikn+ECMZYtd1ffyT0VzobUm+ECeD63mlv/jNE3fFMyF1prgA2GWW/65YPQfq3OhhOADicp+btctnyqCD8SpXJ3bWnsomAuCD8TqYXMJJ/hAJKtzSSP4QLKqd/m9aC7BBB+IVbg6942lOmxN8IF0PWwuoQQfiLbc8n8pGG11LpsSfIDC7+UXzSWQ4APxClfn/mCpDlsRfIDf9bC5hBF8gPbplm91Locl+AD/5V0+hyX4AP9VtTr3ZKkO9yb4AItldW7FLd/qXO5O8AH+6lw01+pc7krwAf6keHXuqWAuIQQf4HO9aK7H+tyN4AP8TeEt3+pc7kbwAb7sXDS3F83l4AQf4AuKV+c+FMzl4AQf4Gm9aK73+axO8AGeUHjLtzqX1Qk+wNedi+b2orkclOADfEXh6ty3luqwJsEHeF4Pm8sBCT7AMwpv+VbnshrBB7jMuWhuL5rLwQg+wGWqVuc+WKrDGgQf4AJW57J3gg9wuYrgt2Z1LisQfIALLbf8qtW5bvncRPABrtOL5p6K5nIQgg9wBatz2SvBB7he1bv8XjSXAxB8gCvN8/xzq1udeyqYywEIPsDL9KK5p6K57JzgA7yA1bnsjeADvJx3+eyG4AO80DzPj61ude73BXPZMcEHuE0vmuuHeLiK4APcwOpc9kLwAW7nXT7DE3yA251bzerc95bqcCnBB7hR4erc1rzL50KCD7COD63mlm91LhcRfIAVLLf8x4LRVudyEcEHWE8vmnsqmsuOCD7ASqzOZWSCD7CuHjaXnRB8gBUtt3yrcxmO4AOsrxfN9Y/3eJLgA6yscHXud1bn8hTBB7gPP7fLUAQf4A6KV+e+K5jL4AQf4H560dxT0VwGJvgAd2J1LiMRfID76mFzGZTgA9zXY6tbnfttwVwGJfgAd1S8OvdUNJcBCT7A/VmdSznBB7iz5ZZ/LhhtdS6fCD7ANqoe6ws+rTXBB9hE4erc15bq0JrgA2yph81lIIIPsJHllv9TwWircxF8gI1ZqkMJwQfYUOHq3DeW6mQTfIDt9bC5DEDwATa23PKtzmVTgg9QoxfN9b38UIIPUKBwde4PlupkEnyAOj1sLoUEH6DIcsu3OpdNCD5ALb+xzyYEH6BW1erck9W5WQQfoNCyOrfilm91bhjBB6h3Lpr7o1t+DsEHKFa5Ore19lAwlwKCDzCGHjaXjQk+wAAKb/lW54YQfIBxnIvm9qK5bEjwAQZhdS73JPgAY+lhc9mI4AMMZLnl/1Iw2urcgxN8gPFU/dxuL5rLBgQfYDCFq3PfWqpzXIIPMKYeNpc7E3yAARXe8q3OPSjBBxjXuWhuL5rLHQk+wLiqVuc+WKpzPIIPMCirc1mT4AOMreorelbnHozgAwxsueVXrc49FczlTgQfYHy9aK7H+gci+ACDszqXNQg+wD74uV1uIvgAOzDP88+tbnXuQ8FcVib4APvRi+Z6l38Agg+wE8vq3IpbvtW5ByD4APtyLprbi+ayEsEH2JHi1bnfF8xlJYIPsD+9aK73+Tsm+AA7Y3UuLyH4APt0Lprbi+ZyI8EH2Keq1bnvLdXZJ8EH2KHC1bmteZe/S4IPsF9Vt3yrc3dI8AF2arnlPxaMft3c8ndH8AH2rRfNPRXN5YUEH2DHrM7lUoIPsH89bC4vIPgAO7fc8qtW554K5vICgg9wDL1o7qloLlcSfIADsDqX5wg+wHFU/RBPL5rLFQQf4CDmeX5sdatz3xXM5QqCD3AsvWjuqWguFxJ8gAOxOpenCD7A8XiXz2cEH+B4zq1ude63BXO5gOADHEzx6txT0VyeIfgAx2R1Ln8h+AAHtNzyzwWjrc4dlOADHFfVY33BH5DgAxxU4erc15bqjEfwAY6th83lCYIPcGDLLf+ngtFW5w5G8AGOz7t8BB/g6ApX535nqc44BB8gQw+by98IPkCA5ZZvdW4wwQfI0Yvmnorm8ieCDxDC6txsgg+QpYfNZSH4AFkem9W5kQQfIEjx6lzfyy8k+AB5qlbnnqzOrSP4AGGszs0k+ACZyh7ru+XXEHyAQJWrc1trDwVz4wk+QK4eNjea4AOEKrzlW51bQPABsp2L5vaiubEEHyBY4ercN5bqbEvwAehhcyMJPkC45Zb/S8Foq3M3JPgAtObndg9P8AGoXJ37g6U62xB8AP7Qw+ZGEXwAWmufbvlW5x6U4APwZ1Xv8nvR3BiCD8CfVa3OfbBU574EH4BPltW5Fbd8q3PvTPAB+Ltz0Vyrc+9I8AH4i+LVuaeCuREEH4Av6UVzPda/E8EH4DNW5x6P4APwFF/ROxDBB+CL5nn+udWtzn0omHtogg/A1/Siud7lr0zwAXjSsjq34pZvde7KBB+A55yL5vaiuYck+AB8VeHq3LeW6qxH8AG4RA+beziCD8CzCm/5VueuRPABuNS5aG4vmnsogg/ApazO3THBB+AiVufum+ADcI2qn9u1OvdGgg/AxZZbftXqXLf8Gwg+ANfqRXNPRXMPQfABuIrVufsk+AC8RA+bu3uCD8DVllt+1ercU8Hc3RN8AF6qF809Fc3dNcEH4EWszt0XwQfgFlXfy+9Fc3dL8AF4sXmeH1vd6tzvC+buluADcKteNNcP8VxB8AG4idW5+yD4AKzBu/zBCT4Aazi3mtW57y3VuYzgA3CzwtW5rXmXfxHBB2AtH1rNLd/q3AsIPgCrWG75jwWjrc69gOADsKZeNFfwnyH4AKymcHXua0t1vk7wAVhbD5u7C4IPwKqszh2T4ANwD71ornf5TxB8AFZXuDr3O6tzv0zwAbiXHjZ3aIIPwF0st/yq1bnvCuYOTfABuKdeNPdUNHdYgg/A3VidOw7BB+DeetjcIQk+APf22OpW535bMHdIgg/AXRWvzj0VzR2O4AOwBatziwk+AHe33PLPBaOtzl0IPgBbqXqs75bfBB+AjVSuzm2tPRTMHYrgA7ClHjZ3GIIPwGaWW/5PBaPjV+cKPgBbq3qX34vmDkHwAdhU4ercN8lLdQQfgAo9bG45wQdgc8st/5eC0bGrcwUfgCpl38svmlvqVfUBAMg0z/N5mqbeWnuz8egfpmmaN55Zzg0fgEq9+gApBB+AMvM8n1vNUp04gg9Atap3+VEEH4BqVaszowg+AKWW1blu+Xcm+ACM4Fx9gKMTfADKFa7OjSH4AIyiVx/gyAQfgCG45d+X4AMwknP1AY5K8AEYRuHq3MMTfABG06sPcESCD8BQ3PLvQ/ABGNG5+gBHI/gADGdZqvNb9TmORPABGFWvPsCRCD4AQ3LLX5fgAzCyc/UBjkLwARiZ1bkrEXwAhmV17noEH4DRCf4KBB+AoS23fEt1biT4AOxBrz7A3gk+AMOzOvd2gg/AXniXf4NX1QfgRc6ttY8bzttyFmM6N//PUWye55+nafpHa+2b6rMU+HjrB0zzPH/+x2n6/I93NM/ztOU8AEjjkT4ABBB8AAgg+AAQQPABIIDgA0AAwQeAAIIPAAEEHwACCD4ABBB8AAgg+AAQQPABIIDgA0AAwQeAAIIPAAEEHwACCD4ABBB8AAgg+AAQQPABIIDgA0AAwQeAAIIPAAEEHwACCD4ABBB8AAgg+AAQQPABIIDgA0AAwQeAAIIPAAEEHwACCD4ABBB8AAgg+AAQQPABIIDgA0AAwQeAAIIPAAEEHwACCD4ABBB8AAgg+AAQQPABIIDgA0AAwQeAAIIPAAEEHwACCD4ABBB8AAgg+AAQQPABIIDgA0AAwQeAAIIPAAEEHwACCD4ABBB8AAjwqvoArbU2TdNcfQYAGNk8z9Mt/70bPgAEEHwACCD4ABBA8AEggOADQADBB4AAgg8AAQQfAAIIPgAEEHwACCD4ABBA8AEggOADQADBB4AAgg8AAQQfAAIIPgAEEHwACCD4ABBA8AEggOADQADBB4AAgg8AAQQfAAIIPgAEEHwACPDqib//e9NTAAB3Nc3zXH0GAODOPNIHgACCDwABBB8AAgg+AAQQfAAIIPgAEEDwASDA/wNdJTFz9ntRgAAAAABJRU5ErkJggg==";

const DRAFT_KEY   = "inside_informe_draft_v2";
const HISTORY_KEY = "inside_informe_history_v2";

function computeFirestore(quotes) {
  const byStatus = k => quotes.filter(q => q.status === k);
  const sum      = qs => qs.reduce((s,q) => s+(q.total||0), 0);
  const grand    = sum(quotes);
  const wMargin  = grand > 0 ? quotes.reduce((s,q) => s+(q.margin_pct||0)*(q.total||0), 0)/grand : 0;
  const sent     = byStatus("sent");
  const accepted = byStatus("accepted");
  const rejected = byStatus("rejected");
  const pending  = byStatus("pending");
  const draft    = byStatus("draft");
  const totalCerradas = accepted.length + rejected.length;
  const tasaCierre = totalCerradas > 0 ? (accepted.length / totalCerradas * 100) : 0;
  return {
    grand, wMargin,
    cotizado:      grand,
    proyectados:   sum(sent),
    generados:     sum(accepted),
    perdidos:      sum(rejected),
    pendientesSum: sum(pending),
    enNeg:         sent.length,
    pendientes:    pending.length,
    ganados:       accepted.length,
    perdidos_n:    rejected.length,
    tasaCierre, totalCerradas,
    byStatus: {
      draft:    {label:"Cotizando",      count:draft.length,    total:sum(draft)},
      sent:     {label:"En negociación", count:sent.length,     total:sum(sent)},
      pending:  {label:"Pendiente",      count:pending.length,  total:sum(pending)},
      accepted: {label:"Adjudicado",     count:accepted.length, total:sum(accepted)},
      rejected: {label:"No adjudicado",  count:rejected.length, total:sum(rejected)},
    },
    top5active: [...sent,...pending].sort((a,b)=>(b.total||0)-(a.total||0)).slice(0,5),
    top5adj:    [...accepted].sort((a,b)=>(b.total||0)-(a.total||0)).slice(0,5),
    totalCount: quotes.length,
  };
}

// ══════════════════════════════════════════════════════
//  HTML BUILDER
// ══════════════════════════════════════════════════════
function buildHTML({periodo, fecha, presentadoPor, avances, riesgos, plan, proyectosCalientes, visitas, feedback, fs, nd}) {
  const fDate = new Date(fecha+"T00:00").toLocaleDateString("es-PA",{day:"2-digit",month:"long",year:"numeric"});

  const nContacts  = nd?.contacts?.total    ?? "—";
  const nActCont   = nd?.contacts?.active   ?? "—";
  const nClients   = nd?.clients?.active    ?? "—";
  const nProspects = nd?.clients?.prospects ?? "—";
  const nProjects  = nd?.projects?.total    ?? "—";
  const cByStatus  = nd?.clients?.byStatus  ?? {};
  const pByType    = nd?.projects?.byType   ?? {};

  const BAR_COLORS = ["#141414","#4a4a4e","#7a7a80","#a8a8ae","#d0d0d4"];

  const makeBars = (entries) => {
    const max = entries.length ? entries[0][1] : 1;
    return entries.map(([name,count],i) => `
    <div style="display:flex;align-items:center;gap:12px;padding:8px 0;border-bottom:1px solid var(--line)">
      <div style="width:130px;font-size:12.5px;color:var(--ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex-shrink:0" contenteditable="false">${esc(name)}</div>
      <div style="flex:1;background:var(--line);border-radius:4px;height:8px;overflow:hidden">
        <div style="height:100%;width:${(count/max*100).toFixed(1)}%;background:${BAR_COLORS[i%BAR_COLORS.length]};border-radius:4px"></div>
      </div>
      <div style="width:28px;text-align:right;font-family:var(--mono);font-size:11px;font-weight:600;color:var(--ink);flex-shrink:0" contenteditable="false">${count}</div>
    </div>`).join("") || `<div style="color:var(--faint);font-size:13px;padding:16px 0">Sin datos disponibles</div>`;
  };

  const typeRows   = makeBars(Object.entries(pByType).sort((a,b)=>b[1]-a[1]));
  const clientRows = makeBars(Object.entries(cByStatus).sort((a,b)=>b[1]-a[1]));

  const bar = key => fs.grand > 0 ? ((fs.byStatus[key]?.total||0)/fs.grand*100).toFixed(1)+"%" : "0%";

  const winPct  = fs.totalCerradas > 0 ? fs.tasaCierre.toFixed(0) : "0";
  const lossPct = fs.totalCerradas > 0 ? (100-fs.tasaCierre).toFixed(0) : "0";

  const topRows = fs.top5active.map(q => `
    <tr>
      <td contenteditable="false">${esc(q.project_name||"—")}</td>
      <td class="estn" contenteditable="false">${q.status==="sent"?"En negociación":q.status==="pending"?"Pendiente":"—"}</td>
      <td class="r" contenteditable="false">${fmtUSD(q.total)}</td>
    </tr>`).join("") || `<tr><td colspan="3" style="color:var(--faint)">Sin proyectos activos</td></tr>`;

  const adjRows = fs.top5adj.map(q => `
    <div class="accrow">
      <span class="an2" contenteditable="false">${esc(q.project_name||"—")}</span>
      <span class="av" contenteditable="false">${fmtUSD(q.total)}</span>
    </div>`).join("") || `<div style="color:var(--faint);font-size:13px;margin-top:8px">Sin adjudicados aún</div>`;

  const avancesCards = avances.map((a,i) => `
    <div class="ncard">
      <div style="font-family:var(--mono);font-size:9.5px;text-transform:uppercase;letter-spacing:.06em;color:var(--faint);margin-bottom:8px" contenteditable="false">Avance ${i+1}</div>
      <div style="font-family:var(--display);font-weight:600;font-size:17px;margin-bottom:8px;color:var(--ink);line-height:1.2" contenteditable="false">${esc(a.titulo||"—")}</div>
      <p contenteditable="false">${esc(a.desc||"")}</p>
    </div>`).join("");

  const riskCards = riesgos.map(r => `
    <div class="rcard">
      <div class="rk" contenteditable="false">RIESGO</div>
      <div class="rv2" contenteditable="false">${esc(r.riesgo||"—")}</div>
      <p contenteditable="false">${esc(r.aprendizaje||"")}</p>
    </div>`).join("");

  const hotTags = proyectosCalientes.map(p =>
    `<div class="hottag" contenteditable="false">${esc(p)}</div>`).join("");

  const visitaTags = visitas.map(v =>
    `<span class="tag2" contenteditable="false">${esc(v)}</span>`).join("");

  const STAGES = [
    "Portada","Resumen ejecutivo","Resultados comerciales",
    "Tasa de adjudicación","Estado financiero","Cartera de clientes",
    "Avances estratégicos","Proyectos calientes","Riesgos y aprendizajes",
    "Plan siguiente período","Sugerencias y feedback"
  ];
  const N = STAGES.length;
  const Npad = String(N).padStart(2,"0");

  return `<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>INside — Informe ${esc(periodo)}</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=Inter:wght@400;500;600&family=JetBrains+Mono:wght@400;500;700&display=swap" rel="stylesheet">
<style>
:root{--bg:#FFFFFF;--surface:#F7F7F5;--surface2:#EFEFEB;--ink:#141414;--ink2:#33333a;--muted:#6B6B70;--faint:#9B9B9E;--line:#E4E4E0;--line2:#D6D6D1;--display:'Space Grotesk',sans-serif;--body:'Inter',sans-serif;--mono:'JetBrains Mono',monospace}
*{box-sizing:border-box;margin:0;padding:0}
html,body{height:100%}
body{background:var(--bg);color:var(--ink);font-family:var(--body);-webkit-font-smoothing:antialiased;line-height:1.4;overflow:hidden}
.app{height:100vh;display:flex;flex-direction:column}
.top{display:flex;align-items:center;justify-content:space-between;padding:18px 34px;border-bottom:1px solid var(--line);flex-shrink:0}
.top .brand{display:flex;align-items:center;gap:10px;flex-shrink:0;overflow:visible}
.top .brand img{height:28px;width:auto;display:block;max-width:220px;object-fit:contain}
.top .brand .ctx{font-family:var(--mono);font-size:10.5px;color:var(--muted);letter-spacing:.04em;border-left:1px solid var(--line2);padding-left:10px;margin-left:2px}
.top .mid{font-family:var(--mono);font-size:11px;color:var(--muted);letter-spacing:.04em}
.top .right{display:flex;align-items:center;gap:14px}
.pbar{display:flex;gap:4px;flex-wrap:wrap;max-width:340px}
.pbar .seg{width:18px;height:3px;background:var(--line2);border-radius:2px;cursor:pointer;transition:background .2s}
.pbar .seg.done{background:#8C8C90}.pbar .seg.cur{background:var(--ink)}
.editbtn{font-family:var(--mono);font-size:10px;letter-spacing:.05em;text-transform:uppercase;padding:6px 12px;border-radius:7px;border:1px solid var(--line2);background:transparent;color:var(--muted);cursor:pointer;transition:all .15s}
.editbtn:hover{border-color:var(--muted);color:var(--ink)}.editbtn.on{background:var(--ink);color:var(--bg);border-color:var(--ink)}
body.editing [contenteditable="true"]{outline:1px dashed #b7b7b2;outline-offset:3px;border-radius:4px;cursor:text}
body.editing [contenteditable="true"]:hover{outline-color:var(--ink)}
body.editing [contenteditable="true"]:focus{outline:1px solid var(--ink);outline-offset:2px}
.editnote{display:none;font-family:var(--mono);font-size:10px;color:var(--faint);padding:8px 34px;border-bottom:1px solid var(--line);flex-shrink:0}
body.editing .editnote{display:block}
.stagewrap{flex:1;position:relative;overflow:hidden}
.stage{position:absolute;inset:0;padding:36px 48px;overflow-y:auto;overflow-x:hidden;opacity:0;pointer-events:none;transform:translateY(10px);transition:opacity .45s ease,transform .45s ease;display:flex;flex-direction:column}
.stage.active{opacity:1;pointer-events:auto;transform:none}
.maxw{max-width:1160px;margin:0 auto;width:100%}
.stage.center{justify-content:center}
.eyebrow{font-family:var(--mono);font-size:11px;letter-spacing:.16em;text-transform:uppercase;color:var(--muted);margin-bottom:10px}
.stage h1{font-family:var(--display);font-weight:600;font-size:32px;line-height:1.08;letter-spacing:-.03em;margin-bottom:22px}
.rv{opacity:0;transform:translateY(12px);transition:opacity .5s ease,transform .5s ease}
.stage.active .rv{opacity:1;transform:none;transition-delay:calc(var(--i,0)*90ms + 100ms)}
.cover{display:flex;flex-direction:column;align-items:flex-start}
.cover .biglogo{height:80px;width:auto;display:block;max-width:300px;margin-bottom:40px;object-fit:contain}
.cover h1{font-size:52px;margin-bottom:10px}
.cover .eyebrow{font-size:14px;margin-top:4px}
.cover .tag{font-family:var(--mono);font-size:11px;color:var(--faint);letter-spacing:.1em;text-transform:uppercase;margin-top:20px}
.cover .by{font-family:var(--mono);font-size:12px;color:var(--muted);margin-top:6px}
.kpis9{display:grid;grid-template-columns:repeat(3,1fr);gap:14px}
.kpis4{display:grid;grid-template-columns:repeat(4,1fr);gap:14px}
.kpi{background:var(--surface);border:1px solid var(--line);border-radius:14px;padding:22px 20px}
.kpi .cap{font-family:var(--mono);font-size:10px;letter-spacing:.05em;text-transform:uppercase;color:var(--muted);margin-bottom:12px}
.kpi .v{font-family:var(--display);font-weight:600;font-size:28px;letter-spacing:-.02em;line-height:1}
.kpi .sub{font-size:11px;color:var(--muted);margin-top:8px}
.kpi.accent{background:var(--ink);color:#fff}.kpi.accent .cap{color:#b5b5b5}.kpi.accent .sub{color:#a5a5a5}
.funnel{display:flex;align-items:stretch;gap:0;margin-top:8px}
.fstep{flex:1;background:var(--surface);border:1px solid var(--line);padding:24px 16px;text-align:center;position:relative}
.fstep:not(:last-child){border-right:none}
.fstep:first-child{border-radius:14px 0 0 14px}.fstep:last-child{border-radius:0 14px 14px 0}
.fstep .fv{font-family:var(--display);font-weight:700;font-size:36px;letter-spacing:-.03em}
.fstep .fl{font-family:var(--mono);font-size:10px;text-transform:uppercase;letter-spacing:.05em;color:var(--muted);margin-top:8px}
.fstep .fx{position:absolute;right:-11px;top:50%;transform:translateY(-50%);width:22px;height:22px;background:var(--bg);border:1px solid var(--line2);border-radius:50%;display:flex;align-items:center;justify-content:center;font-family:var(--mono);font-size:11px;color:var(--muted);z-index:2}
.fstep:nth-child(1) .fv{color:#B5B5B8}.fstep:nth-child(2) .fv{color:#88888c}.fstep:nth-child(3) .fv{color:#4c4c50}.fstep:nth-child(4) .fv{color:var(--ink)}
.split2{display:grid;grid-template-columns:1.3fr 1fr;gap:16px}
.panel{background:var(--surface);border:1px solid var(--line);border-radius:14px;padding:22px 24px}
.panel h3{font-family:var(--mono);font-size:10px;text-transform:uppercase;letter-spacing:.05em;color:var(--muted);margin-bottom:14px;font-weight:500}
.accrow{display:flex;justify-content:space-between;align-items:center;padding:10px 0;border-bottom:1px solid var(--line)}
.accrow:last-child{border:none}
.accrow .an2{font-size:13.5px;font-weight:600}.accrow .av{font-family:var(--display);font-weight:600;font-size:14.5px}
.dtbl{width:100%;border-collapse:separate;border-spacing:0;background:var(--surface);border:1px solid var(--line);border-radius:12px;overflow:hidden}
.dtbl th{font-family:var(--mono);font-size:10px;text-transform:uppercase;letter-spacing:.05em;color:var(--muted);text-align:left;padding:12px 16px;background:var(--surface2);border-bottom:1px solid var(--line)}
.dtbl th.r{text-align:right}.dtbl td{padding:12px 16px;border-bottom:1px solid var(--line);font-size:13.5px}
.dtbl tr:last-child td{border-bottom:none}.dtbl td.r{text-align:right;font-family:var(--display);font-weight:600}
.estn{font-family:var(--mono);font-weight:600;font-size:11px}
.barrow2{display:flex;height:26px;border-radius:6px;overflow:hidden;margin-top:14px;border:1px solid var(--line)}
.barrow2 div{height:100%}
.barlegend2{display:flex;gap:18px;margin-top:10px;flex-wrap:wrap}
.barlegend2 span{font-family:var(--mono);font-size:10.5px;color:var(--muted);display:flex;align-items:center;gap:6px}
.barlegend2 i{width:8px;height:8px;border-radius:2px;display:inline-block}
.riskgrid{display:grid;grid-template-columns:1fr 1fr;gap:14px}
.rcard{background:var(--surface);border:1px solid var(--line);border-radius:14px;padding:20px 22px}
.rcard .rk{font-family:var(--mono);font-size:9.5px;text-transform:uppercase;letter-spacing:.05em;color:var(--faint);margin-bottom:8px}
.rcard .rv2{font-family:var(--display);font-weight:600;font-size:20px;margin-bottom:8px;line-height:1.2}
.rcard p{font-size:12.5px;color:var(--ink2);line-height:1.5}
.nextgrid{display:grid;grid-template-columns:1fr 1fr;gap:14px}
.ncard{background:var(--surface);border:1px solid var(--line);border-radius:14px;padding:22px 24px}
.ncard h3{font-family:var(--mono);font-size:10px;text-transform:uppercase;letter-spacing:.05em;color:var(--muted);margin-bottom:12px;font-weight:500}
.ncard p{font-size:13.5px;color:var(--ink2);line-height:1.55;white-space:pre-wrap}
.taglist{display:flex;flex-wrap:wrap;gap:8px}
.tag2{font-family:var(--mono);font-size:11.5px;background:var(--surface2);border:1px solid var(--line2);padding:6px 12px;border-radius:20px;color:var(--ink2)}
.hotlist{display:flex;flex-wrap:wrap;gap:12px;margin-top:8px}
.hottag{font-family:var(--display);font-size:16px;font-weight:600;background:var(--ink);color:#fff;padding:12px 24px;border-radius:28px}
.bignum{font-family:var(--display);font-weight:700;font-size:88px;letter-spacing:-.04em;line-height:1}
.bignum sup{font-size:40px;vertical-align:super;line-height:0}
.bignum-label{font-family:var(--mono);font-size:11px;color:var(--muted);letter-spacing:.08em;text-transform:uppercase;margin-top:10px}
.qroom{display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:60vh;text-align:center}
.qroom h1{font-size:44px}.qroom .qsub{font-family:var(--mono);font-size:12px;color:var(--faint);letter-spacing:.05em}
.qroom .qnotes{max-width:640px;margin-top:28px;font-size:14px;color:var(--ink2);line-height:1.7;white-space:pre-wrap;text-align:left;background:var(--surface);border:1px solid var(--line);border-radius:12px;padding:20px 24px}
.nav{display:flex;align-items:center;justify-content:space-between;padding:16px 34px;border-top:1px solid var(--line);flex-shrink:0}
.nav .label{font-family:var(--mono);font-size:11px;color:var(--muted);letter-spacing:.03em}
.nav .btns{display:flex;gap:8px}
.nav button{font-family:var(--mono);font-size:11px;letter-spacing:.03em;padding:9px 18px;border-radius:8px;border:1px solid var(--line2);background:transparent;color:var(--ink);cursor:pointer;transition:all .14s}
.nav button:hover:not(:disabled){border-color:var(--muted)}
.nav button.primary{background:var(--ink);color:#fff;border-color:var(--ink)}
.nav button:disabled{opacity:.32;cursor:default}
.hint{font-family:var(--mono);font-size:9.5px;color:var(--faint)}
@media(max-width:900px){.kpis9,.kpis4,.split2,.nextgrid,.riskgrid{grid-template-columns:1fr}.funnel{flex-direction:column}.fstep{border-right:1px solid var(--line)!important;border-radius:0!important}.fstep:first-child{border-radius:14px 14px 0 0!important}.fstep:last-child{border-radius:0 0 14px 14px!important}.fstep .fx{display:none}.stage{padding:24px 18px}.stage h1{font-size:24px}.cover h1{font-size:32px}.top,.nav{padding:14px 16px}.bignum{font-size:56px}}
</style>
</head>
<body>
<div class="app">
<div class="top">
  <div class="brand">
    <img src="${LOGO}" alt="INside">
    <span class="ctx" id="stageMid">Portada</span>
  </div>
  <div class="mid">Informe de Gestión · ${esc(periodo)}</div>
  <div class="right">
    <div class="pbar" id="pbar"></div>
    <button class="editbtn" id="editBtn">Editar</button>
  </div>
</div>
<div class="editnote">Modo edición activo — clic en cualquier texto para modificarlo directamente.</div>
<div class="stagewrap" id="stagewrap">

<!-- 1 · PORTADA -->
<section class="stage active center" data-name="Portada">
  <div class="maxw cover">
    <img class="biglogo rv" style="--i:0" src="${LOGO}" alt="INside">
    <h1 class="rv" style="--i:1" contenteditable="false">Informe de Gestión</h1>
    <div class="eyebrow rv" style="--i:2" contenteditable="false">${esc(periodo)}</div>
    <div class="tag rv" style="--i:3" contenteditable="false">${esc(fDate)}</div>
    ${presentadoPor ? `<div class="by rv" style="--i:4" contenteditable="false">Preparado por ${esc(presentadoPor)}</div>` : ""}
  </div>
</section>

<!-- 2 · RESUMEN EJECUTIVO -->
<section class="stage center" data-name="Resumen ejecutivo">
  <div class="maxw">
    <div class="eyebrow rv" style="--i:0">01 · Resumen ejecutivo</div>
    <h1 class="rv" style="--i:1" contenteditable="false">El período en números</h1>
    <div class="kpis9 rv" style="--i:2">
      <div class="kpi accent">
        <div class="cap" contenteditable="false">Cotizado total</div>
        <div class="v" contenteditable="false">${fmtUSD(fs.cotizado)}</div>
        <div class="sub" contenteditable="false">${fs.totalCount} cotizaciones · todo el período</div>
      </div>
      <div class="kpi">
        <div class="cap" contenteditable="false">Ingresos proyectados</div>
        <div class="v" contenteditable="false">${fmtUSD(fs.proyectados)}</div>
        <div class="sub" contenteditable="false">${fs.enNeg} proyectos en negociación</div>
      </div>
      <div class="kpi accent">
        <div class="cap" contenteditable="false">Ingresos generados</div>
        <div class="v" contenteditable="false">${fmtUSD(fs.generados)}</div>
        <div class="sub" contenteditable="false">${fs.ganados} proyectos adjudicados</div>
      </div>
      <div class="kpi">
        <div class="cap" contenteditable="false">Ingresos perdidos</div>
        <div class="v" contenteditable="false">${fmtUSD(fs.perdidos)}</div>
        <div class="sub" contenteditable="false">${fs.perdidos_n} no adjudicados</div>
      </div>
      <div class="kpi">
        <div class="cap" contenteditable="false">Ingresos pendientes</div>
        <div class="v" contenteditable="false">${fmtUSD(fs.pendientesSum)}</div>
        <div class="sub" contenteditable="false">${fs.pendientes} proyectos pendientes</div>
      </div>
      <div class="kpi">
        <div class="cap" contenteditable="false">Margen promedio</div>
        <div class="v" contenteditable="false">${fmtPct(fs.wMargin)}</div>
        <div class="sub" contenteditable="false">ponderado · todas las cotizaciones</div>
      </div>
      <div class="kpi">
        <div class="cap" contenteditable="false">En negociación</div>
        <div class="v" contenteditable="false">${fs.enNeg}</div>
        <div class="sub" contenteditable="false">propuesta enviada al cliente</div>
      </div>
      <div class="kpi">
        <div class="cap" contenteditable="false">Adjudicados</div>
        <div class="v" contenteditable="false">${fs.ganados}</div>
        <div class="sub" contenteditable="false">confirmados y cerrados</div>
      </div>
      <div class="kpi">
        <div class="cap" contenteditable="false">No adjudicados</div>
        <div class="v" contenteditable="false">${fs.perdidos_n}</div>
        <div class="sub" contenteditable="false">cliente no aceptó la propuesta</div>
      </div>
    </div>
  </div>
</section>

<!-- 3 · RESULTADOS COMERCIALES -->
<section class="stage center" data-name="Resultados comerciales">
  <div class="maxw">
    <div class="eyebrow rv" style="--i:0">02 · Resultados comerciales</div>
    <h1 class="rv" style="--i:1" contenteditable="false">De dónde sale el negocio</h1>
    <div class="funnel rv" style="--i:2">
      <div class="fstep"><div class="fv" contenteditable="false">${esc(String(nContacts))}</div><div class="fl" contenteditable="false">Contactos en base</div><div class="fx">→</div></div>
      <div class="fstep"><div class="fv" contenteditable="false">${esc(String(nActCont))}</div><div class="fl" contenteditable="false">Contactos activos</div><div class="fx">→</div></div>
      <div class="fstep"><div class="fv" contenteditable="false">${esc(String(nProjects))}</div><div class="fl" contenteditable="false">Proyectos en cartera</div><div class="fx">→</div></div>
      <div class="fstep"><div class="fv" contenteditable="false">${fs.totalCount}</div><div class="fl" contenteditable="false">Cotizaciones emitidas</div></div>
    </div>
    <div class="split2 rv" style="--i:3;margin-top:14px">
      <table class="dtbl">
        <thead><tr><th>Top proyectos activos · En negociación y Pendientes</th><th>Estado</th><th class="r">Valor</th></tr></thead>
        <tbody>${topRows}</tbody>
      </table>
      <div class="panel">
        <h3 contenteditable="false">Proyectos por tipo · Notion</h3>
        ${typeRows}
      </div>
    </div>
  </div>
</section>

<!-- 4 · TASA DE ADJUDICACIÓN -->
<section class="stage center" data-name="Tasa de adjudicación">
  <div class="maxw">
    <div class="eyebrow rv" style="--i:0">03 · Tasa de adjudicación</div>
    <h1 class="rv" style="--i:1" contenteditable="false">Conversión de propuestas en proyectos cerrados</h1>
    <div class="split2 rv" style="--i:2">
      <div style="display:flex;flex-direction:column;justify-content:center;padding:32px 28px;background:var(--surface);border:1px solid var(--line);border-radius:14px">
        <div class="bignum" contenteditable="false">${fs.totalCerradas > 0 ? fs.tasaCierre.toFixed(0) : "—"}<sup>%</sup></div>
        <div class="bignum-label" contenteditable="false">tasa de adjudicación</div>
        <div style="font-size:12px;color:var(--muted);margin-top:8px" contenteditable="false">
          ${fs.ganados} adjudicados de ${fs.totalCerradas} propuestas cerradas
        </div>
        <div class="barrow2" style="margin-top:24px">
          <div style="width:${winPct}%;background:#141414" title="Adjudicado ${winPct}%"></div>
          <div style="width:${lossPct}%;background:#d0d0d4" title="No adjudicado ${lossPct}%"></div>
        </div>
        <div class="barlegend2" contenteditable="false">
          <span><i style="background:#141414"></i>Adjudicado ${winPct}%</span>
          <span><i style="background:#d0d0d4"></i>No adjudicado ${lossPct}%</span>
        </div>
      </div>
      <div style="display:flex;flex-direction:column;gap:12px">
        <div class="kpi">
          <div class="cap" contenteditable="false">Propuestas cerradas</div>
          <div class="v" contenteditable="false">${fs.totalCerradas}</div>
          <div class="sub" contenteditable="false">Adjudicadas + No adjudicadas</div>
        </div>
        <div class="kpi accent">
          <div class="cap" contenteditable="false">Adjudicadas</div>
          <div class="v" contenteditable="false">${fs.ganados}</div>
          <div class="sub" contenteditable="false">proyecto confirmado y cerrado</div>
        </div>
        <div class="kpi">
          <div class="cap" contenteditable="false">No adjudicadas</div>
          <div class="v" contenteditable="false">${fs.perdidos_n}</div>
          <div class="sub" contenteditable="false">cliente no aceptó la propuesta</div>
        </div>
        <div class="kpi">
          <div class="cap" contenteditable="false">Aún en proceso</div>
          <div class="v" contenteditable="false">${fs.enNeg + fs.pendientes}</div>
          <div class="sub" contenteditable="false">En negociación + Pendientes</div>
        </div>
      </div>
    </div>
  </div>
</section>

<!-- 5 · ESTADO FINANCIERO -->
<section class="stage center" data-name="Estado financiero">
  <div class="maxw">
    <div class="eyebrow rv" style="--i:0">04 · Estado financiero</div>
    <h1 class="rv" style="--i:1" contenteditable="false">Composición de la cartera</h1>
    <div class="split2 rv" style="--i:2">
      <div class="panel">
        <h3 contenteditable="false">Cartera total — ${fmtUSD(fs.grand)}</h3>
        <div class="barrow2">
          <div style="width:${bar("draft")};background:#141414" title="Cotizando"></div>
          <div style="width:${bar("sent")};background:#4c4c50" title="En negociación"></div>
          <div style="width:${bar("pending")};background:#8C8C90" title="Pendiente"></div>
          <div style="width:${bar("accepted")};background:#33333a" title="Adjudicado"></div>
          <div style="width:${bar("rejected")};background:#C6C6C2" title="No adjudicado"></div>
        </div>
        <div class="barlegend2" contenteditable="false">
          <span><i style="background:#141414"></i>Cotizando — ${fmtUSD(fs.byStatus.draft.total)}</span>
          <span><i style="background:#4c4c50"></i>En negociación — ${fmtUSD(fs.byStatus.sent.total)}</span>
          <span><i style="background:#8C8C90"></i>Pendiente — ${fmtUSD(fs.byStatus.pending.total)}</span>
          <span><i style="background:#33333a"></i>Adjudicado — ${fmtUSD(fs.byStatus.accepted.total)}</span>
          <span><i style="background:#C6C6C2"></i>No adjudicado — ${fmtUSD(fs.byStatus.rejected.total)}</span>
        </div>
      </div>
      <div class="panel">
        <h3 contenteditable="false">Top proyectos adjudicados</h3>
        ${adjRows}
      </div>
    </div>
  </div>
</section>

<!-- 6 · CARTERA DE CLIENTES -->
<section class="stage center" data-name="Cartera de clientes">
  <div class="maxw">
    <div class="eyebrow rv" style="--i:0">05 · Cartera de clientes · Notion</div>
    <h1 class="rv" style="--i:1" contenteditable="false">Estado de nuestra base comercial</h1>
    <div class="kpis4 rv" style="--i:2">
      <div class="kpi">
        <div class="cap" contenteditable="false">Contactos totales</div>
        <div class="v" contenteditable="false">${esc(String(nContacts))}</div>
        <div class="sub" contenteditable="false">registrados en Notion</div>
      </div>
      <div class="kpi">
        <div class="cap" contenteditable="false">Contactos activos</div>
        <div class="v" contenteditable="false">${esc(String(nActCont))}</div>
        <div class="sub" contenteditable="false">en proceso de seguimiento</div>
      </div>
      <div class="kpi accent">
        <div class="cap" contenteditable="false">Clientes activos</div>
        <div class="v" contenteditable="false">${esc(String(nClients))}</div>
        <div class="sub" contenteditable="false">activos o recurrentes</div>
      </div>
      <div class="kpi">
        <div class="cap" contenteditable="false">Prospectos</div>
        <div class="v" contenteditable="false">${esc(String(nProspects))}</div>
        <div class="sub" contenteditable="false">clientes potenciales</div>
      </div>
    </div>
    <div class="panel rv" style="--i:3;margin-top:14px">
      <h3 contenteditable="false">Clientes por estado</h3>
      ${clientRows}
    </div>
  </div>
</section>

<!-- 7 · AVANCES ESTRATÉGICOS -->
<section class="stage center" data-name="Avances estratégicos">
  <div class="maxw">
    <div class="eyebrow rv" style="--i:0">06 · Avances estratégicos</div>
    <h1 class="rv" style="--i:1" contenteditable="false">Lo que se logró este período</h1>
    <div class="nextgrid rv" style="--i:2">${avancesCards}</div>
  </div>
</section>

<!-- 8 · PROYECTOS CALIENTES -->
<section class="stage center" data-name="Proyectos calientes">
  <div class="maxw">
    <div class="eyebrow rv" style="--i:0">07 · Proyectos calientes</div>
    <h1 class="rv" style="--i:1" contenteditable="false">Prioridades para cerrar este período</h1>
    <div class="hotlist rv" style="--i:2">
      ${hotTags || '<div class="hottag" contenteditable="false">Por definir</div>'}
    </div>
  </div>
</section>

<!-- 9 · RIESGOS Y APRENDIZAJES -->
<section class="stage center" data-name="Riesgos y aprendizajes">
  <div class="maxw">
    <div class="eyebrow rv" style="--i:0">08 · Riesgos y aprendizajes</div>
    <h1 class="rv" style="--i:1" contenteditable="false">Lo que hay que atender</h1>
    <div class="riskgrid rv" style="--i:2">${riskCards}</div>
  </div>
</section>

<!-- 10 · PLAN SIGUIENTE PERÍODO -->
<section class="stage center" data-name="Plan siguiente período">
  <div class="maxw">
    <div class="eyebrow rv" style="--i:0">09 · Plan siguiente período</div>
    <h1 class="rv" style="--i:1" contenteditable="false">Qué viene</h1>
    <div class="nextgrid rv" style="--i:2">
      <div class="ncard">
        <h3 contenteditable="false">Próximas visitas</h3>
        <div class="taglist">${visitaTags || '<span class="tag2" contenteditable="false">Por definir</span>'}</div>
      </div>
      <div class="ncard">
        <h3 contenteditable="false">Objetivos y acciones</h3>
        <p contenteditable="false">${esc(plan||"Por definir")}</p>
      </div>
    </div>
  </div>
</section>

<!-- 11 · SUGERENCIAS Y FEEDBACK -->
<section class="stage" data-name="Sugerencias y feedback">
  <div class="maxw qroom">
    <h1 class="rv" style="--i:0" contenteditable="false">Sugerencias y feedback</h1>
    <div class="qsub rv" style="--i:1" contenteditable="false">Espacio abierto para la directiva</div>
    ${feedback ? `<div class="qnotes rv" style="--i:2" contenteditable="false">${esc(feedback)}</div>` : ""}
  </div>
</section>

</div>
<div class="nav">
  <div class="label" id="navLabel">01 / ${Npad}</div>
  <div class="hint">← → para navegar · Editar para ajustar texto</div>
  <div class="btns">
    <button id="prev">Atrás</button>
    <button id="next" class="primary">Siguiente</button>
  </div>
</div>
</div>
<script>
const stages=[...document.querySelectorAll('.stage')];
const segs=stages.map((s,i)=>{const d=document.createElement('div');d.className='seg'+(i===0?' cur':'');d.onclick=()=>goto(i);document.getElementById('pbar').appendChild(d);return d;});
let cur=0;
function goto(i){
  if(i<0||i>=stages.length)return;
  stages[cur].classList.remove('active');stages[i].classList.add('active');
  segs.forEach((s,x)=>{s.classList.toggle('done',x<i);s.classList.toggle('cur',x===i);});
  cur=i;
  document.getElementById('stageMid').textContent=stages[i].dataset.name;
  document.getElementById('navLabel').textContent=String(i+1).padStart(2,'0')+' / '+String(stages.length).padStart(2,'0');
  document.getElementById('prev').disabled=(i===0);
  const nx=document.getElementById('next');nx.disabled=(i===stages.length-1);nx.textContent=(i===stages.length-1)?'Fin':'Siguiente';
  stages[i].scrollTop=0;
}
document.getElementById('next').onclick=()=>goto(cur+1);
document.getElementById('prev').onclick=()=>goto(cur-1);
document.addEventListener('keydown',e=>{
  if(document.body.classList.contains('editing'))return;
  if(e.target&&(e.target.tagName==='INPUT'||e.target.getAttribute('contenteditable')==='true'))return;
  if(e.key==='ArrowRight'||e.key==='PageDown')goto(cur+1);
  if(e.key==='ArrowLeft'||e.key==='PageUp')goto(cur-1);
});
goto(0);
const editBtn=document.getElementById('editBtn');
let editing=false;
function setEditing(on){
  editing=on;
  document.body.classList.toggle('editing',on);
  editBtn.classList.toggle('on',on);
  editBtn.textContent=on?'Listo':'Editar';
  document.querySelectorAll('[contenteditable]').forEach(el=>el.setAttribute('contenteditable',on?'true':'false'));
}
editBtn.addEventListener('click',()=>setEditing(!editing));
</script>
</body>
</html>`;
}

// ══════════════════════════════════════════════════════
//  FORM HELPERS — outside component so React doesn't
//  remount on every keystroke (typing bug fix)
// ══════════════════════════════════════════════════════
const Sect = ({ title, desc, children }) => (
  <div style={{ marginBottom:32 }}>
    <div style={{ fontSize:11,fontWeight:700,letterSpacing:".1em",textTransform:"uppercase",
      color:"var(--muted)",marginBottom:desc?6:14,paddingBottom:desc?0:8,
      borderBottom:desc?"none":"1px solid var(--border)" }}>{title}</div>
    {desc && <div style={{ fontSize:12,color:"var(--muted)",marginBottom:14,paddingBottom:8,
      borderBottom:"1px solid var(--border)",lineHeight:1.55 }}>{desc}</div>}
    {children}
  </div>
);
const Inp = ({ label, value, onChange, placeholder, type="text" }) => (
  <div style={{ marginBottom:14 }}>
    <label style={{ fontSize:11,color:"var(--muted)",display:"block",marginBottom:4 }}>{label}</label>
    <input className="inp" type={type} value={value} onChange={e=>onChange(e.target.value)}
      placeholder={placeholder} style={{ width:"100%" }} />
  </div>
);
const TA = ({ label, value, onChange, rows=3, placeholder }) => (
  <div style={{ marginBottom:14 }}>
    <label style={{ fontSize:11,color:"var(--muted)",display:"block",marginBottom:4 }}>{label}</label>
    <textarea className="inp" rows={rows} value={value} onChange={e=>onChange(e.target.value)}
      placeholder={placeholder} style={{ width:"100%",resize:"vertical",fontFamily:"var(--body)" }} />
  </div>
);

// ══════════════════════════════════════════════════════
//  FORM COMPONENT
// ══════════════════════════════════════════════════════
function InformeView() {
  const { quotes } = useContext(window.AppCtx);

  const [presentadoPor, setPresentadoPor] = useState("");
  const [periodo,   setPeriodo]   = useState("H1 2026");
  const [fecha,     setFecha]     = useState(new Date().toISOString().slice(0,10));
  const [avances,   setAvances]   = useState([
    {titulo:"",desc:""},{titulo:"",desc:""},{titulo:"",desc:""},{titulo:"",desc:""},
  ]);
  const [riesgos,   setRiesgos]   = useState([
    {riesgo:"",aprendizaje:""},{riesgo:"",aprendizaje:""},{riesgo:"",aprendizaje:""},{riesgo:"",aprendizaje:""},
  ]);
  const [plan,      setPlan]      = useState("");
  const [calientes, setCalientes] = useState("");
  const [visitas,   setVisitas]   = useState("");
  const [feedback,  setFeedback]  = useState("");
  const [nd,        setNd]        = useState(null);
  const [ndStatus,  setNdStatus]  = useState("loading");
  const [loading,   setLoading]   = useState(false);
  const [savedAt,   setSavedAt]   = useState(null);
  const [showHist,  setShowHist]  = useState(false);
  const [history,   setHistory]   = useState(() => {
    try { return JSON.parse(localStorage.getItem(HISTORY_KEY) || "[]"); } catch { return []; }
  });

  // Load draft on mount
  useEffect(() => {
    try {
      const d = JSON.parse(localStorage.getItem(DRAFT_KEY) || "{}");
      if (d.presentadoPor !== undefined) setPresentadoPor(d.presentadoPor);
      if (d.periodo)   setPeriodo(d.periodo);
      if (d.fecha)     setFecha(d.fecha);
      if (Array.isArray(d.avances) && d.avances.length === 4) setAvances(d.avances);
      if (Array.isArray(d.riesgos) && d.riesgos.length === 4) setRiesgos(d.riesgos);
      if (d.plan      !== undefined) setPlan(d.plan);
      if (d.calientes !== undefined) setCalientes(d.calientes);
      if (d.visitas   !== undefined) setVisitas(d.visitas);
      if (d.feedback  !== undefined) setFeedback(d.feedback);
    } catch(e) {}
  }, []);

  // Fetch Notion
  useEffect(() => {
    fetch("/api/notion")
      .then(r => r.json())
      .then(d => { setNd(d); setNdStatus(d.error ? "error" : "ok"); })
      .catch(() => setNdStatus("error"));
  }, []);

  // Auto-save draft
  useEffect(() => {
    const draft = { presentadoPor, periodo, fecha, avances, riesgos, plan, calientes, visitas, feedback };
    localStorage.setItem(DRAFT_KEY, JSON.stringify(draft));
    setSavedAt(new Date());
  }, [presentadoPor, periodo, fecha, avances, riesgos, plan, calientes, visitas, feedback]);

  const fs = computeFirestore(quotes);

  const loadFromHistory = (entry) => {
    const d = entry.data;
    if (d.presentadoPor !== undefined) setPresentadoPor(d.presentadoPor);
    if (d.periodo)   setPeriodo(d.periodo);
    if (d.fecha)     setFecha(d.fecha);
    if (Array.isArray(d.avances) && d.avances.length === 4) setAvances(d.avances);
    if (Array.isArray(d.riesgos) && d.riesgos.length === 4) setRiesgos(d.riesgos);
    if (d.plan      !== undefined) setPlan(d.plan);
    if (d.calientes !== undefined) setCalientes(d.calientes);
    if (d.visitas   !== undefined) setVisitas(d.visitas);
    if (d.feedback  !== undefined) setFeedback(d.feedback);
    setShowHist(false);
  };

  const generate = () => {
    setLoading(true);
    try {
      const formData = { presentadoPor, periodo, fecha, avances, riesgos, plan, calientes, visitas, feedback };
      const proyectosCalientes = calientes.split("\n").map(s=>s.trim()).filter(Boolean);
      const visitasList = visitas.split("\n").map(s=>s.trim()).filter(Boolean);
      const html = buildHTML({ ...formData, proyectosCalientes, visitas: visitasList, fs, nd });

      // Save to history
      const entry = { id: Date.now(), periodo, fechaCorte: fecha, generadoEn: new Date().toISOString(), data: formData };
      const newHistory = [entry, ...history].slice(0, 12);
      setHistory(newHistory);
      localStorage.setItem(HISTORY_KEY, JSON.stringify(newHistory));

      const blob = new Blob([html], { type:"text/html;charset=utf-8" });
      const a = document.createElement("a");
      a.href = URL.createObjectURL(blob);
      a.download = `INside_Informe_${periodo.replace(/\s+/g,"_")}.html`;
      a.click();
    } catch(e) {
      alert("Error al generar: " + e.message);
    } finally {
      setLoading(false);
    }
  };

  const notionBadge = ndStatus === "loading"
    ? <span style={{ fontSize:11,color:"var(--muted)" }}>Conectando con Notion…</span>
    : ndStatus === "error"
    ? <span style={{ fontSize:11,color:"var(--red)" }}>⚠ Error al conectar con Notion</span>
    : <span style={{ fontSize:11,color:"var(--green)" }}>
        ✓ Notion — {nd?.contacts?.total} contactos · {nd?.clients?.active} clientes activos · {nd?.projects?.total} proyectos
      </span>;

  const st = { background:"var(--surface)",border:"1px solid var(--border)",borderRadius:10,
    padding:"12px 16px",marginBottom:16,display:"flex",alignItems:"center",gap:10 };

  return (
    <div style={{ maxWidth:760,margin:"0 auto",padding:"32px 24px" }}>

      {/* Header */}
      <div style={{ display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:24 }}>
        <div>
          <div style={{ fontSize:22,fontWeight:700,color:"var(--ink)" }}>Informe de Gestión</div>
          <div style={{ fontSize:13,color:"var(--muted)",marginTop:4 }}>
            Presentación automática para la directiva
            {savedAt && <span style={{ marginLeft:10,fontSize:11,color:"var(--green)" }}>✓ Guardado</span>}
          </div>
        </div>
        <window.Btn variant="gold" icon="doc" onClick={generate} disabled={loading}>
          {loading ? "Generando…" : "Generar presentación"}
        </window.Btn>
      </div>

      {/* Notion status */}
      <div style={st}>
        <window.Icon name="history" size={14} />
        {notionBadge}
      </div>

      {/* History */}
      {history.length > 0 && (
        <div style={{ marginBottom:24,border:"1px solid var(--border)",borderRadius:10,overflow:"hidden" }}>
          <button onClick={() => setShowHist(!showHist)}
            style={{ width:"100%",padding:"11px 16px",display:"flex",alignItems:"center",
              justifyContent:"space-between",background:"var(--surface)",border:"none",
              cursor:"pointer",textAlign:"left" }}>
            <span style={{ fontSize:11,fontWeight:700,letterSpacing:".08em",
              textTransform:"uppercase",color:"var(--muted)" }}>
              Historial — {history.length} informe{history.length!==1?"s":""} generado{history.length!==1?"s":""}
            </span>
            <span style={{ fontSize:11,color:"var(--muted)" }}>{showHist ? "▲" : "▼"}</span>
          </button>
          {showHist && history.map(entry => (
            <div key={entry.id} style={{ display:"flex",alignItems:"center",justifyContent:"space-between",
              padding:"10px 16px",borderTop:"1px solid var(--border)",background:"var(--bg)" }}>
              <div>
                <div style={{ fontSize:13,fontWeight:600,color:"var(--ink)" }}>{entry.periodo}</div>
                <div style={{ fontSize:11,color:"var(--muted)",marginTop:2 }}>
                  Corte: {entry.fechaCorte} · Generado: {fmtHistDate(entry.generadoEn)}
                </div>
              </div>
              <button onClick={() => loadFromHistory(entry)}
                style={{ fontSize:11,fontFamily:"var(--mono)",padding:"5px 14px",borderRadius:6,
                  border:"1px solid var(--border)",background:"none",cursor:"pointer",color:"var(--ink)" }}>
                Cargar
              </button>
            </div>
          ))}
        </div>
      )}

      {/* KPI preview */}
      <Sect title="Resumen ejecutivo · Calculado automáticamente desde el cotizador">
        <div style={{ display:"grid",gridTemplateColumns:"repeat(3,1fr)",gap:10,marginBottom:8 }}>
          {[
            ["Cotizado total",    fmtUSD(fs.cotizado),      "todo lo emitido desde el inicio"],
            ["Ing. proyectados",  fmtUSD(fs.proyectados),   "En negociación"],
            ["Ing. generados",    fmtUSD(fs.generados),     "Adjudicados"],
            ["Ing. perdidos",     fmtUSD(fs.perdidos),      "No adjudicados"],
            ["Ing. pendientes",   fmtUSD(fs.pendientesSum), "Pendientes"],
            ["Margen promedio",   fmtPct(fs.wMargin),       "ponderado · todas las cots."],
            ["En negociación",    fs.enNeg+" proy.",        "propuesta enviada"],
            ["Adjudicados",       fs.ganados+" proy.",      "cerrados con éxito"],
            ["Tasa de cierre",    fs.totalCerradas>0 ? fs.tasaCierre.toFixed(0)+"%" : "—", `${fs.ganados} de ${fs.totalCerradas} cerradas`],
          ].map(([l,v,sub]) => (
            <div key={l} style={{ background:"var(--surface)",border:"1px solid var(--border)",
              borderRadius:8,padding:"10px 14px" }}>
              <div style={{ fontSize:9,fontWeight:700,letterSpacing:".1em",textTransform:"uppercase",
                color:"var(--muted)",marginBottom:4 }}>{l}</div>
              <div style={{ fontSize:16,fontWeight:700,color:"var(--ink)" }}>{v}</div>
              {sub && <div style={{ fontSize:10,color:"var(--muted)",marginTop:2 }}>{sub}</div>}
            </div>
          ))}
        </div>
        <div style={{ fontSize:11,color:"var(--muted)" }}>
          Datos en tiempo real del cotizador al momento de generar. Los datos de Notion se obtienen automáticamente.
        </div>
      </Sect>

      {/* Portada */}
      <Sect title="Portada" desc="Información que aparece en la primera diapositiva de la presentación.">
        <div style={{ display:"grid",gridTemplateColumns:"1fr 1fr 1fr",gap:16 }}>
          <Inp label="Período" value={periodo} onChange={setPeriodo} placeholder="ej. H1 2026" />
          <Inp label="Fecha de corte" value={fecha} onChange={setFecha} type="date" />
          <Inp label="Preparado por" value={presentadoPor} onChange={setPresentadoPor} placeholder="Tu nombre" />
        </div>
      </Sect>

      {/* Avances */}
      <Sect title="Avances estratégicos"
        desc="Describe los 4 logros más relevantes del período: lanzamientos, implementaciones, acuerdos clave o mejoras que hayan impactado el negocio.">
        {avances.map((a,i) => (
          <div key={i} style={{ background:"var(--surface)",border:"1px solid var(--border)",
            borderRadius:8,padding:"14px 16px",marginBottom:12 }}>
            <div style={{ fontSize:11,color:"var(--muted)",marginBottom:8,fontWeight:600 }}>Avance {i+1}</div>
            <Inp label="Título del logro" value={a.titulo}
              onChange={v=>setAvances(av=>av.map((x,j)=>j===i?{...x,titulo:v}:x))}
              placeholder="Ej. Sistema de cotización en producción" />
            <TA label="Descripción breve (qué se logró y por qué importa)" rows={2} value={a.desc}
              onChange={v=>setAvances(av=>av.map((x,j)=>j===i?{...x,desc:v}:x))}
              placeholder="Ej. Se implementó el cotizador digital reduciendo el tiempo de respuesta en un 70%." />
          </div>
        ))}
      </Sect>

      {/* Proyectos calientes */}
      <Sect title="Proyectos calientes"
        desc="Lista los proyectos con mayor probabilidad de cierre o más estratégicos para el próximo período. Aparecerán como etiquetas destacadas en la presentación.">
        <TA label="Un proyecto por línea" rows={5} value={calientes} onChange={setCalientes}
          placeholder={"BARCELONA\nGLOBAL BANK\nOFICINAS LOCATIONS\nCASA LÓPEZ"} />
      </Sect>

      {/* Riesgos */}
      <Sect title="Riesgos y aprendizajes"
        desc="Identifica 4 situaciones que presentaron fricción, riesgo o pérdida durante el período. Para cada una, describe qué aprendiste o cómo lo corregiste.">
        {riesgos.map((r,i) => (
          <div key={i} style={{ background:"var(--surface)",border:"1px solid var(--border)",
            borderRadius:8,padding:"14px 16px",marginBottom:12 }}>
            <div style={{ fontSize:11,color:"var(--muted)",marginBottom:8,fontWeight:600 }}>Situación {i+1}</div>
            <Inp label="Riesgo o situación" value={r.riesgo}
              onChange={v=>setRiesgos(rs=>rs.map((x,j)=>j===i?{...x,riesgo:v}:x))}
              placeholder="Ej. Concentración excesiva en 2 clientes grandes" />
            <TA label="Aprendizaje o acción tomada" rows={2} value={r.aprendizaje}
              onChange={v=>setRiesgos(rs=>rs.map((x,j)=>j===i?{...x,aprendizaje:v}:x))}
              placeholder="Ej. Se inició prospección activa en 3 nuevos sectores para diversificar." />
          </div>
        ))}
      </Sect>

      {/* Plan */}
      <Sect title="Plan siguiente período"
        desc="Acciones y visitas planeadas para el próximo semestre. Las visitas aparecen como etiquetas, los objetivos como texto libre.">
        <TA label="Próximas visitas / cuentas a visitar (una por línea)" rows={4} value={visitas} onChange={setVisitas}
          placeholder={"Bancos\nHoteles\nMallol\nBettis Tarazi"} />
        <TA label="Objetivos y acciones generales" rows={4} value={plan} onChange={setPlan}
          placeholder="Ej. Alcanzar $200K en adjudicaciones · Ampliar presencia en sector hospitalario · Cerrar 3 proyectos pendientes del H1." />
      </Sect>

      {/* Feedback */}
      <Sect title="Sugerencias y feedback"
        desc="Notas, preguntas o temas que quieras plantear a la directiva durante la presentación. Aparecen en la diapositiva final.">
        <TA label="Notas para la reunión" rows={4} value={feedback} onChange={setFeedback}
          placeholder="Ej. ¿Debemos ajustar el margen mínimo en proyectos grandes? · Solicitar presupuesto para feria de arquitectura." />
      </Sect>

      <div style={{ display:"flex",justifyContent:"flex-end",paddingTop:16,borderTop:"1px solid var(--border)" }}>
        <window.Btn variant="gold" icon="doc" onClick={generate} disabled={loading}>
          {loading ? "Generando…" : "Generar presentación"}
        </window.Btn>
      </div>
    </div>
  );
}

window.InformeView = InformeView;
