
const { useState, useEffect, useMemo, useRef } = React;

// -------------------------------------------------------------
// Utilidades de formato
// -------------------------------------------------------------
const fmtNum = (n) => (n !== undefined && n !== null ? Math.round(n).toLocaleString('es-CL') : '0');
const fmtUF = (n) => {
  if (n === undefined || n === null || isNaN(n)) return '0 UF';
  if (Math.abs(n) >= 1000000) return (n / 1000000).toFixed(2).replace('.', ',') + ' mill.';
  return Math.round(n).toLocaleString('es-CL') + ' UF';
};
const fmtPct = (n) => (n !== undefined && !isNaN(n) ? (n * 100).toFixed(1).replace('.', ',') + '%' : '0,0%');

// -------------------------------------------------------------
// Componente de Gráfico Apache ECharts
// -------------------------------------------------------------
function EChart({ option, height = '320px', onChartClick }) {
  const chartRef = useRef(null);
  const chartInstance = useRef(null);
  const prevWidth = useRef(null);

  useEffect(() => {
    if (!chartRef.current) return;
    if (!chartInstance.current) {
      chartInstance.current = echarts.init(chartRef.current);
    }
    chartInstance.current.setOption(option, true);

    if (onChartClick) {
      chartInstance.current.off('click');
      chartInstance.current.on('click', onChartClick);
    }

    const resizeObserver = new ResizeObserver((entries) => {
      for (let entry of entries) {
        const cr = entry.contentRect;
        if (prevWidth.current !== null && Math.abs(cr.width - prevWidth.current) > 2) {
          chartInstance.current?.resize();
        }
        prevWidth.current = cr.width;
      }
    });
    resizeObserver.observe(chartRef.current);

    const handleResize = () => chartInstance.current?.resize();
    window.addEventListener('resize', handleResize);

    return () => {
      resizeObserver.disconnect();
      window.removeEventListener('resize', handleResize);
    };
  }, [option, onChartClick]);

  useEffect(() => {
    return () => {
      chartInstance.current?.dispose();
      chartInstance.current = null;
    };
  }, []);

  return <div ref={chartRef} style={{ width: '100%', height }} />;
}

// -------------------------------------------------------------
// Aplicación Principal
// -------------------------------------------------------------

// -------------------------------------------------------------
// Función generadora de Plantilla HTML Oficial para Correos Gmail
// -------------------------------------------------------------
// -------------------------------------------------------------
// Función auxiliar para formatear fechas y reemplazar variables en textos
// -------------------------------------------------------------
function replaceDateVariables(text) {
  if (!text) return '';
  const now = new Date();
  const dia = String(now.getDate()).padStart(2, '0');
  const mesesNombre = [
    'Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio',
    'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'
  ];
  const mes = mesesNombre[now.getMonth()];
  const ano = String(now.getFullYear());
  const fecha = `${dia}-${String(now.getMonth() + 1).padStart(2, '0')}-${ano}`;

  return text
    .replace(/\(D[IÍ]A\)/gi, dia)
    .replace(/\{D[IÍ]A\}/gi, dia)
    .replace(/\(MES\)/gi, mes)
    .replace(/\{MES\}/gi, mes)
    .replace(/\(A[NÑ]O\)/gi, ano)
    .replace(/\{A[NÑ]O\}/gi, ano)
    .replace(/\(FECHA\)/gi, fecha)
    .replace(/\{FECHA\}/gi, fecha);
}

// -------------------------------------------------------------
// Función generadora de Plantilla HTML Oficial para Correos Gmail con Imágenes Inline (CID)
// -------------------------------------------------------------
function buildReportEmailHtml(schedule, metrics, chartImages = {}) {
  const rawIntro = schedule.emailIntro || 'Estimado equipo,\n\nCompartimos el reporte oficial de avance de escrituración correspondiente al período (DÍA) (MES) (AÑO).';
  const intro = replaceDateVariables(rawIntro).replace(/\n/g, '<br/>');

  const rawOutro = schedule.emailOutro || 'Saludos cordiales,\nControl de Gestión Fundamenta';
  const outro = replaceDateVariables(rawOutro).replace(/\n/g, '<br/>');

  const now = new Date();
  const dateStr = now.toLocaleDateString('es-CL', { day: '2-digit', month: '2-digit', year: 'numeric' });

  let blocks = '';

  // 1. Tarjetas KPI
  if ((schedule.elements || []).includes('kpis') && metrics) {
    blocks += `
    <div style="margin: 20px 0; padding: 16px; background-color: #f8fafc; border-radius: 12px; border: 1px solid #e2e8f0;">
      <div style="font-weight: bold; color: #064e3b; font-size: 13px; margin-bottom: 12px; border-bottom: 1px solid #cbd5e1; padding-bottom: 6px;">
        Cumplimiento de Metas Consolidadas YTD 2026
      </div>
      <table width="100%" cellpadding="0" cellspacing="0" border="0">
        <tr>
          <td width="48%" style="background-color: #ffffff; border: 1px solid #e2e8f0; border-radius: 8px; padding: 14px; text-align: center;">
            <span style="font-size: 11px; color: #64748b; text-transform: uppercase; font-weight: 600; display: block;">Cumplimiento Unidades YTD</span>
            <b style="font-size: 22px; color: #047857; display: block; margin: 4px 0;">${Math.round(metrics.pctCumplimientoUniMesVigente * 100)}%</b>
            <span style="font-size: 11px; color: #94a3b8;">${metrics.totalRealUni} de ${metrics.totalPptoUniMesVigente} un.</span>
          </td>
          <td width="4%"></td>
          <td width="48%" style="background-color: #ffffff; border: 1px solid #e2e8f0; border-radius: 8px; padding: 14px; text-align: center;">
            <span style="font-size: 11px; color: #64748b; text-transform: uppercase; font-weight: 600; display: block;">Cumplimiento UF YTD</span>
            <b style="font-size: 22px; color: #047857; display: block; margin: 4px 0;">${Math.round(metrics.pctCumplimientoUFMesVigente * 100)}%</b>
            <span style="font-size: 11px; color: #94a3b8;">${Math.round(metrics.totalRealUF).toLocaleString('es-CL')} UF</span>
          </td>
        </tr>
      </table>
    </div>`;
  }

  // 2. Gráficos Seleccionados insertados como imágenes reales (CID Inline)
  const chartConfigs = [
    { id: 'uni_parcial', title: 'Escrituras Parciales (Mes a Mes) · Unidades', cid: 'chart_uni_parcial@fundamenta' },
    { id: 'uni_acum', title: 'Escrituras Acumuladas YTD · Unidades', cid: 'chart_uni_acum@fundamenta' },
    { id: 'uf_parcial', title: 'Escrituras Parciales (Mes a Mes) · Monto UF', cid: 'chart_uf_parcial@fundamenta' },
    { id: 'uf_acum', title: 'Escrituras Acumuladas YTD · Monto UF', cid: 'chart_uf_acum@fundamenta' },
    { id: 'estados', title: 'Estado de Firmas por Proyecto (100% Apilado)', cid: 'chart_estados@fundamenta' }
  ];

  chartConfigs.forEach(cfg => {
    if ((schedule.elements || []).includes(cfg.id)) {
      const hasImage = Boolean(chartImages[cfg.id]);
      const imgSrc = hasImage ? `cid:${cfg.cid}` : '';
      if (hasImage) {
        blocks += `
        <div style="margin: 22px 0; border: 1px solid #e2e8f0; border-radius: 12px; overflow: hidden; background-color: #ffffff;">
          <div style="background-color: #064e3b; color: #ffffff; padding: 10px 14px; font-weight: bold; font-size: 12px; letter-spacing: 0.2px;">
            Gráfico: ${cfg.title}
          </div>
          <div style="padding: 12px; text-align: center; background-color: #ffffff;">
            <img src="${imgSrc}" alt="${cfg.title}" style="max-width: 100%; height: auto; display: block; margin: 0 auto; border-radius: 6px;" />
          </div>
        </div>`;
      }
    }
  });

  // 3. Tabla Desglose Unidades
  if ((schedule.elements || []).includes('uni_tabla') && metrics && metrics.projectBreakdown) {
    let rows = '';
    metrics.projectBreakdown.slice(0, 8).forEach(p => {
      const pct = p.pptoUni > 0 ? Math.round((p.realUni / p.pptoUni) * 100) : 0;
      const badgeBg = pct >= 90 ? '#d1fae5' : '#fef3c7';
      const badgeColor = pct >= 90 ? '#065f46' : '#92400e';
      rows += `
      <tr style="border-bottom: 1px solid #f1f5f9;">
        <td style="padding: 8px 10px; font-weight: 600; color: #1e293b;">${p.proyecto}</td>
        <td style="padding: 8px 10px; text-align: right; font-weight: bold; color: #047857;">${p.realUni}</td>
        <td style="padding: 8px 10px; text-align: right; color: #64748b;">${p.pptoUni}</td>
        <td style="padding: 8px 10px; text-align: right;">
          <span style="background-color: ${badgeBg}; color: ${badgeColor}; padding: 2px 6px; border-radius: 4px; font-weight: bold; font-size: 10px;">${pct}%</span>
        </td>
      </tr>`;
    });

    blocks += `
    <div style="margin: 20px 0; border: 1px solid #e2e8f0; border-radius: 10px; overflow: hidden;">
      <div style="background-color: #064e3b; color: #ffffff; padding: 10px 14px; font-weight: bold; font-size: 12px;">
        Tabla: Cumplimiento por Proyecto · Unidades (Mes Vigente: ${metrics.mesVigenteLabel} 2026)
      </div>
      <table width="100%" cellpadding="0" cellspacing="0" style="font-size: 11px; text-align: left;">
        <thead style="background-color: #f8fafc; color: #64748b; border-bottom: 1px solid #e2e8f0;">
          <tr>
            <th style="padding: 8px 10px;">Proyecto</th>
            <th style="padding: 8px 10px; text-align: right;">Real Unidades</th>
            <th style="padding: 8px 10px; text-align: right;">Ppto Mes</th>
            <th style="padding: 8px 10px; text-align: right;">% Cumpl.</th>
          </tr>
        </thead>
        <tbody>${rows}</tbody>
      </table>
    </div>`;
  }

  // 4. Tabla Desglose UF
  if ((schedule.elements || []).includes('uf_tabla') && metrics && metrics.projectBreakdown) {
    let rowsUF = '';
    metrics.projectBreakdown.slice(0, 8).forEach(p => {
      const pct = p.pptoUF > 0 ? Math.round((p.realUF / p.pptoUF) * 100) : 0;
      const badgeBg = pct >= 90 ? '#d1fae5' : '#fef3c7';
      const badgeColor = pct >= 90 ? '#065f46' : '#92400e';
      rowsUF += `
      <tr style="border-bottom: 1px solid #f1f5f9;">
        <td style="padding: 8px 10px; font-weight: 600; color: #1e293b;">${p.proyecto}</td>
        <td style="padding: 8px 10px; text-align: right; font-weight: bold; color: #047857;">${Math.round(p.realUF).toLocaleString('es-CL')}</td>
        <td style="padding: 8px 10px; text-align: right; color: #64748b;">${Math.round(p.pptoUF).toLocaleString('es-CL')}</td>
        <td style="padding: 8px 10px; text-align: right;">
          <span style="background-color: ${badgeBg}; color: ${badgeColor}; padding: 2px 6px; border-radius: 4px; font-weight: bold; font-size: 10px;">${pct}%</span>
        </td>
      </tr>`;
    });

    blocks += `
    <div style="margin: 20px 0; border: 1px solid #e2e8f0; border-radius: 10px; overflow: hidden;">
      <div style="background-color: #064e3b; color: #ffffff; padding: 10px 14px; font-weight: bold; font-size: 12px;">
        Tabla: Cumplimiento por Proyecto · Monto UF (Mes Vigente: ${metrics.mesVigenteLabel} 2026)
      </div>
      <table width="100%" cellpadding="0" cellspacing="0" style="font-size: 11px; text-align: left;">
        <thead style="background-color: #f8fafc; color: #64748b; border-bottom: 1px solid #e2e8f0;">
          <tr>
            <th style="padding: 8px 10px;">Proyecto</th>
            <th style="padding: 8px 10px; text-align: right;">Real UF</th>
            <th style="padding: 8px 10px; text-align: right;">Ppto UF</th>
            <th style="padding: 8px 10px; text-align: right;">% Cumpl.</th>
          </tr>
        </thead>
        <tbody>${rowsUF}</tbody>
      </table>
    </div>`;
  }

  return `
  <!DOCTYPE html>
  <html>
  <head><meta charset="utf-8"></head>
  <body style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; margin: 0; padding: 20px; background-color: #f1f5f9; color: #334155;">
    <div style="max-width: 650px; margin: 0 auto; background-color: #ffffff; border-radius: 14px; overflow: hidden; border: 1px solid #e2e8f0; box-shadow: 0 4px 6px -1px rgba(0,0,0,0.05);">
      <div style="background-color: #064e3b; padding: 20px 24px; color: #ffffff;">
        <table width="100%">
          <tr>
            <td>
              <b style="font-size: 18px; letter-spacing: 0.5px;">FUNDAMENTA</b><br/>
              <span style="font-size: 11px; color: #a7f3d0;">Reportería Automática · Control de Gestión</span>
            </td>
            <td align="right" style="font-size: 11px; color: #cbd5e1; font-family: monospace;">
              ${dateStr}
            </td>
          </tr>
        </table>
      </div>
      <div style="padding: 24px; font-size: 13px; line-height: 1.6; color: #334155;">
        <div>${intro}</div>
        ${blocks}
        <div style="margin-top: 24px; padding-top: 16px; border-top: 1px solid #e2e8f0; color: #475569; font-size: 12px;">${outro}</div>
        <div style="margin-top: 24px; padding: 18px; background-color: #f0fdf4; border: 1px solid #bbf7d0; border-radius: 10px; text-align: center;">
          <span style="font-size: 12px; color: #166534; font-weight: 600; display: block; margin-bottom: 8px;">
            Interactúa con los datos consolidados y filtros en el tablero oficial:
          </span>
          <a href="http://localhost:3000" style="display: inline-block; background-color: #047857; color: #ffffff; text-decoration: none; padding: 9px 18px; border-radius: 6px; font-weight: bold; font-size: 12px;">
            Abrir Plataforma Fundamenta
          </a>
        </div>
      </div>
      <div style="background-color: #f8fafc; padding: 12px 24px; border-top: 1px solid #e2e8f0; text-align: center; font-size: 10px; color: #94a3b8;">
        Este es un reporte oficial automatizado emitido por Grupo Fundamenta.
      </div>
    </div>
  </body>
  </html>`;
}

function App() {
  const [tab, setTab] = useState('unidades'); // 'unidades' | 'uf' | 'estados' | 'admin'
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [selectedProyectos, setSelectedProyectos] = useState([]);
  const [sidebarOpen, setSidebarOpen] = useState(true);
  const [filterModalOpen, setFilterModalOpen] = useState(false);
  const [viewModeUni, setViewModeUni] = useState('parcial'); // 'parcial' | 'acumulado'
  const [viewModeUF, setViewModeUF] = useState('parcial');   // 'parcial' | 'acumulado'
  const [escrituracionOpen, setEscrituracionOpen] = useState(true);
  const [drilldownModal, setDrilldownModal] = useState(null);

  // -------------------------------------------------------------
  // Autenticación estilo BSC · Exclusiva con Google Identity (GSI)
  // -------------------------------------------------------------
  const [currentUser, setCurrentUser] = useState(null);
  const [authChecking, setAuthChecking] = useState(true);
  const [loginError, setLoginError] = useState('');
  const [adminUsersList, setAdminUsersList] = useState([]);
  const [newAdminInput, setNewAdminInput] = useState('');
  const [newAdminRole, setNewAdminRole] = useState('admin');

  // Chequear sesión activa al arrancar (/api/auth/me)
  const checkSession = async () => {
    try {
      const res = await fetch('/api/auth/me');
      const data = await res.json();
      if (data && data.authenticated) {
        setCurrentUser({
          email: data.email,
          name: data.name,
          role: data.role,
          isAdmin: data.isAdmin
        });
      } else {
        // Fallback a localStorage por persistencia en refresh
        try {
          const saved = localStorage.getItem('fundamenta_auth_user');
          if (saved) setCurrentUser(JSON.parse(saved));
        } catch(e) {}
      }
    } catch(err) {
      console.warn('Error verificando sesión en servidor:', err);
    } finally {
      setAuthChecking(false);
    }
  };

  useEffect(() => {
    checkSession();
  }, []);

  // Cargar lista de usuarios administradores desde el servidor si es admin
  const fetchAdminUsers = async () => {
    try {
      const res = await fetch('/api/admin/users');
      if (res.ok) {
        const list = await res.json();
        setAdminUsersList(list);
      }
    } catch(e) {}
  };

  useEffect(() => {
    if (currentUser && currentUser.role === 'admin') {
      fetchAdminUsers();
    }
  }, [currentUser]);

  // Login con credencial de Google o con correo directo validado por el backend
  const handleGoogleCredential = async (resp) => {
    setLoginError('');
    try {
      const res = await fetch('/api/auth/google', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ credential: resp.credential })
      });
      const data = await res.json();
      if (!res.ok || !data.ok) {
        throw new Error(data.message || 'No fue posible validar la cuenta con Google.');
      }
      setCurrentUser(data.user);
      localStorage.setItem('fundamenta_auth_user', JSON.stringify(data.user));
    } catch(err) {
      setLoginError(err.message || 'Error al autenticar con Google.');
    }
  };



  // Inicializar Google Sign-In (GSI) estilo BSC
  useEffect(() => {
    if (!currentUser && window.google && window.google.accounts && window.google.accounts.id) {
      try {
        window.google.accounts.id.initialize({
          client_id: "418027069264-8ntj4skqd10ovgf3f3k3faffos96i4vo.apps.googleusercontent.com",
          callback: handleGoogleCredential
        });
        const btnContainer = document.getElementById('googleSignInBtn');
        if (btnContainer) {
          window.google.accounts.id.renderButton(btnContainer, {
            theme: "outline",
            size: "large",
            text: "signin_with",
            shape: "pill",
            width: 280
          });
        }
      } catch(e) {
        console.warn('GSI init:', e);
      }
    }
  }, [currentUser, authChecking]);

  const handleLogout = async () => {
    try {
      await fetch('/api/auth/logout', { method: 'POST' });
    } catch(e) {}
    setCurrentUser(null);
    localStorage.removeItem('fundamenta_auth_user');
  };

  // Filtros y búsqueda para el desglose de presupuestos en el panel admin
  const [adminReportSelected, setAdminReportSelected] = useState(null); // null muestra el catálogo de reportes (ej: Escrituración)
  const [adminPptoSearch, setAdminPptoSearch] = useState('');
  const [adminPptoYear, setAdminPptoYear] = useState('2026');
  const [adminPptoMetric, setAdminPptoMetric] = useState('all'); // 'all', 'UF', 'Unidades'
  const [editingPptoItem, setEditingPptoItem] = useState(null);
  const [newPptoModalOpen, setNewPptoModalOpen] = useState(false);

  // Estados de automatización de correos Gmail con persistencia
  const defaultSchedules = [
    {
      id: 1,
      name: 'Reporte Semanal de Escrituración',
      reportId: 'escrituracion', // 'escrituracion', 'ventas', etc.
      frequency: 'semanal', // 'diario', 'semanal', 'quincenal', 'mensual'
      days: ['1', '5'],
      time: '08:30',
      recipients: 'gerencia@fundamenta.cl, finanzas@fundamenta.cl',
      cc: 'tcarvallo@fundamenta.cl',
      subject: 'Reporte de Avance de Escrituración - Fundamenta',
      emailIntro: 'Estimado equipo,\n\nCompartimos el reporte oficial de avance de escrituración correspondiente al período, con el desglose de cumplimiento de metas en Unidades y montos UF.',
      emailOutro: 'Quedamos atentos a sus consultas y comentarios.\n\nSaludos cordiales,\nEquipo de Finanzas y Control de Gestión\nFundamenta',
      elements: ['kpis', 'uni_parcial', 'uf_parcial', 'uni_tabla', 'estados'],
      isActive: true
    },
    {
      id: 2,
      name: 'Flash Diario de Firmas',
      reportId: 'escrituracion',
      frequency: 'diario',
      days: ['1', '2', '3', '4', '5'],
      time: '18:00',
      recipients: 'comercial@fundamenta.cl, operaciones@fundamenta.cl',
      cc: 'tcarvallo@fundamenta.cl',
      subject: 'Flash Diario de Firmas y Escrituración - Fundamenta',
      emailIntro: 'Buenas tardes equipo,\n\nAdjuntamos el estado diario de avance en firmas y cumplimiento de escrituras al cierre de jornada.',
      emailOutro: 'Reporte generado automáticamente por la plataforma de reportería Fundamenta.\n\nSaludos,\nOperaciones Fundamenta',
      elements: ['kpis', 'estados', 'uni_acum'],
      isActive: true
    }
  ];
  const [schedules, setSchedules] = useState(() => {
    try {
      const saved = localStorage.getItem('fundamenta_schedules');
      return saved ? JSON.parse(saved) : defaultSchedules;
    } catch(e) {
      return defaultSchedules;
    }
  });

  // Guardar programaciones automáticamente al cambiar
  useEffect(() => {
    try {
      localStorage.setItem('fundamenta_schedules', JSON.stringify(schedules));
    } catch(e) {}
  }, [schedules]);

  const [editingSchedule, setEditingSchedule] = useState(null);
  const [gmailAccount, setGmailAccount] = useState(() => localStorage.getItem('fundamenta_gmail_user') || 'reportes@fundamenta.cl');
  const [gmailSenderName, setGmailSenderName] = useState(() => localStorage.getItem('fundamenta_gmail_sender_name') || 'Tomás Carvallo');
  const [gmailPass, setGmailPass] = useState(() => localStorage.getItem('fundamenta_gmail_pass') || '');
  const [gmailConnected, setGmailConnected] = useState(() => Boolean(localStorage.getItem('fundamenta_gmail_pass')));
  const [gmailModalOpen, setGmailModalOpen] = useState(false);
  const [gmailModalUser, setGmailModalUser] = useState(gmailAccount);
  const [gmailModalSenderName, setGmailModalSenderName] = useState(gmailSenderName);
  const [gmailModalPass, setGmailModalPass] = useState(gmailPass);
  const [gmailTesting, setGmailTesting] = useState(false);
  const [testSending, setTestSending] = useState(false);
  const [previewEmailModal, setPreviewEmailModal] = useState(null);

  // Función para capturar un gráfico de ECharts como PNG Base64 en alta definición
  const captureChartAsImage = (chartOption, width = 640, height = 340) => {
    return new Promise((resolve) => {
      try {
        const offscreenDiv = document.createElement('div');
        offscreenDiv.style.width = width + 'px';
        offscreenDiv.style.height = height + 'px';
        offscreenDiv.style.position = 'fixed';
        offscreenDiv.style.top = '-9999px';
        offscreenDiv.style.left = '-9999px';
        offscreenDiv.style.visibility = 'hidden';
        document.body.appendChild(offscreenDiv);

        // Sin animaciones para captura inmediata
        const staticOption = {
          ...chartOption,
          animation: false
        };

        const chart = echarts.init(offscreenDiv, null, { renderer: 'canvas', devicePixelRatio: 2 });
        chart.setOption(staticOption);

        setTimeout(() => {
          try {
            const dataUrl = chart.getDataURL({
              type: 'png',
              pixelRatio: 2,
              backgroundColor: '#ffffff'
            });
            chart.dispose();
            document.body.removeChild(offscreenDiv);
            resolve(dataUrl);
          } catch (e) {
            console.error('Error capturando gráfico:', e);
            try { chart.dispose(); } catch(_) {}
            try { document.body.removeChild(offscreenDiv); } catch(_) {}
            resolve(null);
          }
        }, 150);
      } catch (err) {
        console.error('Error inicializando captura:', err);
        resolve(null);
      }
    });
  };

  // Función real de despacho de correo vía API backend con soporte para captura de gráficos y remitente personalizado
  const sendActualEmail = async (scheduleItem) => {
    if (!gmailConnected || !gmailPass) {
      alert('Debes vincular una cuenta de Gmail con su Contraseña de Aplicación antes de realizar envíos.');
      setGmailModalOpen(true);
      return;
    }

    if (!scheduleItem.recipients || !scheduleItem.recipients.trim()) {
      alert('Por favor especifica al menos un destinatario en el campo "Para".');
      return;
    }

    setTestSending(true);
    try {
      // 1. Capturar en vivo los gráficos seleccionados como imágenes PNG
      const chartImages = {};
      const attachments = [];
      const elems = scheduleItem.elements || [];

      if (elems.includes('uni_parcial')) {
        const img = await captureChartAsImage(optUnidadesParcial, 640, 320);
        if (img) {
          chartImages['uni_parcial'] = img;
          attachments.push({ filename: 'grafico_unidades_mensual.png', content: img, cid: 'chart_uni_parcial@fundamenta' });
        }
      }
      if (elems.includes('uni_acum')) {
        const img = await captureChartAsImage(optUnidadesAcum, 640, 320);
        if (img) {
          chartImages['uni_acum'] = img;
          attachments.push({ filename: 'grafico_unidades_acumulado.png', content: img, cid: 'chart_uni_acum@fundamenta' });
        }
      }
      if (elems.includes('uf_parcial')) {
        const img = await captureChartAsImage(optUFParcial, 640, 320);
        if (img) {
          chartImages['uf_parcial'] = img;
          attachments.push({ filename: 'grafico_uf_mensual.png', content: img, cid: 'chart_uf_parcial@fundamenta' });
        }
      }
      if (elems.includes('uf_acum')) {
        const img = await captureChartAsImage(optUFAcum, 640, 320);
        if (img) {
          chartImages['uf_acum'] = img;
          attachments.push({ filename: 'grafico_uf_acumulado.png', content: img, cid: 'chart_uf_acum@fundamenta' });
        }
      }
      if (elems.includes('estados')) {
        const img = await captureChartAsImage(optEstadosFirma, 640, 480);
        if (img) {
          chartImages['estados'] = img;
          attachments.push({ filename: 'grafico_estados_firma.png', content: img, cid: 'chart_estados@fundamenta' });
        }
      }

      // 2. Generar el HTML final con las referencias CID a las imágenes y reemplazo de fechas
      const emailHtml = buildReportEmailHtml(scheduleItem, metrics, chartImages);
      const emailSubject = replaceDateVariables(scheduleItem.subject || 'Reporte de Escrituración - Fundamenta');

      const res = await fetch('/api/send-email', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          user: gmailAccount,
          pass: gmailPass,
          senderName: gmailSenderName,
          to: scheduleItem.recipients,
          cc: scheduleItem.cc || undefined,
          subject: emailSubject,
          html: emailHtml,
          attachments: attachments
        })
      });

      const dataRes = await res.json();
      if (dataRes.success) {
        const graficosCount = Object.keys(chartImages).length;
        alert('✓ ¡Correo despachado exitosamente a través de Gmail!\n\n' +
              '• Remitente: ' + gmailSenderName + ' <' + gmailAccount + '>\n' +
              '• Para: ' + scheduleItem.recipients + '\n' +
              '• Asunto: ' + emailSubject + '\n' +
              '• Gráficos incrustados: ' + (graficosCount > 0 ? graficosCount + ' capturas HD' : 'Ninguno seleccionado'));
      } else {
        alert('Error al despachar el correo: ' + (dataRes.error || 'Error desconocido'));
      }
    } catch (err) {
      alert('Error conectando con el servidor de correos: ' + err.message);
    } finally {
      setTestSending(false);
    }
  };

  // Función para obtener únicamente los proyectos activos con escrituras reales o presupuesto en 2026
  const getProyectos2026 = (d) => {
    if (!d) return [];
    const projs = new Set();

    // 1. Proyectos con escrituras reales en 2026 (departamentos con fecha de firma cliente en 2026)
    d.real.forEach(r => {
      const isDep = (r['Tipo Unidad'] || '').toLowerCase() === 'departamento';
      if (isDep && r['Fecha Firma Cliente']) {
        const parts = r['Fecha Firma Cliente'].split(' ')[0].split('-');
        if (parts[2] === '2026' && r['Unidades escrituradas'] === '1') {
          projs.add(r.Proyecto);
        }
      }
    });

    // 2. Proyectos que figuran en las planillas de presupuesto 2026
    d.unidadesPpto.forEach(p => {
      if (p.Proyecto) projs.add(p.Proyecto);
    });
    d.ufPpto.forEach(p => {
      if (p.Proyecto) projs.add(p.Proyecto);
    });

    return Array.from(projs).filter(Boolean).sort();
  };

  // Carga de datos iniciales con soporte para presupuestos modificados guardados y actualización automática en vivo
  useEffect(() => {
    const loadSnapshot = (isInterval = false) => {
      fetch('data/snapshot.json?t=' + Date.now())
        .then(res => res.json())
        .then(d => {
          let finalData = d;
          try {
            const savedPpto = localStorage.getItem('fundamenta_custom_ppto');
            if (savedPpto) {
              const parsed = JSON.parse(savedPpto);
              finalData = {
                ...d,
                unidadesPpto: parsed.unidadesPpto || d.unidadesPpto,
                ufPpto: parsed.ufPpto || d.ufPpto
              };
            }
          } catch (e) {
            console.error('Error recuperando presupuestos modificados:', e);
          }
          setData(finalData);
          if (!isInterval) {
            const projs2026 = getProyectos2026(finalData);
            setSelectedProyectos(projs2026);
            setLoading(false);
          }
        })
        .catch(err => {
          console.error('Error cargando snapshot:', err);
          if (!isInterval) setLoading(false);
        });
    };

    loadSnapshot(false);
    // Sondeo periódico cada 60 segundos para refrescar automáticamente la hora de sincronización y datos nuevos
    const timer = setInterval(() => loadSnapshot(true), 60000);
    return () => clearInterval(timer);
  }, []);

  // Función para guardar cambios de presupuestos tanto en estado como en localStorage
  const updateBudgets = (newUnidades, newUF) => {
    if (!data) return;
    const updated = { ...data, unidadesPpto: newUnidades, ufPpto: newUF };
    setData(updated);
    try {
      localStorage.setItem('fundamenta_custom_ppto', JSON.stringify({
        unidadesPpto: newUnidades,
        ufPpto: newUF
      }));
    } catch (e) {
      console.error('Error guardando presupuestos en localStorage:', e);
    }
  };

  // Función para restablecer presupuestos a los valores originales
  const resetBudgetsToOriginal = () => {
    if (confirm('¿Deseas restablecer todos los presupuestos a los valores originales de fábrica? Todos los cambios manuales y planillas importadas se descartarán.')) {
      localStorage.removeItem('fundamenta_custom_ppto');
      fetch('data/snapshot.json?t=' + Date.now())
        .then(res => res.json())
        .then(d => {
          setData(d);
          alert('✓ Presupuestos restablecidos exitosamente a los valores de fábrica.');
        })
        .catch(err => alert('Error recargando datos originales: ' + err.message));
    }
  };

  // Lista de todos los proyectos relevantes de 2026
  const allProyectos = useMemo(() => {
    return getProyectos2026(data);
  }, [data]);

  // Manejador de selección de proyectos (slicer)
  const toggleProyecto = (proj) => {
    if (selectedProyectos.includes(proj)) {
      if (selectedProyectos.length === 1) return; // evitar dejar vacío
      setSelectedProyectos(selectedProyectos.filter(p => p !== proj));
    } else {
      setSelectedProyectos([...selectedProyectos, proj]);
    }
  };

  const selectAllProyectos = () => {
    if (selectedProyectos.length === allProyectos.length) {
      setSelectedProyectos([allProyectos[0]]);
    } else {
      setSelectedProyectos([...allProyectos]);
    }
  };

  // -----------------------------------------------------------
  // Cálculos de Métricas y Agregaciones (Equivalente al motor DAX)
  // -----------------------------------------------------------
  const metrics = useMemo(() => {
    if (!data) return null;

    const MESES = [
      { key: '01', label: 'ene 2026', fullDate: '01-01-2026' },
      { key: '02', label: 'feb 2026', fullDate: '01-02-2026' },
      { key: '03', label: 'mar 2026', fullDate: '01-03-2026' },
      { key: '04', label: 'abr 2026', fullDate: '01-04-2026' },
      { key: '05', label: 'may 2026', fullDate: '01-05-2026' },
      { key: '06', label: 'jun 2026', fullDate: '01-06-2026' },
      { key: '07', label: 'jul 2026', fullDate: '01-07-2026' },
      { key: '08', label: 'ago 2026', fullDate: '01-08-2026' },
      { key: '09', label: 'sep 2026', fullDate: '01-09-2026' },
      { key: '10', label: 'oct 2026', fullDate: '01-10-2026' },
      { key: '11', label: 'nov 2026', fullDate: '01-11-2026' },
      { key: '12', label: 'dic 2026', fullDate: '01-12-2026' },
    ];

    // 1. Filtrar datos reales por proyectos seleccionados y Filtro Global de Informe: Tipo Unidad = departamento
    const filteredReal = data.real.filter(r => {
      const matchProj = selectedProyectos.includes(r.Proyecto);
      const isDep = (r['Tipo Unidad'] || '').toLowerCase() === 'departamento';
      return matchProj && isDep;
    });

    // 2. Presupuestos filtrados
    const filteredPptoUni = data.unidadesPpto.filter(p => selectedProyectos.includes(p.Proyecto));
    const filteredPptoUF = data.ufPpto.filter(p => selectedProyectos.includes(p.Proyecto));

    // Agrupación mensual
    const monthlyData = MESES.map((m, idx) => {
      // Real Unidades en el mes
      const realUni = filteredReal.filter(r => {
        if (!r['Fecha Firma Cliente']) return false;
        const [d, mo, y] = r['Fecha Firma Cliente'].split(' ')[0].split('-');
        return mo === m.key && y === '2026' && r['Unidades escrituradas'] === '1';
      }).length;

      // Real UF en el mes (solo departamentos con unidad escriturada = 1)
      const realUF = filteredReal.filter(r => {
        if (!r['Fecha Firma Cliente']) return false;
        const [d, mo, y] = r['Fecha Firma Cliente'].split(' ')[0].split('-');
        const isDep = (r['Tipo Unidad'] || '').toLowerCase() === 'departamento';
        return mo === m.key && y === '2026' && r['Unidades escrituradas'] === '1' && isDep;
      }).reduce((acc, r) => {
        const val = parseFloat((r['UF sin Abono Cliente'] || '0').replace(',', '.'));
        return acc + (isNaN(val) ? 0 : val);
      }, 0);

      // Ppto Unidades en el mes
      const pptoUni = filteredPptoUni.filter(p => p.Fecha.startsWith(m.fullDate))
        .reduce((acc, p) => acc + (parseInt(p.Unidades, 10) || 0), 0);

      // Ppto UF en el mes
      const pptoUF = filteredPptoUF.filter(p => p.Fecha.startsWith(m.fullDate))
        .reduce((acc, p) => {
          const val = parseFloat((p.UF || '0').replace(',', '.'));
          return acc + (isNaN(val) ? 0 : val);
        }, 0);

      return {
        mes: m.label,
        key: m.key,
        realUni,
        pptoUni,
        realUF,
        pptoUF
      };
    });

    // Determinar el último mes con datos reales registrados en 2026 (mes vigente)
    // Buscamos el mes más alto que tiene registros reales
    let currentMonthIdx = 0;
    monthlyData.forEach((m, idx) => {
      if (m.realUni > 0 || m.realUF > 0) {
        currentMonthIdx = Math.max(currentMonthIdx, idx);
      }
    });
    // currentMonthIdx corresponde al mes vigente (0-indexed, ej: 8 para sep 2026)
    const mesVigenteLabel = MESES[currentMonthIdx].label;

    // Calcular acumulados YTD
    let runRealUni = 0, runPptoUni = 0, runRealUF = 0, runPptoUF = 0;
    const accumulatedData = monthlyData.map(m => {
      runRealUni += m.realUni;
      runPptoUni += m.pptoUni;
      runRealUF += m.realUF;
      runPptoUF += m.pptoUF;
      return {
        mes: m.mes,
        accRealUni: runRealUni,
        accPptoUni: runPptoUni,
        accRealUF: runRealUF,
        accPptoUF: runPptoUF
      };
    });

    // 1. Métricas Totales al Mes Vigente (para Real vs Ppto acumulado a la fecha)
    const totalRealUni = runRealUni; // Real total ejecutado
    const totalPptoUniMesVigente = accumulatedData[currentMonthIdx].accPptoUni;
    const pctCumplimientoUniMesVigente = totalPptoUniMesVigente > 0 ? (totalRealUni / totalPptoUniMesVigente) : 0;

    const totalRealUF = runRealUF;
    const totalPptoUFMesVigente = accumulatedData[currentMonthIdx].accPptoUF;
    const pctCumplimientoUFMesVigente = totalPptoUFMesVigente > 0 ? (totalRealUF / totalPptoUFMesVigente) : 0;

    // 2. Metas Anuales Totales (los 12 meses presupuestados de 2026)
    const totalPptoUniAnual = runPptoUni;
    const pctCumplimientoUniAnual = totalPptoUniAnual > 0 ? (totalRealUni / totalPptoUniAnual) : 0;

    const totalPptoUFAnual = runPptoUF;
    const pctCumplimientoUFAnual = totalPptoUFAnual > 0 ? (totalRealUF / totalPptoUFAnual) : 0;

    // Desglose por Proyecto
    const projectBreakdown = selectedProyectos.map(proj => {
      const pReal = filteredReal.filter(r => r.Proyecto === proj);
      const pRealUni = pReal.filter(r => {
        if (!r['Fecha Firma Cliente']) return false;
        const [d, mo, y] = r['Fecha Firma Cliente'].split(' ')[0].split('-');
        return y === '2026' && r['Unidades escrituradas'] === '1';
      }).length;

      const pRealUF = pReal.filter(r => {
        if (!r['Fecha Firma Cliente']) return false;
        const [d, mo, y] = r['Fecha Firma Cliente'].split(' ')[0].split('-');
        const isDep = (r['Tipo Unidad'] || '').toLowerCase() === 'departamento';
        return y === '2026' && r['Unidades escrituradas'] === '1' && isDep;
      }).reduce((acc, r) => acc + (parseFloat((r['UF sin Abono Cliente'] || '0').replace(',', '.')) || 0), 0);

      // Presupuesto al mes vigente por proyecto
      const pPptoUniMesVigente = filteredPptoUni.filter(p => {
        if (p.Proyecto !== proj) return false;
        const m = parseInt(p.Fecha.split('-')[1], 10);
        return m <= (currentMonthIdx + 1);
      }).reduce((acc, p) => acc + (parseInt(p.Unidades, 10) || 0), 0);

      const pPptoUFMesVigente = filteredPptoUF.filter(p => {
        if (p.Proyecto !== proj) return false;
        const m = parseInt(p.Fecha.split('-')[1], 10);
        return m <= (currentMonthIdx + 1);
      }).reduce((acc, p) => acc + (parseFloat((p.UF || '0').replace(',', '.')) || 0), 0);

      // Meta anual por proyecto
      const pPptoUniAnual = filteredPptoUni.filter(p => p.Proyecto === proj)
        .reduce((acc, p) => acc + (parseInt(p.Unidades, 10) || 0), 0);

      const pPptoUFAnual = filteredPptoUF.filter(p => p.Proyecto === proj)
        .reduce((acc, p) => acc + (parseFloat((p.UF || '0').replace(',', '.')) || 0), 0);

      return {
        proyecto: proj,
        realUni: pRealUni,
        pptoUni: pPptoUniMesVigente,
        pptoUniAnual: pPptoUniAnual,
        realUF: pRealUF,
        pptoUF: pPptoUFMesVigente,
        pptoUFAnual: pPptoUFAnual
      };
    });

    // Conteo para gráfico de Estados de Firma
    const estadosPorProyecto = selectedProyectos.map(proj => {
      const pReal = filteredReal.filter(r => r.Proyecto === proj);
      const total = pReal.length || 1;
      const escriturada = pReal.filter(r => r['Estado de Firma'] === 'Escriturada').length;
      const firmadaCliente = pReal.filter(r => r['Estado de Firma'] === 'Firmada por cliente').length;
      const preescriturada = pReal.filter(r => r['Estado de Firma'] === 'Pre-escriturada').length;
      const promesada = pReal.filter(r => r['Estado de Firma'] === 'Promesada').length;
      const reservada = pReal.filter(r => r['Estado de Firma'] === 'Reservada').length;

      return {
        proyecto: proj,
        total: pReal.length,
        escriturada,
        firmadaCliente,
        preescriturada,
        promesada,
        reservada,
        pctEscriturada: (escriturada / total) * 100,
        pctFirmadaCliente: (firmadaCliente / total) * 100,
        pctPreescriturada: (preescriturada / total) * 100,
        pctPromesada: (promesada / total) * 100,
        pctReservada: (reservada / total) * 100,
      };
    });

    return {
      monthlyData,
      accumulatedData,
      mesVigenteLabel,
      totalRealUni,
      totalPptoUni: totalPptoUniMesVigente, // ppto al mes vigente
      pctCumplimientoUni: pctCumplimientoUniMesVigente,
      totalPptoUniAnual,
      pctCumplimientoUniAnual,
      totalRealUF,
      totalPptoUF: totalPptoUFMesVigente, // ppto al mes vigente
      pctCumplimientoUF: pctCumplimientoUFMesVigente,
      totalPptoUFAnual,
      pctCumplimientoUFAnual,
      projectBreakdown,
      estadosPorProyecto
    };
  }, [data, selectedProyectos]);

  
  // Manejador de click en gráfico de Unidades
  const handleUnidadesClick = (params) => {
    if (!data || !params) return;
    const mesLabel = params.name; // Ej: "mar 2026"
    const seriesName = params.seriesName; // 'Real unidades escrituradas' etc.
    const monthKey = metrics.monthlyData.find(m => m.mes === mesLabel)?.key;

    if (!monthKey) return;

    // Filtrar las ofertas de departamentos que corresponden a ese mes
    const records = data.real.filter(r => {
      const matchProj = selectedProyectos.includes(r.Proyecto);
      const isDep = (r['Tipo Unidad'] || '').toLowerCase() === 'departamento';
      if (!matchProj || !isDep || !r['Fecha Firma Cliente']) return false;
      const [d, mo, y] = r['Fecha Firma Cliente'].split(' ')[0].split('-');
      return mo === monthKey && y === '2026' && r['Unidades escrituradas'] === '1';
    });

    setDrilldownModal({
      title: `Detalle de Unidades Escrituradas · ${mesLabel}`,
      subtitle: `${records.length} unidades encontradas en proyectos seleccionados`,
      records
    });
  };

  // Manejador de click en gráfico de Estados de Firma
  const handleEstadosClick = (params) => {
    if (!data || !params || !params.data) return;
    const proj = params.data.proj;
    const stage = params.data.stage;

    const records = data.real.filter(r => {
      const matchProj = r.Proyecto === proj;
      const isDep = (r['Tipo Unidad'] || '').toLowerCase() === 'departamento';
      return matchProj && isDep && r['Estado de Firma'] === stage;
    });

    setDrilldownModal({
      title: `Detalle de Unidades: ${proj} · Estado: ${stage}`,
      subtitle: `${records.length} unidades encontradas`,
      records
    });
  };

  // Pantalla de Bloqueo y Autenticación Corporativa Exclusiva Google (Estilo BSC)
  if (!currentUser) {
    return (
      <div className="min-h-screen flex items-center justify-center bg-gradient-to-br from-emerald-950 via-emerald-900 to-slate-950 p-4 relative overflow-hidden font-sans">
        {/* Decoraciones de fondo */}
        <div className="absolute top-0 right-0 w-96 h-96 bg-emerald-500/10 rounded-full blur-3xl pointer-events-none"></div>
        <div className="absolute bottom-0 left-0 w-96 h-96 bg-emerald-400/5 rounded-full blur-3xl pointer-events-none"></div>

        <div className="max-w-md w-full bg-white rounded-3xl p-8 shadow-2xl border border-white/20 relative z-10 animate-in fade-in zoom-in-95 duration-200">
          <div className="text-center space-y-3 mb-6">
            <div className="w-16 h-16 rounded-2xl bg-emerald-900 flex items-center justify-center p-2.5 mx-auto shadow-lg shadow-emerald-950/20">
              <img src="/logo-fundamenta.png" alt="Fundamenta" className="w-full h-full object-contain" />
            </div>
            <div>
              <h2 className="text-xl font-bold text-gray-900 tracking-tight">Reportería Automática</h2>
              <p className="text-xs text-emerald-800 font-semibold mt-0.5">Control de Gestión</p>
            </div>
          </div>

          <div className="space-y-5">
            {loginError && (
              <div className="p-3 bg-red-50 border border-red-200 rounded-xl text-xs text-red-700 flex items-start gap-2 animate-in fade-in">
                <i className="bi bi-shield-x text-base text-red-600 flex-shrink-0 mt-0.5"></i>
                <div className="flex-1 font-medium leading-relaxed">{loginError}</div>
              </div>
            )}

            {/* Contenedor oficial Google Sign-In (GSI) estilo BSC */}
            <div className="p-4 flex flex-col items-center justify-center text-center">
              <div id="googleSignInBtn" className="min-h-[44px] flex items-center justify-center"></div>
            </div>
          </div>
        </div>
      </div>
    );
  }

  if (loading) {
    return (
      <div className="flex items-center justify-center min-h-screen">
        <div className="text-center">
          <div className="w-12 h-12 border-4 border-emerald-600 border-t-transparent rounded-full animate-spin mx-auto mb-4"></div>
          <p className="text-gray-600 font-medium">Cargando reporte de escrituración...</p>
        </div>
      </div>
    );
  }

  // Opciones de Gráficos ECharts
  const optUnidadesParcial = {
    tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' } },
    legend: { data: ['Real unidades escrituradas', 'Ppto unidades escrituradas'], top: 0 },
    grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true },
    xAxis: { type: 'category', data: metrics.monthlyData.slice(0, 9).map(m => m.mes) },
    yAxis: { type: 'value' },
    series: [
      {
        name: 'Real unidades escrituradas',
        type: 'bar',
        data: metrics.monthlyData.slice(0, 9).map(m => m.realUni),
        itemStyle: { color: '#22c55e', borderRadius: [4, 4, 0, 0] },
        label: { show: true, position: 'top', fontSize: 11 }
      },
      {
        name: 'Ppto unidades escrituradas',
        type: 'bar',
        data: metrics.monthlyData.slice(0, 9).map(m => m.pptoUni),
        itemStyle: { color: '#14532d', borderRadius: [4, 4, 0, 0] },
        label: { show: true, position: 'top', fontSize: 11 }
      }
    ]
  };

  const optUnidadesAcum = {
    tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' } },
    legend: { data: ['Real Unidades Acumuladas', 'Ppto Unidades acumuladas'], top: 0 },
    grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true },
    xAxis: { type: 'category', data: metrics.accumulatedData.slice(0, 9).map(m => m.mes) },
    yAxis: { type: 'value' },
    series: [
      {
        name: 'Real Unidades Acumuladas',
        type: 'bar',
        data: metrics.accumulatedData.slice(0, 9).map(m => m.accRealUni),
        itemStyle: { color: '#38bdf8', borderRadius: [4, 4, 0, 0] },
        label: { show: true, position: 'top', fontSize: 11 }
      },
      {
        name: 'Ppto Unidades acumuladas',
        type: 'bar',
        data: metrics.accumulatedData.slice(0, 9).map(m => m.accPptoUni),
        itemStyle: { color: '#1e3a8a', borderRadius: [4, 4, 0, 0] },
        label: { show: true, position: 'top', fontSize: 11 }
      }
    ]
  };

  const optUFParcial = {
    tooltip: {
      trigger: 'axis',
      axisPointer: { type: 'shadow' },
      formatter: (params) => {
        let tip = params[0].name + '<br/>';
        params.forEach(p => {
          tip += p.marker + ' ' + p.seriesName + ': <b>' + fmtUF(p.value) + '</b><br/>';
        });
        return tip;
      }
    },
    legend: { data: ['Total UF Escrituradas', 'Total Ppto UF'], top: 0 },
    grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true },
    xAxis: { type: 'category', data: metrics.monthlyData.slice(0, 9).map(m => m.mes) },
    yAxis: {
      type: 'value',
      axisLabel: { formatter: (v) => (v / 1000000).toFixed(1) + ' mill.' }
    },
    series: [
      {
        name: 'Total UF Escrituradas',
        type: 'bar',
        data: metrics.monthlyData.slice(0, 9).map(m => m.realUF),
        itemStyle: { color: '#22c55e', borderRadius: [4, 4, 0, 0] },
        label: {
          show: true,
          position: 'top',
          fontSize: 10,
          formatter: (p) => (p.value / 1000000).toFixed(2).replace('.', ',') + ' mill.'
        }
      },
      {
        name: 'Total Ppto UF',
        type: 'bar',
        data: metrics.monthlyData.slice(0, 9).map(m => m.pptoUF),
        itemStyle: { color: '#14532d', borderRadius: [4, 4, 0, 0] },
        label: {
          show: true,
          position: 'top',
          fontSize: 10,
          formatter: (p) => (p.value / 1000000).toFixed(2).replace('.', ',') + ' mill.'
        }
      }
    ]
  };

  const optUFAcum = {
    tooltip: {
      trigger: 'axis',
      axisPointer: { type: 'shadow' },
      formatter: (params) => {
        let tip = params[0].name + '<br/>';
        params.forEach(p => {
          tip += p.marker + ' ' + p.seriesName + ': <b>' + fmtUF(p.value) + '</b><br/>';
        });
        return tip;
      }
    },
    legend: { data: ['Real UF Acumuladas', 'Ppto UF acumuladas'], top: 0 },
    grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true },
    xAxis: { type: 'category', data: metrics.accumulatedData.slice(0, 9).map(m => m.mes) },
    yAxis: {
      type: 'value',
      axisLabel: { formatter: (v) => (v / 1000000).toFixed(1) + ' mill.' }
    },
    series: [
      {
        name: 'Real UF Acumuladas',
        type: 'bar',
        data: metrics.accumulatedData.slice(0, 9).map(m => m.accRealUF),
        itemStyle: { color: '#22c55e', borderRadius: [4, 4, 0, 0] },
        label: {
          show: true,
          position: 'top',
          fontSize: 10,
          formatter: (p) => (p.value / 1000000).toFixed(1).replace('.', ',') + ' mill.'
        }
      },
      {
        name: 'Ppto UF acumuladas',
        type: 'bar',
        data: metrics.accumulatedData.slice(0, 9).map(m => m.accPptoUF),
        itemStyle: { color: '#14532d', borderRadius: [4, 4, 0, 0] },
        label: {
          show: true,
          position: 'top',
          fontSize: 10,
          formatter: (p) => (p.value / 1000000).toFixed(1).replace('.', ',') + ' mill.'
        }
      }
    ]
  };

  const optEstadosFirma = {
    animation: true,
    animationDuration: 400,
    animationEasing: 'cubicOut',
    animationThreshold: 5000,
    tooltip: {
      trigger: 'axis',
      axisPointer: { type: 'shadow' },
      formatter: (params) => {
        let tip = '<div style="font-size:13px; font-weight:bold; margin-bottom:4px; color:#111827;">' + params[0].name + '</div>';
        params.forEach(p => {
          const rawUnits = p.data && p.data.raw !== undefined ? Math.round(p.data.raw) : Math.round(p.value);
          const pct = typeof p.value === 'number' ? p.value.toFixed(1).replace('.', ',') + '%' : '';
          tip += '<div style="display:flex; justify-content:space-between; gap:16px; font-size:12px; margin:2px 0;">'
              + '<span>' + p.marker + ' ' + p.seriesName + '</span>'
              + '<b>' + rawUnits.toLocaleString('es-CL') + ' un. (' + pct + ')</b>'
              + '</div>';
        });
        return tip;
      }
    },
    legend: {
      data: ['Escriturada', 'Firmada por cliente', 'Pre-escriturada', 'Promesada', 'Reservada'],
      top: 0
    },
    grid: { left: '15%', right: '4%', top: '35px', bottom: '3%', containLabel: true },
    xAxis: { type: 'value', max: 100, axisLabel: { formatter: '{value}%' } },
    yAxis: {
      type: 'category',
      data: metrics.estadosPorProyecto.map(e => e.proyecto),
      inverse: true
    },
    series: [
      {
        name: 'Escriturada',
        type: 'bar',
        stack: 'total',
        animationDelay: 0,
        animationDuration: 350,
        itemStyle: { color: '#22c55e' },
        data: metrics.estadosPorProyecto.map(e => ({ value: e.pctEscriturada, raw: e.escriturada, proj: e.proyecto, stage: 'Escriturada' })),
        label: { show: true, position: 'inside', formatter: (p) => p.data.raw > 0 ? Math.round(p.data.raw) : '' }
      },
      {
        name: 'Firmada por cliente',
        type: 'bar',
        stack: 'total',
        animationDelay: 350,
        animationDuration: 350,
        itemStyle: { color: '#eab308' },
        data: metrics.estadosPorProyecto.map(e => ({ value: e.pctFirmadaCliente, raw: e.firmadaCliente, proj: e.proyecto, stage: 'Firmada por cliente' })),
        label: { show: true, position: 'inside', formatter: (p) => p.data.raw > 0 ? Math.round(p.data.raw) : '' }
      },
      {
        name: 'Pre-escriturada',
        type: 'bar',
        stack: 'total',
        animationDelay: 700,
        animationDuration: 350,
        itemStyle: { color: '#f97316' },
        data: metrics.estadosPorProyecto.map(e => ({ value: e.pctPreescriturada, raw: e.preescriturada, proj: e.proyecto, stage: 'Pre-escriturada' })),
        label: { show: true, position: 'inside', formatter: (p) => p.data.raw > 0 ? Math.round(p.data.raw) : '' }
      },
      {
        name: 'Promesada',
        type: 'bar',
        stack: 'total',
        animationDelay: 1050,
        animationDuration: 350,
        itemStyle: { color: '#881337' },
        data: metrics.estadosPorProyecto.map(e => ({ value: e.pctPromesada, raw: e.promesada, proj: e.proyecto, stage: 'Promesada' })),
        label: { show: true, position: 'inside', formatter: (p) => p.data.raw > 0 ? Math.round(p.data.raw) : '' }
      },
      {
        name: 'Reservada',
        type: 'bar',
        stack: 'total',
        animationDelay: 1400,
        animationDuration: 350,
        itemStyle: { color: '#0f172a' },
        data: metrics.estadosPorProyecto.map(e => ({ value: e.pctReservada, raw: e.reservada, proj: e.proyecto, stage: 'Reservada' })),
        label: { show: true, position: 'inside', formatter: (p) => p.data.raw > 0 ? Math.round(p.data.raw) : '' }
      }
    ]
  };

  return (
    <div className="flex h-screen overflow-hidden bg-gray-50">
      {/* Sidebar Lateral */}
      {/* Sidebar Lateral Izquierda Desplegable */}
      <aside className={`sidebar-gradient text-white flex flex-col flex-shrink-0 z-30 transition-all duration-300 ease-in-out ${sidebarOpen ? 'w-64' : 'w-0 overflow-hidden'}`}>
        <div className="p-5 border-b border-emerald-800 flex items-center justify-between">
          <div className="flex items-center gap-3">
            <div className="w-9 h-9 rounded-lg bg-white/10 flex items-center justify-center p-1.5 flex-shrink-0">
              <img src="/logo-fundamenta.png" alt="Fundamenta" className="w-full h-full object-contain" />
            </div>
            <div>
              <h1 className="font-bold text-sm tracking-wide">Fundamenta</h1>
              <p className="text-xs text-emerald-300/80">Reportería Automática</p>
            </div>
          </div>
          <button
            onClick={() => setSidebarOpen(false)}
            className="text-emerald-300/70 hover:text-white p-1 rounded-lg hover:bg-white/10 transition text-sm"
            title="Ocultar menú lateral"
          >
            <i className="bi bi-chevron-left"></i>
          </button>
        </div>

        <nav className="flex-1 p-4 space-y-1 overflow-y-auto">
          <div className="text-[11px] font-semibold text-emerald-300/60 uppercase tracking-wider px-3 mb-2">
            Módulos
          </div>

          {/* Grupo Acordeón: Escrituración */}
          <div className="space-y-1">
            <button
              onClick={() => setEscrituracionOpen(!escrituracionOpen)}
              className="w-full flex items-center justify-between px-3 py-2 rounded-lg text-sm font-bold text-white hover:bg-white/10 transition"
            >
              <div className="flex items-center gap-2.5">
                <i className="bi bi-folder2-open text-emerald-300"></i>
                <span>Escrituración</span>
              </div>
              <i className={`bi bi-chevron-down text-xs text-emerald-300 transition-transform duration-200 ${escrituracionOpen ? 'rotate-0' : '-rotate-90'}`}></i>
            </button>

            {escrituracionOpen && (
              <div className="pl-3 space-y-1 border-l-2 border-emerald-700/60 ml-3">
                <button
                  onClick={() => setTab('unidades')}
                  className={"w-full flex items-center gap-2.5 px-3 py-2 rounded-lg text-xs font-semibold transition " + (tab === 'unidades' ? 'bg-white text-emerald-900 shadow' : 'text-emerald-100/90 hover:bg-white/10')}
                >
                  <i className="bi bi-buildings"></i>
                  <span>Real / Ppto - Unidades</span>
                </button>
                <button
                  onClick={() => setTab('uf')}
                  className={"w-full flex items-center gap-2.5 px-3 py-2 rounded-lg text-xs font-semibold transition " + (tab === 'uf' ? 'bg-white text-emerald-900 shadow' : 'text-emerald-100/90 hover:bg-white/10')}
                >
                  <i className="bi bi-cash-stack"></i>
                  <span>Real / Ppto - UF</span>
                </button>
                <button
                  onClick={() => setTab('estados')}
                  className={"w-full flex items-center gap-2.5 px-3 py-2 rounded-lg text-xs font-semibold transition " + (tab === 'estados' ? 'bg-white text-emerald-900 shadow' : 'text-emerald-100/90 hover:bg-white/10')}
                >
                  <i className="bi bi-bar-chart-steps"></i>
                  <span>Estado de Firmas</span>
                </button>
              </div>
            )}
          </div>

          <div className="text-[11px] font-semibold text-emerald-300/60 uppercase tracking-wider px-3 pt-6 mb-2">
            Automatización y Gestión
          </div>
          <button
            onClick={() => setTab('email')}
            className={"w-full flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm font-medium transition " + (tab === 'email' ? 'bg-white text-emerald-900 shadow' : 'text-emerald-100 hover:bg-white/10')}
          >
            <i className="bi bi-envelope-paper"></i>
            <span>Gestionar Reportes</span>
          </button>

          {/* Configuración de Presupuestos solo visible para Administradores */}
          {currentUser.role === 'admin' && (
            <button
              onClick={() => { setTab('admin'); setAdminReportSelected(null); }}
              className={"w-full flex items-center justify-between px-3 py-2.5 rounded-lg text-sm font-medium transition " + (tab === 'admin' ? 'bg-white text-emerald-900 shadow' : 'text-emerald-100 hover:bg-white/10')}
            >
              <div className="flex items-center gap-3">
                <i className="bi bi-sliders2-vertical"></i>
                <span>Gestión de Presupuestos</span>
              </div>
              <span className="text-[9px] bg-emerald-800 text-emerald-200 px-1.5 py-0.5 rounded font-bold border border-emerald-600">Admin</span>
            </button>
          )}
        </nav>

        {/* Footer Sidebar con estado del Cron de sincronización y última hora de chequeo */}
        <div className="p-4 border-t border-emerald-800/60 text-xs text-emerald-200/80">
          <div className="flex items-center gap-2 mb-1.5">
            <span className="w-2 h-2 rounded-full bg-emerald-400 animate-pulse"></span>
            <span className="font-semibold text-white">Sync Automático</span>
          </div>
          <div className="bg-emerald-950/40 p-2 rounded-lg border border-emerald-700/50 mb-2">
            <span className="text-[10px] text-emerald-300/80 block uppercase tracking-wider font-bold">Último Chequeo CRM:</span>
            <b className="text-white text-[12px] block">
              {data && data.timestamp ? (() => {
                const d = new Date(data.timestamp);
                return d.toLocaleDateString('es-CL', { day: '2-digit', month: '2-digit', year: 'numeric' }) + ' ' + 
                       d.toLocaleTimeString('es-CL', { hour: '2-digit', minute: '2-digit' }) + ' hrs';
              })() : 'Cargando...'}
            </b>
          </div>
          <p className="text-[11px] text-emerald-300/70">Horarios: 9:00 · 13:00 · 17:00 (Chile)</p>
          <p className="text-[10px] text-emerald-400/90 mt-0.5">Conectado a SugarCRM RDS</p>
        </div>
      </aside>

      {/* Contenido Principal */}
      <div className="flex-1 flex flex-col min-w-0 overflow-hidden">
        {/* Barra Superior */}
        <header className="bg-white border-b border-gray-200 px-6 py-3.5 flex items-center justify-between flex-shrink-0">
          <div className="flex items-center gap-4">
            {!sidebarOpen && (
              <button
                onClick={() => setSidebarOpen(true)}
                className="p-2 text-gray-600 hover:text-emerald-800 hover:bg-emerald-50 rounded-lg border border-gray-200 transition shadow-sm"
                title="Mostrar menú lateral"
              >
                <i className="bi bi-layout-sidebar text-base"></i>
              </button>
            )}
            <div>
              <h2 className="text-lg font-bold text-gray-900">
                {tab === 'unidades' && 'ESCRITURACIÓN REAL / PPTO - Unidades'}
                {tab === 'uf' && 'ESCRITURACIÓN REAL / PPTO - UF'}
                {tab === 'estados' && 'Recuento de Estado de Firma por Proyecto'}
                {tab === 'admin' && 'Panel de Administración de Presupuestos'}
                {tab === 'email' && 'Automatización de Reportes por Gmail'}
              </h2>
              <p className="text-xs text-gray-500">Datos consolidados año 2026 · Actualización independiente</p>
            </div>
          </div>

          <div className="flex items-center gap-2.5">
            {/* Indicador de Última Verificación de Datos CRM en Taskbar */}
            <div className="hidden lg:flex items-center gap-2 px-3 py-1.5 bg-gray-50 border border-gray-200 rounded-xl text-xs text-gray-600" title="Hora de la última verificación automática con SugarCRM RDS">
              <span className="w-2 h-2 rounded-full bg-emerald-500 animate-pulse"></span>
              <span className="text-[11px] text-gray-400 font-medium">Último chequeo:</span>
              <b className="text-[11px] font-bold text-gray-800 font-mono">
                {data && data.timestamp ? (() => {
                  const d = new Date(data.timestamp);
                  return d.toLocaleTimeString('es-CL', { hour: '2-digit', minute: '2-digit' }) + ' hrs';
                })() : '--:--'}
              </b>
            </div>

            {/* Botón en Taskbar para ir directamente a Gestionar Reportes / Programar Envío */}
            <button
              onClick={() => setTab('email')}
              className={"flex items-center gap-2 px-3.5 py-1.5 rounded-xl text-xs font-semibold transition shadow-sm border " + (tab === 'email' ? 'bg-emerald-700 text-white border-emerald-800 ring-2 ring-emerald-400/30' : 'bg-white hover:bg-emerald-50 text-emerald-800 border-emerald-300')}
              title="Ir al módulo de automatización y gestión de reportes de correo"
            >
              <i className="bi bi-send-check text-sm"></i>
              <span className="hidden sm:inline">Gestionar Reportes</span>
              <span className="bg-emerald-100 text-emerald-800 text-[10px] px-1.5 py-0.2 rounded-full font-bold border border-emerald-200">
                {schedules.filter(s => s.isActive).length} activos
              </span>
            </button>

            {/* Perfil del Usuario Autenticado y Salir */}
            <div className="flex items-center gap-2 bg-gray-50 pl-3 pr-1.5 py-1 rounded-xl border border-gray-200">
              <div className="flex items-center gap-1.5">
                <span className={"w-2 h-2 rounded-full " + (currentUser.role === 'admin' ? 'bg-emerald-500' : 'bg-blue-500')}></span>
                <div className="flex flex-col text-left">
                  <span className="text-[11px] font-bold text-gray-800 leading-tight max-w-[120px] truncate" title={currentUser.email}>
                    {currentUser.name || currentUser.email.split('@')[0]}
                  </span>
                  <span className={"text-[9px] font-bold uppercase " + (currentUser.role === 'admin' ? 'text-emerald-700' : 'text-blue-700')}>
                    {currentUser.role === 'admin' ? 'Administrador' : 'Visualizador'}
                  </span>
                </div>
              </div>
              
              <button
                type="button"
                onClick={() => {
                  if (confirm('¿Deseas cerrar tu sesión corporativa?')) {
                    handleLogout();
                  }
                }}
                className="p-1 text-gray-400 hover:text-red-600 rounded-lg hover:bg-gray-200/60 transition ml-1"
                title="Cerrar sesión segura"
              >
                <i className="bi bi-box-arrow-right text-sm"></i>
              </button>
            </div>

            <button
              onClick={() => setFilterModalOpen(true)}
              className="flex items-center gap-2 px-3.5 py-1.5 bg-emerald-50 hover:bg-emerald-100 text-emerald-800 border border-emerald-300/80 rounded-xl text-xs font-semibold transition shadow-sm"
            >
              <i className="bi bi-funnel text-sm"></i>
              <span>Filtro por Proyecto</span>
              <span className="bg-emerald-700 text-white text-[10px] px-2 py-0.5 rounded-full font-bold">
                {selectedProyectos.length === allProyectos.length ? 'Todos' : selectedProyectos.length}
              </span>
            </button>
          </div>
        </header>

        {/* Cuerpo con Scroll y Slicer */}
        <div className="flex-1 flex overflow-hidden">
          {/* Área de Visualizaciones */}
          <main className="flex-1 overflow-y-auto p-6 space-y-6">
            {tab === 'unidades' && (
              <div className="space-y-6">
                {/* FILA 1: Gráfico Principal a Ancho Completo con Selector Acumulado / Parcial */}
                <div className="bg-white p-6 rounded-2xl border border-gray-200 card-shadow">
                  <div className="flex flex-col sm:flex-row sm:items-center justify-between gap-3 mb-4 pb-3 border-b border-gray-100">
                    <div>
                      <h3 className="text-base font-bold text-gray-900">
                        {viewModeUni === 'parcial'
                          ? 'Comparativo Escrituras Parciales (Mes a Mes) · Unidades'
                          : 'Comparativo Escrituras Acumuladas (YTD) · Unidades'}
                      </h3>
                      <p className="text-xs text-gray-500 mt-0.5">
                        {viewModeUni === 'parcial'
                          ? 'Evolución mensual comparando Unidades Reales vs Presupuesto'
                          : 'Progresión acumulada anual comparando ritmo de escrituración'}
                      </p>
                    </div>

                    {/* Botón Selector Toggle: Parcial vs Acumulado */}
                    <div className="inline-flex p-1 bg-gray-100/90 rounded-xl border border-gray-200 self-start sm:self-auto">
                      <button
                        type="button"
                        onClick={() => setViewModeUni('parcial')}
                        className={`px-4 py-1.5 rounded-lg text-xs font-bold transition-all duration-200 ${viewModeUni === 'parcial' ? 'bg-white text-emerald-800 shadow-sm' : 'text-gray-600 hover:text-gray-900'}`}
                      >
                        <i className="bi bi-bar-chart-fill mr-1.5"></i>
                        Mes a Mes (Parcial)
                      </button>
                      <button
                        type="button"
                        onClick={() => setViewModeUni('acumulado')}
                        className={`px-4 py-1.5 rounded-lg text-xs font-bold transition-all duration-200 ${viewModeUni === 'acumulado' ? 'bg-white text-emerald-800 shadow-sm' : 'text-gray-600 hover:text-gray-900'}`}
                      >
                        <i className="bi bi-graph-up-arrow mr-1.5"></i>
                        Acumulado (YTD)
                      </button>
                    </div>
                  </div>

                  {/* Renderizado de gráfico dinámico a todo el ancho */}
                  <EChart
                    option={viewModeUni === 'parcial' ? optUnidadesParcial : optUnidadesAcum}
                    height="380px"
                    onChartClick={handleUnidadesClick}
                  />
                </div>

                {/* FILA 2: Tarjetas KPI + Tablas Debajo en Segunda Fila */}
                <div className="grid grid-cols-1 lg:grid-cols-12 gap-6 items-stretch">
                  {/* Tarjeta 1: % Cumplimiento Real vs Ppto al Mes Vigente */}
                  <div className="lg:col-span-3 bg-white p-5 rounded-2xl border border-gray-200 card-shadow flex flex-col justify-between text-center kpi-gradient">
                    <div>
                      <div className="flex items-center justify-between gap-1 mb-1">
                        <span className="text-[11px] font-bold uppercase tracking-wider text-gray-500">
                          % Cumplimiento a la Fecha
                        </span>
                        <span className="px-2 py-0.5 bg-emerald-100 text-emerald-800 rounded-full text-[10px] font-bold">
                          {metrics.mesVigenteLabel}
                        </span>
                      </div>
                      <div className="text-4xl font-extrabold text-emerald-800 my-2">
                        {fmtPct(metrics.pctCumplimientoUni)}
                      </div>
                      <div className="w-full bg-gray-200 h-2 rounded-full overflow-hidden my-2.5 max-w-[200px] mx-auto">
                        <div
                          className="bg-emerald-600 h-full rounded-full transition-all duration-700"
                          style={{ width: Math.min(100, metrics.pctCumplimientoUni * 100) + '%' }}
                        ></div>
                      </div>
                      <p className="text-[11px] text-gray-500">
                        Real vs Presupuesto acumulado al mes vigente
                      </p>
                    </div>

                    <div className="grid grid-cols-2 gap-2 pt-3 border-t border-emerald-100/80 text-xs mt-3">
                      <div className="bg-white/80 p-2.5 rounded-xl border border-emerald-100">
                        <span className="text-gray-400 block text-[10px] mb-0.5">Total Real</span>
                        <b className="text-sm text-gray-900">{fmtNum(metrics.totalRealUni)}</b>
                        <span className="text-[9px] text-gray-400 block">unidades</span>
                      </div>
                      <div className="bg-white/80 p-2.5 rounded-xl border border-emerald-100">
                        <span className="text-gray-400 block text-[10px] mb-0.5">Ppto a la Fecha</span>
                        <b className="text-sm text-gray-900">{fmtNum(metrics.totalPptoUni)}</b>
                        <span className="text-[9px] text-gray-400 block">unidades</span>
                      </div>
                    </div>
                  </div>

                  {/* Tarjeta 2: Real vs Meta Anual 2026 (Exclusiva) */}
                  <div className="lg:col-span-3 bg-white p-5 rounded-2xl border border-gray-200 card-shadow flex flex-col justify-between text-center bg-gradient-to-br from-white to-blue-50/40">
                    <div>
                      <div className="flex items-center justify-between gap-1 mb-1">
                        <span className="text-[11px] font-bold uppercase tracking-wider text-blue-900/70">
                          Avance Meta Anual 2026
                        </span>
                        <span className="px-2 py-0.5 bg-blue-100 text-blue-800 rounded-full text-[10px] font-bold">
                          Meta Total
                        </span>
                      </div>
                      <div className="text-4xl font-extrabold text-blue-900 my-2">
                        {fmtPct(metrics.pctCumplimientoUniAnual)}
                      </div>
                      <div className="w-full bg-gray-200 h-2 rounded-full overflow-hidden my-2.5 max-w-[200px] mx-auto">
                        <div
                          className="bg-blue-600 h-full rounded-full transition-all duration-700"
                          style={{ width: Math.min(100, metrics.pctCumplimientoUniAnual * 100) + '%' }}
                        ></div>
                      </div>
                      <p className="text-[11px] text-gray-500">
                        Total escriturado vs presupuesto anual completo
                      </p>
                    </div>

                    <div className="grid grid-cols-2 gap-2 pt-3 border-t border-blue-100/80 text-xs mt-3">
                      <div className="bg-white/80 p-2.5 rounded-xl border border-blue-100">
                        <span className="text-gray-400 block text-[10px] mb-0.5">Real Ejecutado</span>
                        <b className="text-sm text-blue-950">{fmtNum(metrics.totalRealUni)}</b>
                        <span className="text-[9px] text-gray-400 block">unidades</span>
                      </div>
                      <div className="bg-white/80 p-2.5 rounded-xl border border-blue-100">
                        <span className="text-gray-400 block text-[10px] mb-0.5">Meta Anual 2026</span>
                        <b className="text-sm text-blue-950">{fmtNum(metrics.totalPptoUniAnual)}</b>
                        <span className="text-[9px] text-gray-400 block">unidades</span>
                      </div>
                    </div>
                  </div>

                  {/* Tabla Desglose por Proyecto (Ocupa 6 columnas para equilibrio perfecto) */}
                  <div className="lg:col-span-6 bg-white p-5 rounded-2xl border border-gray-200 card-shadow flex flex-col justify-between">
                    <div className="flex items-center justify-between mb-3">
                      <div>
                        <h3 className="text-sm font-bold text-gray-900">Desglose Comparativo por Proyecto</h3>
                        <p className="text-xs text-gray-400">Total unidades escrituradas vs presupuesto acumulado a {metrics.mesVigenteLabel}</p>
                      </div>
                      <span className="text-xs font-semibold px-2.5 py-0.5 bg-gray-100 text-gray-600 rounded-full">
                        {metrics.projectBreakdown.length} proyectos
                      </span>
                    </div>

                    <div className="flex-1 overflow-y-auto max-h-[280px] border border-gray-100 rounded-xl">
                      <table className="w-full text-xs text-left">
                        <thead className="bg-gray-50 text-gray-600 sticky top-0 border-b border-gray-200">
                          <tr>
                            <th className="py-2.5 px-4 font-semibold">Proyecto</th>
                            <th className="py-2.5 px-4 text-right font-semibold">Real Unidades</th>
                            <th className="py-2.5 px-4 text-right font-semibold">Ppto Unidades</th>
                            <th className="py-2.5 px-4 text-right font-semibold">% Cumplimiento</th>
                          </tr>
                        </thead>
                        <tbody className="divide-y divide-gray-100">
                          {metrics.projectBreakdown.map((row, idx) => {
                            const pct = row.pptoUni > 0 ? (row.realUni / row.pptoUni) * 100 : 0;
                            return (
                              <tr key={idx} className="hover:bg-gray-50/80 transition-colors">
                                <td className="py-2.5 px-4 font-medium text-gray-900">{row.proyecto}</td>
                                <td className="py-2.5 px-4 text-right text-emerald-700 font-bold">{fmtNum(row.realUni)}</td>
                                <td className="py-2.5 px-4 text-right text-gray-600 font-medium">{fmtNum(row.pptoUni)}</td>
                                <td className="py-2.5 px-4 text-right">
                                  <span className={`font-bold ${pct >= 100 ? 'text-emerald-700' : pct >= 70 ? 'text-amber-600' : 'text-gray-600'}`}>
                                    {pct.toFixed(1).replace('.', ',')}%
                                  </span>
                                </td>
                              </tr>
                            );
                          })}
                        </tbody>
                        <tfoot className="bg-gray-100/90 font-bold sticky bottom-0 border-t border-gray-200">
                          <tr>
                            <td className="py-2.5 px-4">Total</td>
                            <td className="py-2.5 px-4 text-right text-emerald-800 text-sm">{fmtNum(metrics.totalRealUni)}</td>
                            <td className="py-2.5 px-4 text-right text-sm">{fmtNum(metrics.totalPptoUni)}</td>
                            <td className="py-2.5 px-4 text-right text-emerald-800 text-sm">{fmtPct(metrics.pctCumplimientoUni)}</td>
                          </tr>
                        </tfoot>
                      </table>
                    </div>
                  </div>
                </div>
              </div>
            )}

            {tab === 'uf' && (
              <div className="space-y-6">
                {/* FILA 1: Gráfico Principal a Ancho Completo con Selector Acumulado / Parcial */}
                <div className="bg-white p-6 rounded-2xl border border-gray-200 card-shadow">
                  <div className="flex flex-col sm:flex-row sm:items-center justify-between gap-3 mb-4 pb-3 border-b border-gray-100">
                    <div>
                      <h3 className="text-base font-bold text-gray-900">
                        {viewModeUF === 'parcial'
                          ? 'Comparativo Escrituras Parciales (Mes a Mes) · Montos UF'
                          : 'Comparativo Escrituras Acumuladas (YTD) · Montos UF'}
                      </h3>
                      <p className="text-xs text-gray-500 mt-0.5">
                        {viewModeUF === 'parcial'
                          ? 'Montos totales escriturados en UF vs Presupuesto mensual'
                          : 'Progresión acumulada anual en UF vs meta anual'}
                      </p>
                    </div>

                    {/* Botón Selector Toggle: Parcial vs Acumulado */}
                    <div className="inline-flex p-1 bg-gray-100/90 rounded-xl border border-gray-200 self-start sm:self-auto">
                      <button
                        type="button"
                        onClick={() => setViewModeUF('parcial')}
                        className={`px-4 py-1.5 rounded-lg text-xs font-bold transition-all duration-200 ${viewModeUF === 'parcial' ? 'bg-white text-emerald-800 shadow-sm' : 'text-gray-600 hover:text-gray-900'}`}
                      >
                        <i className="bi bi-bar-chart-fill mr-1.5"></i>
                        Mes a Mes (Parcial)
                      </button>
                      <button
                        type="button"
                        onClick={() => setViewModeUF('acumulado')}
                        className={`px-4 py-1.5 rounded-lg text-xs font-bold transition-all duration-200 ${viewModeUF === 'acumulado' ? 'bg-white text-emerald-800 shadow-sm' : 'text-gray-600 hover:text-gray-900'}`}
                      >
                        <i className="bi bi-graph-up-arrow mr-1.5"></i>
                        Acumulado (YTD)
                      </button>
                    </div>
                  </div>

                  {/* Renderizado de gráfico dinámico a todo el ancho */}
                  <EChart
                    option={viewModeUF === 'parcial' ? optUFParcial : optUFAcum}
                    height="380px"
                    onChartClick={handleUnidadesClick}
                  />
                </div>

                {/* FILA 2: Tarjetas KPI + Tablas Debajo en Segunda Fila */}
                <div className="grid grid-cols-1 lg:grid-cols-12 gap-6 items-stretch">
                  {/* Tarjeta 1: % Cumplimiento Real vs Ppto UF al Mes Vigente */}
                  <div className="lg:col-span-3 bg-white p-5 rounded-2xl border border-gray-200 card-shadow flex flex-col justify-between text-center kpi-gradient">
                    <div>
                      <div className="flex items-center justify-between gap-1 mb-1">
                        <span className="text-[11px] font-bold uppercase tracking-wider text-gray-500">
                          % Cumplimiento a la Fecha
                        </span>
                        <span className="px-2 py-0.5 bg-emerald-100 text-emerald-800 rounded-full text-[10px] font-bold">
                          {metrics.mesVigenteLabel}
                        </span>
                      </div>
                      <div className="text-4xl font-extrabold text-emerald-800 my-2">
                        {fmtPct(metrics.pctCumplimientoUF)}
                      </div>
                      <div className="w-full bg-gray-200 h-2 rounded-full overflow-hidden my-2.5 max-w-[200px] mx-auto">
                        <div
                          className="bg-emerald-600 h-full rounded-full transition-all duration-700"
                          style={{ width: Math.min(100, metrics.pctCumplimientoUF * 100) + '%' }}
                        ></div>
                      </div>
                      <p className="text-[11px] text-gray-500">
                        Real vs Presupuesto acumulado al mes vigente
                      </p>
                    </div>

                    <div className="grid grid-cols-2 gap-2 pt-3 border-t border-emerald-100/80 text-xs mt-3">
                      <div className="bg-white/80 p-2.5 rounded-xl border border-emerald-100">
                        <span className="text-gray-400 block text-[10px] mb-0.5">Total Real</span>
                        <b className="text-xs text-gray-900 block truncate" title={fmtUF(metrics.totalRealUF)}>{fmtUF(metrics.totalRealUF)}</b>
                      </div>
                      <div className="bg-white/80 p-2.5 rounded-xl border border-emerald-100">
                        <span className="text-gray-400 block text-[10px] mb-0.5">Ppto a la Fecha</span>
                        <b className="text-xs text-gray-900 block truncate" title={fmtUF(metrics.totalPptoUF)}>{fmtUF(metrics.totalPptoUF)}</b>
                      </div>
                    </div>
                  </div>

                  {/* Tarjeta 2: Real vs Meta Anual UF 2026 (Exclusiva) */}
                  <div className="lg:col-span-3 bg-white p-5 rounded-2xl border border-gray-200 card-shadow flex flex-col justify-between text-center bg-gradient-to-br from-white to-blue-50/40">
                    <div>
                      <div className="flex items-center justify-between gap-1 mb-1">
                        <span className="text-[11px] font-bold uppercase tracking-wider text-blue-900/70">
                          Avance Meta Anual 2026
                        </span>
                        <span className="px-2 py-0.5 bg-blue-100 text-blue-800 rounded-full text-[10px] font-bold">
                          Meta Total
                        </span>
                      </div>
                      <div className="text-4xl font-extrabold text-blue-900 my-2">
                        {fmtPct(metrics.pctCumplimientoUFAnual)}
                      </div>
                      <div className="w-full bg-gray-200 h-2 rounded-full overflow-hidden my-2.5 max-w-[200px] mx-auto">
                        <div
                          className="bg-blue-600 h-full rounded-full transition-all duration-700"
                          style={{ width: Math.min(100, metrics.pctCumplimientoUFAnual * 100) + '%' }}
                        ></div>
                      </div>
                      <p className="text-[11px] text-gray-500">
                        Total escriturado vs presupuesto anual completo
                      </p>
                    </div>

                    <div className="grid grid-cols-2 gap-2 pt-3 border-t border-blue-100/80 text-xs mt-3">
                      <div className="bg-white/80 p-2.5 rounded-xl border border-blue-100">
                        <span className="text-gray-400 block text-[10px] mb-0.5">Real Ejecutado</span>
                        <b className="text-xs text-blue-950 block truncate" title={fmtUF(metrics.totalRealUF)}>{fmtUF(metrics.totalRealUF)}</b>
                      </div>
                      <div className="bg-white/80 p-2.5 rounded-xl border border-blue-100">
                        <span className="text-gray-400 block text-[10px] mb-0.5">Meta Anual 2026</span>
                        <b className="text-xs text-blue-950 block truncate" title={fmtUF(metrics.totalPptoUFAnual)}>{fmtUF(metrics.totalPptoUFAnual)}</b>
                      </div>
                    </div>
                  </div>

                  {/* Tabla Desglose UF (Ocupa 6 columnas) */}
                  <div className="lg:col-span-6 bg-white p-5 rounded-2xl border border-gray-200 card-shadow flex flex-col justify-between">
                    <div className="flex items-center justify-between mb-3">
                      <div>
                        <h3 className="text-sm font-bold text-gray-900">Desglose Comparativo en UF por Proyecto</h3>
                        <p className="text-xs text-gray-400">Total UF escrituradas vs presupuesto acumulado a {metrics.mesVigenteLabel}</p>
                      </div>
                      <span className="text-xs font-semibold px-2.5 py-0.5 bg-gray-100 text-gray-600 rounded-full">
                        {metrics.projectBreakdown.length} proyectos
                      </span>
                    </div>

                    <div className="flex-1 overflow-y-auto max-h-[280px] border border-gray-100 rounded-xl">
                      <table className="w-full text-xs text-left">
                        <thead className="bg-gray-50 text-gray-600 sticky top-0 border-b border-gray-200">
                          <tr>
                            <th className="py-2.5 px-4 font-semibold">Proyecto</th>
                            <th className="py-2.5 px-4 text-right font-semibold">Total UF Esc.</th>
                            <th className="py-2.5 px-4 text-right font-semibold">Total Ppto UF</th>
                            <th className="py-2.5 px-4 text-right font-semibold">% Cumplimiento</th>
                          </tr>
                        </thead>
                        <tbody className="divide-y divide-gray-100">
                          {metrics.projectBreakdown.map((row, idx) => {
                            const pct = row.pptoUF > 0 ? (row.realUF / row.pptoUF) * 100 : 0;
                            return (
                              <tr key={idx} className="hover:bg-gray-50/80 transition-colors">
                                <td className="py-2.5 px-4 font-medium text-gray-900">{row.proyecto}</td>
                                <td className="py-2.5 px-4 text-right text-emerald-700 font-bold">{fmtNum(row.realUF)}</td>
                                <td className="py-2.5 px-4 text-right text-gray-600 font-medium">{fmtNum(row.pptoUF)}</td>
                                <td className="py-2.5 px-4 text-right">
                                  <span className={`font-bold ${pct >= 100 ? 'text-emerald-700' : pct >= 70 ? 'text-amber-600' : 'text-gray-600'}`}>
                                    {pct.toFixed(1).replace('.', ',')}%
                                  </span>
                                </td>
                              </tr>
                            );
                          })}
                        </tbody>
                        <tfoot className="bg-gray-100/90 font-bold sticky bottom-0 border-t border-gray-200">
                          <tr>
                            <td className="py-2.5 px-4">Total</td>
                            <td className="py-2.5 px-4 text-right text-emerald-800 text-sm">{fmtNum(metrics.totalRealUF)}</td>
                            <td className="py-2.5 px-4 text-right text-sm">{fmtNum(metrics.totalPptoUF)}</td>
                            <td className="py-2.5 px-4 text-right text-emerald-800 text-sm">{fmtPct(metrics.pctCumplimientoUF)}</td>
                          </tr>
                        </tfoot>
                      </table>
                    </div>
                  </div>
                </div>
              </div>
            )}

            {tab === 'estados' && (
              <div className="bg-white p-6 rounded-xl border border-gray-200 card-shadow space-y-4">
                <div className="flex items-center justify-between">
                  <div>
                    <h3 className="text-base font-bold text-gray-800">Recuento de Estado de Firma por Proyecto (100% Apilado)</h3>
                    <p className="text-xs text-gray-500">Distribución de ofertas según etapa alcanzada</p>
                  </div>
                </div>
                <EChart key="chart-estados" option={optEstadosFirma} height="650px" onChartClick={handleEstadosClick} />

                {/* Sección Explicativa de Criterios de Estado según CRM */}
                <div className="pt-4 border-t border-gray-100">
                  <div className="flex items-center gap-2 mb-2">
                    <i className="bi bi-info-circle-fill text-emerald-700 text-sm"></i>
                    <h4 className="text-xs font-bold uppercase tracking-wider text-gray-700">
                      ¿Qué determina cada estado de firma en el CRM?
                    </h4>
                  </div>
                  <p className="text-xs text-gray-500 mb-4">
                    La clasificación se asigna de forma jerárquica de acuerdo a la fecha más avanzada registrada en el CRM:
                  </p>

                  <div className="grid grid-cols-1 md:grid-cols-5 gap-3 text-xs">
                    {/* 1. Escriturada */}
                    <div className="p-3.5 rounded-xl border border-emerald-200 bg-emerald-50/50 space-y-1.5">
                      <div className="flex items-center gap-2">
                        <span className="w-3 h-3 rounded-full bg-[#22c55e] flex-shrink-0"></span>
                        <b className="text-emerald-950 font-bold">1. Escriturada</b>
                      </div>
                      <p className="text-gray-600 text-[11px] leading-relaxed">
                        Tiene <b>Fecha de Firma Inmobiliaria</b> en el CRM. Ambas partes firmaron ante notario y la escritura cerró formalmente su ciclo.
                      </p>
                    </div>

                    {/* 2. Firmada por cliente */}
                    <div className="p-3.5 rounded-xl border border-amber-200 bg-amber-50/40 space-y-1.5">
                      <div className="flex items-center gap-2">
                        <span className="w-3 h-3 rounded-full bg-[#eab308] flex-shrink-0"></span>
                        <b className="text-amber-950 font-bold">2. Firmada cliente</b>
                      </div>
                      <p className="text-gray-600 text-[11px] leading-relaxed">
                        Tiene <b>Fecha de Firma Cliente</b> en el CRM. El cliente ya firmó en notaría y se encuentra en espera del cierre de la inmobiliaria.
                      </p>
                    </div>

                    {/* 3. Pre-escriturada */}
                    <div className="p-3.5 rounded-xl border border-orange-200 bg-orange-50/40 space-y-1.5">
                      <div className="flex items-center gap-2">
                        <span className="w-3 h-3 rounded-full bg-[#f97316] flex-shrink-0"></span>
                        <b className="text-orange-950 font-bold">3. Pre-escriturada</b>
                      </div>
                      <p className="text-gray-600 text-[11px] leading-relaxed">
                        Tiene <b>Fecha de Pre-Escritura</b> en el CRM. Se emitió y visó la matriz legal con el banco o notaría, previa a la citación del cliente.
                      </p>
                    </div>

                    {/* 4. Promesada */}
                    <div className="p-3.5 rounded-xl border border-rose-200 bg-rose-50/40 space-y-1.5">
                      <div className="flex items-center gap-2">
                        <span className="w-3 h-3 rounded-full bg-[#881337] flex-shrink-0"></span>
                        <b className="text-rose-950 font-bold">4. Promesada</b>
                      </div>
                      <p className="text-gray-600 text-[11px] leading-relaxed">
                        Tiene <b>Fecha de Promesa / Cesión</b> en el CRM. Contrato de promesa vigente firmado formalmente entre las partes.
                      </p>
                    </div>

                    {/* 5. Reservada */}
                    <div className="p-3.5 rounded-xl border border-slate-300 bg-slate-50/70 space-y-1.5">
                      <div className="flex items-center gap-2">
                        <span className="w-3 h-3 rounded-full bg-[#0f172a] flex-shrink-0"></span>
                        <b className="text-slate-900 font-bold">5. Reservada</b>
                      </div>
                      <p className="text-gray-600 text-[11px] leading-relaxed">
                        Tiene <b>Fecha de Reserva</b> en el CRM. Oferta inicial con pago de reserva y en proceso de evaluación de crédito hipotecario.
                      </p>
                    </div>
                  </div>
                </div>
              </div>
            )}

            {/* ========================================================================= */}
            {/* PANEL DE GESTIÓN DE PRESUPUESTOS (SOLO ADMINISTRADOR)                     */}
            {/* ========================================================================= */}
            {tab === 'admin' && (
              <div className="max-w-6xl mx-auto space-y-6">
                {/* PÁGINA 1: CATÁLOGO / SELECCIÓN DE REPORTE PARA GESTIÓN DE PRESUPUESTOS */}
                {!adminReportSelected ? (
                  <div className="space-y-6">
                    <div className="bg-white p-6 rounded-2xl border border-gray-200 card-shadow">
                      <div className="flex items-center gap-2 mb-1">
                        <span className="px-2.5 py-1 bg-emerald-100 text-emerald-800 text-xs font-bold rounded-lg border border-emerald-200 flex items-center gap-1.5">
                          <i className="bi bi-shield-lock-fill"></i> Panel de Administración
                        </span>
                        <span className="text-xs text-gray-500">· Centro de Control Multi-Reporte</span>
                      </div>
                      <h3 className="text-xl font-bold text-gray-900">Gestión de Presupuestos y Metas</h3>
                      <p className="text-xs text-gray-500 mt-1">
                        Selecciona el módulo o reporte sobre el cual deseas administrar, desglosar o cargar presupuestos en UF y Unidades.
                      </p>
                    </div>

                    <div className="grid grid-cols-1 md:grid-cols-3 gap-6">
                      {/* TARJETA 1: ESCRITURACIÓN (ACTIVA) */}
                      <div
                        onClick={() => setAdminReportSelected('escrituracion')}
                        className="bg-white p-6 rounded-2xl border-2 border-emerald-500/40 hover:border-emerald-600 card-shadow hover:shadow-lg transition-all duration-200 cursor-pointer flex flex-col justify-between group relative overflow-hidden"
                      >
                        <div className="absolute top-0 right-0 bg-emerald-600 text-white text-[10px] font-bold px-3 py-1 rounded-bl-xl uppercase tracking-wider">
                          Disponible
                        </div>
                        <div className="space-y-4">
                          <div className="w-12 h-12 rounded-xl bg-emerald-50 text-emerald-800 flex items-center justify-center text-2xl group-hover:bg-emerald-600 group-hover:text-white transition">
                            <i className="bi bi-file-earmark-check"></i>
                          </div>
                          <div>
                            <h4 className="text-lg font-bold text-gray-900 group-hover:text-emerald-800 transition">
                              Escrituración
                            </h4>
                            <p className="text-xs text-gray-500 mt-1 leading-relaxed">
                              Control y metas de departamentos escriturados. Administra presupuestos de <b>Unidades</b> y <b>UF</b> mes a mes por proyecto y fecha.
                            </p>
                          </div>
                          <div className="pt-2 flex items-center gap-2 text-xs font-semibold text-emerald-700">
                            <span className="bg-emerald-50 px-2.5 py-1 rounded-lg border border-emerald-200">
                              {data ? data.unidadesPpto.length + data.ufPpto.length : 0} metas registradas
                            </span>
                          </div>
                        </div>

                        <div className="mt-6 pt-4 border-t border-gray-100 flex items-center justify-between text-xs font-bold text-emerald-700 group-hover:text-emerald-900">
                          <span>Gestionar Presupuestos</span>
                          <i className="bi bi-arrow-right text-base transform group-hover:translate-x-1 transition-transform"></i>
                        </div>
                      </div>

                      {/* TARJETA 2: VENTAS Y PROMESAS (PRÓXIMAMENTE) */}
                      <div className="bg-white/70 p-6 rounded-2xl border border-gray-200 card-shadow flex flex-col justify-between opacity-80 hover:opacity-100 transition">
                        <div className="space-y-4">
                          <div className="w-12 h-12 rounded-xl bg-gray-100 text-gray-500 flex items-center justify-center text-2xl">
                            <i className="bi bi-graph-up-arrow"></i>
                          </div>
                          <div>
                            <div className="flex items-center gap-2">
                              <h4 className="text-base font-bold text-gray-800">Ventas y Promesas</h4>
                              <span className="text-[10px] bg-gray-100 text-gray-600 font-bold px-2 py-0.5 rounded-full">Próximamente</span>
                            </div>
                            <p className="text-xs text-gray-500 mt-1 leading-relaxed">
                              Presupuestos de colocación comercial, promesas netas y flujo de reservas por sala de ventas.
                            </p>
                          </div>
                        </div>
                        <div className="mt-6 pt-4 border-t border-gray-100 text-xs text-gray-400 font-medium">
                          Módulo en preparación
                        </div>
                      </div>

                      {/* TARJETA 3: CONTROL DE COSTOS Y FLUJO (PRÓXIMAMENTE) */}
                      <div className="bg-white/70 p-6 rounded-2xl border border-gray-200 card-shadow flex flex-col justify-between opacity-80 hover:opacity-100 transition">
                        <div className="space-y-4">
                          <div className="w-12 h-12 rounded-xl bg-gray-100 text-gray-500 flex items-center justify-center text-2xl">
                            <i className="bi bi-cash-coin"></i>
                          </div>
                          <div>
                            <div className="flex items-center gap-2">
                              <h4 className="text-base font-bold text-gray-800">Flujo y Cobranza</h4>
                              <span className="text-[10px] bg-gray-100 text-gray-600 font-bold px-2 py-0.5 rounded-full">Próximamente</span>
                            </div>
                            <p className="text-xs text-gray-500 mt-1 leading-relaxed">
                              Presupuesto financiero de recuperación de abonos, subsidios y liquidación bancaria de alzamientos.
                            </p>
                          </div>
                        </div>
                        <div className="mt-6 pt-4 border-t border-gray-100 text-xs text-gray-400 font-medium">
                          Módulo en preparación
                        </div>
                      </div>
                    </div>

                    {/* SECCIÓN EXCLUSIVA: GESTIÓN DE USUARIOS ADMINISTRADORES */}
                    <div className="bg-white p-6 rounded-2xl border border-gray-200 card-shadow space-y-4">
                      <div className="flex flex-col sm:flex-row sm:items-center justify-between gap-2 pb-3 border-b border-gray-100">
                        <div className="flex items-center gap-2.5">
                          <div className="w-9 h-9 rounded-xl bg-emerald-50 text-emerald-800 flex items-center justify-center text-lg border border-emerald-200">
                            <i className="bi bi-people-fill"></i>
                          </div>
                          <div>
                            <h4 className="text-base font-bold text-gray-900">Control de Usuarios Administradores</h4>
                            <p className="text-xs text-gray-500">Gestión de cuentas autorizadas con privilegios totales de edición y configuración</p>
                          </div>
                        </div>
                        <span className="text-xs bg-emerald-100 text-emerald-800 px-3 py-1 rounded-full font-bold border border-emerald-200 self-start sm:self-auto">
                          {adminUsersList.length} Administradores Registrados en Servidor
                        </span>
                      </div>

                      {/* Añadir nuevo administrador conectado al backend */}
                      <div className="flex flex-col sm:flex-row items-center gap-2">
                        <div className="relative flex-1 w-full">
                          <div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none text-gray-400">
                            <i className="bi bi-person-plus text-sm"></i>
                          </div>
                          <input
                            type="email"
                            value={newAdminInput}
                            onChange={(e) => setNewAdminInput(e.target.value)}
                            placeholder="Añadir nuevo administrador (ej: nombre.apellido@fundamenta.cl)..."
                            className="w-full pl-9 pr-4 py-2 border border-gray-300 rounded-xl text-xs bg-gray-50/50 focus:bg-white focus:ring-1 focus:ring-emerald-500"
                          />
                        </div>
                        <button
                          type="button"
                          onClick={async () => {
                            const newEm = (newAdminInput || '').trim().toLowerCase();
                            if (!newEm) return;
                            if (!newEm.endsWith('@fundamenta.cl')) {
                              alert('Solo correos @fundamenta.cl pueden ser administradores.');
                              return;
                            }
                            try {
                              const res = await fetch('/api/admin/users', {
                                method: 'POST',
                                headers: { 'Content-Type': 'application/json' },
                                body: JSON.stringify({ email: newEm, role: 'admin' })
                              });
                              const resp = await res.json();
                              if (!res.ok) throw new Error(resp.message || 'Error al guardar');
                              setAdminUsersList(resp.users || []);
                              setNewAdminInput('');
                              alert('✓ Nuevo administrador registrado exitosamente en el servidor: ' + newEm);
                            } catch(err) {
                              alert('Error: ' + err.message);
                            }
                          }}
                          className="w-full sm:w-auto px-4 py-2 bg-emerald-700 hover:bg-emerald-800 text-white rounded-xl text-xs font-semibold transition flex items-center justify-center gap-1.5 shadow-sm"
                        >
                          <i className="bi bi-plus-lg"></i>
                          <span>Guardar en Servidor</span>
                        </button>
                      </div>

                      {/* Lista de administradores consultada desde el servidor */}
                      <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3 pt-2">
                        {adminUsersList.map((adm) => {
                          const isSelf = currentUser && currentUser.email.toLowerCase() === adm.email.toLowerCase();
                          return (
                            <div key={adm.id || adm.email} className="p-3 bg-gray-50 border border-gray-200 rounded-xl flex items-center justify-between gap-2">
                              <div className="flex items-center gap-2 min-w-0">
                                <span className={"w-2 h-2 rounded-full " + (adm.role === 'admin' ? 'bg-emerald-500' : 'bg-blue-500') + " flex-shrink-0"}></span>
                                <div className="min-w-0">
                                  <b className="text-xs text-gray-900 block truncate" title={adm.email}>{adm.email}</b>
                                  <span className="text-[10px] text-emerald-700 font-semibold block">
                                    {isSelf ? 'Tu usuario actual' : (adm.role === 'admin' ? 'Administrador Oficial' : 'Visualizador')}
                                  </span>
                                </div>
                              </div>
                              {!isSelf && (
                                <button
                                  type="button"
                                  onClick={async () => {
                                    if (confirm('¿Quitar el acceso de Administrador a ' + adm.email + '?')) {
                                      try {
                                        const res = await fetch('/api/admin/users/' + adm.id, { method: 'DELETE' });
                                        const resp = await res.json();
                                        if (res.ok) {
                                          setAdminUsersList(resp.users || []);
                                        }
                                      } catch(e) {
                                        alert('No se pudo remover: ' + e.message);
                                      }
                                    }
                                  }}
                                  className="p-1 text-gray-400 hover:text-red-600 rounded-lg hover:bg-white transition flex-shrink-0"
                                  title="Remover permisos de administrador"
                                >
                                  <i className="bi bi-trash text-sm"></i>
                                </button>
                              )}
                            </div>
                          );
                        })}
                      </div>
                    </div>
                  </div>
                ) : (
                  <div className="space-y-6">
                    {/* Botón Volver al Catálogo de Reportes */}
                    <div className="flex items-center justify-between">
                      <button
                        type="button"
                        onClick={() => setAdminReportSelected(null)}
                        className="inline-flex items-center gap-2 px-3.5 py-1.5 bg-white hover:bg-emerald-50 text-emerald-800 border border-emerald-300 rounded-xl text-xs font-bold transition shadow-sm"
                      >
                        <i className="bi bi-arrow-left"></i>
                        <span>Volver a Selección de Reportes</span>
                      </button>

                      <div className="flex items-center gap-2 text-xs">
                        <span className="text-gray-400">Módulo actual:</span>
                        <span className="px-2.5 py-1 bg-emerald-800 text-white rounded-lg font-bold flex items-center gap-1.5">
                          <i className="bi bi-file-earmark-check"></i> Escrituración
                        </span>
                      </div>
                    </div>

                    {/* Cabecera del Panel Admin */}
                    <div className="bg-white p-6 rounded-2xl border border-gray-200 card-shadow flex flex-col md:flex-row md:items-center justify-between gap-4">
                      <div>
                        <div className="flex items-center gap-2">
                          <span className="px-2.5 py-1 bg-emerald-100 text-emerald-800 text-xs font-bold rounded-lg border border-emerald-200 flex items-center gap-1.5">
                            <i className="bi bi-shield-lock-fill"></i> Rol Administrador Activo
                          </span>
                          <span className="text-xs text-gray-500">· Edición de metas en tiempo real</span>
                        </div>
                        <h3 className="text-xl font-bold text-gray-900 mt-1">Presupuestos: Escrituración (UF y Unidades)</h3>
                        <p className="text-xs text-gray-500 mt-0.5">
                          Desglose mes a mes por proyecto y fecha. Los cambios modifican automáticamente los acumulados e indicadores en toda la reportería.
                        </p>
                      </div>

                  <div className="flex flex-wrap items-center gap-2.5">
                    {/* Botón Restablecer Presupuestos Originales */}
                    <button
                      type="button"
                      onClick={resetBudgetsToOriginal}
                      className="px-3.5 py-2 bg-gray-100 hover:bg-gray-200 text-gray-700 border border-gray-300 rounded-xl text-xs font-semibold flex items-center gap-2 transition shadow-sm"
                      title="Descarta modificaciones y vuelve a los presupuestos iniciales"
                    >
                      <i className="bi bi-arrow-counterclockwise text-base"></i>
                      <span>Restablecer Fábrica</span>
                    </button>

                    {/* Botón Descargar Formato Excel con Base Actual */}
                    <button
                      type="button"
                      onClick={() => {
                        if (!data) return;
                        try {
                          const wb = XLSX.utils.book_new();
                          
                          // Hoja Unidades 2026
                          const wsUni = XLSX.utils.json_to_sheet(data.unidadesPpto.map(u => ({
                            Proyecto: u.Proyecto,
                            Fecha: u.Fecha,
                            Unidades: parseInt(u.Unidades, 10) || 0
                          })));
                          XLSX.utils.book_append_sheet(wb, wsUni, "Unidades 2026");

                          // Hoja UF 2026
                          const wsUF = XLSX.utils.json_to_sheet(data.ufPpto.map(u => ({
                            Proyecto: u.Proyecto,
                            Fecha: u.Fecha,
                            UF: parseFloat((u.UF || '0').replace(',', '.')) || 0
                          })));
                          XLSX.utils.book_append_sheet(wb, wsUF, "UF 2026");

                          XLSX.writeFile(wb, "Presupuesto_Fundamenta_Base_2026.xlsx");
                        } catch (err) {
                          alert('Error al exportar Excel: ' + err.message);
                        }
                      }}
                      className="px-3.5 py-2 bg-emerald-50 hover:bg-emerald-100 text-emerald-800 border border-emerald-300 rounded-xl text-xs font-semibold flex items-center gap-2 transition shadow-sm"
                      title="Descarga la plantilla oficial con todos los presupuestos actuales para editar o añadir filas"
                    >
                      <i className="bi bi-file-earmark-arrow-down text-base"></i>
                      <span>Descargar Formato Excel</span>
                    </button>

                    {/* Botón Cargar / Importar Excel */}
                    <label
                      htmlFor="excelUploadInput"
                      className="px-3.5 py-2 bg-white hover:bg-gray-50 text-gray-700 border border-gray-300 rounded-xl text-xs font-semibold flex items-center gap-2 cursor-pointer transition shadow-sm"
                      title="Sube un archivo Excel para actualizar o añadir presupuestos"
                    >
                      <i className="bi bi-cloud-arrow-up text-base text-emerald-700"></i>
                      <span>Cargar Planilla Excel</span>
                    </label>
                    <input
                      type="file"
                      id="excelUploadInput"
                      accept=".xlsx, .xls"
                      className="hidden"
                      onChange={(e) => {
                        const file = e.target.files[0];
                        if (!file) return;
                        const reader = new FileReader();
                        reader.onload = (evt) => {
                          try {
                            const bstr = evt.target.result;
                            const wb = XLSX.read(bstr, { type: 'binary' });
                            let newUnidades = [...data.unidadesPpto];
                            let newUF = [...data.ufPpto];
                            let importedUniCount = 0;
                            let importedUFCount = 0;

                            // Procesar Hoja Unidades
                            const uniSheetName = wb.SheetNames.find(n => n.toLowerCase().includes('unidad'));
                            if (uniSheetName) {
                              const rows = XLSX.utils.sheet_to_json(wb.Sheets[uniSheetName]);
                              rows.forEach(r => {
                                if (r.Proyecto && r.Fecha) {
                                  const dateVal = String(r.Fecha).trim();
                                  const formattedDate = dateVal.includes(' ') ? dateVal : dateVal + ' 0:00:00';
                                  const idx = newUnidades.findIndex(x => x.Proyecto === r.Proyecto && x.Fecha.startsWith(dateVal.substring(0, 10)));
                                  const item = {
                                    Proyecto: String(r.Proyecto).trim(),
                                    Fecha: formattedDate,
                                    Unidades: String(r.Unidades || '0')
                                  };
                                  if (idx >= 0) newUnidades[idx] = item;
                                  else newUnidades.push(item);
                                  importedUniCount++;
                                }
                              });
                            }

                            // Procesar Hoja UF
                            const ufSheetName = wb.SheetNames.find(n => n.toLowerCase().includes('uf'));
                            if (ufSheetName) {
                              const rows = XLSX.utils.sheet_to_json(wb.Sheets[ufSheetName]);
                              rows.forEach(r => {
                                if (r.Proyecto && r.Fecha) {
                                  const dateVal = String(r.Fecha).trim();
                                  const formattedDate = dateVal.includes(' ') ? dateVal : dateVal + ' 0:00:00';
                                  const idx = newUF.findIndex(x => x.Proyecto === r.Proyecto && x.Fecha.startsWith(dateVal.substring(0, 10)));
                                  const item = {
                                    Proyecto: String(r.Proyecto).trim(),
                                    Fecha: formattedDate,
                                    UF: String(r.UF || '0').replace('.', ',')
                                  };
                                  if (idx >= 0) newUF[idx] = item;
                                  else newUF.push(item);
                                  importedUFCount++;
                                }
                              });
                            }

                            updateBudgets(newUnidades, newUF);
                            alert('✓ Planilla importada con éxito:\n- ' + importedUniCount + ' registros de Unidades procesados.\n- ' + importedUFCount + ' registros de UF procesados.\n\nLos acumulados y gráficos se actualizaron automáticamente.');
                          } catch (err) {
                            alert('Error al leer el archivo Excel: ' + err.message);
                          }
                        };
                        reader.readAsBinaryString(file);
                      }}
                    />

                    {/* Botón Añadir Presupuesto Manual */}
                    <button
                      type="button"
                      onClick={() => {
                        setEditingPptoItem({
                          isNew: true,
                          metric: 'Unidades',
                          proyecto: allProyectos[0] || 'Eco Arauco',
                          mes: '01',
                          year: '2026',
                          valor: '10'
                        });
                      }}
                      className="px-4 py-2 bg-emerald-700 hover:bg-emerald-800 text-white rounded-xl text-xs font-bold flex items-center gap-2 transition shadow"
                    >
                      <i className="bi bi-plus-circle"></i>
                      <span>Nuevo Presupuesto</span>
                    </button>
                  </div>
                </div>

                {/* Filtros de Búsqueda y Navegación en la Tabla de Presupuestos */}
                <div className="bg-white p-4 rounded-xl border border-gray-200 card-shadow flex flex-col sm:flex-row items-center justify-between gap-3 text-xs">
                  <div className="flex items-center gap-2 w-full sm:w-auto">
                    <div className="relative w-full sm:w-64">
                      <i className="bi bi-search absolute left-3 top-2.5 text-gray-400"></i>
                      <input
                        type="text"
                        placeholder="Buscar por proyecto..."
                        value={adminPptoSearch}
                        onChange={(e) => setAdminPptoSearch(e.target.value)}
                        className="w-full pl-8 pr-3 py-1.5 border border-gray-300 rounded-lg focus:ring-emerald-500 focus:border-emerald-500"
                      />
                    </div>
                  </div>

                  <div className="flex items-center gap-2 w-full sm:w-auto justify-end">
                    <span className="text-gray-500 font-medium">Métrica:</span>
                    <div className="inline-flex p-0.5 bg-gray-100 rounded-lg border border-gray-200">
                      <button
                        onClick={() => setAdminPptoMetric('all')}
                        className={'px-2.5 py-1 rounded-md font-semibold transition ' + (adminPptoMetric === 'all' ? 'bg-white text-emerald-800 shadow-sm' : 'text-gray-600')}
                      >
                        Todas
                      </button>
                      <button
                        onClick={() => setAdminPptoMetric('Unidades')}
                        className={'px-2.5 py-1 rounded-md font-semibold transition ' + (adminPptoMetric === 'Unidades' ? 'bg-white text-emerald-800 shadow-sm' : 'text-gray-600')}
                      >
                        Unidades
                      </button>
                      <button
                        onClick={() => setAdminPptoMetric('UF')}
                        className={'px-2.5 py-1 rounded-md font-semibold transition ' + (adminPptoMetric === 'UF' ? 'bg-white text-emerald-800 shadow-sm' : 'text-gray-600')}
                      >
                        UF
                      </button>
                    </div>

                    <span className="text-gray-500 font-medium ml-2">Año:</span>
                    <select
                      value={adminPptoYear}
                      onChange={(e) => setAdminPptoYear(e.target.value)}
                      className="border border-gray-300 rounded-lg px-2.5 py-1 bg-white font-semibold text-gray-700"
                    >
                      <option value="2026">2026</option>
                      <option value="2027">2027 (Futuro)</option>
                    </select>
                  </div>
                </div>

                {/* Tabla de Presupuestos Desglosados */}
                <div className="bg-white rounded-2xl border border-gray-200 card-shadow overflow-hidden">
                  <div className="px-6 py-4 border-b border-gray-100 flex items-center justify-between">
                    <div>
                      <h4 className="font-bold text-sm text-gray-900">Registros Presupuestarios Detallados</h4>
                      <p className="text-xs text-gray-500">Puedes editar cualquier valor haciendo clic en el lápiz o eliminarlo</p>
                    </div>
                    <span className="text-xs bg-emerald-50 text-emerald-800 px-3 py-1 rounded-full font-bold border border-emerald-200">
                      {(() => {
                        const totalUni = data ? data.unidadesPpto.length : 0;
                        const totalUF = data ? data.ufPpto.length : 0;
                        return (totalUni + totalUF) + ' registros totales';
                      })()}
                    </span>
                  </div>

                  <div className="overflow-x-auto max-h-[500px]">
                    <table className="w-full text-xs text-left">
                      <thead className="bg-gray-50 text-gray-600 font-semibold border-b border-gray-200 sticky top-0 z-10">
                        <tr>
                          <th className="py-3 px-4">Proyecto</th>
                          <th className="py-3 px-4">Métrica</th>
                          <th className="py-3 px-4">Fecha Asignada</th>
                          <th className="py-3 px-4 text-right">Monto / Valor Presupuestado</th>
                          <th className="py-3 px-4 text-center">Acciones</th>
                        </tr>
                      </thead>
                      <tbody className="divide-y divide-gray-100 text-gray-700">
                        {(() => {
                          if (!data) return null;
                          let rows = [];

                          if (adminPptoMetric === 'all' || adminPptoMetric === 'Unidades') {
                            data.unidadesPpto.forEach((u, i) => {
                              rows.push({
                                type: 'Unidades',
                                originalIndex: i,
                                proyecto: u.Proyecto,
                                fecha: u.Fecha,
                                valorRaw: u.Unidades,
                                valorFormatted: (parseInt(u.Unidades, 10) || 0) + ' un.'
                              });
                            });
                          }

                          if (adminPptoMetric === 'all' || adminPptoMetric === 'UF') {
                            data.ufPpto.forEach((u, i) => {
                              rows.push({
                                type: 'UF',
                                originalIndex: i,
                                proyecto: u.Proyecto,
                                fecha: u.Fecha,
                                valorRaw: u.UF,
                                valorFormatted: (parseFloat((u.UF || '0').replace(',', '.')) || 0).toLocaleString('es-CL', { maximumFractionDigits: 1 }) + ' UF'
                              });
                            });
                          }

                          if (adminPptoSearch.trim()) {
                            rows = rows.filter(r => r.proyecto.toLowerCase().includes(adminPptoSearch.toLowerCase()));
                          }

                          rows = rows.filter(r => r.fecha.includes(adminPptoYear));

                          if (rows.length === 0) {
                            return (
                              <tr>
                                <td colSpan="5" className="py-8 text-center text-gray-400">
                                  No se encontraron presupuestos que coincidan con el filtro.
                                </td>
                              </tr>
                            );
                          }

                          return rows.slice(0, 150).map((r, idx) => (
                            <tr key={idx} className="hover:bg-emerald-50/40 transition">
                              <td className="py-2.5 px-4 font-semibold text-gray-900">{r.proyecto}</td>
                              <td className="py-2.5 px-4">
                                <span className={'px-2 py-0.5 rounded-full text-[10px] font-bold ' + (r.type === 'Unidades' ? 'bg-blue-50 text-blue-700 border border-blue-200' : 'bg-amber-50 text-amber-800 border border-amber-200')}>
                                  {r.type}
                                </span>
                              </td>
                              <td className="py-2.5 px-4 font-mono text-gray-600">{r.fecha.split(' ')[0]}</td>
                              <td className="py-2.5 px-4 text-right font-bold text-emerald-800 font-mono">
                                {r.valorFormatted}
                              </td>
                              <td className="py-2.5 px-4 text-center">
                                <div className="flex items-center justify-center gap-1.5">
                                  <button
                                    onClick={() => {
                                      const parts = r.fecha.split(' ')[0].split('-');
                                      setEditingPptoItem({
                                        isNew: false,
                                        type: r.type,
                                        originalIndex: r.originalIndex,
                                        proyecto: r.proyecto,
                                        mes: parts[1] || '01',
                                        year: parts[2] || '2026',
                                        valor: r.type === 'Unidades' ? String(r.valorRaw) : String(r.valorRaw).replace(',', '.')
                                      });
                                    }}
                                    className="p-1.5 text-gray-400 hover:text-emerald-700 rounded-lg hover:bg-white transition"
                                    title="Editar este presupuesto"
                                  >
                                    <i className="bi bi-pencil-square text-sm"></i>
                                  </button>
                                  <button
                                    onClick={() => {
                                      if (confirm('¿Seguro que deseas eliminar el presupuesto de ' + r.proyecto + ' (' + r.type + ') para ' + r.fecha.split(' ')[0] + '?')) {
                                        if (r.type === 'Unidades') {
                                          const updated = [...data.unidadesPpto];
                                          updated.splice(r.originalIndex, 1);
                                          updateBudgets(updated, data.ufPpto);
                                        } else {
                                          const updated = [...data.ufPpto];
                                          updated.splice(r.originalIndex, 1);
                                          updateBudgets(data.unidadesPpto, updated);
                                        }
                                      }
                                    }}
                                    className="p-1.5 text-gray-400 hover:text-red-600 rounded-lg hover:bg-white transition"
                                    title="Eliminar este presupuesto"
                                  >
                                    <i className="bi bi-trash text-sm"></i>
                                  </button>
                                </div>
                              </td>
                            </tr>
                          ));
                        })()}
                      </tbody>
                    </table>
                  </div>
                </div>

                {/* Modal para Crear / Editar Presupuesto Específico */}
                {editingPptoItem && (
                  <div className="fixed inset-0 bg-black/40 backdrop-blur-sm z-50 flex items-center justify-center p-4">
                    <div className="bg-white rounded-2xl max-w-md w-full p-6 space-y-4 shadow-2xl animate-in fade-in zoom-in-95 duration-150">
                      <div className="flex items-center justify-between border-b pb-3">
                        <h3 className="font-bold text-base text-gray-900 flex items-center gap-2">
                          <i className="bi bi-sliders text-emerald-700"></i>
                          <span>{editingPptoItem.isNew ? 'Añadir Nuevo Presupuesto' : 'Editar Presupuesto'}</span>
                        </h3>
                        <button
                          onClick={() => setEditingPptoItem(null)}
                          className="text-gray-400 hover:text-gray-600 text-lg"
                        >
                          ✕
                        </button>
                      </div>

                      <div className="space-y-3 text-xs">
                        <div>
                          <label className="font-semibold text-gray-700 block mb-1">Métrica:</label>
                          {editingPptoItem.isNew ? (
                            <select
                              value={editingPptoItem.metric}
                              onChange={(e) => setEditingPptoItem({ ...editingPptoItem, metric: e.target.value })}
                              className="w-full border border-gray-300 rounded-lg p-2 font-semibold"
                            >
                              <option value="Unidades">Unidades Presupuestadas</option>
                              <option value="UF">Monto UF Presupuestado</option>
                            </select>
                          ) : (
                            <span className="font-bold text-emerald-800 text-sm">{editingPptoItem.type}</span>
                          )}
                        </div>

                        <div>
                          <label className="font-semibold text-gray-700 block mb-1">Proyecto:</label>
                          <select
                            value={editingPptoItem.proyecto}
                            onChange={(e) => setEditingPptoItem({ ...editingPptoItem, proyecto: e.target.value })}
                            className="w-full border border-gray-300 rounded-lg p-2"
                          >
                            {allProyectos.map(p => (
                              <option key={p} value={p}>{p}</option>
                            ))}
                          </select>
                        </div>

                        <div className="grid grid-cols-2 gap-3">
                          <div>
                            <label className="font-semibold text-gray-700 block mb-1">Mes:</label>
                            <select
                              value={editingPptoItem.mes}
                              onChange={(e) => setEditingPptoItem({ ...editingPptoItem, mes: e.target.value })}
                              className="w-full border border-gray-300 rounded-lg p-2"
                            >
                              {[
                                { k: '01', l: 'Enero' }, { k: '02', l: 'Febrero' }, { k: '03', l: 'Marzo' },
                                { k: '04', l: 'Abril' }, { k: '05', l: 'Mayo' }, { k: '06', l: 'Junio' },
                                { k: '07', l: 'Julio' }, { k: '08', l: 'Agosto' }, { k: '09', l: 'Septiembre' },
                                { k: '10', l: 'Octubre' }, { k: '11', l: 'Noviembre' }, { k: '12', l: 'Diciembre' }
                              ].map(m => (
                                <option key={m.k} value={m.k}>{m.l}</option>
                              ))}
                            </select>
                          </div>
                          <div>
                            <label className="font-semibold text-gray-700 block mb-1">Año:</label>
                            <input
                              type="number"
                              value={editingPptoItem.year}
                              onChange={(e) => setEditingPptoItem({ ...editingPptoItem, year: e.target.value })}
                              className="w-full border border-gray-300 rounded-lg p-2"
                            />
                          </div>
                        </div>

                        <div>
                          <label className="font-semibold text-gray-700 block mb-1">
                            Valor {(editingPptoItem.isNew ? editingPptoItem.metric : editingPptoItem.type) === 'Unidades' ? '(Número de departamentos)' : '(Monto total UF)'}:
                          </label>
                          <input
                            type="number"
                            step="any"
                            value={editingPptoItem.valor}
                            onChange={(e) => setEditingPptoItem({ ...editingPptoItem, valor: e.target.value })}
                            className="w-full border border-gray-300 rounded-lg p-2 text-sm font-bold text-emerald-800"
                          />
                        </div>
                      </div>

                      <div className="flex items-center justify-end gap-2 pt-4 border-t">
                        <button
                          type="button"
                          onClick={() => setEditingPptoItem(null)}
                          className="px-4 py-2 border border-gray-300 text-gray-700 text-xs font-semibold rounded-lg hover:bg-gray-50 transition"
                        >
                          Cancelar
                        </button>
                        <button
                          type="button"
                          onClick={() => {
                            const dateStr = '01-' + editingPptoItem.mes + '-' + editingPptoItem.year + ' 0:00:00';
                            const metricType = editingPptoItem.isNew ? editingPptoItem.metric : editingPptoItem.type;

                            if (metricType === 'Unidades') {
                              const updated = [...data.unidadesPpto];
                              const item = {
                                Proyecto: editingPptoItem.proyecto,
                                Fecha: dateStr,
                                Unidades: String(Math.round(parseFloat(editingPptoItem.valor) || 0))
                              };
                              if (editingPptoItem.isNew) {
                                const existingIdx = updated.findIndex(x => x.Proyecto === item.Proyecto && x.Fecha.startsWith('01-' + editingPptoItem.mes + '-' + editingPptoItem.year));
                                if (existingIdx >= 0) updated[existingIdx] = item;
                                else updated.push(item);
                              } else {
                                updated[editingPptoItem.originalIndex] = item;
                              }
                              updateBudgets(updated, data.ufPpto);
                            } else {
                              const updated = [...data.ufPpto];
                              const item = {
                                Proyecto: editingPptoItem.proyecto,
                                Fecha: dateStr,
                                UF: String(parseFloat(editingPptoItem.valor) || 0).replace('.', ',')
                              };
                              if (editingPptoItem.isNew) {
                                const existingIdx = updated.findIndex(x => x.Proyecto === item.Proyecto && x.Fecha.startsWith('01-' + editingPptoItem.mes + '-' + editingPptoItem.year));
                                if (existingIdx >= 0) updated[existingIdx] = item;
                                else updated.push(item);
                              } else {
                                updated[editingPptoItem.originalIndex] = item;
                              }
                              updateBudgets(data.unidadesPpto, updated);
                            }

                            setEditingPptoItem(null);
                            alert('✓ Presupuesto guardado. Los gráficos y acumulados fueron recalculados en toda la plataforma.');
                          }}
                          className="px-4 py-2 bg-emerald-700 hover:bg-emerald-800 text-white text-xs font-semibold rounded-lg transition shadow"
                        >
                          Guardar y Recalcular
                        </button>
                      </div>
                    </div>
                  </div>
                )}
                  </div>
                )}
              </div>
            )}

            {/* ========================================================================= */}
            {/* PANEL DE AUTOMATIZACIÓN DE REPORTES Y CONSTRUCTOR DE CORREOS INTERACTIVO   */}
            {/* ========================================================================= */}
            {tab === 'email' && (
              <div className="max-w-6xl mx-auto space-y-6">
                {/* 1. Tarjeta Estado de Conexión Gmail con Autenticación de Aplicación */}
                <div className="bg-white p-6 rounded-2xl border border-gray-200 card-shadow flex flex-col md:flex-row md:items-center justify-between gap-4">
                  <div className="flex items-center gap-4">
                    <div className="w-12 h-12 rounded-xl bg-red-50 text-red-600 flex items-center justify-center text-2xl border border-red-100 flex-shrink-0">
                      <i className="bi bi-google"></i>
                    </div>
                    <div>
                      <div className="flex items-center gap-2">
                        <h3 className="text-base font-bold text-gray-900">Cuenta de Gmail Remitente Vinculada</h3>
                        {gmailConnected ? (
                          <span className="px-2.5 py-0.5 bg-emerald-100 text-emerald-800 text-[11px] font-bold rounded-full flex items-center gap-1.5 border border-emerald-200">
                            <span className="w-2 h-2 rounded-full bg-emerald-500 animate-pulse"></span> Lista para Enviar
                          </span>
                        ) : (
                          <span className="px-2.5 py-0.5 bg-amber-100 text-amber-800 text-[11px] font-semibold rounded-full border border-amber-200">
                            Pendiente de Vinculación
                          </span>
                        )}
                      </div>
                      <p className="text-xs text-gray-500 mt-1">
                        {gmailConnected
                          ? 'Enviando reportes oficiales como: ' + gmailSenderName + ' <' + gmailAccount + '> (Autenticado vía Gmail)'
                          : 'Vincula una cuenta corporativa de Gmail con su Contraseña de Aplicación para habilitar el despacho de reportes.'}
                      </p>
                    </div>
                  </div>

                  <div className="flex items-center gap-2">
                    {gmailConnected ? (
                      <>
                        <button
                          type="button"
                          onClick={() => {
                            setGmailModalUser(gmailAccount);
                            setGmailModalPass(gmailPass);
                            setGmailModalOpen(true);
                          }}
                          className="px-3.5 py-2 border border-gray-300 text-gray-700 hover:bg-gray-50 text-xs font-semibold rounded-xl transition shadow-sm flex items-center gap-1.5"
                        >
                          <i className="bi bi-gear"></i>
                          <span>Configurar Cuenta</span>
                        </button>
                        <button
                          type="button"
                          onClick={() => {
                            if (confirm('¿Deseas desvincular la cuenta de Gmail remitente? Los envíos quedarán en pausa hasta que vincules otra.')) {
                              setGmailConnected(false);
                              setGmailPass('');
                              localStorage.removeItem('fundamenta_gmail_pass');
                            }
                          }}
                          className="px-3.5 py-2 border border-red-200 text-red-600 hover:bg-red-50 text-xs font-semibold rounded-xl transition shadow-sm"
                        >
                          Desconectar
                        </button>
                      </>
                    ) : (
                      <button
                        type="button"
                        onClick={() => {
                          setGmailModalUser(gmailAccount);
                          setGmailModalPass('');
                          setGmailModalOpen(true);
                        }}
                        className="px-4 py-2 bg-red-600 hover:bg-red-700 text-white text-xs font-semibold rounded-xl transition flex items-center gap-2 shadow"
                      >
                        <i className="bi bi-google"></i>
                        <span>Vincular Cuenta de Gmail</span>
                      </button>
                    )}
                  </div>
                </div>

                {/* 2. Cabecera de Reglas Programadas */}
                <div className="flex items-center justify-between pt-2">
                  <div>
                    <h3 className="text-lg font-bold text-gray-900">Programaciones y Plantillas de Envío</h3>
                    <p className="text-xs text-gray-500">Configura la frecuencia, destinatarios y personaliza el contenido interactivo del correo.</p>
                  </div>
                  <button
                    onClick={() => {
                      setEditingSchedule({
                        id: Date.now(),
                        name: 'Nuevo Reporte de Escrituración',
                        frequency: 'semanal',
                        days: ['1'],
                        time: '09:00',
                        recipients: 'gerencia@fundamenta.cl, finanzas@fundamenta.cl',
                        cc: '',
                        subject: 'Reporte de Escrituración - Fundamenta',
                        emailIntro: 'Compartimos el avance de escrituración correspondiente al período.',
                        emailOutro: 'Saludos cordiales,\nControl de Gestión Fundamenta',
                        elements: ['kpis', 'uni_parcial', 'uf_parcial'],
                        customTextBlocks: [],
                        includeTables: true,
                        isActive: true
                      });
                    }}
                    className="px-4 py-2 bg-emerald-700 hover:bg-emerald-800 text-white text-xs font-semibold rounded-xl transition flex items-center gap-2 shadow"
                  >
                    <i className="bi bi-plus-lg"></i>
                    <span>Programar Nuevo Envío</span>
                  </button>
                </div>

                {/* 3. Listado de Reportes Programados */}
                <div className="grid grid-cols-1 md:grid-cols-2 gap-5">
                  {schedules.map((sc) => (
                    <div key={sc.id} className="bg-white p-5 rounded-2xl border border-gray-200 card-shadow space-y-4 flex flex-col justify-between">
                      <div className="space-y-3">
                        <div className="flex items-start justify-between">
                          <div>
                            <div className="flex items-center gap-2">
                              <h4 className="font-bold text-sm text-gray-900">{sc.name}</h4>
                              <span className={'text-[10px] font-bold px-2 py-0.5 rounded-full ' + (sc.isActive ? 'bg-emerald-50 text-emerald-700 border border-emerald-200' : 'bg-gray-100 text-gray-500')}>
                                {sc.isActive ? 'Activo' : 'Pausado'}
                              </span>
                            </div>
                            <p className="text-xs text-gray-500 mt-1 flex items-center gap-1.5">
                              <i className="bi bi-calendar3 text-emerald-600"></i>
                              <span>Frecuencia: <b className="capitalize">{sc.frequency || 'Semanal'}</b> · {sc.days.map(d => ['Lun', 'Mar', 'Mié', 'Jue', 'Vie', 'Sáb', 'Dom'][parseInt(d)-1]).join(', ')} a las <b>{sc.time} hrs</b></span>
                            </p>
                          </div>
                          <div className="flex items-center gap-1">
                            <button
                              onClick={() => setEditingSchedule(sc)}
                              className="p-1.5 text-gray-400 hover:text-emerald-700 rounded-lg hover:bg-gray-50 transition"
                              title="Editar contenido y programación"
                            >
                              <i className="bi bi-pencil-square text-base"></i>
                            </button>
                            <button
                              onClick={() => {
                                if (confirm('¿Deseas eliminar esta programación de reporte?')) {
                                  setSchedules(schedules.filter(s => s.id !== sc.id));
                                }
                              }}
                              className="p-1.5 text-gray-400 hover:text-red-600 rounded-lg hover:bg-gray-50 transition"
                              title="Eliminar"
                            >
                              <i className="bi bi-trash text-base"></i>
                            </button>
                          </div>
                        </div>

                        {/* Destinatarios */}
                        <div className="text-xs bg-gray-50 p-2.5 rounded-xl border border-gray-100 space-y-1">
                          <div className="truncate"><span className="text-gray-400 font-medium">Para:</span> <span className="text-gray-700 font-medium">{sc.recipients}</span></div>
                          {sc.cc && <div className="truncate"><span className="text-gray-400 font-medium">CC:</span> <span className="text-gray-700 font-medium">{sc.cc}</span></div>}
                          <div className="truncate"><span className="text-gray-400 font-medium">Asunto:</span> <span className="text-gray-800 font-bold">{sc.subject || 'Reporte de Escrituración'}</span></div>
                        </div>

                        {/* Elementos Incluidos en el Correo (Pantallazos y Tablas) */}
                        <div className="space-y-1.5">
                          <span className="text-[11px] font-semibold text-gray-500 uppercase tracking-wider block">
                            Contenido del Correo ({sc.elements.length} elementos gráficos):
                          </span>
                          <div className="flex flex-wrap gap-1.5">
                            {sc.elements.includes('kpis') && <span className="text-[10px] bg-emerald-50 text-emerald-700 px-2 py-0.5 rounded-md border border-emerald-200">Tarjetas KPI</span>}
                            {sc.elements.includes('uni_parcial') && <span className="text-[10px] bg-emerald-50 text-emerald-700 px-2 py-0.5 rounded-md border border-emerald-200">Gráfico Unidades</span>}
                            {sc.elements.includes('uf_parcial') && <span className="text-[10px] bg-emerald-50 text-emerald-700 px-2 py-0.5 rounded-md border border-emerald-200">Gráfico UF</span>}
                            {sc.elements.includes('uni_tabla') && <span className="text-[10px] bg-emerald-50 text-emerald-700 px-2 py-0.5 rounded-md border border-emerald-200">Tabla Proyectos</span>}
                            {sc.elements.includes('estados') && <span className="text-[10px] bg-emerald-50 text-emerald-700 px-2 py-0.5 rounded-md border border-emerald-200">Estados de Firma</span>}
                            {sc.customTextBlocks && sc.customTextBlocks.length > 0 && (
                              <span className="text-[10px] bg-purple-50 text-purple-700 px-2 py-0.5 rounded-md border border-purple-200">
                                +{sc.customTextBlocks.length} texto personalizado
                              </span>
                            )}
                          </div>
                        </div>
                      </div>

                      {/* Footer de Tarjeta con botón de Vista Previa y Envío Inmediato */}
                      <div className="pt-3 border-t border-gray-100 flex items-center justify-between">
                        <div className="flex items-center gap-2">
                          <button
                            type="button"
                            onClick={() => setPreviewEmailModal(sc)}
                            className="px-2.5 py-1 border border-gray-300 hover:bg-gray-50 text-gray-700 text-xs font-semibold rounded-lg flex items-center gap-1 transition"
                            title="Ver cómo llegará el correo a los destinatarios"
                          >
                            <i className="bi bi-eye"></i>
                            <span>Vista Previa</span>
                          </button>

                          <button
                            disabled={testSending}
                            onClick={() => sendActualEmail(sc)}
                            className="px-3 py-1 bg-emerald-700 hover:bg-emerald-800 text-white text-xs font-semibold rounded-lg flex items-center gap-1 transition shadow-sm disabled:opacity-50"
                          >
                            <i className="bi bi-send"></i>
                            <span>{testSending ? 'Enviando...' : 'Enviar Ahora'}</span>
                          </button>
                        </div>

                        <label className="flex items-center gap-1.5 text-xs text-gray-600 cursor-pointer">
                          <input
                            type="checkbox"
                            checked={sc.isActive}
                            onChange={(e) => {
                              setSchedules(schedules.map(s => s.id === sc.id ? { ...s, isActive: e.target.checked } : s));
                            }}
                            className="rounded text-emerald-600 focus:ring-emerald-500"
                          />
                          <span>Activo</span>
                        </label>
                      </div>
                    </div>
                  ))}
                </div>

                {/* 4. MODAL / EDITOR INTERACTIVO DE CORREO Y PROGRAMACIÓN */}
                {editingSchedule && (
                  <div className="fixed inset-0 bg-black/50 backdrop-blur-sm z-50 flex items-center justify-center p-3 sm:p-4">
                    <div className="bg-white rounded-2xl max-w-5xl w-full shadow-2xl max-h-[92vh] flex flex-col overflow-hidden animate-in fade-in zoom-in-95 duration-150">
                      
                      {/* Cabecera Sticky con Selector de Modo (Editor / Vista Previa en Vivo) */}
                      <div className="flex flex-col sm:flex-row sm:items-center justify-between border-b px-6 py-3.5 bg-white sticky top-0 z-20 flex-shrink-0 shadow-sm gap-3">
                        <div className="flex items-center gap-3">
                          <div className="w-9 h-9 rounded-xl bg-emerald-50 text-emerald-800 flex items-center justify-center text-lg border border-emerald-100 flex-shrink-0">
                            <i className="bi bi-envelope-paper-heart"></i>
                          </div>
                          <div>
                            <h3 className="font-bold text-sm text-gray-900 leading-tight">Configurar y Personalizar Reporte de Correo</h3>
                            <p className="text-[11px] text-gray-500">Diseña el mensaje con bloques interactivos y visualiza el reporte real en vivo</p>
                          </div>
                        </div>

                        <div className="flex items-center gap-2">
                          {/* Selector de Pestañas: Edición vs Vista Previa */}
                          <div className="inline-flex p-1 bg-gray-100 rounded-xl border border-gray-200 text-xs font-semibold">
                            <button
                              type="button"
                              onClick={() => setEditingSchedule({ ...editingSchedule, _activeTab: 'edit' })}
                              className={'px-3.5 py-1.5 rounded-lg transition flex items-center gap-1.5 ' + ((editingSchedule._activeTab || 'edit') === 'edit' ? 'bg-white text-emerald-900 shadow-sm' : 'text-gray-600 hover:text-gray-900')}
                            >
                              <i className="bi bi-pencil-square"></i>
                              <span>Editor</span>
                            </button>
                            <button
                              type="button"
                              onClick={() => setEditingSchedule({ ...editingSchedule, _activeTab: 'preview' })}
                              className={'px-3.5 py-1.5 rounded-lg transition flex items-center gap-1.5 ' + (editingSchedule._activeTab === 'preview' ? 'bg-white text-emerald-900 shadow-sm' : 'text-gray-600 hover:text-gray-900')}
                            >
                              <i className="bi bi-eye"></i>
                              <span>Vista Previa del Correo</span>
                            </button>
                          </div>

                          <button
                            onClick={() => setEditingSchedule(null)}
                            className="text-gray-400 hover:text-gray-600 text-base w-8 h-8 rounded-full flex items-center justify-center hover:bg-gray-100 transition ml-1"
                            title="Cerrar modal"
                          >
                            ✕
                          </button>
                        </div>
                      </div>

                      {/* Cuerpo Central con Scroll */}
                      <div className="p-6 overflow-y-auto flex-1 space-y-5 text-xs bg-gray-50/50">
                        
                        {/* ========================================================================= */}
                        {/* VISTA 1: EDITOR DE CORREO                                                 */}
                        {/* ========================================================================= */}
                        {(editingSchedule._activeTab || 'edit') === 'edit' && (
                          <div className="space-y-5 max-w-4xl mx-auto">
                            
                            {/* 1. SELECCIÓN DEL REPORTE AUTOMÁTICO A ENVIAR */}
                            <div className="bg-white p-4 rounded-xl border border-gray-200 card-shadow space-y-3">
                              <div className="flex items-center justify-between">
                                <label className="font-bold text-gray-800 flex items-center gap-2">
                                  <span className="w-5 h-5 rounded-full bg-emerald-100 text-emerald-800 flex items-center justify-center text-[10px] font-bold">1</span>
                                  <span>¿Qué reporte deseas enviar automáticamente?</span>
                                </label>
                                <span className="text-[10px] bg-emerald-50 text-emerald-700 font-bold px-2 py-0.5 rounded border border-emerald-200">
                                  Reporte Activo
                                </span>
                              </div>

                              <div className="grid grid-cols-1 sm:grid-cols-3 gap-3">
                                {/* Opción 1: Escrituración */}
                                <label
                                  className={'p-3 rounded-xl border-2 transition cursor-pointer flex flex-col justify-between ' + ((editingSchedule.reportId || 'escrituracion') === 'escrituracion' ? 'border-emerald-600 bg-emerald-50/60 text-emerald-950 shadow-sm' : 'border-gray-200 bg-white hover:bg-gray-50 text-gray-700')}
                                >
                                  <div className="flex items-start justify-between">
                                    <div className="flex items-center gap-2 font-bold text-xs">
                                      <i className="bi bi-file-earmark-check text-emerald-700 text-sm"></i>
                                      <span>Escrituración</span>
                                    </div>
                                    <input
                                      type="radio"
                                      name="reportChoice"
                                      value="escrituracion"
                                      checked={(editingSchedule.reportId || 'escrituracion') === 'escrituracion'}
                                      onChange={() => setEditingSchedule({ ...editingSchedule, reportId: 'escrituracion' })}
                                      className="text-emerald-600 focus:ring-emerald-500"
                                    />
                                  </div>
                                  <p className="text-[11px] text-gray-500 mt-2">
                                    Metas UF, Unidades, estados de firma y avance de departamentos 2026.
                                  </p>
                                </label>

                                {/* Opción 2: Ventas y Promesas (Próximamente) */}
                                <label className="p-3 rounded-xl border border-gray-200 bg-gray-50 opacity-60 flex flex-col justify-between cursor-not-allowed">
                                  <div className="flex items-start justify-between">
                                    <div className="flex items-center gap-2 font-bold text-xs text-gray-500">
                                      <i className="bi bi-graph-up-arrow"></i>
                                      <span>Ventas y Promesas</span>
                                    </div>
                                    <span className="text-[9px] bg-gray-200 text-gray-600 px-1.5 py-0.5 rounded font-bold">Próx.</span>
                                  </div>
                                  <p className="text-[11px] text-gray-400 mt-2">
                                    Flujo comercial, promesas netas y ritmo de colocación.
                                  </p>
                                </label>

                                {/* Opción 3: Cobranza y Alzamientos (Próximamente) */}
                                <label className="p-3 rounded-xl border border-gray-200 bg-gray-50 opacity-60 flex flex-col justify-between cursor-not-allowed">
                                  <div className="flex items-start justify-between">
                                    <div className="flex items-center gap-2 font-bold text-xs text-gray-500">
                                      <i className="bi bi-cash-coin"></i>
                                      <span>Flujo y Cobranza</span>
                                    </div>
                                    <span className="text-[9px] bg-gray-200 text-gray-600 px-1.5 py-0.5 rounded font-bold">Próx.</span>
                                  </div>
                                  <p className="text-[11px] text-gray-400 mt-2">
                                    Recuperación de subsidios, abonos clientes y liquidación.
                                  </p>
                                </label>
                              </div>
                            </div>

                            {/* 2. DESTINATARIOS Y FRECUENCIA */}
                            <div className="bg-white p-4 rounded-xl border border-gray-200 card-shadow space-y-3">
                              <label className="font-bold text-gray-800 flex items-center gap-2">
                                <span className="w-5 h-5 rounded-full bg-emerald-100 text-emerald-800 flex items-center justify-center text-[10px] font-bold">2</span>
                                <span>Frecuencia y Destinatarios del Envío</span>
                              </label>

                              <div className="grid grid-cols-1 md:grid-cols-2 gap-3">
                                <div>
                                  <span className="font-semibold text-gray-700 block mb-1">Nombre del Reporte:</span>
                                  <input
                                    type="text"
                                    value={editingSchedule.name}
                                    onChange={(e) => setEditingSchedule({ ...editingSchedule, name: e.target.value })}
                                    className="w-full border border-gray-300 rounded-lg p-2 font-semibold bg-gray-50/50"
                                  />
                                </div>
                                <div>
                                  <span className="font-semibold text-gray-700 block mb-1">Asunto de Correo (Gmail):</span>
                                  <input
                                    type="text"
                                    value={editingSchedule.subject || ''}
                                    onChange={(e) => setEditingSchedule({ ...editingSchedule, subject: e.target.value })}
                                    placeholder="ej: Reporte de Avance de Escrituración - Fundamenta"
                                    className="w-full border border-gray-300 rounded-lg p-2 bg-gray-50/50"
                                  />
                                </div>
                              </div>

                              <div className="grid grid-cols-1 sm:grid-cols-3 gap-3">
                                <div>
                                  <span className="font-semibold text-gray-700 block mb-1">Frecuencia:</span>
                                  <select
                                    value={editingSchedule.frequency || 'semanal'}
                                    onChange={(e) => setEditingSchedule({ ...editingSchedule, frequency: e.target.value })}
                                    className="w-full border border-gray-300 rounded-lg p-2 bg-white"
                                  >
                                    <option value="diario">Diario (Lunes a Viernes)</option>
                                    <option value="semanal">Semanal</option>
                                    <option value="quincenal">Quincenal</option>
                                    <option value="mensual">Mensual (Cierre de mes)</option>
                                  </select>
                                </div>
                                <div>
                                  <span className="font-semibold text-gray-700 block mb-1">Hora de Envío (Chile):</span>
                                  <input
                                    type="time"
                                    value={editingSchedule.time}
                                    onChange={(e) => setEditingSchedule({ ...editingSchedule, time: e.target.value })}
                                    className="w-full border border-gray-300 rounded-lg p-2 bg-white"
                                  />
                                </div>
                                <div>
                                  <span className="font-semibold text-gray-700 block mb-1">Días de la semana:</span>
                                  <div className="flex gap-1 pt-0.5">
                                    {[
                                      { id: '1', l: 'L' },
                                      { id: '2', l: 'M' },
                                      { id: '3', l: 'X' },
                                      { id: '4', l: 'J' },
                                      { id: '5', l: 'V' }
                                    ].map(d => (
                                      <button
                                        type="button"
                                        key={d.id}
                                        onClick={() => {
                                          const exists = editingSchedule.days.includes(d.id);
                                          const updated = exists
                                            ? editingSchedule.days.filter(x => x !== d.id)
                                            : [...editingSchedule.days, d.id];
                                          setEditingSchedule({ ...editingSchedule, days: updated });
                                        }}
                                        className={'w-7 h-7 rounded-lg font-bold text-xs transition ' + (editingSchedule.days.includes(d.id) ? 'bg-emerald-700 text-white shadow' : 'bg-gray-200 text-gray-700 hover:bg-gray-300')}
                                      >
                                        {d.l}
                                      </button>
                                    ))}
                                  </div>
                                </div>
                              </div>

                              <div className="grid grid-cols-1 md:grid-cols-2 gap-3">
                                <div>
                                  <span className="font-semibold text-gray-700 block mb-1">Para (destinatarios separados por coma):</span>
                                  <input
                                    type="text"
                                    value={editingSchedule.recipients}
                                    onChange={(e) => setEditingSchedule({ ...editingSchedule, recipients: e.target.value })}
                                    placeholder="ej: gerencia@fundamenta.cl, finanzas@fundamenta.cl"
                                    className="w-full border border-gray-300 rounded-lg p-2"
                                  />
                                </div>
                                <div>
                                  <span className="font-semibold text-gray-700 block mb-1">CC (con copia):</span>
                                  <input
                                    type="text"
                                    value={editingSchedule.cc}
                                    onChange={(e) => setEditingSchedule({ ...editingSchedule, cc: e.target.value })}
                                    placeholder="ej: mi_correo@fundamenta.cl"
                                    className="w-full border border-gray-300 rounded-lg p-2"
                                  />
                                </div>
                              </div>
                            </div>

                            {/* 3. ELEMENTOS DISPONIBLES DEL REPORTE (CATÁLOGO ARRASTRABLE O CLICKEABLE) */}
                            <div className="bg-white p-4 rounded-xl border border-gray-200 card-shadow space-y-3">
                              <div className="flex items-center justify-between">
                                <label className="font-bold text-gray-800 flex items-center gap-2">
                                  <span className="w-5 h-5 rounded-full bg-emerald-100 text-emerald-800 flex items-center justify-center text-[10px] font-bold">3</span>
                                  <span>Elementos del Reporte a incluir en el correo</span>
                                </label>
                                <span className="text-gray-500 text-[11px] hidden sm:inline">
                                  Arrastra hacia el lienzo o haz clic para agregar/quitar
                                </span>
                              </div>

                              <div className="grid grid-cols-2 sm:grid-cols-4 gap-2.5">
                                {[
                                  { id: 'kpis', icon: 'bi-speedometer2', label: 'Tarjetas KPI Cumplimiento', aspect: '3:1 (Horizontal)', aspectClass: 'aspect-[3/1]' },
                                  { id: 'uni_parcial', icon: 'bi-bar-chart-fill', label: 'Gráfico: Unidades Mensuales', aspect: '16:9 (Gráfico)', aspectClass: 'aspect-[16/9]' },
                                  { id: 'uni_acum', icon: 'bi-graph-up', label: 'Gráfico: Unidades YTD', aspect: '16:9 (Gráfico)', aspectClass: 'aspect-[16/9]' },
                                  { id: 'uf_parcial', icon: 'bi-currency-dollar', label: 'Gráfico: UF Mensuales', aspect: '16:9 (Gráfico)', aspectClass: 'aspect-[16/9]' },
                                  { id: 'uf_acum', icon: 'bi-cash-stack', label: 'Gráfico: UF YTD', aspect: '16:9 (Gráfico)', aspectClass: 'aspect-[16/9]' },
                                  { id: 'estados', icon: 'bi-bar-chart-steps', label: 'Gráfico: Estados de Firma', aspect: '16:9 (Barras)', aspectClass: 'aspect-[16/9]' },
                                  { id: 'uni_tabla', icon: 'bi-table', label: 'Tabla: Desglose Unidades', aspect: '4:3 (Tabla)', aspectClass: 'aspect-[4/3]' },
                                  { id: 'uf_tabla', icon: 'bi-grid-3x3', label: 'Tabla: Desglose UF', aspect: '4:3 (Tabla)', aspectClass: 'aspect-[4/3]' }
                                ].map(elem => {
                                  const isSelected = (editingSchedule.elements || []).includes(elem.id);
                                  return (
                                    <div
                                      key={elem.id}
                                      draggable
                                      onDragStart={(e) => {
                                        e.dataTransfer.setData('text/plain', elem.id);
                                      }}
                                      onClick={() => {
                                        const curElems = editingSchedule.elements || [];
                                        const updated = isSelected
                                          ? curElems.filter(x => x !== elem.id)
                                          : [...curElems, elem.id];
                                        setEditingSchedule({ ...editingSchedule, elements: updated });
                                      }}
                                      className={'p-2.5 rounded-xl border transition cursor-grab active:cursor-grabbing select-none flex flex-col justify-between ' + (isSelected ? 'border-emerald-600 bg-emerald-50/70 text-emerald-950 font-semibold shadow-sm' : 'border-gray-200 bg-gray-50 hover:bg-gray-100 text-gray-700')}
                                      title="Haz clic para agregar o arrastra a la caja inferior"
                                    >
                                      <div className="flex items-center justify-between">
                                        <i className={'bi ' + elem.icon + ' text-base ' + (isSelected ? 'text-emerald-700' : 'text-gray-500')}></i>
                                        <span className={'w-4 h-4 rounded-full flex items-center justify-center text-[10px] ' + (isSelected ? 'bg-emerald-600 text-white' : 'border border-gray-300 bg-white')}>
                                          {isSelected ? '✓' : ''}
                                        </span>
                                      </div>
                                      <span className="text-[11px] mt-2 line-clamp-2 leading-tight">{elem.label}</span>
                                      <span className="text-[9px] text-gray-400 font-mono mt-1 block truncate">Dim: {elem.aspect}</span>
                                    </div>
                                  );
                                })}
                              </div>
                            </div>

                            {/* 4. CUERPO DEL CORREO: TEXTO EDITABLE Y PLACEHOLDERS CON DIMENSIÓN REAL */}
                            <div className="bg-white rounded-xl border border-gray-200 card-shadow overflow-hidden space-y-0">
                              <div className="p-4 border-b border-gray-100 flex items-center justify-between">
                                <label className="font-bold text-gray-800 flex items-center gap-2">
                                  <span className="w-5 h-5 rounded-full bg-emerald-100 text-emerald-800 flex items-center justify-center text-[10px] font-bold">4</span>
                                  <span>Cuerpo del Correo y Elementos Insertados</span>
                                </label>
                                <span className="text-[11px] text-emerald-700 font-medium flex items-center gap-1">
                                  <i className="bi bi-google text-red-500"></i> Formato Gmail Activo
                                </span>
                              </div>

                              {/* Barra de Herramientas de Formato Gmail */}
                              <div className="bg-gray-50 border-b border-gray-200 px-3 py-1.5 flex flex-wrap items-center gap-1 text-gray-700 select-none">
                                <button
                                  type="button"
                                  onClick={() => {
                                    setEditingSchedule({
                                      ...editingSchedule,
                                      emailIntro: (editingSchedule.emailIntro || '') + ' **Texto en Negrita** '
                                    });
                                  }}
                                  className="p-1.5 hover:bg-gray-200 rounded font-bold text-xs"
                                  title="Negrita"
                                >
                                  B
                                </button>
                                <button
                                  type="button"
                                  onClick={() => {
                                    setEditingSchedule({
                                      ...editingSchedule,
                                      emailIntro: (editingSchedule.emailIntro || '') + ' *Texto en Cursiva* '
                                    });
                                  }}
                                  className="p-1.5 hover:bg-gray-200 rounded italic text-xs font-serif"
                                  title="Cursiva"
                                >
                                  I
                                </button>
                                <button
                                  type="button"
                                  onClick={() => {
                                    setEditingSchedule({
                                      ...editingSchedule,
                                      emailIntro: (editingSchedule.emailIntro || '') + ' <u>Texto Subrayado</u> '
                                    });
                                  }}
                                  className="p-1.5 hover:bg-gray-200 rounded underline text-xs"
                                  title="Subrayado"
                                >
                                  U
                                </button>

                                <div className="w-px h-4 bg-gray-300 mx-1"></div>

                                <button
                                  type="button"
                                  onClick={() => {
                                    setEditingSchedule({
                                      ...editingSchedule,
                                      emailIntro: (editingSchedule.emailIntro || '') + '\n• Punto destacado 1\n• Punto destacado 2\n'
                                    });
                                  }}
                                  className="p-1.5 hover:bg-gray-200 rounded text-xs"
                                  title="Lista con viñetas"
                                >
                                  <i className="bi bi-list-ul"></i>
                                </button>
                                <button
                                  type="button"
                                  onClick={() => {
                                    setEditingSchedule({
                                      ...editingSchedule,
                                      emailIntro: (editingSchedule.emailIntro || '') + '\n1. Primer paso\n2. Segundo paso\n'
                                    });
                                  }}
                                  className="p-1.5 hover:bg-gray-200 rounded text-xs"
                                  title="Lista numerada"
                                >
                                  <i className="bi bi-list-ol"></i>
                                </button>

                                <div className="w-px h-4 bg-gray-300 mx-1"></div>

                                <button
                                  type="button"
                                  onClick={() => {
                                    setEditingSchedule({
                                      ...editingSchedule,
                                      emailIntro: (editingSchedule.emailIntro || '') + ' [Plataforma Fundamenta](http://localhost:3000) '
                                    });
                                  }}
                                  className="p-1.5 hover:bg-gray-200 rounded text-xs flex items-center gap-1 text-gray-600 hover:text-emerald-800"
                                  title="Insertar enlace"
                                >
                                  <i className="bi bi-link-45deg text-sm"></i>
                                  <span className="text-[10px]">Enlace</span>
                                </button>

                                <button
                                  type="button"
                                  onClick={() => {
                                    setEditingSchedule({
                                      ...editingSchedule,
                                      emailIntro: (editingSchedule.emailIntro || '') + '\n\n> **Nota de Control de Gestión:** Las metas registradas consideran el avance real al cierre de la última jornada.\n\n'
                                    });
                                  }}
                                  className="p-1.5 hover:bg-gray-200 rounded text-xs flex items-center gap-1 text-gray-600 hover:text-emerald-800"
                                  title="Insertar cita o nota destacada"
                                >
                                  <i className="bi bi-quote text-sm"></i>
                                  <span className="text-[10px]">Cita</span>
                                </button>

                                <div className="w-px h-4 bg-gray-300 mx-1"></div>

                                {/* Botones de Variables Automáticas de Fecha */}
                                <div className="flex items-center gap-1">
                                  <span className="text-[10px] font-bold text-emerald-800 uppercase tracking-wider mr-0.5">Insertar:</span>
                                  <button
                                    type="button"
                                    onClick={() => {
                                      setEditingSchedule({
                                        ...editingSchedule,
                                        emailIntro: (editingSchedule.emailIntro || '') + ' (DÍA)'
                                      });
                                    }}
                                    className="px-2 py-1 bg-emerald-50 hover:bg-emerald-100 text-emerald-900 border border-emerald-300 rounded text-[11px] font-bold transition shadow-xs"
                                    title="Inserta el día actual en número (ej: 15)"
                                  >
                                    (DÍA)
                                  </button>
                                  <button
                                    type="button"
                                    onClick={() => {
                                      setEditingSchedule({
                                        ...editingSchedule,
                                        emailIntro: (editingSchedule.emailIntro || '') + ' (MES)'
                                      });
                                    }}
                                    className="px-2 py-1 bg-emerald-50 hover:bg-emerald-100 text-emerald-900 border border-emerald-300 rounded text-[11px] font-bold transition shadow-xs"
                                    title="Inserta el mes actual (ej: Septiembre)"
                                  >
                                    (MES)
                                  </button>
                                  <button
                                    type="button"
                                    onClick={() => {
                                      setEditingSchedule({
                                        ...editingSchedule,
                                        emailIntro: (editingSchedule.emailIntro || '') + ' (AÑO)'
                                      });
                                    }}
                                    className="px-2 py-1 bg-emerald-50 hover:bg-emerald-100 text-emerald-900 border border-emerald-300 rounded text-[11px] font-bold transition shadow-xs"
                                    title="Inserta el año actual (ej: 2026)"
                                  >
                                    (AÑO)
                                  </button>
                                  <button
                                    type="button"
                                    onClick={() => {
                                      setEditingSchedule({
                                        ...editingSchedule,
                                        emailIntro: (editingSchedule.emailIntro || '') + ' (FECHA)'
                                      });
                                    }}
                                    className="px-2 py-1 bg-emerald-50 hover:bg-emerald-100 text-emerald-900 border border-emerald-300 rounded text-[11px] font-bold transition shadow-xs"
                                    title="Inserta la fecha completa (ej: 15-09-2026)"
                                  >
                                    (FECHA)
                                  </button>
                                </div>
                              </div>

                              {/* Zona de Redacción Principal */}
                              <div className="p-4 space-y-4">
                                <div>
                                  <span className="text-[11px] font-semibold text-gray-600 block mb-1.5">
                                    Texto introductorio del correo:
                                  </span>
                                  <textarea
                                    rows="4"
                                    value={editingSchedule.emailIntro || ''}
                                    onChange={(e) => setEditingSchedule({ ...editingSchedule, emailIntro: e.target.value })}
                                    placeholder="Escribe aquí el saludo y la introducción del correo..."
                                    className="w-full p-3 text-xs text-gray-800 border border-gray-200 rounded-xl focus:ring-1 focus:ring-emerald-500 focus:border-emerald-500 leading-relaxed font-sans resize-y"
                                  ></textarea>
                                </div>

                                {/* Zona de Dropzone y Placeholders con Aspect Ratio Proporcional */}
                                <div
                                  onDragOver={(e) => {
                                    e.preventDefault();
                                    e.currentTarget.classList.add('border-emerald-500', 'bg-emerald-50/40');
                                  }}
                                  onDragLeave={(e) => {
                                    e.preventDefault();
                                    e.currentTarget.classList.remove('border-emerald-500', 'bg-emerald-50/40');
                                  }}
                                  onDrop={(e) => {
                                    e.preventDefault();
                                    e.currentTarget.classList.remove('border-emerald-500', 'bg-emerald-50/40');
                                    const elemId = e.dataTransfer.getData('text/plain');
                                    if (elemId) {
                                      const curElems = editingSchedule.elements || [];
                                      if (!curElems.includes(elemId)) {
                                        setEditingSchedule({
                                          ...editingSchedule,
                                          elements: [...curElems, elemId]
                                        });
                                      }
                                    }
                                  }}
                                  className="p-4 border-2 border-dashed border-gray-300 rounded-2xl bg-gray-50/60 transition space-y-4 min-h-[140px]"
                                >
                                  <div className="flex items-center justify-between text-xs pb-1 border-b border-gray-200">
                                    <div className="flex items-center gap-2">
                                      <i className="bi bi-box-arrow-in-down text-emerald-700 text-sm"></i>
                                      <span className="font-bold text-gray-800">
                                        Lienzo de Elementos Insertados ({(editingSchedule.elements || []).length})
                                      </span>
                                    </div>
                                    <span className="text-[11px] text-gray-500">
                                      Suelta aquí elementos del reporte para agregarlos
                                    </span>
                                  </div>

                                  {(editingSchedule.elements || []).length === 0 ? (
                                    <div className="py-8 text-center text-gray-400 space-y-2">
                                      <i className="bi bi-plus-circle-dotted text-3xl block text-gray-300"></i>
                                      <p className="text-xs">No has agregado elementos del reporte al correo aún.</p>
                                      <p className="text-[11px] text-gray-400">
                                        Arrastra cualquier tarjeta desde el catálogo superior o haz clic en ella.
                                      </p>
                                    </div>
                                  ) : (
                                    <div className="space-y-4">
                                      {(editingSchedule.elements || []).map((elemId, index) => {
                                        const catalogMap = {
                                          kpis: { icon: 'bi-speedometer2', label: 'Tarjetas KPI Cumplimiento', desc: 'Resumen en vivo de Cumplimiento Unidades y UF vs Metas', aspect: '3:1 (Horizontal)', aspectClass: 'aspect-[3/1]' },
                                          uni_parcial: { icon: 'bi-bar-chart-fill', label: 'Gráfico: Unidades Mensuales', desc: 'Barras comparativas Real vs Presupuesto mes a mes', aspect: '16:9 (Panorámica)', aspectClass: 'aspect-[16/9]' },
                                          uni_acum: { icon: 'bi-graph-up', label: 'Gráfico: Unidades YTD', desc: 'Evolución de departamentos escriturados acumulados', aspect: '16:9 (Panorámica)', aspectClass: 'aspect-[16/9]' },
                                          uf_parcial: { icon: 'bi-currency-dollar', label: 'Gráfico: UF Mensuales', desc: 'Monto mensual recaudado vs presupuesto financiero', aspect: '16:9 (Panorámica)', aspectClass: 'aspect-[16/9]' },
                                          uf_acum: { icon: 'bi-cash-stack', label: 'Gráfico: UF YTD', desc: 'Facturación y cobranza en UF acumulada a la fecha', aspect: '16:9 (Panorámica)', aspectClass: 'aspect-[16/9]' },
                                          estados: { icon: 'bi-bar-chart-steps', label: 'Gráfico: Estados de Firma por Proyecto', desc: 'Desglose porcentual 100% apilado por etapa de tramitación', aspect: '16:9 (Panorámica)', aspectClass: 'aspect-[16/9]' },
                                          uni_tabla: { icon: 'bi-table', label: 'Tabla: Desglose Unidades por Proyecto', desc: 'Tabla detallada con Real, Presupuesto y % Cumplimiento', aspect: '4:3 (Tabla Estructurada)', aspectClass: 'aspect-[4/3]' },
                                          uf_tabla: { icon: 'bi-grid-3x3', label: 'Tabla: Desglose UF por Proyecto', desc: 'Tabla detallada de montos UF por cada proyecto activo', aspect: '4:3 (Tabla Estructurada)', aspectClass: 'aspect-[4/3]' }
                                        };
                                        const info = catalogMap[elemId] || { icon: 'bi-card-image', label: elemId, desc: 'Elemento del reporte', aspect: '16:9', aspectClass: 'aspect-[16/9]' };

                                        return (
                                          <div
                                            key={elemId}
                                            className="w-full bg-white rounded-xl border-2 border-emerald-500/80 shadow-sm overflow-hidden flex flex-col group transition hover:border-emerald-600 hover:shadow-md"
                                          >
                                            {/* Cabecera del Placeholder */}
                                            <div className="bg-emerald-50/90 px-4 py-2 border-b border-emerald-200 flex items-center justify-between">
                                              <div className="flex items-center gap-2 font-bold text-emerald-950 text-xs">
                                                <span className="w-5 h-5 rounded-full bg-emerald-700 text-white flex items-center justify-center text-[10px]">
                                                  {index + 1}
                                                </span>
                                                <i className={'bi ' + info.icon + ' text-emerald-700'}></i>
                                                <span>{info.label}</span>
                                              </div>

                                              <div className="flex items-center gap-2">
                                                <span className="text-[10px] font-mono bg-white text-emerald-800 px-2 py-0.5 rounded border border-emerald-200 font-semibold">
                                                  Dimensión: {info.aspect}
                                                </span>
                                                {/* Mover hacia arriba */}
                                                {index > 0 && (
                                                  <button
                                                    type="button"
                                                    onClick={() => {
                                                      const arr = [...editingSchedule.elements];
                                                      const temp = arr[index - 1];
                                                      arr[index - 1] = arr[index];
                                                      arr[index] = temp;
                                                      setEditingSchedule({ ...editingSchedule, elements: arr });
                                                    }}
                                                    className="w-6 h-6 rounded bg-white hover:bg-emerald-100 text-gray-600 hover:text-emerald-900 border border-gray-200 flex items-center justify-center text-xs transition"
                                                    title="Mover arriba"
                                                  >
                                                    ↑
                                                  </button>
                                                )}
                                                {/* Mover hacia abajo */}
                                                {index < editingSchedule.elements.length - 1 && (
                                                  <button
                                                    type="button"
                                                    onClick={() => {
                                                      const arr = [...editingSchedule.elements];
                                                      const temp = arr[index + 1];
                                                      arr[index + 1] = arr[index];
                                                      arr[index] = temp;
                                                      setEditingSchedule({ ...editingSchedule, elements: arr });
                                                    }}
                                                    className="w-6 h-6 rounded bg-white hover:bg-emerald-100 text-gray-600 hover:text-emerald-900 border border-gray-200 flex items-center justify-center text-xs transition"
                                                    title="Mover abajo"
                                                  >
                                                    ↓
                                                  </button>
                                                )}
                                                {/* Eliminar elemento */}
                                                <button
                                                  type="button"
                                                  onClick={() => {
                                                    const updated = editingSchedule.elements.filter(x => x !== elemId);
                                                    setEditingSchedule({ ...editingSchedule, elements: updated });
                                                  }}
                                                  className="w-6 h-6 rounded bg-white hover:bg-red-50 text-gray-400 hover:text-red-600 border border-gray-200 flex items-center justify-center text-xs transition"
                                                  title="Remover este elemento del correo"
                                                >
                                                  ✕
                                                </button>
                                              </div>
                                            </div>

                                            {/* Área Placeholder que respeta la razón de aspecto real del elemento */}
                                            <div className={'w-full ' + info.aspectClass + ' max-h-[220px] bg-gradient-to-br from-emerald-50/20 via-gray-50 to-white flex flex-col items-center justify-center p-6 text-center border-dashed border-gray-200 relative'}>
                                              <div className="w-12 h-12 rounded-2xl bg-emerald-100/70 text-emerald-800 flex items-center justify-center text-2xl mb-2 shadow-inner">
                                                <i className={'bi ' + info.icon}></i>
                                              </div>
                                              <h5 className="font-bold text-gray-800 text-xs">{info.label}</h5>
                                              <p className="text-[11px] text-gray-500 max-w-sm mt-0.5">{info.desc}</p>
                                              <div className="mt-3 flex items-center gap-2 text-[10px] text-emerald-700 bg-emerald-50/80 px-2.5 py-1 rounded-full border border-emerald-200 font-medium">
                                                <i className="bi bi-eye"></i>
                                                <span>Se renderizará con los datos reales vigentes en la pestaña <b>Vista Previa</b></span>
                                              </div>
                                            </div>
                                          </div>
                                        );
                                      })}
                                    </div>
                                  )}
                                </div>

                                {/* Texto de Cierre o Despedida */}
                                <div>
                                  <span className="text-[11px] font-semibold text-gray-600 block mb-1.5">
                                    Texto de cierre y firma del correo:
                                  </span>
                                  <textarea
                                    rows="2"
                                    value={editingSchedule.emailOutro || ''}
                                    onChange={(e) => setEditingSchedule({ ...editingSchedule, emailOutro: e.target.value })}
                                    placeholder="Saludos cordiales,..."
                                    className="w-full p-3 text-xs text-gray-800 border border-gray-200 rounded-xl focus:ring-1 focus:ring-emerald-500 focus:border-emerald-500 leading-relaxed font-sans resize-y"
                                  ></textarea>
                                </div>
                              </div>

                              <div className="bg-gray-50 p-3 border-t border-gray-100 flex items-center justify-between text-[11px] text-gray-500">
                                <span>Tip: Puedes alternar en cualquier instante a la pestaña <b>Vista Previa del Correo</b> para ver las tablas y gráficos renderizados en tiempo real.</span>
                              </div>
                            </div>
                          </div>
                        )}

                        {/* ========================================================================= */}
                        {/* VISTA 2: VISTA PREVIA EN VIVO RENDERIZADA EN TIEMPO REAL CON DATOS REALES */}
                        {/* ========================================================================= */}
                        {editingSchedule._activeTab === 'preview' && (
                          <div className="max-w-3xl mx-auto space-y-4">
                            {/* Simulación Ventana Gmail */}
                            <div className="border border-gray-200 rounded-2xl overflow-hidden shadow-sm bg-white">
                              
                              {/* Barra de correo Gmail */}
                              <div className="bg-gray-100/80 px-5 py-3 border-b border-gray-200 text-xs space-y-1">
                                <div className="flex items-center justify-between">
                                  <div><span className="text-gray-400 font-medium">De:</span> <span className="font-bold text-gray-900">{gmailSenderName} &lt;{gmailAccount}&gt;</span></div>
                                  <span className="text-[10px] text-emerald-700 bg-emerald-50 px-2 py-0.5 rounded font-semibold border border-emerald-200">
                                    Vista Previa Renderizada
                                  </span>
                                </div>
                                <div><span className="text-gray-400 font-medium">Para:</span> <span className="text-gray-800">{editingSchedule.recipients || 'destinatarios@fundamenta.cl'}</span></div>
                                {editingSchedule.cc && <div><span className="text-gray-400 font-medium">CC:</span> <span className="text-gray-800">{editingSchedule.cc}</span></div>}
                                <div><span className="text-gray-400 font-medium">Asunto:</span> <span className="font-bold text-emerald-950">{replaceDateVariables(editingSchedule.subject || 'Reporte de Avance - Fundamenta')}</span></div>
                              </div>

                              {/* Contenido HTML Efectivo del Correo */}
                              <div className="p-6 sm:p-8 space-y-6 text-xs text-gray-800">
                                
                                {/* Header con Logo Fundamenta */}
                                <div className="flex items-center justify-between pb-4 border-b border-emerald-900/20">
                                  <div className="flex items-center gap-2.5">
                                    <div className="w-8 h-8 rounded-lg bg-emerald-900 flex items-center justify-center p-1 flex-shrink-0">
                                      <img src="/logo-fundamenta.png" alt="Fundamenta" className="w-full h-full object-contain" />
                                    </div>
                                    <div>
                                      <b className="text-sm font-bold text-emerald-950 block">Fundamenta</b>
                                      <span className="text-[10px] text-emerald-700 font-medium">
                                        Reportería Automática · {editingSchedule.reportId === 'escrituracion' ? 'Escrituración' : 'Comercial'}
                                      </span>
                                    </div>
                                  </div>
                                  <span className="text-[11px] text-gray-400 font-mono">
                                    {new Date().toLocaleDateString('es-CL', { day: '2-digit', month: '2-digit', year: 'numeric' })}
                                  </span>
                                </div>

                                {/* Texto redactado por el usuario (Introducción) */}
                                <div className="whitespace-pre-line text-gray-700 leading-relaxed font-sans">
                                  {replaceDateVariables(editingSchedule.emailIntro || 'Estimado equipo, adjuntamos el reporte consolidado correspondiente al período (DÍA) (MES) (AÑO).')}
                                </div>

                                {/* Elementos seleccionados incrustados en el correo en el orden configurado */}
                                <div className="space-y-6 pt-2">
                                  {(editingSchedule.elements || []).map((elemId) => {
                                    if (elemId === 'kpis' && metrics) {
                                      return (
                                        <div key={elemId} className="bg-gray-50 p-4 rounded-xl border border-gray-200 space-y-2">
                                          <div className="font-bold text-emerald-950 flex items-center gap-1.5 pb-1 border-b border-gray-200">
                                            <i className="bi bi-speedometer2 text-emerald-700"></i>
                                            <span>Cumplimiento de Metas Consolidadas YTD 2026</span>
                                          </div>
                                          <div className="grid grid-cols-2 gap-3 pt-1">
                                            <div className="p-3 bg-white rounded-lg border text-center shadow-sm">
                                              <span className="text-[10px] text-gray-500 uppercase font-semibold block">Cumplimiento Unidades YTD</span>
                                              <b className="text-xl text-emerald-700 font-bold">{Math.round(metrics.pctCumplimientoUniMesVigente * 100)}%</b>
                                              <span className="text-[10px] text-gray-400 block mt-0.5">{metrics.totalRealUni} de {metrics.totalPptoUniMesVigente} un.</span>
                                            </div>
                                            <div className="p-3 bg-white rounded-lg border text-center shadow-sm">
                                              <span className="text-[10px] text-gray-500 uppercase font-semibold block">Cumplimiento UF YTD</span>
                                              <b className="text-xl text-emerald-700 font-bold">{Math.round(metrics.pctCumplimientoUFMesVigente * 100)}%</b>
                                              <span className="text-[10px] text-gray-400 block mt-0.5">{Math.round(metrics.totalRealUF).toLocaleString('es-CL')} UF</span>
                                            </div>
                                          </div>
                                        </div>
                                      );
                                    }

                                    if (elemId === 'uni_parcial' && metrics) {
                                      return (
                                        <div key={elemId} className="border border-gray-200 rounded-xl overflow-hidden shadow-sm bg-white">
                                          <div className="bg-emerald-900 text-white p-2.5 font-bold text-xs flex items-center justify-between">
                                            <span>Gráfico: Escrituras Parciales (Mes a Mes) · Unidades</span>
                                            <span className="text-[10px] bg-emerald-800 px-2 py-0.5 rounded font-mono">Render en Vivo</span>
                                          </div>
                                          <div className="p-3">
                                            <EChart option={optUnidadesParcial} height="280px" />
                                          </div>
                                        </div>
                                      );
                                    }

                                    if (elemId === 'uni_acum' && metrics) {
                                      return (
                                        <div key={elemId} className="border border-gray-200 rounded-xl overflow-hidden shadow-sm bg-white">
                                          <div className="bg-emerald-900 text-white p-2.5 font-bold text-xs flex items-center justify-between">
                                            <span>Gráfico: Escrituras Acumuladas YTD · Unidades</span>
                                            <span className="text-[10px] bg-emerald-800 px-2 py-0.5 rounded font-mono">Render en Vivo</span>
                                          </div>
                                          <div className="p-3">
                                            <EChart option={optUnidadesAcum} height="280px" />
                                          </div>
                                        </div>
                                      );
                                    }

                                    if (elemId === 'uf_parcial' && metrics) {
                                      return (
                                        <div key={elemId} className="border border-gray-200 rounded-xl overflow-hidden shadow-sm bg-white">
                                          <div className="bg-emerald-900 text-white p-2.5 font-bold text-xs flex items-center justify-between">
                                            <span>Gráfico: Escrituras Parciales (Mes a Mes) · Monto UF</span>
                                            <span className="text-[10px] bg-emerald-800 px-2 py-0.5 rounded font-mono">Render en Vivo</span>
                                          </div>
                                          <div className="p-3">
                                            <EChart option={optUFParcial} height="280px" />
                                          </div>
                                        </div>
                                      );
                                    }

                                    if (elemId === 'uf_acum' && metrics) {
                                      return (
                                        <div key={elemId} className="border border-gray-200 rounded-xl overflow-hidden shadow-sm bg-white">
                                          <div className="bg-emerald-900 text-white p-2.5 font-bold text-xs flex items-center justify-between">
                                            <span>Gráfico: Escrituras Acumuladas YTD · Monto UF</span>
                                            <span className="text-[10px] bg-emerald-800 px-2 py-0.5 rounded font-mono">Render en Vivo</span>
                                          </div>
                                          <div className="p-3">
                                            <EChart option={optUFAcum} height="280px" />
                                          </div>
                                        </div>
                                      );
                                    }

                                    if (elemId === 'estados' && metrics) {
                                      return (
                                        <div key={elemId} className="border border-gray-200 rounded-xl overflow-hidden shadow-sm bg-white">
                                          <div className="bg-emerald-900 text-white p-2.5 font-bold text-xs flex items-center justify-between">
                                            <span>Gráfico: Estados de Firma por Proyecto (100% Apilado)</span>
                                            <span className="text-[10px] bg-emerald-800 px-2 py-0.5 rounded font-mono">Render en Vivo</span>
                                          </div>
                                          <div className="p-3">
                                            <EChart option={optEstadosFirma} height="320px" />
                                          </div>
                                        </div>
                                      );
                                    }

                                    if (elemId === 'uni_tabla' && metrics) {
                                      return (
                                        <div key={elemId} className="border border-gray-200 rounded-xl overflow-hidden shadow-sm bg-white">
                                          <div className="bg-emerald-900 text-white p-2.5 font-bold text-xs flex items-center justify-between">
                                            <span>Tabla de Cumplimiento por Proyecto · Unidades (Mes Vigente: {metrics.mesVigenteLabel})</span>
                                            <span className="text-[10px] bg-emerald-800 px-2 py-0.5 rounded font-mono">YTD 2026</span>
                                          </div>
                                          <table className="w-full text-xs text-left">
                                            <thead className="bg-gray-50 text-gray-600 border-b border-gray-200">
                                              <tr>
                                                <th className="p-2.5 font-bold">Proyecto</th>
                                                <th className="p-2.5 text-right font-bold">Real Unidades</th>
                                                <th className="p-2.5 text-right font-bold">Ppto Mes</th>
                                                <th className="p-2.5 text-right font-bold">% Cumpl.</th>
                                              </tr>
                                            </thead>
                                            <tbody className="divide-y divide-gray-100">
                                              {metrics.projectBreakdown.slice(0, 8).map(p => {
                                                const pct = p.pptoUni > 0 ? Math.round((p.realUni / p.pptoUni) * 100) : 0;
                                                return (
                                                  <tr key={p.proyecto} className="hover:bg-gray-50">
                                                    <td className="p-2.5 font-semibold text-gray-800">{p.proyecto}</td>
                                                    <td className="p-2.5 text-right font-bold text-emerald-700">{p.realUni}</td>
                                                    <td className="p-2.5 text-right text-gray-600">{p.pptoUni}</td>
                                                    <td className="p-2.5 text-right font-bold">
                                                      <span className={'px-1.5 py-0.5 rounded text-[10px] ' + (pct >= 90 ? 'bg-emerald-100 text-emerald-800' : 'bg-amber-100 text-amber-800')}>
                                                        {pct}%
                                                      </span>
                                                    </td>
                                                  </tr>
                                                );
                                              })}
                                            </tbody>
                                          </table>
                                        </div>
                                      );
                                    }

                                    if (elemId === 'uf_tabla' && metrics) {
                                      return (
                                        <div key={elemId} className="border border-gray-200 rounded-xl overflow-hidden shadow-sm bg-white">
                                          <div className="bg-emerald-900 text-white p-2.5 font-bold text-xs flex items-center justify-between">
                                            <span>Tabla de Cumplimiento por Proyecto · Montos UF (Mes Vigente: {metrics.mesVigenteLabel})</span>
                                            <span className="text-[10px] bg-emerald-800 px-2 py-0.5 rounded font-mono">YTD 2026</span>
                                          </div>
                                          <table className="w-full text-xs text-left">
                                            <thead className="bg-gray-50 text-gray-600 border-b border-gray-200">
                                              <tr>
                                                <th className="p-2.5 font-bold">Proyecto</th>
                                                <th className="p-2.5 text-right font-bold">Real UF</th>
                                                <th className="p-2.5 text-right font-bold">Ppto UF</th>
                                                <th className="p-2.5 text-right font-bold">% Cumpl.</th>
                                              </tr>
                                            </thead>
                                            <tbody className="divide-y divide-gray-100">
                                              {metrics.projectBreakdown.slice(0, 8).map(p => {
                                                const pct = p.pptoUF > 0 ? Math.round((p.realUF / p.pptoUF) * 100) : 0;
                                                return (
                                                  <tr key={p.proyecto} className="hover:bg-gray-50">
                                                    <td className="p-2.5 font-semibold text-gray-800">{p.proyecto}</td>
                                                    <td className="p-2.5 text-right font-bold text-emerald-700">
                                                      {Math.round(p.realUF).toLocaleString('es-CL')}
                                                    </td>
                                                    <td className="p-2.5 text-right text-gray-600">
                                                      {Math.round(p.pptoUF).toLocaleString('es-CL')}
                                                    </td>
                                                    <td className="p-2.5 text-right font-bold">
                                                      <span className={'px-1.5 py-0.5 rounded text-[10px] ' + (pct >= 90 ? 'bg-emerald-100 text-emerald-800' : 'bg-amber-100 text-amber-800')}>
                                                        {pct}%
                                                      </span>
                                                    </td>
                                                  </tr>
                                                );
                                              })}
                                            </tbody>
                                          </table>
                                        </div>
                                      );
                                    }

                                    return null;
                                  })}
                                </div>

                                {/* Despedida */}
                                <div className="whitespace-pre-line text-gray-700 leading-relaxed pt-3 border-t">
                                  {replaceDateVariables(editingSchedule.emailOutro || 'Saludos cordiales,\nControl de Gestión Fundamenta')}
                                </div>

                                {/* Botón de llamada a la acción */}
                                <div className="bg-emerald-50 p-3.5 rounded-xl text-center space-y-1.5 border border-emerald-200/60">
                                  <span className="text-[11px] text-emerald-900 font-semibold block">
                                    Puedes interactuar con los datos y filtros en línea:
                                  </span>
                                  <span className="inline-block px-4 py-1.5 bg-emerald-700 text-white rounded-lg text-xs font-bold shadow-sm">
                                    Abrir Tablero Fundamenta
                                  </span>
                                </div>
                              </div>
                            </div>
                          </div>
                        )}
                      </div>

                      {/* Barra Inferior Sticky con botones Cancelar, Enviar Prueba y Guardar */}
                      <div className="flex items-center justify-between gap-3 px-6 py-4 bg-gray-50 border-t border-gray-200 sticky bottom-0 z-20 flex-shrink-0">
                        <div className="flex items-center gap-2">
                          <button
                            type="button"
                            onClick={() => {
                              const toggleTab = (editingSchedule._activeTab || 'edit') === 'edit' ? 'preview' : 'edit';
                              setEditingSchedule({ ...editingSchedule, _activeTab: toggleTab });
                            }}
                            className="px-3.5 py-2 border border-gray-300 bg-white hover:bg-gray-100 text-gray-700 text-xs font-semibold rounded-xl transition shadow-sm flex items-center gap-1.5"
                          >
                            <i className={'bi ' + ((editingSchedule._activeTab || 'edit') === 'edit' ? 'bi-eye' : 'bi-pencil-square')}></i>
                            <span>{(editingSchedule._activeTab || 'edit') === 'edit' ? 'Ver Vista Previa' : 'Volver a Editar'}</span>
                          </button>

                          <button
                            type="button"
                            disabled={testSending}
                            onClick={() => sendActualEmail(editingSchedule)}
                            className="px-3.5 py-2 bg-white border border-emerald-300 text-emerald-800 hover:bg-emerald-50 text-xs font-semibold rounded-xl transition shadow-sm flex items-center gap-1.5 disabled:opacity-50"
                          >
                            <i className="bi bi-send text-emerald-700"></i>
                            <span>{testSending ? 'Enviando...' : 'Enviar Prueba'}</span>
                          </button>
                        </div>

                        <div className="flex items-center gap-2">
                          <button
                            type="button"
                            onClick={() => setEditingSchedule(null)}
                            className="px-4 py-2 border border-gray-300 text-gray-700 text-xs font-semibold rounded-xl hover:bg-white transition shadow-sm"
                          >
                            Cancelar
                          </button>
                          <button
                            type="button"
                            onClick={() => {
                              const exists = schedules.some(s => s.id === editingSchedule.id);
                              if (exists) {
                                setSchedules(schedules.map(s => s.id === editingSchedule.id ? editingSchedule : s));
                              } else {
                                setSchedules([...schedules, editingSchedule]);
                              }
                              setEditingSchedule(null);
                              alert('✓ Programación y contenido guardados correctamente.');
                            }}
                            className="px-5 py-2 bg-emerald-700 hover:bg-emerald-800 text-white text-xs font-semibold rounded-xl transition shadow flex items-center gap-2"
                          >
                            <i className="bi bi-check2-circle text-sm"></i>
                            <span>Guardar Programación</span>
                          </button>
                        </div>
                      </div>
                    </div>
                  </div>
                )}

{/* 5. MODAL DE VISTA PREVIA DEL CORREO */}
                {previewEmailModal && (
                  <div className="fixed inset-0 bg-black/60 backdrop-blur-sm z-50 flex items-center justify-center p-4">
                    <div className="bg-white rounded-2xl max-w-3xl w-full p-6 space-y-4 shadow-2xl max-h-[90vh] overflow-y-auto animate-in fade-in zoom-in-95 duration-150">
                      <div className="flex items-center justify-between border-b pb-3">
                        <div>
                          <h3 className="font-bold text-base text-gray-900 flex items-center gap-2">
                            <i className="bi bi-eye text-emerald-700"></i>
                            <span>Vista Previa del Correo Interactivo</span>
                          </h3>
                          <p className="text-xs text-gray-500">Así visualizará el destinatario el reporte en su cliente de Gmail</p>
                        </div>
                        <button
                          onClick={() => setPreviewEmailModal(null)}
                          className="text-gray-400 hover:text-gray-600 text-lg"
                        >
                          ✕
                        </button>
                      </div>

                      {/* Simulación del Correo en Gmail */}
                      <div className="border border-gray-200 rounded-xl overflow-hidden shadow-sm bg-gray-50">
                        {/* Cabecera del correo */}
                        <div className="bg-white p-4 border-b border-gray-200 space-y-1.5 text-xs">
                          <div><span className="text-gray-400 font-medium">De:</span> <span className="font-bold text-gray-900">{gmailSenderName} &lt;{gmailAccount}&gt;</span></div>
                          <div><span className="text-gray-400 font-medium">Para:</span> <span className="text-gray-800">{previewEmailModal.recipients}</span></div>
                          {previewEmailModal.cc && <div><span className="text-gray-400 font-medium">CC:</span> <span className="text-gray-800">{previewEmailModal.cc}</span></div>}
                          <div><span className="text-gray-400 font-medium">Asunto:</span> <span className="font-bold text-emerald-950">{replaceDateVariables(previewEmailModal.subject || 'Reporte de Escrituración')}</span></div>
                        </div>

                        {/* Cuerpo del correo con branding Fundamenta */}
                        <div className="p-6 bg-white space-y-6 text-xs text-gray-800 max-w-2xl mx-auto my-4 rounded-xl border border-gray-100 shadow-sm">
                          <div className="flex items-center justify-between pb-4 border-b border-emerald-800/20">
                            <div className="flex items-center gap-2.5">
                              <div className="w-8 h-8 rounded-lg bg-emerald-900 flex items-center justify-center p-1">
                                <img src="/logo-fundamenta.png" alt="Fundamenta" className="w-full h-full object-contain" />
                              </div>
                              <div>
                                <b className="text-sm font-bold text-emerald-950 block">Fundamenta</b>
                                <span className="text-[10px] text-emerald-700">Reportería Automática de Escrituración</span>
                              </div>
                            </div>
                            <span className="text-[11px] text-gray-400 font-mono">
                              {new Date().toLocaleDateString('es-CL')}
                            </span>
                          </div>

                          {/* Introducción */}
                          <p className="whitespace-pre-line text-gray-700 leading-relaxed">
                            {replaceDateVariables(previewEmailModal.emailIntro || 'Estimado equipo, adjuntamos el reporte consolidado correspondiente al período (DÍA) (MES) (AÑO).')}
                          </p>

                          {/* Bloques de Texto Personalizado */}
                          {(previewEmailModal.customTextBlocks || []).map(b => (
                            <div key={b.id} className="bg-emerald-50/60 p-3.5 rounded-xl border-l-4 border-emerald-700 space-y-1">
                              <b className="text-emerald-900 text-xs block">{b.title}</b>
                              <p className="text-gray-700 whitespace-pre-line text-xs">{b.text}</p>
                            </div>
                          ))}

                          {/* Elementos Gráficos Simulados */}
                          <div className="space-y-3">
                            <b className="text-xs text-gray-900 block font-bold border-b pb-1">Visualizaciones y Datos Consolidados:</b>
                            
                            {previewEmailModal.elements.includes('kpis') && metrics && (
                              <div className="grid grid-cols-2 gap-3">
                                <div className="p-3 bg-gray-50 rounded-lg border text-center">
                                  <span className="text-[10px] text-gray-500 uppercase block">Cumplimiento Unidades YTD</span>
                                  <b className="text-lg text-emerald-700 font-bold">{Math.round(metrics.pctCumplimientoUniMesVigente * 100)}%</b>
                                  <span className="text-[10px] text-gray-400 block">{metrics.totalRealUni} / {metrics.totalPptoUniMesVigente} un.</span>
                                </div>
                                <div className="p-3 bg-gray-50 rounded-lg border text-center">
                                  <span className="text-[10px] text-gray-500 uppercase block">Cumplimiento UF YTD</span>
                                  <b className="text-lg text-emerald-700 font-bold">{Math.round(metrics.pctCumplimientoUFMesVigente * 100)}%</b>
                                  <span className="text-[10px] text-gray-400 block">{Math.round(metrics.totalRealUF).toLocaleString('es-CL')} UF</span>
                                </div>
                              </div>
                            )}

                            {previewEmailModal.elements.includes('uni_parcial') && (
                              <div className="p-4 bg-gray-50 rounded-xl border border-dashed border-gray-300 text-center text-gray-500">
                                <i className="bi bi-image text-2xl text-emerald-600 block mb-1"></i>
                                <span className="font-semibold text-gray-700 block">[Pantallazo HD: Comparativo Escrituras Parciales - Unidades]</span>
                                <span className="text-[10px] text-gray-400">Capturado automáticamente al momento de emitir el correo</span>
                              </div>
                            )}

                            {previewEmailModal.elements.includes('uf_parcial') && (
                              <div className="p-4 bg-gray-50 rounded-xl border border-dashed border-gray-300 text-center text-gray-500">
                                <i className="bi bi-image text-2xl text-emerald-600 block mb-1"></i>
                                <span className="font-semibold text-gray-700 block">[Pantallazo HD: Comparativo Escrituras Parciales - UF]</span>
                                <span className="text-[10px] text-gray-400">Capturado automáticamente al momento de emitir el correo</span>
                              </div>
                            )}

                            {previewEmailModal.elements.includes('uni_tabla') && metrics && (
                              <div className="border rounded-lg overflow-hidden">
                                <table className="w-full text-[11px] text-left">
                                  <thead className="bg-emerald-900 text-white">
                                    <tr>
                                      <th className="p-2">Proyecto</th>
                                      <th className="p-2 text-right">Real Unidades</th>
                                      <th className="p-2 text-right">Ppto Unidades</th>
                                    </tr>
                                  </thead>
                                  <tbody className="divide-y divide-gray-100">
                                    {metrics.projectBreakdown.slice(0, 5).map(p => (
                                      <tr key={p.proyecto}>
                                        <td className="p-2 font-medium">{p.proyecto}</td>
                                        <td className="p-2 text-right font-bold text-emerald-700">{p.realUni}</td>
                                        <td className="p-2 text-right">{p.pptoUni}</td>
                                      </tr>
                                    ))}
                                  </tbody>
                                </table>
                              </div>
                            )}

                            {previewEmailModal.elements.includes('estados') && (
                              <div className="p-4 bg-gray-50 rounded-xl border border-dashed border-gray-300 text-center text-gray-500">
                                <i className="bi bi-bar-chart-steps text-2xl text-emerald-600 block mb-1"></i>
                                <span className="font-semibold text-gray-700 block">[Pantallazo HD: Estado de Firmas por Proyecto (100% Apilado)]</span>
                              </div>
                            )}
                          </div>

                          {/* Despedida */}
                          <p className="whitespace-pre-line text-gray-700 leading-relaxed pt-2 border-t">
                            {replaceDateVariables(previewEmailModal.emailOutro || 'Saludos cordiales,\nControl de Gestión Fundamenta')}
                          </p>

                          {/* Footer de enlace web */}
                          <div className="bg-emerald-50 p-3 rounded-xl text-center space-y-1">
                            <span className="text-[11px] text-emerald-800 font-semibold block">
                              Accede a la plataforma web para interactuar con los filtros y gráficos:
                            </span>
                            <a href="#" className="inline-block px-4 py-1.5 bg-emerald-700 text-white rounded-lg text-xs font-bold shadow-sm">
                              Abrir Tablero Interactivo
                            </a>
                          </div>
                        </div>
                      </div>

                      <div className="flex items-center justify-end pt-2">
                        <button
                          type="button"
                          onClick={() => setPreviewEmailModal(null)}
                          className="px-5 py-2 bg-gray-800 hover:bg-gray-900 text-white text-xs font-semibold rounded-xl transition"
                        >
                          Cerrar Vista Previa
                        </button>
                      </div>
                    </div>
                  </div>
                )}

                {/* MODAL PARA VINCULACIÓN Y TEST DE CONEXIÓN GMAIL */}
                {gmailModalOpen && (
                  <div className="fixed inset-0 bg-black/50 backdrop-blur-sm z-50 flex items-center justify-center p-4">
                    <div className="bg-white rounded-2xl max-w-lg w-full p-6 space-y-4 shadow-2xl animate-in fade-in zoom-in-95 duration-150">
                      <div className="flex items-center justify-between border-b pb-3">
                        <div className="flex items-center gap-2.5">
                          <div className="w-8 h-8 rounded-lg bg-red-50 text-red-600 flex items-center justify-center text-lg border border-red-100">
                            <i className="bi bi-google"></i>
                          </div>
                          <div>
                            <h3 className="font-bold text-sm text-gray-900 leading-tight">Vincular Cuenta de Gmail</h3>
                            <p className="text-[11px] text-gray-500">Configuración segura con Contraseña de Aplicación</p>
                          </div>
                        </div>
                        <button
                          type="button"
                          onClick={() => setGmailModalOpen(false)}
                          className="text-gray-400 hover:text-gray-600 text-base"
                        >
                          ✕
                        </button>
                      </div>

                      <div className="space-y-3.5 text-xs">
                        <div className="bg-emerald-50/70 p-3 rounded-xl border border-emerald-200 text-emerald-900 space-y-1">
                          <b className="block text-[11px]">¿Cómo obtener tu Contraseña de Aplicación de 16 letras?</b>
                          <ol className="list-decimal pl-4 space-y-0.5 text-[11px] text-emerald-800">
                            <li>Ingresa a tu cuenta en <a href="https://myaccount.google.com/apppasswords" target="_blank" className="font-bold underline">myaccount.google.com/apppasswords</a></li>
                            <li>Escribe el nombre <b>Reportería Fundamenta</b> y presiona Crear.</li>
                            <li>Copia el código generado de 16 letras y pégalo abajo.</li>
                          </ol>
                        </div>

                        <div>
                          <label className="font-semibold text-gray-700 block mb-1">Nombre a Mostrar en Remitente:</label>
                          <input
                            type="text"
                            value={gmailModalSenderName}
                            onChange={(e) => setGmailModalSenderName(e.target.value)}
                            placeholder="ej: Tomás Carvallo"
                            className="w-full border border-gray-300 rounded-lg p-2.5 bg-gray-50/50 font-medium text-gray-800"
                          />
                          <span className="text-[10px] text-gray-400 mt-0.5 block">Este nombre aparecerá como remitente en la bandeja de entrada del destinatario.</span>
                        </div>

                        <div>
                          <label className="font-semibold text-gray-700 block mb-1">Correo Corporativo Gmail:</label>
                          <input
                            type="email"
                            value={gmailModalUser}
                            onChange={(e) => setGmailModalUser(e.target.value)}
                            placeholder="ej: tcarvallo@fundamenta.cl"
                            className="w-full border border-gray-300 rounded-lg p-2.5 bg-gray-50/50"
                          />
                        </div>

                        <div>
                          <label className="font-semibold text-gray-700 block mb-1">Contraseña de Aplicación (16 letras):</label>
                          <input
                            type="password"
                            value={gmailModalPass}
                            onChange={(e) => setGmailModalPass(e.target.value)}
                            placeholder="abcd efgh ijkl mnop"
                            className="w-full border border-gray-300 rounded-lg p-2.5 font-mono text-sm tracking-widest bg-gray-50/50"
                          />
                        </div>
                      </div>

                      <div className="flex items-center justify-between pt-3 border-t">
                        <button
                          type="button"
                          onClick={() => setGmailModalOpen(false)}
                          className="px-4 py-2 border border-gray-300 text-gray-700 text-xs font-semibold rounded-xl hover:bg-gray-50 transition"
                        >
                          Cancelar
                        </button>

                        <button
                          type="button"
                          disabled={gmailTesting || !gmailModalUser || !gmailModalPass}
                          onClick={async () => {
                            setGmailTesting(true);
                            try {
                              const res = await fetch('/api/test-connection', {
                                method: 'POST',
                                headers: { 'Content-Type': 'application/json' },
                                body: JSON.stringify({ user: gmailModalUser, pass: gmailModalPass })
                              });
                              const resData = await res.json();
                              if (resData.success) {
                                const finalSender = (gmailModalSenderName || '').trim() || gmailModalUser;
                                setGmailAccount(gmailModalUser);
                                setGmailSenderName(finalSender);
                                setGmailPass(gmailModalPass);
                                setGmailConnected(true);
                                localStorage.setItem('fundamenta_gmail_user', gmailModalUser);
                                localStorage.setItem('fundamenta_gmail_sender_name', finalSender);
                                localStorage.setItem('fundamenta_gmail_pass', gmailModalPass);
                                setGmailModalOpen(false);
                                alert('✓ ¡Cuenta de Gmail conectada y verificada exitosamente! Ya puedes despachar reportes oficiales.');
                              } else {
                                alert('Error al verificar: ' + (resData.error || 'Credenciales inválidas.'));
                              }
                            } catch (err) {
                              alert('Error de conexión con el servidor: ' + err.message);
                            } finally {
                              setGmailTesting(false);
                            }
                          }}
                          className="px-5 py-2 bg-emerald-700 hover:bg-emerald-800 text-white text-xs font-semibold rounded-xl transition shadow flex items-center gap-2 disabled:opacity-50"
                        >
                          {gmailTesting ? (
                            <>
                              <span className="w-3 h-3 border-2 border-white border-t-transparent rounded-full animate-spin"></span>
                              <span>Verificando conexión...</span>
                            </>
                          ) : (
                            <>
                              <i className="bi bi-shield-check text-sm"></i>
                              <span>Guardar y Probar Conexión</span>
                            </>
                          )}
                        </button>
                      </div>
                    </div>
                  </div>
                )}

              </div>
            )}
</main>

          
          {/* Modal de Detalle / Drilldown al hacer clic en barras */}
          {drilldownModal && (
            <div className="fixed inset-0 bg-black/50 backdrop-blur-sm z-50 flex items-center justify-center p-4">
              <div className="bg-white rounded-2xl max-w-4xl w-full p-6 space-y-4 shadow-2xl animate-in fade-in zoom-in-95 duration-150 max-h-[85vh] flex flex-col">
                <div className="flex items-center justify-between border-b pb-3 flex-shrink-0">
                  <div>
                    <h3 className="font-bold text-base text-gray-900 flex items-center gap-2">
                      <i className="bi bi-card-list text-emerald-700"></i>
                      <span>{drilldownModal.title}</span>
                    </h3>
                    <p className="text-xs text-gray-500 mt-0.5">{drilldownModal.subtitle}</p>
                  </div>
                  <button
                    onClick={() => setDrilldownModal(null)}
                    className="text-gray-400 hover:text-gray-600 text-lg w-8 h-8 rounded-full flex items-center justify-center hover:bg-gray-100 transition"
                  >
                    ✕
                  </button>
                </div>

                <div className="flex-1 overflow-y-auto border border-gray-200 rounded-xl">
                  <table className="w-full text-xs text-left">
                    <thead className="bg-gray-50 text-gray-600 sticky top-0 border-b border-gray-200">
                      <tr>
                        <th className="py-2.5 px-3 font-semibold">Proyecto</th>
                        <th className="py-2.5 px-3 font-semibold">Unidad</th>
                        <th className="py-2.5 px-3 font-semibold">Cliente</th>
                        <th className="py-2.5 px-3 font-semibold">RUT</th>
                        <th className="py-2.5 px-3 font-semibold">Firma Cliente</th>
                        <th className="py-2.5 px-3 font-semibold">Banco</th>
                        <th className="py-2.5 px-3 text-right font-semibold">UF sin Abono Cliente</th>
                      </tr>
                    </thead>
                    <tbody className="divide-y divide-gray-100">
                      {drilldownModal.records.map((r, idx) => (
                        <tr key={idx} className="hover:bg-gray-50/80 transition-colors">
                          <td className="py-2 px-3 font-medium text-gray-900">{r.Proyecto}</td>
                          <td className="py-2 px-3 font-bold text-emerald-800">{r.Unidad}</td>
                          <td className="py-2 px-3 text-gray-800">
                            {r.Nombre} {r.Apellido}
                          </td>
                          <td className="py-2 px-3 text-gray-500">{r['RUT Cliente']}</td>
                          <td className="py-2 px-3 text-gray-600">{r['Fecha Firma Cliente'] || '-'}</td>
                          <td className="py-2 px-3 text-gray-600">{r.Banco || '-'}</td>
                          <td className="py-2 px-3 text-right font-semibold text-emerald-800">
                            {r['UF sin Abono Cliente'] ? parseFloat(r['UF sin Abono Cliente'].replace(',', '.')).toLocaleString('es-CL', { minimumFractionDigits: 1, maximumFractionDigits: 2 }) + ' UF' : '-'}
                          </td>
                        </tr>
                      ))}
                    </tbody>
                  </table>
                </div>

                <div className="flex items-center justify-between pt-2 border-t flex-shrink-0">
                  <span className="text-xs text-gray-500">
                    Total registros: <b>{drilldownModal.records.length}</b>
                  </span>
                  <button
                    type="button"
                    onClick={() => setDrilldownModal(null)}
                    className="px-4 py-1.5 bg-gray-900 hover:bg-black text-white text-xs font-semibold rounded-lg transition"
                  >
                    Cerrar
                  </button>
                </div>
              </div>
            </div>
          )}

          {/* Modal / Menú Sobrepuesto para Filtros de Proyectos */}
          {filterModalOpen && (
            <div className="fixed inset-0 bg-black/40 backdrop-blur-sm z-50 flex items-center justify-center p-4">
              <div className="bg-white rounded-2xl max-w-lg w-full p-6 space-y-4 shadow-2xl animate-in fade-in zoom-in-95 duration-150">
                <div className="flex items-center justify-between border-b pb-3">
                  <div className="flex items-center gap-2">
                    <i className="bi bi-funnel text-emerald-700 text-base"></i>
                    <h3 className="font-bold text-base text-gray-900">Filtrar por Proyecto</h3>
                  </div>
                  <button
                    onClick={() => setFilterModalOpen(false)}
                    className="text-gray-400 hover:text-gray-600 text-lg w-8 h-8 rounded-full flex items-center justify-center hover:bg-gray-100 transition"
                  >
                    ✕
                  </button>
                </div>

                <div className="flex items-center justify-between bg-emerald-50/60 p-2.5 rounded-xl border border-emerald-100 text-xs">
                  <label className="flex items-center gap-2 font-bold text-emerald-900 cursor-pointer select-none">
                    <input
                      type="checkbox"
                      checked={selectedProyectos.length === allProyectos.length}
                      onChange={selectAllProyectos}
                      className="rounded text-emerald-600 focus:ring-emerald-500"
                    />
                    <span>Seleccionar todos los proyectos</span>
                  </label>
                  <span className="text-emerald-700 font-medium">
                    {selectedProyectos.length} de {allProyectos.length} seleccionados
                  </span>
                </div>

                <div className="grid grid-cols-2 gap-2 max-h-[360px] overflow-y-auto p-1 text-xs">
                  {allProyectos.map(p => (
                    <label
                      key={p}
                      className={`flex items-center gap-2.5 p-2 rounded-lg border transition cursor-pointer select-none ${selectedProyectos.includes(p) ? 'border-emerald-300 bg-emerald-50/50 text-emerald-900 font-semibold' : 'border-gray-200 hover:bg-gray-50 text-gray-700'}`}
                    >
                      <input
                        type="checkbox"
                        checked={selectedProyectos.includes(p)}
                        onChange={() => toggleProyecto(p)}
                        className="rounded text-emerald-600 focus:ring-emerald-500"
                      />
                      <span className="truncate" title={p}>{p}</span>
                    </label>
                  ))}
                </div>

                <div className="flex items-center justify-between pt-3 border-t">
                  <button
                    type="button"
                    onClick={() => setSelectedProyectos(allProyectos)}
                    className="text-xs text-gray-500 hover:text-emerald-700 font-medium"
                  >
                    Restablecer selección
                  </button>
                  <button
                    type="button"
                    onClick={() => setFilterModalOpen(false)}
                    className="px-5 py-2 bg-emerald-700 hover:bg-emerald-800 text-white text-xs font-semibold rounded-xl transition shadow"
                  >
                    Aplicar Filtro
                  </button>
                </div>
              </div>
            </div>
          )}
        </div>
      </div>
    </div>
  );
}

ReactDOM.render(<App />, document.getElementById('root'));
