// ============================================================================
// CONTAINER COMPONENT: App.jsx (SHADCN/UI STYLE + TAGS & CONFIGURAÇÕES COMPLETAS)
// Ponto de integração de todas as abas, rotas sem '#' e regras contábeis
// ============================================================================

const { useState, useEffect, useMemo } = React;

function getRouteFromLocation() {
  // Lê rota da URL limpa (/servicos, /lancamentos, /imprimir, /configuracoes, /dashboard)
  let path = window.location.pathname.replace(/^\//, '').trim();
  if (!path && window.location.hash) {
    path = window.location.hash.replace(/^#\/?/, '').trim();
  }
  
  if (path === 'services') path = 'servicos';
  if (path === 'print') path = 'imprimir';
  if (path === 'transactions') path = 'lancamentos';
  if (path === 'settings' || path === 'backup') path = 'configuracoes';
  if (path === 'projections' || path === 'futuro' || path === 'simulador') path = 'proyecciones';

  const valid = ['dashboard', 'lancamentos', 'proyecciones', 'servicos', 'imprimir', 'configuracoes', 'backup'];
  return valid.includes(path) ? path : 'dashboard';
}

function MovementTypesConfigForm({ settings, onSave }) {
  const { Button, Lucide } = window.Shadcn || {};
  const { showToast } = window.useFinance ? window.useFinance() : {};

  const [formData, setFormData] = useState({
    movement_credit_title: settings?.movement_credit_title || 'Servicio Prestado',
    movement_credit_desc: settings?.movement_credit_desc !== undefined ? settings.movement_credit_desc : 'Crédito a mi favor / Cobro a la universidad',
    movement_debit_title: settings?.movement_debit_title || 'Cuota Universitaria',
    movement_debit_desc: settings?.movement_debit_desc !== undefined ? settings.movement_debit_desc : 'Débito / Descuento de cuotas en cuenta',
    movement_payment_received_title: settings?.movement_payment_received_title || 'Pago Recibido',
    movement_payment_received_desc: settings?.movement_payment_received_desc !== undefined ? settings.movement_payment_received_desc : 'Efectivo / Transferencia de Tesorería',
    movement_payment_made_title: settings?.movement_payment_made_title || 'Pago Efectuado',
    movement_payment_made_desc: settings?.movement_payment_made_desc !== undefined ? settings.movement_payment_made_desc : 'Pago realizado a la universidad',
  });

  useEffect(() => {
    if (settings) {
      setFormData({
        movement_credit_title: settings.movement_credit_title || 'Servicio Prestado',
        movement_credit_desc: settings.movement_credit_desc !== undefined ? settings.movement_credit_desc : 'Crédito a mi favor / Cobro a la universidad',
        movement_debit_title: settings.movement_debit_title || 'Cuota Universitaria',
        movement_debit_desc: settings.movement_debit_desc !== undefined ? settings.movement_debit_desc : 'Débito / Descuento de cuotas en cuenta',
        movement_payment_received_title: settings.movement_payment_received_title || 'Pago Recibido',
        movement_payment_received_desc: settings.movement_payment_received_desc !== undefined ? settings.movement_payment_received_desc : 'Efectivo / Transferencia de Tesorería',
        movement_payment_made_title: settings.movement_payment_made_title || 'Pago Efectuado',
        movement_payment_made_desc: settings.movement_payment_made_desc !== undefined ? settings.movement_payment_made_desc : 'Pago realizado a la universidad',
      });
    }
  }, [settings]);

  const handleResetDefaults = () => {
    setFormData({
      movement_credit_title: 'Servicio Prestado',
      movement_credit_desc: 'Crédito a mi favor / Cobro a la universidad',
      movement_debit_title: 'Cuota Universitaria',
      movement_debit_desc: 'Débito / Descuento de cuotas en cuenta',
      movement_payment_received_title: 'Pago Recibido',
      movement_payment_received_desc: 'Efectivo / Transferencia de Tesorería',
      movement_payment_made_title: 'Pago Efectuado',
      movement_payment_made_desc: 'Pago realizado a la universidad',
    });
    if (showToast) showToast('Valores restaurados por defecto. Haga clic en Guardar para aplicar.');
  };

  const handleChange = (e) => {
    const { name, value } = e.target;
    setFormData(prev => ({ ...prev, [name]: value }));
  };

  return (
    <div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
      {/* COLUMNA IZQUIERDA: FORMULARIO DE EDICIÓN */}
      <div className="lg:col-span-2 space-y-4">
        <form onSubmit={onSave} className="space-y-4">
          {/* 1. CRÉDITO */}
          <div className="bg-white p-5 rounded-xl border border-zinc-200 shadow-xs space-y-3">
            <div className="flex items-center justify-between border-b border-zinc-100 pb-2.5">
              <div className="flex items-center gap-2">
                <span className="w-2.5 h-2.5 rounded-full bg-zinc-950" />
                <h4 className="font-bold text-sm text-zinc-950">1. Crédito a su favor (Servicios Ejecutados)</h4>
              </div>
              <span className="text-[10px] font-mono font-bold bg-zinc-950 text-white px-2 py-0.5 rounded">
                + CRÉDITO
              </span>
            </div>
            <div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
              <div>
                <label className="block text-xs font-semibold text-zinc-700 mb-1">Nombre Principal / Etiqueta</label>
                <input 
                  type="text" 
                  name="movement_credit_title"
                  value={formData.movement_credit_title}
                  onChange={handleChange}
                  placeholder="Ej: Servicio Prestado u Honorarios"
                  className="w-full h-9 px-3 text-sm rounded-md border border-zinc-200 bg-white text-zinc-950 focus:outline-none focus:ring-1 focus:ring-zinc-950 font-medium"
                  required
                />
              </div>
              <div>
                <label className="block text-xs font-semibold text-zinc-700 mb-1">Texto Explicativo (entre paréntesis)</label>
                <input 
                  type="text" 
                  name="movement_credit_desc"
                  value={formData.movement_credit_desc}
                  onChange={handleChange}
                  placeholder="Ej: Crédito a mi favor / Cobro a la universidad"
                  className="w-full h-9 px-3 text-sm rounded-md border border-zinc-200 bg-white text-zinc-950 focus:outline-none focus:ring-1 focus:ring-zinc-950 text-xs"
                />
              </div>
            </div>
            <p className="text-[11px] text-zinc-500">
              Genera crédito para su saldo acumulado a cobrar cuando presta un servicio o realiza una entrega.
            </p>
          </div>

          {/* 2. DÉBITO */}
          <div className="bg-white p-5 rounded-xl border border-zinc-200 shadow-xs space-y-3">
            <div className="flex items-center justify-between border-b border-zinc-100 pb-2.5">
              <div className="flex items-center gap-2">
                <span className="w-2.5 h-2.5 rounded-full bg-zinc-400" />
                <h4 className="font-bold text-sm text-zinc-950">2. Débito contra usted (Cuotas / Descuentos)</h4>
              </div>
              <span className="text-[10px] font-mono font-bold bg-zinc-100 text-zinc-900 border border-zinc-200 px-2 py-0.5 rounded">
                - DÉBITO
              </span>
            </div>
            <div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
              <div>
                <label className="block text-xs font-semibold text-zinc-700 mb-1">Nombre Principal / Etiqueta</label>
                <input 
                  type="text" 
                  name="movement_debit_title"
                  value={formData.movement_debit_title}
                  onChange={handleChange}
                  placeholder="Ej: Cuota Universitaria"
                  className="w-full h-9 px-3 text-sm rounded-md border border-zinc-200 bg-white text-zinc-950 focus:outline-none focus:ring-1 focus:ring-zinc-950 font-medium"
                  required
                />
              </div>
              <div>
                <label className="block text-xs font-semibold text-zinc-700 mb-1">Texto Explicativo (entre paréntesis)</label>
                <input 
                  type="text" 
                  name="movement_debit_desc"
                  value={formData.movement_debit_desc}
                  onChange={handleChange}
                  placeholder="Ej: Débito / Descuento de cuotas en cuenta"
                  className="w-full h-9 px-3 text-sm rounded-md border border-zinc-200 bg-white text-zinc-950 focus:outline-none focus:ring-1 focus:ring-zinc-950 text-xs"
                />
              </div>
            </div>
            <p className="text-[11px] text-zinc-500">
              Descuentos de cuotas, aranceles académicos u obligaciones periódicas que se compensan contra su saldo.
            </p>
          </div>

          {/* 3. PAGO RECIBIDO */}
          <div className="bg-white p-5 rounded-xl border border-zinc-200 shadow-xs space-y-3">
            <div className="flex items-center justify-between border-b border-zinc-100 pb-2.5">
              <div className="flex items-center gap-2">
                <span className="w-2.5 h-2.5 rounded-full bg-zinc-800" />
                <h4 className="font-bold text-sm text-zinc-950">3. Pago Recibido (Entrada Directa en Mano / Cuenta)</h4>
              </div>
              <span className="text-[10px] font-mono font-bold bg-zinc-100 text-zinc-800 border border-zinc-200 px-2 py-0.5 rounded">
                ENTRADA FINANCIERA
              </span>
            </div>
            <div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
              <div>
                <label className="block text-xs font-semibold text-zinc-700 mb-1">Nombre Principal / Etiqueta</label>
                <input 
                  type="text" 
                  name="movement_payment_received_title"
                  value={formData.movement_payment_received_title}
                  onChange={handleChange}
                  placeholder="Ej: Pago Recibido o Transferencia Recibida"
                  className="w-full h-9 px-3 text-sm rounded-md border border-zinc-200 bg-white text-zinc-950 focus:outline-none focus:ring-1 focus:ring-zinc-950 font-medium"
                  required
                />
              </div>
              <div>
                <label className="block text-xs font-semibold text-zinc-700 mb-1">Texto Explicativo (entre paréntesis)</label>
                <input 
                  type="text" 
                  name="movement_payment_received_desc"
                  value={formData.movement_payment_received_desc}
                  onChange={handleChange}
                  placeholder="Ej: Efectivo / Transferencia de Tesorería"
                  className="w-full h-9 px-3 text-sm rounded-md border border-zinc-200 bg-white text-zinc-950 focus:outline-none focus:ring-1 focus:ring-zinc-950 text-xs"
                />
              </div>
            </div>
            <p className="text-[11px] text-zinc-500">
              Registra cuando la universidad liquida importes entregando dinero en efectivo o transferencia bancaria directa.
            </p>
          </div>

          {/* 4. PAGO EFECTUADO */}
          <div className="bg-white p-5 rounded-xl border border-zinc-200 shadow-xs space-y-3">
            <div className="flex items-center justify-between border-b border-zinc-100 pb-2.5">
              <div className="flex items-center gap-2">
                <span className="w-2.5 h-2.5 rounded-full bg-zinc-600" />
                <h4 className="font-bold text-sm text-zinc-950">4. Pago Efectuado (Salida Directa de Dinero)</h4>
              </div>
              <span className="text-[10px] font-mono font-bold bg-zinc-100 text-zinc-600 border border-zinc-200 px-2 py-0.5 rounded">
                SALIDA FINANCIERA
              </span>
            </div>
            <div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
              <div>
                <label className="block text-xs font-semibold text-zinc-700 mb-1">Nombre Principal / Etiqueta</label>
                <input 
                  type="text" 
                  name="movement_payment_made_title"
                  value={formData.movement_payment_made_title}
                  onChange={handleChange}
                  placeholder="Ej: Pago Efectuado"
                  className="w-full h-9 px-3 text-sm rounded-md border border-zinc-200 bg-white text-zinc-950 focus:outline-none focus:ring-1 focus:ring-zinc-950 font-medium"
                  required
                />
              </div>
              <div>
                <label className="block text-xs font-semibold text-zinc-700 mb-1">Texto Explicativo (entre paréntesis)</label>
                <input 
                  type="text" 
                  name="movement_payment_made_desc"
                  value={formData.movement_payment_made_desc}
                  onChange={handleChange}
                  placeholder="Ej: Pago realizado a la universidad"
                  className="w-full h-9 px-3 text-sm rounded-md border border-zinc-200 bg-white text-zinc-950 focus:outline-none focus:ring-1 focus:ring-zinc-950 text-xs"
                />
              </div>
            </div>
            <p className="text-[11px] text-zinc-500">
              Registra pagos directos realizados por usted (en ventanilla o transferencia) para amortizar débitos.
            </p>
          </div>

          <div className="flex items-center justify-between pt-2">
            <button
              type="button"
              onClick={handleResetDefaults}
              className="text-xs text-zinc-500 hover:text-zinc-800 underline cursor-pointer"
            >
              Restaurar Valores por Defecto
            </button>
            <Button type="submit" variant="default" size="sm" className="font-semibold px-5">
              Guardar Tipos de Movimiento
            </Button>
          </div>
        </form>
      </div>

      {/* COLUMNA DERECHA: LIVE PREVIEW DEL SELECTOR */}
      <div className="space-y-4">
        <div className="bg-zinc-50 border border-zinc-200 rounded-xl p-5 space-y-4 sticky top-6">
          <div className="flex items-center gap-2 border-b border-zinc-200 pb-3">
            <Lucide.Sparkles size={16} className="text-zinc-900" />
            <h4 className="font-bold text-sm text-zinc-950">Vista Previa en Tiempo Real</h4>
          </div>
          <p className="text-xs text-zinc-600 leading-relaxed">
            Vea exactamente cómo aparecerán las opciones en el selector de <strong>Nuevo Movimiento</strong>:
          </p>

          <div className="bg-white border border-zinc-300 rounded-lg p-4 shadow-xs space-y-2">
            <label className="block text-[11px] font-bold text-zinc-700 uppercase tracking-wider">
              TIPO DE MOVIMIENTO
            </label>
            <select className="select-control w-full text-xs font-medium cursor-default" disabled>
              <option>
                {formData.movement_credit_title} {formData.movement_credit_desc ? `(${formData.movement_credit_desc})` : ''}
              </option>
              <option>
                {formData.movement_debit_title} {formData.movement_debit_desc ? `(${formData.movement_debit_desc})` : ''}
              </option>
              <option>
                {formData.movement_payment_received_title} {formData.movement_payment_received_desc ? `(${formData.movement_payment_received_desc})` : ''}
              </option>
              <option>
                {formData.movement_payment_made_title} {formData.movement_payment_made_desc ? `(${formData.movement_payment_made_desc})` : ''}
              </option>
            </select>
            <span className="text-[10px] text-zinc-400 block pt-1">
              ✓ Se actualiza instantáneamente en todo el sistema al guardar.
            </span>
          </div>

          <div className="rounded-lg bg-zinc-100 p-3 text-xs text-zinc-700 space-y-1">
            <span className="font-bold block text-zinc-900">📌 Personalización de Términos:</span>
            <span>
              Puede cambiar la terminología según las preferencias de su contrato o institución.
            </span>
          </div>
        </div>
      </div>
    </div>
  );
}

function App() {
  const [activeTab, setActiveTab] = useState(getRouteFromLocation());
  const [printMonth, setPrintMonth] = useState(new Date().toISOString().substring(0, 7));

  // Filtros de Lançamentos: Modo Mensal vs Modo Por Período (Início ao Fim)
  const [periodMode, setPeriodMode] = useState('month'); // 'month' ou 'range'
  const [selectedMonth, setSelectedMonth] = useState(new Date().toISOString().substring(0, 7));
  const [startDate, setStartDate] = useState('');
  const [endDate, setEndDate] = useState('');

  // Sub-aba ativa em Configurações
  const [settingsTab, setSettingsTab] = useState('tags'); // 'tags' | 'instituicao' | 'preferencias' | 'backup'
  const [dashboardChartView, setDashboardChartView] = useState('all'); // 'all' | 'bars' | 'line' | 'donut'
  const [activePresetFilter, setActivePresetFilter] = useState('all');

  const { 
    session,
    user,
    isAuthChecking,
    setSession,
    setModalTxOpen, 
    setEditingTx, 
    setModalServiceOpen, 
    setModalRecurringOpen,
    setModalTagOpen,
    setEditingTag,
    isCmdPaletteOpen,
    setIsCmdPaletteOpen,
    isWhatsAppModalOpen,
    setIsWhatsAppModalOpen,
    services,
    recurringRules,
    tags,
    settings,
    triggerRefresh,
    showToast,
    confirmDialog
  } = window.useFinance();

  const { Button, Card, CardHeader, CardTitle, CardDescription, CardContent, Badge, Lucide } = window.Shadcn;

  // Custom Hooks
  const dashboard = window.useDashboard();
  const txManager = window.useTransactions({ month: selectedMonth });
  const reportManager = window.useMonthlyReport(printMonth);

  // Sincronização de Rotas HTML5 (History API sem '#')
  useEffect(() => {
    const handlePopState = () => {
      setActiveTab(getRouteFromLocation());
    };
    window.addEventListener('popstate', handlePopState);
    window.addEventListener('hashchange', handlePopState);
    return () => {
      window.removeEventListener('popstate', handlePopState);
      window.removeEventListener('hashchange', handlePopState);
    };
  }, []);

  const navigateToTab = (tab) => {
    const targetPath = `/${tab}`;
    if (window.location.pathname !== targetPath) {
      window.history.pushState({ tab }, '', targetPath);
    }
    setActiveTab(tab);
  };

  // Funções de Navegação de Mês
  const shiftMonth = (delta) => {
    const [y, m] = selectedMonth.split('-').map(Number);
    const date = new Date(y, m - 1 + delta, 1);
    const newY = date.getFullYear();
    const newM = String(date.getMonth() + 1).padStart(2, '0');
    const newMonthStr = `${newY}-${newM}`;
    setSelectedMonth(newMonthStr);
    txManager.updateFilters({ month: newMonthStr, startDate: '', endDate: '' });
  };

  const handleMonthChange = (newMonth) => {
    setSelectedMonth(newMonth);
    txManager.updateFilters({ month: newMonth, startDate: '', endDate: '' });
  };

  // Funções de Navegação de Período (Início ao Fim)
  const applyDateRange = (start, end) => {
    setStartDate(start);
    setEndDate(end);
    txManager.updateFilters({ startDate: start, endDate: end, month: '' });
  };

  const handleShortcutRange = (type) => {
    const now = new Date();
    const todayStr = now.toISOString().substring(0, 10);

    if (type === 'this_month') {
      const startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1).toISOString().substring(0, 10);
      applyDateRange(startOfMonth, todayStr);
    } else if (type === 'last_30') {
      const past30 = new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000).toISOString().substring(0, 10);
      applyDateRange(past30, todayStr);
    } else if (type === 'last_90') {
      const past90 = new Date(now.getTime() - 90 * 24 * 60 * 60 * 1000).toISOString().substring(0, 10);
      applyDateRange(past90, todayStr);
    } else if (type === 'this_year') {
      const startOfYear = `${now.getFullYear()}-01-01`;
      applyDateRange(startOfYear, todayStr);
    } else if (type === 'all') {
      setStartDate('');
      setEndDate('');
      setSelectedMonth('');
      txManager.updateFilters({ startDate: '', endDate: '', month: '', tag: '' });
    }
  };

  // Totais calculados do período filtrado
  const periodTotals = useMemo(() => {
    let credits = 0;
    let debits = 0;
    txManager.transactions.forEach(t => {
      if (t.type === 'CREDIT' || t.type === 'PAYMENT_MADE') {
        credits += t.amount;
      } else if (t.type === 'DEBIT' || t.type === 'PAYMENT_RECEIVED') {
        debits += t.amount;
      }
    });
    return {
      credits,
      debits,
      net: credits - debits,
      count: txManager.transactions.length
    };
  }, [txManager.transactions]);

  const handleOpenNewTx = () => {
    setEditingTx(null);
    setModalTxOpen(true);
  };

  const handleEditTx = (tx) => {
    setEditingTx(tx);
    setModalTxOpen(true);
  };

  const handleApplyRecurringRules = async () => {
    const currentMonth = new Date().toISOString().substring(0, 7);
    const ok = await confirmDialog({
      title: 'Generar Recurrentes del Mes',
      description: `¿Desea generar los movimientos recurrentes (cuota universitaria) para el mes ${currentMonth}? Los movimientos existentes no se duplicarán.`,
      confirmText: 'Generar Recurrentes',
      cancelText: 'Cancelar',
      variant: 'default'
    });
    if (!ok) return;

    try {
      const res = await window.Api.applyRecurringRules(currentMonth);
      showToast(res.message);
      triggerRefresh();
    } catch (err) {
      showToast('Error al aplicar reglas recurrentes.');
    }
  };

  const handleDeleteService = async (id, serviceData = null) => {
    const s = serviceData || services.find(item => item.id === id);
    const ok = await confirmDialog({
      title: '¿Realmente desea eliminar este servicio del catálogo?',
      description: 'El servicio será removido del catálogo de precios y no estará disponible para selección rápida.',
      confirmText: 'Sí, Eliminar Servicio',
      cancelText: 'Cancelar y Mantener',
      variant: 'destructive',
      itemDetails: s ? {
        itemType: 'Servicio del Catálogo',
        title: s.name,
        amount: s.default_amount,
        extra: `Categoría: ${s.category || 'General'} • Unidad: ${s.unit || 'servicio'}`,
        description: s.description
      } : {
        itemType: 'Servicio del Catálogo',
        title: `Servicio #${id}`
      }
    });
    if (!ok) return;

    try {
      await window.Api.deleteService(id);
      showToast('Servicio eliminado con éxito.');
      triggerRefresh();
    } catch (err) {
      showToast('Error al eliminar servicio.');
    }
  };

  const handleDeleteRecurring = async (id, ruleData = null) => {
    const r = ruleData || recurringRules.find(rule => rule.id === id);
    let durationLabel = 'Continuo todos los meses';
    if (r) {
      if (r.duration_type === 'months') {
        durationLabel = `Fijo por ${r.total_installments} cuotas (${r.applied_count || 0} ya generadas)`;
      } else if (r.duration_type === 'until_date') {
        durationLabel = `Hasta el período ${r.end_date}`;
      }
    }

    const ok = await confirmDialog({
      title: '¿Realmente desea eliminar esta regla recurrente?',
      description: 'Esta automatización mensual se interrumpirá de inmediato. No se generarán nuevos movimientos en los próximos meses.',
      confirmText: 'Sí, Eliminar Regla',
      cancelText: 'Cancelar y Mantener',
      variant: 'destructive',
      itemDetails: r ? {
        itemType: 'Regla de Recurrencia Mensual',
        title: r.title,
        amount: r.amount,
        extra: `Vencimiento: Cada día ${r.day_of_month || '05'}`,
        duration: durationLabel,
        description: r.notes
      } : {
        itemType: 'Regra de Recurrencia Mensual',
        title: `Regla #${id}`
      }
    });
    if (!ok) return;

    try {
      await window.Api.deleteRecurringRule(id);
      showToast('Regla de recurrencia eliminada con éxito.');
      triggerRefresh();
    } catch (err) {
      showToast('Error al eliminar regla.');
    }
  };

  const handleDeleteTag = async (id, tagData = null) => {
    const t = (typeof tagData === 'object' && tagData !== null) 
      ? tagData 
      : (tags.find(item => item.id === id) || { name: tagData || `Etiqueta #${id}` });

    const ok = await confirmDialog({
      title: '¿Realmente desea eliminar esta etiqueta?',
      description: 'Esta etiqueta se eliminará permanentemente y se desvinculará de todos los movimientos asociados.',
      confirmText: 'Sí, Eliminar Etiqueta',
      cancelText: 'Cancelar y Mantener',
      variant: 'destructive',
      itemDetails: {
        itemType: 'Etiqueta de Clasificación',
        title: `#${t.name}`,
        color: t.color || '#18181b',
        extra: t.usage_count !== undefined 
          ? `${t.usage_count} movimiento(s) utilizan esta etiqueta` 
          : 'Se desvinculará de todos los movimientos asociados'
      }
    });
    if (!ok) return;

    try {
      await window.Api.deleteTag(id);
      showToast(`Etiqueta #${t.name} eliminada.`);
      triggerRefresh();
    } catch (err) {
      showToast('Error al eliminar etiqueta.');
    }
  };

  const handleSaveSettings = async (e) => {
    e.preventDefault();
    const form = e.target;
    const formData = {};
    const elements = form.elements;
    for (let i = 0; i < elements.length; i++) {
      const item = elements[i];
      if (item.name) {
        formData[item.name] = item.value;
      }
    }

    try {
      await window.Api.saveSettings(formData);
      showToast('¡Configuraciones guardadas con éxito!');
      triggerRefresh();
    } catch (err) {
      showToast('Error al guardar configuraciones.');
    }
  };

  // 1. CARGA INICIAL DE SESIÓN
  if (isAuthChecking) {
    return (
      <div className="min-h-screen w-full flex items-center justify-center bg-zinc-950 text-white">
        <div className="flex flex-col items-center gap-3 animate-pulse">
          <div className="w-12 h-12 rounded-xl bg-white text-zinc-950 font-black text-lg flex items-center justify-center shadow-lg">
            CP
          </div>
          <span className="text-xs font-mono tracking-widest text-zinc-400 uppercase">Verificando sesión...</span>
        </div>
      </div>
    );
  }

  // 2. CONTROL DE ACCESO (LOGIN REQUERIDO)
  if (!session) {
    return <window.LoginScreen onLoginSuccess={(newSession) => setSession(newSession)} />;
  }

  return (
    <div className="min-h-screen bg-white">
      <window.Navbar 
        activeTab={activeTab} 
        onSelectTab={navigateToTab} 
        onOpenNewTx={handleOpenNewTx} 
      />

      <main className="main-content py-8">
        <div className="container max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">

          {/* ================================================================
              PESTAÑA: DASHBOARD
              ================================================================ */}
          {activeTab === 'dashboard' && (
            <section className="space-y-6">
              <div className="flex flex-col md:flex-row md:items-center md:justify-between gap-4 border-b border-zinc-200 dark:border-zinc-800 pb-5">
                <div>
                  <h1 className="text-2xl font-bold tracking-tight text-zinc-950 dark:text-white">Flujo de Caja & Compensación</h1>
                  <p className="text-sm text-zinc-500 mt-1">Control contable de servicios prestados vs. cuotas compensadas</p>
                </div>
                <div className="flex items-center gap-2 flex-wrap">
                  {isAdmin && (
                    <Button 
                      variant="outline" 
                      size="sm" 
                      onClick={() => setIsWhatsAppModalOpen && setIsWhatsAppModalOpen(true)}
                      className="flex items-center gap-1.5 border-emerald-300 bg-emerald-50 text-emerald-800 hover:bg-emerald-100 dark:bg-emerald-950/40 dark:text-emerald-400 dark:border-emerald-800 cursor-pointer"
                    >
                      <span>💬</span>
                      <span>Resumen WhatsApp</span>
                    </Button>
                  )}
                  <Button 
                    variant="secondary" 
                    size="sm" 
                    onClick={() => navigateToTab('proyecciones')}
                    className="flex items-center gap-1.5 cursor-pointer"
                  >
                    <span>🔮</span>
                    <span>Proyecciones Futuras</span>
                  </Button>
                  {isAdmin && (
                    <Button variant="secondary" size="sm" onClick={handleApplyRecurringRules} className="cursor-pointer">
                      <Lucide.Sparkles size={14} className="text-zinc-600" />
                      <span>Generar Recurrentes</span>
                    </Button>
                  )}
                  <Button variant="default" size="sm" onClick={() => navigateToTab('imprimir')} className="cursor-pointer">
                    <Lucide.Printer size={14} />
                    <span>Rendición A4</span>
                  </Button>
                </div>
              </div>

              {/* BANNER INSTITUCIONAL PARA AUDITORÍA / FACULTAD */}
              {!isAdmin && (
                <div className="p-4 rounded-xl bg-blue-50/90 border border-blue-200 text-blue-950 flex items-start gap-3.5 shadow-xs">
                  <span className="text-2xl leading-none">🏛️</span>
                  <div className="space-y-1">
                    <h3 className="text-sm font-bold tracking-tight text-blue-950">
                      Portal Oficial de Fiscalización y Auditoría • Universidad Columbia
                    </h3>
                    <p className="text-xs text-blue-800 leading-relaxed">
                      Bienvenido/a. Su perfil tiene acceso de <strong>Consulta y Auditoría</strong>. 
                      Puede fiscalizar todos los servicios prestados, inspeccionar las especificaciones técnicas y enlaces de entregables (archivos/videos), 
                      revisar las cuotas universitarias compensadas y generar el balance oficial en <strong>Rendición A4</strong> con firma y código QR.
                    </p>
                  </div>
                </div>
              )}

              {dashboard.loading || !dashboard.data ? (
                <div className="text-center text-zinc-400 py-16 text-sm">
                  Cargando indicadores...
                </div>
              ) : (
                <>
                  {/* CARDS DE SALDO COLORIDOS */}
                  <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
                    <window.StatCard 
                      title="Situación Contable Actual"
                      value={window.formatCurrencyPYG(Math.abs(dashboard.data.totals.netBalance))}
                      badgeText={dashboard.data.totals.netBalance > 0 ? 'A SU FAVOR' : (dashboard.data.totals.netBalance < 0 ? 'A PAGAR' : 'SALDADO')}
                      badgeType={dashboard.data.totals.netBalance > 0 ? 'favorable' : (dashboard.data.totals.netBalance < 0 ? 'unfavorable' : 'warning')}
                      colorScheme={dashboard.data.totals.netBalance > 0 ? 'emerald' : (dashboard.data.totals.netBalance < 0 ? 'rose' : 'amber')}
                      prefix={dashboard.data.totals.netBalance > 0 ? '+' : (dashboard.data.totals.netBalance < 0 ? '-' : '•')}
                      isHighlight={true}
                      helper={
                        dashboard.data.totals.netBalance > 0 
                          ? <span className="text-emerald-700 font-medium"><strong>La Universidad le debe:</strong> {window.formatCurrencyPYG(dashboard.data.totals.netBalance)}</span>
                          : (dashboard.data.totals.netBalance < 0 
                              ? <span className="text-rose-700 font-medium"><strong>Usted debe a la Universidad:</strong> {window.formatCurrencyPYG(Math.abs(dashboard.data.totals.netBalance))}</span>
                              : <span className="text-zinc-600">Cuentas conciliadas sin pendientes</span>)
                      }
                    />

                    <window.StatCard 
                      title="Servicios Prestados"
                      value={window.formatCurrencyPYG(dashboard.data.totals.total_credits)}
                      badgeText="Crédito"
                      colorScheme="emerald"
                      prefix="+"
                      helper="Total facturado a la universidad"
                    />

                    <window.StatCard 
                      title="Cuotas / Débitos"
                      value={window.formatCurrencyPYG(dashboard.data.totals.total_debits)}
                      badgeText="Débito"
                      colorScheme="rose"
                      prefix="-"
                      helper="Valores de cuotas compensadas"
                    />

                    <window.StatCard 
                      title="Recibido en Efectivo / Banco"
                      value={window.formatCurrencyPYG(dashboard.data.totals.total_received)}
                      badgeText="Liquidado"
                      colorScheme="blue"
                      prefix="✓"
                      helper="Dinero recibido de Tesorería"
                    />
                  </div>

                  {/* BARRA DE DISTRIBUCIÓN CONTABLE DEL TOTAL DE SERVICIOS */}
                  {dashboard.data.totals.total_credits > 0 && (() => {
                    const totalCreds = dashboard.data.totals.total_credits || 1;
                    const debits = dashboard.data.totals.total_debits || 0;
                    const received = dashboard.data.totals.total_received || 0;
                    const net = Math.max(dashboard.data.totals.netBalance || 0, 0);

                    const pctDebits = Math.min(Math.round((debits / totalCreds) * 100), 100);
                    const pctReceived = Math.min(Math.round((received / totalCreds) * 100), 100);
                    const pctNet = Math.max(100 - pctDebits - pctReceived, 0);

                    return (
                      <div className="p-4 rounded-xl bg-zinc-50/80 dark:bg-zinc-900/60 border border-zinc-200 dark:border-zinc-800 space-y-3">
                        <div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-1 text-xs">
                          <div>
                            <span className="font-bold text-zinc-950 dark:text-white">Distribución de los Servicios Prestados</span>
                            <span className="text-zinc-500 ml-1.5">({window.formatCurrencyPYG(totalCreds)} en total facturado)</span>
                          </div>
                          <span className="text-[11px] font-mono text-zinc-500">
                            100% compensado o disponible
                          </span>
                        </div>

                        {/* Barra segmentada */}
                        <div className="w-full h-3 rounded-full bg-zinc-200 dark:bg-zinc-700 overflow-hidden flex shadow-inner">
                          <div 
                            style={{ width: `${pctNet}%` }} 
                            className="bg-emerald-500 h-full transition-all" 
                            title={`Saldo Pendiente a Favor: ${pctNet}% (${window.formatCurrencyPYG(net)})`}
                          />
                          <div 
                            style={{ width: `${pctDebits}%` }} 
                            className="bg-rose-500 h-full transition-all" 
                            title={`Cuotas Universitarias: ${pctDebits}% (${window.formatCurrencyPYG(debits)})`}
                          />
                          <div 
                            style={{ width: `${pctReceived}%` }} 
                            className="bg-sky-500 h-full transition-all" 
                            title={`Cobrado en Efectivo: ${pctReceived}% (${window.formatCurrencyPYG(received)})`}
                          />
                        </div>

                        {/* Leyenda con importes */}
                        <div className="flex items-center justify-between flex-wrap gap-3 text-xs pt-0.5">
                          <div className="flex items-center gap-1.5">
                            <span className="w-2.5 h-2.5 rounded-full bg-emerald-500 shrink-0" />
                            <span className="text-zinc-600 dark:text-zinc-400">Saldo a su Favor:</span>
                            <strong className="text-emerald-700 dark:text-emerald-400 font-mono">{pctNet}% ({window.formatCurrencyPYG(net)})</strong>
                          </div>
                          <div className="flex items-center gap-1.5">
                            <span className="w-2.5 h-2.5 rounded-full bg-rose-500 shrink-0" />
                            <span className="text-zinc-600 dark:text-zinc-400">Cuotas Descontadas:</span>
                            <strong className="text-rose-700 dark:text-rose-400 font-mono">{pctDebits}% ({window.formatCurrencyPYG(debits)})</strong>
                          </div>
                          <div className="flex items-center gap-1.5">
                            <span className="w-2.5 h-2.5 rounded-full bg-sky-500 shrink-0" />
                            <span className="text-zinc-600 dark:text-zinc-400">Dinero Cobrado en Mano:</span>
                            <strong className="text-sky-700 dark:text-sky-400 font-mono">{pctReceived}% ({window.formatCurrencyPYG(received)})</strong>
                          </div>
                        </div>
                      </div>
                    );
                  })()}

                  {/* ================================================================
                      TERMÓMETRO DE COBERTURA DE CUOTA ACADÉMICA (CONCILIACIÓN DEL MES)
                      ================================================================ */}
                  {(() => {
                    const history = dashboard.data.monthlyHistory || [];
                    if (history.length === 0) return null;

                    // El período por defecto es el último mes registrado o el mes seleccionado
                    const defaultMonth = history[history.length - 1]?.month || selectedMonth;
                    const activeMonthData = history.find(h => h.month === selectedMonth) || history[history.length - 1];
                    const activeMonthStr = activeMonthData?.month || defaultMonth;

                    const mCredits = activeMonthData?.credits || 0;
                    const mDebits = activeMonthData?.debits || 0;
                    const mReceived = activeMonthData?.received || 0;
                    const mNet = mCredits - (mDebits + mReceived);

                    // Cobertura porcentual:
                    const hasDebits = mDebits > 0;
                    const coveragePercent = hasDebits 
                      ? Math.round((mCredits / mDebits) * 100) 
                      : (mCredits > 0 ? 100 : 0);
                    
                    const isFullyCovered = hasDebits ? (mCredits >= mDebits) : (mCredits > 0);
                    const deficit = hasDebits ? Math.max(mDebits - mCredits, 0) : 0;
                    const surplus = hasDebits ? Math.max(mCredits - mDebits, 0) : mCredits;

                    const monthDisplayName = (() => {
                      if (!activeMonthStr) return 'Mes Actual';
                      const [y, m] = activeMonthStr.split('-');
                      const months = ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio', 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'];
                      const idx = parseInt(m, 10) - 1;
                      return `${months[idx] || m} / ${y}`;
                    })();

                    return (
                      <div className="rounded-2xl border-2 border-zinc-200 dark:border-zinc-800 bg-white dark:bg-zinc-900 p-5 shadow-xs space-y-4">
                        {/* ENCABEZADO CON SELECTOR DE MES Y BADGE DE ESTADO */}
                        <div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3 border-b border-zinc-100 dark:border-zinc-800 pb-3.5">
                          <div className="flex items-center gap-2.5">
                            <span className="w-9 h-9 rounded-xl bg-zinc-950 text-white flex items-center justify-center text-lg shrink-0 shadow-2xs">
                              🎯
                            </span>
                            <div>
                              <div className="flex items-center gap-2">
                                <h3 className="font-bold text-sm text-zinc-950 dark:text-white">
                                  Termómetro de Cobertura de Cuota
                                </h3>
                                <span className="text-xs text-zinc-400 font-mono">
                                  • {monthDisplayName}
                                </span>
                              </div>
                              <p className="text-xs text-zinc-500">
                                Diagnóstico en tiempo real: ¿Tus servicios cubren la mensualidad universitaria de este período?
                              </p>
                            </div>
                          </div>

                          <div className="flex items-center gap-2 shrink-0">
                            {/* SELECTOR RÁPIDO DE MES PARA AUDITORÍA */}
                            <select
                              value={activeMonthStr}
                              onChange={(e) => {
                                setSelectedMonth(e.target.value);
                                txManager.updateFilters({ month: e.target.value });
                              }}
                              className="text-xs font-semibold py-1.5 px-2.5 rounded-lg border border-zinc-200 dark:border-zinc-700 bg-zinc-50 dark:bg-zinc-800 text-zinc-900 dark:text-zinc-100 cursor-pointer shadow-2xs"
                              title="Seleccionar mes para analizar cobertura"
                            >
                              {history.map(h => (
                                <option key={h.month} value={h.month}>
                                  Período {h.month}
                                </option>
                              ))}
                            </select>

                            {/* BADGE DE DIAGNÓSTICO */}
                            <span className={`inline-flex items-center gap-1.5 px-3 py-1 rounded-full text-xs font-bold font-mono shadow-2xs ${
                              isFullyCovered 
                                ? 'bg-emerald-50 text-emerald-800 border border-emerald-300 dark:bg-emerald-950/60 dark:text-emerald-300 dark:border-emerald-700' 
                                : (hasDebits 
                                    ? 'bg-amber-50 text-amber-800 border border-amber-300 dark:bg-amber-950/60 dark:text-amber-300 dark:border-amber-700' 
                                    : 'bg-blue-50 text-blue-800 border border-blue-300 dark:bg-blue-950/60 dark:text-blue-300 dark:border-blue-700')
                            }`}>
                              <span className={`w-2 h-2 rounded-full ${
                                isFullyCovered ? 'bg-emerald-500 animate-pulse' : (hasDebits ? 'bg-amber-500' : 'bg-blue-500')
                              }`} />
                              <span>
                                {isFullyCovered 
                                  ? `CUOTA 100% CUBIERTA (${coveragePercent}%)` 
                                  : (hasDebits ? `COBERTURA ${coveragePercent}%` : 'CRÉDITO DISPONIBLE')}
                              </span>
                            </span>
                          </div>
                        </div>

                        {/* BARRA VISUAL DE PROGRESO DE COBERTURA */}
                        <div className="space-y-1.5">
                          <div className="flex items-center justify-between text-xs">
                            <span className="font-semibold text-zinc-600 dark:text-zinc-300">
                              Progreso de Cobertura de la Mensualidad
                            </span>
                            <span className="font-mono font-bold text-sm text-zinc-950 dark:text-white">
                              {coveragePercent}% {coveragePercent >= 100 ? '✓' : ''}
                            </span>
                          </div>

                          <div className="w-full h-3.5 rounded-full bg-zinc-100 dark:bg-zinc-800 overflow-hidden border border-zinc-200 dark:border-zinc-700 p-0.5">
                            <div 
                              className={`h-full rounded-full transition-all duration-500 ${
                                isFullyCovered 
                                  ? 'bg-gradient-to-r from-emerald-500 to-teal-500 shadow-sm' 
                                  : 'bg-gradient-to-r from-amber-500 to-orange-500'
                              }`}
                              style={{ width: `${Math.min(coveragePercent, 100)}%` }}
                            />
                          </div>
                        </div>

                        {/* CUADRICULA DE DETALLE FINANCIERO DEL MES */}
                        <div className="grid grid-cols-2 sm:grid-cols-4 gap-2.5 text-xs">
                          <div className="p-3 rounded-xl bg-zinc-50 dark:bg-zinc-800/60 border border-zinc-200/80 dark:border-zinc-700/80">
                            <span className="text-[10px] text-zinc-500 dark:text-zinc-400 font-semibold uppercase block">Servicios Prestados</span>
                            <span className="text-sm font-bold font-mono text-emerald-700 dark:text-emerald-400">
                              +{window.formatCurrencyPYG(mCredits)}
                            </span>
                          </div>

                          <div className="p-3 rounded-xl bg-zinc-50 dark:bg-zinc-800/60 border border-zinc-200/80 dark:border-zinc-700/80">
                            <span className="text-[10px] text-zinc-500 dark:text-zinc-400 font-semibold uppercase block">Cuota Universitaria</span>
                            <span className="text-sm font-bold font-mono text-rose-700 dark:text-rose-400">
                              -{window.formatCurrencyPYG(mDebits)}
                            </span>
                          </div>

                          <div className="p-3 rounded-xl bg-zinc-50 dark:bg-zinc-800/60 border border-zinc-200/80 dark:border-zinc-700/80">
                            <span className="text-[10px] text-zinc-500 dark:text-zinc-400 font-semibold uppercase block">Cobrado en Mano</span>
                            <span className="text-sm font-bold font-mono text-sky-700 dark:text-sky-400">
                              {window.formatCurrencyPYG(mReceived)}
                            </span>
                          </div>

                          <div className={`p-3 rounded-xl border ${
                            mNet >= 0 
                              ? 'bg-emerald-50/70 border-emerald-200 dark:bg-emerald-950/40 dark:border-emerald-800' 
                              : 'bg-rose-50/70 border-rose-200 dark:bg-rose-950/40 dark:border-rose-800'
                          }`}>
                            <span className="text-[10px] text-zinc-500 dark:text-zinc-400 font-semibold uppercase block">Saldo Neto del Mes</span>
                            <span className={`text-sm font-bold font-mono ${
                              mNet >= 0 ? 'text-emerald-800 dark:text-emerald-300' : 'text-rose-800 dark:text-rose-300'
                            }`}>
                              {mNet >= 0 ? '+' : ''}{window.formatCurrencyPYG(mNet)}
                            </span>
                          </div>
                        </div>

                        {/* EXPLICACIÓN EN LENGUAJE CLARO Y BOTONES DE ACCIÓN RÁPIDA */}
                        <div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3 pt-1 text-xs">
                          <p className="text-zinc-600 dark:text-zinc-300 m-0 leading-normal flex-1">
                            {isFullyCovered ? (
                              <span>
                                💡 <strong>Excelente:</strong> Tus servicios de este período cubren la totalidad de la cuota universitaria. Tienes un excedente de <strong className="text-emerald-700 dark:text-emerald-400 font-mono font-bold">+{window.formatCurrencyPYG(surplus)}</strong> a tu favor a cobrar o compensar.
                              </span>
                            ) : (hasDebits ? (
                              <span>
                                ⚠️ <strong>Pendiente:</strong> Faltan <strong className="text-rose-700 dark:text-rose-400 font-mono font-bold">{window.formatCurrencyPYG(deficit)}</strong> en servicios para liquidar al 100% la cuota de este mes.
                              </span>
                            ) : (
                              <span>
                                ℹ️ No se registraron cuotas este mes. Los <strong className="text-emerald-700 font-mono">{window.formatCurrencyPYG(mCredits)}</strong> prestados quedan como saldo acumulado disponible.
                              </span>
                            ))}
                          </p>

                          <div className="flex items-center gap-2 shrink-0">
                            <button
                              type="button"
                              onClick={() => {
                                setPrintMonth(activeMonthStr);
                                navigateToTab('imprimir');
                              }}
                              className="px-3 py-1.5 rounded-lg border border-zinc-300 dark:border-zinc-700 bg-white dark:bg-zinc-800 hover:bg-zinc-100 dark:hover:bg-zinc-700 text-zinc-800 dark:text-zinc-200 font-semibold flex items-center gap-1.5 transition-colors cursor-pointer shadow-2xs"
                              title="Imprimir Rendición Oficial A4 de este mes"
                            >
                              <span>🖨️ Rendición A4</span>
                            </button>

                            <button
                              type="button"
                              onClick={() => {
                                setPeriodMode('month');
                                setSelectedMonth(activeMonthStr);
                                txManager.updateFilters({ month: activeMonthStr });
                                navigateToTab('lancamentos');
                              }}
                              className="px-3 py-1.5 rounded-lg bg-zinc-950 dark:bg-white hover:bg-zinc-800 dark:hover:bg-zinc-100 text-white dark:text-zinc-950 font-semibold flex items-center gap-1.5 transition-colors cursor-pointer shadow-xs"
                              title="Ver todos los movimientos del mes"
                            >
                              <span>Ver Movimientos ➔</span>
                            </button>
                          </div>
                        </div>
                      </div>
                    );
                  })()}

                  {/* GRÁFICOS */}
                  <div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
                    <Card className="p-5">
                      <div className="flex items-center justify-between mb-4">
                        <div>
                          <h3 className="font-semibold text-sm text-zinc-950 dark:text-white">Evolución Mensual: Servicios vs. Cuotas</h3>
                          <p className="text-xs text-zinc-500">Historial por período contable</p>
                        </div>
                        <div className="flex items-center gap-3 text-xs text-zinc-600 dark:text-zinc-400">
                          <div className="flex items-center gap-1.5"><div className="w-2.5 h-2.5 rounded-xs bg-emerald-500"></div><span>Servicios</span></div>
                          <div className="flex items-center gap-1.5"><div className="w-2.5 h-2.5 rounded-xs bg-rose-500"></div><span>Cuotas</span></div>
                        </div>
                      </div>
                      <window.ComparisonBarChart history={dashboard.data.monthlyHistory} />
                    </Card>

                    <Card className="p-5">
                      <div className="flex items-center justify-between mb-4">
                        <div>
                          <h3 className="font-semibold text-sm text-zinc-950 dark:text-white">Curva de Saldo Líquido Acumulado</h3>
                          <p className="text-xs text-zinc-500">Curva de compensación continua</p>
                        </div>
                        <div className="flex items-center gap-1.5 text-xs text-zinc-600 dark:text-zinc-400">
                          <div className="w-2.5 h-2.5 rounded-full bg-zinc-950 dark:bg-white"></div><span>Saldo General</span>
                        </div>
                      </div>
                      <window.RunningBalanceLineChart history={dashboard.data.monthlyHistory} />
                    </Card>

                    {/* GRÁFICO DE DISTRIBUCIÓN POR CATEGORÍAS */}
                    {window.CategoryDonutChart && (
                      <Card className="p-5 lg:col-span-2">
                        <div className="flex items-center justify-between mb-3 border-b border-zinc-100 dark:border-zinc-800 pb-2">
                          <div>
                            <h3 className="font-semibold text-sm text-zinc-950 dark:text-white">Distribución por Tipo de Servicio & Categoría</h3>
                            <p className="text-xs text-zinc-500">Desglose de eventos, audiovisuales, creativos y cuotas</p>
                          </div>
                          <span className="text-[10px] font-mono font-bold bg-zinc-100 dark:bg-zinc-800 px-2 py-0.5 rounded text-zinc-600 dark:text-zinc-400">
                            ANÁLISIS GLOBAL
                          </span>
                        </div>
                        <window.CategoryDonutChart transactions={dashboard.data.recentTransactions} />
                      </Card>
                    )}
                  </div>

                  {/* ÚLTIMOS MOVIMIENTOS */}
                  <div className="space-y-3 pt-2">
                    <div className="flex items-center justify-between">
                      <h2 className="text-base font-bold text-zinc-950 dark:text-white">Movimientos Recientes</h2>
                      <Button variant="ghost" size="sm" onClick={() => navigateToTab('lancamentos')}>
                        <span>Ver Extracto Completo</span>
                        <Lucide.ArrowUpRight size={14} />
                      </Button>
                    </div>
                    <window.TransactionTable 
                      transactions={dashboard.data.recentTransactions} 
                      onEdit={handleEditTx} 
                      showDelete={false} 
                    />
                  </div>
                </>
              )}
            </section>
          )}

          {/* ================================================================
              PESTAÑA: PROYECCIONES FUTURAS & SIMULADOR DE ESCENARIOS
              ================================================================ */}
          {activeTab === 'proyecciones' && (
            <section>
              <window.FutureProjections />
            </section>
          )}

          {/* ================================================================
              PESTAÑA: MOVIMIENTOS (EXTRACTO DE CUENTA CON FILTROS POR ETIQUETA Y PERÍODO)
              ================================================================ */}
          {(activeTab === 'lancamentos' || activeTab === 'transactions') && (
            <section className="space-y-6">
              <div className="flex flex-col md:flex-row md:items-center md:justify-between gap-4 border-b border-zinc-200 pb-5">
                <div>
                  <h1 className="text-2xl font-bold tracking-tight text-zinc-950">Extracto de Cuenta Corriente</h1>
                  <p className="text-sm text-zinc-500 mt-1">Consulte movimientos por mes o rango de fechas con filtros de etiquetas y tipo</p>
                </div>
                {isAdmin && (
                  <Button variant="default" size="sm" onClick={handleOpenNewTx}>
                    <Lucide.Plus size={15} />
                    <span>Nuevo Movimiento</span>
                  </Button>
                )}
              </div>

              {/* PRESETS DE FILTRADO RÁPIDO (1 CLIC) */}
              <div className="flex items-center gap-1.5 flex-wrap pt-1">
                <span className="text-xs font-semibold text-zinc-500 mr-1 flex items-center gap-1">
                  <span>⚡</span>
                  <span>Filtros Rápidos:</span>
                </span>
                {[
                  { id: 'all', label: 'Todos los Registros', action: () => { setPeriodMode('month'); setSelectedMonth(''); txManager.updateFilters({ month: '', startDate: '', endDate: '', type: '', tag: '' }); } },
                  { id: 'this_month', label: 'Octubre / Actual', action: () => { setPeriodMode('month'); const m = '2026-10'; setSelectedMonth(m); txManager.updateFilters({ month: m, startDate: '', endDate: '', type: '', tag: '' }); } },
                  { id: 'last_month', label: 'Septiembre', action: () => { setPeriodMode('month'); const m = '2026-09'; setSelectedMonth(m); txManager.updateFilters({ month: m, startDate: '', endDate: '', type: '', tag: '' }); } },
                  { id: 'august', label: 'Agosto', action: () => { setPeriodMode('month'); const m = '2026-08'; setSelectedMonth(m); txManager.updateFilters({ month: m, startDate: '', endDate: '', type: '', tag: '' }); } },
                  { id: 'services_only', label: 'Solo Servicios (+)', action: () => { txManager.updateFilters({ type: 'CREDIT' }); } },
                  { id: 'cuotas_only', label: 'Solo Cuotas (-)', action: () => { txManager.updateFilters({ type: 'DEBIT' }); } },
                  { id: 'payments_only', label: 'Solo Pagos (💵)', action: () => { txManager.updateFilters({ type: 'PAYMENT_RECEIVED' }); } }
                ].map(pill => (
                  <button
                    key={pill.id}
                    type="button"
                    onClick={() => {
                      setActivePresetFilter(pill.id);
                      pill.action();
                    }}
                    className={`px-2.5 py-1 text-xs rounded-full border transition-all cursor-pointer font-medium ${
                      activePresetFilter === pill.id
                        ? 'bg-zinc-950 text-white dark:bg-white dark:text-zinc-950 border-zinc-950 shadow-2xs font-semibold'
                        : 'bg-white text-zinc-600 dark:bg-zinc-800 dark:text-zinc-300 border-zinc-200 dark:border-zinc-700 hover:bg-zinc-100 hover:text-zinc-950'
                    }`}
                  >
                    {pill.label}
                  </button>
                ))}
              </div>

              {/* TOGGLE: MENSUAL O RANGO DE FECHAS */}
              <div className="inline-flex rounded-lg border border-zinc-200 bg-zinc-100 p-1">
                <button 
                  type="button" 
                  className={`flex items-center gap-2 px-3 py-1.5 text-xs font-semibold rounded-md transition-all cursor-pointer ${
                    periodMode === 'month' 
                      ? 'bg-white text-zinc-950 shadow-xs' 
                      : 'text-zinc-600 hover:text-zinc-950'
                  }`}
                  onClick={() => {
                    setPeriodMode('month');
                    txManager.updateFilters({ month: selectedMonth || new Date().toISOString().substring(0, 7), startDate: '', endDate: '' });
                  }}
                >
                  <Lucide.Calendar size={14} />
                  <span>Ver por Mes</span>
                </button>
                <button 
                  type="button" 
                  className={`flex items-center gap-2 px-3 py-1.5 text-xs font-semibold rounded-md transition-all cursor-pointer ${
                    periodMode === 'range' 
                      ? 'bg-white text-zinc-950 shadow-xs' 
                      : 'text-zinc-600 hover:text-zinc-950'
                  }`}
                  onClick={() => {
                    setPeriodMode('range');
                    handleShortcutRange('this_month');
                  }}
                >
                  <Lucide.Filter size={14} />
                  <span>Rango de Fechas</span>
                </button>
              </div>

              {/* FILTROS DEL MODO MENSUAL */}
              {periodMode === 'month' && (
                <div className="flex flex-wrap items-center justify-between gap-3 p-3 rounded-xl border border-zinc-200 bg-zinc-50/70">
                  <div className="flex items-center gap-2">
                    <Button variant="outline" size="sm" onClick={() => shiftMonth(-1)} title="Mes Anterior">
                      <Lucide.ChevronLeft size={14} />
                      <span>Anterior</span>
                    </Button>
                    <input 
                      type="month" 
                      className="h-8 px-3 text-xs font-semibold rounded-md border border-zinc-200 bg-white text-zinc-950 focus:outline-none focus:ring-1 focus:ring-zinc-950" 
                      value={selectedMonth} 
                      onChange={(e) => handleMonthChange(e.target.value)} 
                    />
                    <Button variant="outline" size="sm" onClick={() => shiftMonth(1)} title="Siguiente Mes">
                      <span>Siguiente</span>
                      <Lucide.ChevronRight size={14} />
                    </Button>
                    <Button 
                      variant="ghost" 
                      size="sm" 
                      onClick={() => handleMonthChange(new Date().toISOString().substring(0, 7))}
                    >
                      Mes Actual
                    </Button>
                  </div>

                  <div className="flex items-center gap-2 flex-wrap">
                    {/* FILTRO POR ETIQUETA */}
                    <select 
                      className="h-8 px-2.5 text-xs rounded-md border border-zinc-200 bg-white text-zinc-950 focus:outline-none focus:ring-1 focus:ring-zinc-950"
                      value={txManager.filters.tag || ''}
                      onChange={(e) => txManager.updateFilters({ tag: e.target.value })}
                    >
                      <option value="">Todas las Etiquetas</option>
                      {tags.map(t => (
                        <option key={t.id} value={t.name}>#{t.name}</option>
                      ))}
                    </select>

                    <select 
                      className="h-8 px-2.5 text-xs rounded-md border border-zinc-200 bg-white text-zinc-950 focus:outline-none focus:ring-1 focus:ring-zinc-950"
                      value={txManager.filters.type || ''}
                      onChange={(e) => txManager.updateFilters({ type: e.target.value })}
                    >
                      <option value="">Todos los Tipos</option>
                      <option value="CREDIT">Servicios Prestados (+)</option>
                      <option value="DEBIT">Cuotas / Débitos (-)</option>
                      <option value="PAYMENT_RECEIVED">Pagos Recibidos (Efectivo/Banco)</option>
                      <option value="PAYMENT_MADE">Pagos Efectuados</option>
                    </select>

                    <div className="relative">
                      <input 
                        type="text" 
                        className="h-8 pl-8 pr-3 text-xs rounded-md border border-zinc-200 bg-white text-zinc-950 placeholder-zinc-400 focus:outline-none focus:ring-1 focus:ring-zinc-950 w-44 sm:w-56" 
                        placeholder="Buscar texto, OS, etiqueta..." 
                        value={txManager.filters.q || ''}
                        onChange={(e) => txManager.updateFilters({ q: e.target.value })}
                      />
                      <div className="absolute left-2.5 top-2 text-zinc-400 pointer-events-none">
                        <Lucide.Search size={13} />
                      </div>
                    </div>
                  </div>
                </div>
              )}

              {/* FILTROS DEL MODO RANGO DE FECHAS */}
              {periodMode === 'range' && (
                <div className="p-4 rounded-xl border border-zinc-200 bg-zinc-50/70 space-y-3">
                  <div className="flex flex-wrap items-center gap-3">
                    <div className="flex items-center gap-1.5">
                      <span className="text-xs font-semibold text-zinc-500">Desde:</span>
                      <input 
                        type="date" 
                        className="h-8 px-2.5 text-xs font-medium rounded-md border border-zinc-200 bg-white text-zinc-950 focus:outline-none focus:ring-1 focus:ring-zinc-950" 
                        value={startDate} 
                        onChange={(e) => applyDateRange(e.target.value, endDate)} 
                      />
                    </div>

                    <div className="flex items-center gap-1.5">
                      <span className="text-xs font-semibold text-zinc-500">Hasta:</span>
                      <input 
                        type="date" 
                        className="h-8 px-2.5 text-xs font-medium rounded-md border border-zinc-200 bg-white text-zinc-950 focus:outline-none focus:ring-1 focus:ring-zinc-950" 
                        value={endDate} 
                        onChange={(e) => applyDateRange(startDate, e.target.value)} 
                      />
                    </div>

                    {/* FILTRO POR ETIQUETA EN MODO RANGO */}
                    <select 
                      className="h-8 px-2.5 text-xs rounded-md border border-zinc-200 bg-white text-zinc-950 focus:outline-none focus:ring-1 focus:ring-zinc-950"
                      value={txManager.filters.tag || ''}
                      onChange={(e) => txManager.updateFilters({ tag: e.target.value })}
                    >
                      <option value="">Todas las Etiquetas</option>
                      {tags.map(t => (
                        <option key={t.id} value={t.name}>#{t.name}</option>
                      ))}
                    </select>

                    <select 
                      className="h-8 px-2.5 text-xs rounded-md border border-zinc-200 bg-white text-zinc-950 focus:outline-none focus:ring-1 focus:ring-zinc-950"
                      value={txManager.filters.type || ''}
                      onChange={(e) => txManager.updateFilters({ type: e.target.value })}
                    >
                      <option value="">Todos los Tipos</option>
                      <option value="CREDIT">Servicios Prestados</option>
                      <option value="DEBIT">Cuotas Universitarias</option>
                      <option value="PAYMENT_RECEIVED">Pagos Recibidos</option>
                    </select>

                    <div className="relative">
                      <input 
                        type="text" 
                        className="h-8 pl-8 pr-3 text-xs rounded-md border border-zinc-200 bg-white text-zinc-950 placeholder-zinc-400 focus:outline-none focus:ring-1 focus:ring-zinc-950 w-44 sm:w-56" 
                        placeholder="Buscar texto, OS, etiqueta..." 
                        value={txManager.filters.q || ''}
                        onChange={(e) => txManager.updateFilters({ q: e.target.value })}
                      />
                      <div className="absolute left-2.5 top-2 text-zinc-400 pointer-events-none">
                        <Lucide.Search size={13} />
                      </div>
                    </div>
                  </div>

                  {/* ACCESOS RÁPIDOS DE INTERVALO */}
                  <div className="flex items-center gap-1.5 flex-wrap pt-1 border-t border-zinc-200/60">
                    <span className="text-[11px] font-medium text-zinc-400">Accesos rápidos:</span>
                    <Button variant="secondary" size="sm" className="h-7 text-[11px] py-0 px-2.5" onClick={() => handleShortcutRange('this_month')}>Este Mes</Button>
                    <Button variant="secondary" size="sm" className="h-7 text-[11px] py-0 px-2.5" onClick={() => handleShortcutRange('last_30')}>Últimos 30 días</Button>
                    <Button variant="secondary" size="sm" className="h-7 text-[11px] py-0 px-2.5" onClick={() => handleShortcutRange('last_90')}>Últimos 90 días</Button>
                    <Button variant="secondary" size="sm" className="h-7 text-[11px] py-0 px-2.5" onClick={() => handleShortcutRange('this_year')}>Este Año</Button>
                    <Button variant="ghost" size="sm" className="h-7 text-[11px] py-0 px-2.5" onClick={() => handleShortcutRange('all')}>Ver Todos</Button>
                  </div>
                </div>
              )}

              {/* CARD RESUMEN DEL PERÍODO SELECCIONADO */}
              <div className="grid grid-cols-1 sm:grid-cols-3 gap-3">
                <Card className="p-4 border-zinc-200">
                  <div className="text-xs uppercase font-semibold text-zinc-500">
                    (+) Servicios en el Período
                  </div>
                  <div className="text-xl font-bold font-mono text-zinc-950 mt-1">
                    {window.formatCurrencyPYG(periodTotals.credits)}
                  </div>
                </Card>

                <Card className="p-4 border-zinc-200">
                  <div className="text-xs uppercase font-semibold text-zinc-500">
                    (-) Cuotas en el Período
                  </div>
                  <div className="text-xl font-bold font-mono text-zinc-600 mt-1">
                    {window.formatCurrencyPYG(periodTotals.debits)}
                  </div>
                </Card>

                <Card className="p-4 border-zinc-950 bg-zinc-50/50 ring-1 ring-zinc-950">
                  <div className="text-xs uppercase font-semibold text-zinc-700">
                    Saldo Líquido ({periodTotals.count} movimientos)
                  </div>
                  <div className="text-xl font-bold font-mono text-zinc-950 mt-1">
                    {window.formatCurrencyPYG(periodTotals.net)}
                  </div>
                </Card>
              </div>

              {/* TABLA DE MOVIMIENTOS CON ETIQUETAS */}
              <window.TransactionTable 
                transactions={txManager.transactions} 
                onEdit={handleEditTx} 
                onDelete={txManager.removeTransaction} 
                showDelete={true} 
              />
            </section>
          )}

          {/* ================================================================
              PESTAÑA: SERVICIOS & REGLAS
              ================================================================ */}
          {(activeTab === 'servicos' || activeTab === 'services') && (
            <section className="space-y-8">
              <div className="flex flex-col md:flex-row md:items-center md:justify-between gap-4 border-b border-zinc-200 pb-5">
                <div>
                  <h1 className="text-2xl font-bold tracking-tight text-zinc-950">Servicios & Recurrencia</h1>
                  <p className="text-sm text-zinc-500 mt-1">Lista de precios de servicios y automatizaciones mensuales (cuotas universitarias)</p>
                </div>
                {isAdmin && (
                  <div className="flex items-center gap-2">
                    <Button variant="secondary" size="sm" onClick={() => setModalRecurringOpen(true)}>
                      <Lucide.Plus size={14} />
                      <span>Nueva Regla Mensual</span>
                    </Button>
                    <Button variant="default" size="sm" onClick={() => setModalServiceOpen(true)}>
                      <Lucide.Plus size={14} />
                      <span>Registrar Servicio</span>
                    </Button>
                  </div>
                )}
              </div>

              {/* REGLAS RECURRENTES */}
              <div className="space-y-4">
                {/* BANNER EXPLICATIVO */}
                <div className="p-4 rounded-xl border border-zinc-200 bg-zinc-50/70 flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3">
                  <div className="space-y-1">
                    <div className="flex items-center gap-2">
                      <span className="text-xs font-bold text-zinc-950 uppercase tracking-wider">💡 ¿Cómo funcionan las Reglas Recurrentes?</span>
                      <Badge variant="outline" className="text-[10px]">Automatización</Badge>
                    </div>
                    <p className="text-xs text-zinc-600 max-w-2xl leading-relaxed">
                      Registre cuotas o cobros fijos que se repiten cada mes (o fijos por X cuotas). El sistema <strong>procesa y genera los movimientos en el extracto automáticamente</strong> al iniciar cada nuevo mes, sin duplicar valores y sin necesidad de ingresarlos a mano.
                    </p>
                  </div>
                  {isAdmin && (
                    <Button variant="outline" size="sm" onClick={handleApplyRecurringRules} className="whitespace-nowrap shrink-0">
                      <Lucide.Sparkles size={14} />
                      <span>Sincronizar Mes Actual</span>
                    </Button>
                  )}
                </div>

                <div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-2">
                  <div>
                    <h2 className="text-base font-bold text-zinc-950">Reglas Recurrentes Programadas</h2>
                    <p className="text-xs text-zinc-500">Cobros continuos, en cuotas o con fecha de vencimiento</p>
                  </div>
                </div>

                <div className="table-container rounded-xl border border-zinc-200 bg-white shadow-xs overflow-hidden">
                  <table className="data-table w-full text-sm">
                    <thead>
                      <tr className="border-b border-zinc-200 bg-zinc-50/70 text-left">
                        <th className="py-3 px-4 text-xs font-semibold text-zinc-500 uppercase tracking-wider w-36">Tipo</th>
                        <th className="py-3 px-4 text-xs font-semibold text-zinc-500 uppercase tracking-wider">Título del Cobro / Descuento</th>
                        <th className="py-3 px-4 text-xs font-semibold text-zinc-500 uppercase tracking-wider w-44">Duración & Repetición</th>
                        <th className="py-3 px-4 text-xs font-semibold text-zinc-500 uppercase tracking-wider w-32">Vencimiento</th>
                        <th className="py-3 px-4 text-xs font-semibold text-zinc-500 uppercase tracking-wider">Observación</th>
                        <th className="py-3 px-4 text-xs font-semibold text-zinc-500 uppercase tracking-wider text-right w-36">Monto Mensual</th>
                        <th className="py-3 px-4 text-xs font-semibold text-zinc-500 uppercase tracking-wider text-right w-20">Acciones</th>
                      </tr>
                    </thead>
                    <tbody className="divide-y divide-zinc-100">
                      {recurringRules.length === 0 ? (
                        <tr><td colSpan="7" className="p-8 text-center text-zinc-400 text-sm">Ninguna regla recurrente registrada.</td></tr>
                      ) : (
                        recurringRules.map(r => (
                          <tr key={r.id} className="hover:bg-zinc-50/70 transition-colors">
                            <td className="py-3 px-4">
                              {r.type === 'DEBIT' ? (
                                <Badge variant="secondary" className="font-mono text-[11px]">- Cuota</Badge>
                              ) : (
                                <Badge variant="default" className="font-mono text-[11px]">+ Cobro Fijo</Badge>
                              )}
                            </td>
                            <td className="py-3 px-4">
                              <div className="font-semibold text-zinc-950">{r.title}</div>
                              {r.service_name && (
                                <div className="text-xs text-zinc-400 mt-0.5">Servicio: {r.service_name}</div>
                              )}
                            </td>
                            <td className="py-3 px-4">
                              {r.duration_type === 'months' ? (
                                <span className="inline-flex items-center text-[10px] font-mono bg-zinc-100 text-zinc-800 border border-zinc-200 px-2 py-0.5 rounded font-medium">
                                  {r.applied_count || 0} de {r.total_installments} meses
                                </span>
                              ) : r.duration_type === 'until_date' ? (
                                <span className="inline-flex items-center text-[10px] font-mono bg-zinc-100 text-zinc-800 border border-zinc-200 px-2 py-0.5 rounded font-medium">
                                  Hasta {r.end_date}
                                </span>
                              ) : (
                                <span className="inline-flex items-center text-[10px] font-mono bg-zinc-100 text-zinc-700 border border-zinc-200 px-2 py-0.5 rounded font-medium">
                                  Continuo (Todos los meses)
                                </span>
                              )}
                            </td>
                            <td className="py-3 px-4 font-mono text-zinc-600 text-xs">Cada día {r.day_of_month}</td>
                            <td className="py-3 px-4 text-zinc-500 text-xs">{r.notes || '-'}</td>
                            <td className="py-3 px-4 text-right font-mono font-bold text-zinc-950">
                              {window.formatCurrencyPYG(r.amount)}
                            </td>
                            <td className="py-3 px-4 text-right">
                              {isAdmin ? (
                                <Button 
                                  variant="ghost" 
                                  size="icon" 
                                  onClick={() => handleDeleteRecurring(r.id, r)}
                                  className="h-7 w-7 text-zinc-400 hover:text-red-600 hover:bg-red-50"
                                >
                                  <Lucide.Trash size={14} />
                                </Button>
                              ) : (
                                <span className="text-zinc-300 font-mono text-xs">-</span>
                              )}
                            </td>
                          </tr>
                        ))
                      )}
                    </tbody>
                  </table>
                </div>
              </div>

              {/* CATÁLOGO DE SERVICIOS */}
              <div className="space-y-4">
                <div>
                  <h2 className="text-base font-bold text-zinc-950">Catálogo de Servicios Prestados</h2>
                  <p className="text-xs text-zinc-500">Registre aquí sus servicios para seleccionarlos rápidamente al crear movimientos</p>
                </div>

                <div className="table-container rounded-xl border border-zinc-200 bg-white shadow-xs overflow-hidden">
                  <table className="data-table w-full text-sm">
                    <thead>
                      <tr className="border-b border-zinc-200 bg-zinc-50/70 text-left">
                        <th className="py-3 px-4 text-xs font-semibold text-zinc-500 uppercase tracking-wider w-24">ID</th>
                        <th className="py-3 px-4 text-xs font-semibold text-zinc-500 uppercase tracking-wider">Nombre del Servicio</th>
                        <th className="py-3 px-4 text-xs font-semibold text-zinc-500 uppercase tracking-wider w-32">Categoría</th>
                        <th className="py-3 px-4 text-xs font-semibold text-zinc-500 uppercase tracking-wider w-28">Unidad</th>
                        <th className="py-3 px-4 text-xs font-semibold text-zinc-500 uppercase tracking-wider">Descripción</th>
                        <th className="py-3 px-4 text-xs font-semibold text-zinc-500 uppercase tracking-wider text-right w-36">Precio Estándar</th>
                        <th className="py-3 px-4 text-xs font-semibold text-zinc-500 uppercase tracking-wider text-right w-20">Acciones</th>
                      </tr>
                    </thead>
                    <tbody className="divide-y divide-zinc-100">
                      {services.length === 0 ? (
                        <tr><td colSpan="7" className="p-8 text-center text-zinc-400 text-sm">Ningún servicio registrado.</td></tr>
                      ) : (
                        services.map(s => (
                          <tr key={s.id} className="hover:bg-zinc-50/70 transition-colors">
                            <td className="py-3 px-4 font-mono font-bold text-xs text-zinc-800 whitespace-nowrap">
                              <span className="px-2 py-0.5 rounded bg-zinc-100 border border-zinc-200">
                                #SRV-{String(s.id).padStart(3, '0')}
                              </span>
                            </td>
                            <td className="py-3 px-4 font-semibold text-zinc-950">{s.name}</td>
                            <td className="py-3 px-4">
                              <Badge variant="outline" className="text-[11px]">{s.category || 'General'}</Badge>
                            </td>
                            <td className="py-3 px-4 text-zinc-500 text-xs">{s.unit || 'servicio'}</td>
                            <td className="py-3 px-4 text-zinc-600 text-xs max-w-sm">{s.description || '-'}</td>
                            <td className="py-3 px-4 text-right font-mono font-bold text-zinc-950">
                              {window.formatCurrencyPYG(s.default_amount)}
                            </td>
                            <td className="py-3 px-4 text-right">
                              {isAdmin ? (
                                <Button 
                                  variant="ghost" 
                                  size="icon" 
                                  onClick={() => handleDeleteService(s.id, s)}
                                  className="h-7 w-7 text-zinc-400 hover:text-red-600 hover:bg-red-50"
                                >
                                  <Lucide.Trash size={14} />
                                </Button>
                              ) : (
                                <span className="text-zinc-300 font-mono text-xs">-</span>
                              )}
                            </td>
                          </tr>
                        ))
                      )}
                    </tbody>
                  </table>
                </div>
              </div>
            </section>
          )}

          {/* ================================================================
              ABA: IMPRESSÃO A4 DO MÊS
              ================================================================ */}
          {(activeTab === 'imprimir' || activeTab === 'print') && (
            <section>
              <window.PrintSheetA4 
                report={reportManager.report} 
                selectedMonth={printMonth} 
                onMonthChange={setPrintMonth} 
                onTriggerPrint={() => window.print()} 
              />
            </section>
          )}

          {/* ================================================================
              ABA: CONFIGURAÇÕES COMPLETAS (TAGS, DADOS CADASTRAIS, PARÂMETROS E BACKUP)
              ================================================================ */}
          {(activeTab === 'configuracoes' || activeTab === 'backup') && (
            !isAdmin ? (
              <section className="py-12">
                <div className="p-8 text-center bg-zinc-50 border border-zinc-200 rounded-2xl max-w-lg mx-auto space-y-3 shadow-xs">
                  <span className="text-4xl block">🔒</span>
                  <h2 className="text-lg font-bold text-zinc-950">Acceso Reservado al Administrador</h2>
                  <p className="text-xs text-zinc-600 leading-relaxed">
                    Las configuraciones contables, parámetros del sistema y copias de seguridad están protegidas contra modificaciones institucionales.
                  </p>
                  <p className="text-xs text-blue-700 font-medium">
                    Su perfil de Auditoría puede consultar con total transparencia las pestañas de Dashboard, Movimientos, Proyecciones, Servicios e Imprimir Rendición A4.
                  </p>
                </div>
              </section>
            ) : (
            <section className="space-y-6">
              <div className="border-b border-zinc-200 pb-5">
                <h1 className="text-2xl font-bold tracking-tight text-zinc-950">Configuración & Panel de Control</h1>
                <p className="text-sm text-zinc-500 mt-1">Administre etiquetas, datos institucionales de la universidad, moneda y copias de seguridad</p>
              </div>

              {/* SEGMENTED TABS DE CONFIGURACIÓN */}
              <div className="flex items-center gap-1.5 border-b border-zinc-200 pb-2 overflow-x-auto">
                <button
                  type="button"
                  onClick={() => setSettingsTab('tags')}
                  className={`flex items-center gap-2 px-3.5 py-2 text-xs font-semibold rounded-lg transition-all cursor-pointer whitespace-nowrap ${
                    settingsTab === 'tags'
                      ? 'bg-zinc-900 text-white shadow-xs'
                      : 'text-zinc-600 hover:text-zinc-950 hover:bg-zinc-100'
                  }`}
                >
                  <Lucide.Sparkles size={14} />
                  <span>Etiquetas & Tags</span>
                  <span className="text-[10px] bg-zinc-700 text-zinc-200 px-1.5 py-0.2 rounded-full font-mono">{tags.length}</span>
                </button>

                <button
                  type="button"
                  onClick={() => setSettingsTab('movimentacoes')}
                  className={`flex items-center gap-2 px-3.5 py-2 text-xs font-semibold rounded-lg transition-all cursor-pointer whitespace-nowrap ${
                    settingsTab === 'movimentacoes'
                      ? 'bg-zinc-900 text-white shadow-xs'
                      : 'text-zinc-600 hover:text-zinc-950 hover:bg-zinc-100'
                  }`}
                >
                  <Lucide.Layers size={14} />
                  <span>Tipos de Movimiento</span>
                  <span className="text-[10px] bg-zinc-700 text-zinc-200 px-1.5 py-0.2 rounded-full font-mono">4</span>
                </button>

                <button
                  type="button"
                  onClick={() => setSettingsTab('instituicao')}
                  className={`flex items-center gap-2 px-3.5 py-2 text-xs font-semibold rounded-lg transition-all cursor-pointer whitespace-nowrap ${
                    settingsTab === 'instituicao'
                      ? 'bg-zinc-900 text-white shadow-xs'
                      : 'text-zinc-600 hover:text-zinc-950 hover:bg-zinc-100'
                  }`}
                >
                  <Lucide.FileText size={14} />
                  <span>Datos de la Universidad & Prestador</span>
                </button>

                <button
                  type="button"
                  onClick={() => setSettingsTab('preferencias')}
                  className={`flex items-center gap-2 px-3.5 py-2 text-xs font-semibold rounded-lg transition-all cursor-pointer whitespace-nowrap ${
                    settingsTab === 'preferencias'
                      ? 'bg-zinc-900 text-white shadow-xs'
                      : 'text-zinc-600 hover:text-zinc-950 hover:bg-zinc-100'
                  }`}
                >
                  <Lucide.Settings size={14} />
                  <span>Parámetros & Moneda</span>
                </button>

                <button
                  type="button"
                  onClick={() => setSettingsTab('backup')}
                  className={`flex items-center gap-2 px-3.5 py-2 text-xs font-semibold rounded-lg transition-all cursor-pointer whitespace-nowrap ${
                    settingsTab === 'backup'
                      ? 'bg-zinc-900 text-white shadow-xs'
                      : 'text-zinc-600 hover:text-zinc-950 hover:bg-zinc-100'
                  }`}
                >
                  <Lucide.Database size={14} />
                  <span>Base de Datos & Respaldo</span>
                </button>
              </div>

              {/* -------------------------------------------------------------
                  SUB-PESTAÑA: GESTIÓN DE ETIQUETAS & TAGS
                  ------------------------------------------------------------- */}
              {settingsTab === 'tags' && (
                <div className="space-y-4">
                  <div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3 bg-zinc-50 p-4 rounded-xl border border-zinc-200">
                    <div>
                      <h3 className="font-bold text-sm text-zinc-950">Catálogo de Etiquetas</h3>
                      <p className="text-xs text-zinc-500 mt-0.5">
                        Las etiquetas organizan y filtran sus trabajos (ej: grabación, edición, entrega). También puede crear nuevas etiquetas directamente al registrar movimientos.
                      </p>
                    </div>
                    <Button 
                      variant="default" 
                      size="sm"
                      onClick={() => {
                        setEditingTag(null);
                        setModalTagOpen(true);
                      }}
                    >
                      <Lucide.Plus size={14} />
                      <span>Nueva Etiqueta</span>
                    </Button>
                  </div>

                  <div className="table-container rounded-xl border border-zinc-200 bg-white shadow-xs overflow-hidden">
                    <table className="data-table w-full text-sm">
                      <thead>
                        <tr className="border-b border-zinc-200 bg-zinc-50/70 text-left">
                          <th className="py-3 px-4 text-xs font-semibold text-zinc-500 uppercase tracking-wider w-48">Muestra Visual</th>
                          <th className="py-3 px-4 text-xs font-semibold text-zinc-500 uppercase tracking-wider">Nombre de la Etiqueta</th>
                          <th className="py-3 px-4 text-xs font-semibold text-zinc-500 uppercase tracking-wider w-40 text-center">Uso en Movimientos</th>
                          <th className="py-3 px-4 text-xs font-semibold text-zinc-500 uppercase tracking-wider text-right w-28">Acciones</th>
                        </tr>
                      </thead>
                      <tbody className="divide-y divide-zinc-100">
                        {tags.length === 0 ? (
                          <tr><td colSpan="4" className="p-8 text-center text-zinc-400 text-sm">Ninguna etiqueta registrada todavía.</td></tr>
                        ) : (
                          tags.map(t => (
                            <tr key={t.id} className="hover:bg-zinc-50/70 transition-colors">
                              <td className="py-3 px-4">
                                <div className="flex items-center gap-3">
                                  <span 
                                    className="inline-flex items-center px-2.5 py-1 rounded-full text-xs font-bold text-white shadow-2xs font-mono shrink-0"
                                    style={{ backgroundColor: t.color || '#18181b' }}
                                  >
                                    #{t.name}
                                  </span>

                                  {/* SELECTOR RÁPIDO DE COLOR (1 CLIC) */}
                                  <div className="flex items-center gap-1.5 p-1 rounded-md bg-zinc-100 border border-zinc-200">
                                    {[
                                      { val: '#dc2626', name: 'Rojo' },
                                      { val: '#d97706', name: 'Amarillo / Ámbar' },
                                      { val: '#059669', name: 'Verde' },
                                      { val: '#2563eb', name: 'Azul' },
                                      { val: '#7c3aed', name: 'Púrpura' },
                                      { val: '#db2777', name: 'Rosa' },
                                      { val: '#18181b', name: 'Negro' }
                                    ].map(item => (
                                      <button
                                        key={item.val}
                                        type="button"
                                        title={`Cambiar a ${item.name}`}
                                        className={`w-3.5 h-3.5 rounded-full border border-white cursor-pointer hover:scale-125 transition-transform ${
                                          t.color === item.val ? 'ring-2 ring-zinc-950 scale-110' : ''
                                        }`}
                                        style={{ backgroundColor: item.val }}
                                        onClick={async () => {
                                          try {
                                            await window.Api.updateTag(t.id, { name: t.name, color: item.val });
                                            triggerRefresh();
                                            showToast(`¡Color de la etiqueta #${t.name} actualizado a ${item.name}!`);
                                          } catch (err) {
                                            showToast('Error al actualizar color.');
                                          }
                                        }}
                                      />
                                    ))}

                                    {/* COLOR PICKER PERSONALIZADO */}
                                    <label title="Elegir color personalizado" className="relative cursor-pointer flex items-center">
                                      <span className="text-[10px] text-zinc-500 font-bold hover:text-zinc-900 px-0.5">🎨</span>
                                      <input 
                                        type="color"
                                        className="opacity-0 absolute inset-0 w-full h-full cursor-pointer"
                                        value={t.color || '#18181b'}
                                        onChange={async (e) => {
                                          try {
                                            await window.Api.updateTag(t.id, { name: t.name, color: e.target.value });
                                            triggerRefresh();
                                            showToast(`¡Color de la etiqueta #${t.name} actualizado!`);
                                          } catch (err) {}
                                        }}
                                      />
                                    </label>
                                  </div>
                                </div>
                              </td>
                              <td className="py-3 px-4 font-semibold text-zinc-950">
                                {t.name}
                              </td>
                              <td className="py-3 px-4 text-center">
                                <span className="font-mono text-xs bg-zinc-100 text-zinc-700 px-2 py-0.5 rounded border border-zinc-200">
                                  {t.usage_count || 0} movimiento(s)
                                </span>
                              </td>
                              <td className="py-3 px-4 text-right">
                                <div className="flex items-center justify-end gap-1.5">
                                  <Button 
                                    variant="ghost" 
                                    size="icon" 
                                    onClick={() => {
                                      setEditingTag(t);
                                      setModalTagOpen(true);
                                    }}
                                    title="Editar Etiqueta"
                                    className="h-7 w-7 text-zinc-600 hover:text-zinc-950"
                                  >
                                    <Lucide.Edit size={14} />
                                  </Button>
                                  <Button 
                                    variant="ghost" 
                                    size="icon" 
                                    onClick={() => handleDeleteTag(t.id, t)}
                                    title="Eliminar Etiqueta"
                                    className="h-7 w-7 text-zinc-400 hover:text-red-600 hover:bg-red-50"
                                  >
                                    <Lucide.Trash size={14} />
                                  </Button>
                                </div>
                              </td>
                            </tr>
                          ))
                        )}
                      </tbody>
                    </table>
                  </div>
                </div>
              )}

              {/* -------------------------------------------------------------
                  SUB-PESTAÑA: TIPOS DE MOVIMIENTO
                  ------------------------------------------------------------- */}
              {settingsTab === 'movimentacoes' && (
                <div className="space-y-6">
                  <div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3 bg-zinc-50 p-4 rounded-xl border border-zinc-200">
                    <div>
                      <h3 className="font-bold text-sm text-zinc-950">Personalización de Tipos de Movimiento</h3>
                      <p className="text-xs text-zinc-500 mt-0.5">
                        Defina cómo debe mostrarse cada tipo contable en el formulario de nuevos movimientos, en el extracto y en la rendición A4.
                      </p>
                    </div>
                    <div className="flex items-center gap-2">
                      <span className="text-xs bg-zinc-200 text-zinc-800 px-2.5 py-1 rounded-md font-mono font-medium">
                        4 Estándares Contables
                      </span>
                    </div>
                  </div>

                  <MovementTypesConfigForm settings={settings} onSave={handleSaveSettings} />
                </div>
              )}

              {/* -------------------------------------------------------------
                  SUB-PESTAÑA: INSTITUCIÓN & PRESTADOR
                  ------------------------------------------------------------- */}
              {settingsTab === 'instituicao' && (
                <Card className="p-6 max-w-2xl">
                  <div className="mb-5 border-b border-zinc-100 pb-3">
                    <h3 className="text-base font-bold text-zinc-950">Datos para Rendición de Cuentas (Hoja A4 & Documentos)</h3>
                    <p className="text-xs text-zinc-500 mt-1">Esta información identifica a las partes en el encabezado y firmas de la rendición oficial</p>
                  </div>

                  <form onSubmit={handleSaveSettings} className="space-y-4">
                    <div>
                      <label className="block text-xs font-semibold text-zinc-700 mb-1.5">Nombre de la Universidad / Institución Contratante</label>
                      <input 
                        type="text" 
                        name="institution_name"
                        className="w-full h-9 px-3 text-sm rounded-md border border-zinc-200 bg-white text-zinc-950 focus:outline-none focus:ring-1 focus:ring-zinc-950" 
                        defaultValue={settings.institution_name || 'Universidad Columbia del Paraguay'} 
                        required 
                      />
                    </div>

                    <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
                      <div>
                        <label className="block text-xs font-semibold text-zinc-700 mb-1.5">Su Nombre / Nombre del Prestador de Servicios</label>
                        <input 
                          type="text" 
                          name="contractor_name"
                          className="w-full h-9 px-3 text-sm rounded-md border border-zinc-200 bg-white text-zinc-950 focus:outline-none focus:ring-1 focus:ring-zinc-950" 
                          defaultValue={settings.contractor_name || 'Alan Collins Bazzano Pinheiro'} 
                          required 
                        />
                      </div>

                      <div>
                        <label className="block text-xs font-semibold text-zinc-700 mb-1.5">Matrícula / RA / Contrato</label>
                        <input 
                          type="text" 
                          name="student_id"
                          className="w-full h-9 px-3 text-sm rounded-md border border-zinc-200 bg-white text-zinc-950 focus:outline-none focus:ring-1 focus:ring-zinc-950" 
                          defaultValue={settings.student_id || 'RA-20240982'} 
                        />
                      </div>
                    </div>

                    <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
                      <div>
                        <label className="block text-xs font-semibold text-zinc-700 mb-1.5">Departamento / Sector Vinculado</label>
                        <input 
                          type="text" 
                          name="department"
                          className="w-full h-9 px-3 text-sm rounded-md border border-zinc-200 bg-white text-zinc-950 focus:outline-none focus:ring-1 focus:ring-zinc-950" 
                          defaultValue={settings.department || 'Audiovisual & TI'} 
                        />
                      </div>

                      <div>
                        <label className="block text-xs font-semibold text-zinc-700 mb-1.5">Datos Bancarios / Cobro / Transferencia</label>
                        <input 
                          type="text" 
                          name="pix_key"
                          className="w-full h-9 px-3 text-sm rounded-md border border-zinc-200 bg-white text-zinc-950 focus:outline-none focus:ring-1 focus:ring-zinc-950" 
                          defaultValue={settings.pix_key || 'alan@columbia.edu.py'} 
                        />
                      </div>
                    </div>

                    {/* SECCIÓN: QUIÉN FIRMA POR LA UNIVERSIDAD */}
                    <div className="pt-4 border-t border-zinc-100 space-y-3">
                      <div>
                        <h4 className="text-xs font-bold uppercase tracking-wider text-zinc-900 flex items-center gap-1.5">
                          <span>✍️</span>
                          <span>Firma de la Universidad en los Documentos (Quién Firma)</span>
                        </h4>
                        <p className="text-[11px] text-zinc-500 mt-0.5">
                          Configure quién firma por la institución. En la hoja impresa aparecerá el nombre de la universidad junto con el nombre y cargo del firmante responsable.
                        </p>
                      </div>

                      <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
                        <div>
                          <label className="block text-xs font-semibold text-zinc-700 mb-1.5">
                            Nombre de Quién Firma por la Universidad
                          </label>
                          <input 
                            type="text" 
                            name="institution_signer_name"
                            className="w-full h-9 px-3 text-sm rounded-md border border-zinc-200 bg-white text-zinc-950 focus:outline-none focus:ring-1 focus:ring-zinc-950 font-medium" 
                            defaultValue={settings.institution_signer_name || 'Dirección General / Coordinación de Medicina'} 
                            placeholder="Ej: Lic. Carlos Gómez o Dirección General"
                          />
                          <p className="text-[10px] text-zinc-400 mt-1">Nombre del responsable por la firma de la universidad</p>
                        </div>

                        <div>
                          <label className="block text-xs font-semibold text-zinc-700 mb-1.5">
                            Cargo / Función del Firmante
                          </label>
                          <input 
                            type="text" 
                            name="institution_signer_role"
                            className="w-full h-9 px-3 text-sm rounded-md border border-zinc-200 bg-white text-zinc-950 focus:outline-none focus:ring-1 focus:ring-zinc-950" 
                            defaultValue={settings.institution_signer_role || 'Tesorería & Gestión de Contratos'} 
                            placeholder="Ej: Dirección General, Coordinador, Tesorería"
                          />
                          <p className="text-[10px] text-zinc-400 mt-1">Cargo que figurará debajo de la firma</p>
                        </div>
                      </div>

                      <div>
                        <label className="block text-xs font-semibold text-zinc-700 mb-1.5">
                          Opciones Rápidas de Firmantes (separadas por coma para elegir al imprimir)
                        </label>
                        <input 
                          type="text" 
                          name="institution_signers_list"
                          className="w-full h-9 px-3 text-sm rounded-md border border-zinc-200 bg-white text-zinc-950 focus:outline-none focus:ring-1 focus:ring-zinc-950" 
                          defaultValue={settings.institution_signers_list || 'Tesorería & Gestión de Contratos, Dirección General, Coordinación Académica, Coordinación de Marketing & TI'} 
                          placeholder="Ej: Tesorería & Contratos, Dirección General, Coordinación Académica"
                        />
                        <p className="text-[10px] text-zinc-400 mt-1">
                          Estas opciones aparecerán en un selector al imprimir, permitiendo elegir quién firma en el momento.
                        </p>
                      </div>
                    </div>

                    <Button type="submit" variant="default" size="sm" className="mt-3">
                      Guardar Datos Institucionales
                    </Button>
                  </form>
                </Card>
              )}

              {/* -------------------------------------------------------------
                  SUB-PESTAÑA: PARÁMETROS & MONEDA
                  ------------------------------------------------------------- */}
              {settingsTab === 'preferencias' && (
                <Card className="p-6 max-w-2xl">
                  <div className="mb-5 border-b border-zinc-100 pb-3">
                    <h3 className="text-base font-bold text-zinc-950">Parámetros del Sistema & Moneda</h3>
                    <p className="text-xs text-zinc-500 mt-1">Configuraciones regionales y formatos contables</p>
                  </div>

                  <form onSubmit={handleSaveSettings} className="space-y-4">
                    <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
                      <div>
                        <label className="block text-xs font-semibold text-zinc-700 mb-1.5">Símbolo de la Moneda</label>
                        <input 
                          type="text" 
                          name="currency_symbol"
                          className="w-full h-9 px-3 text-sm rounded-md border border-zinc-200 bg-white text-zinc-950 font-mono font-bold" 
                          defaultValue={settings.currency_symbol || 'G$'} 
                          required 
                        />
                        <span className="text-[11px] text-zinc-400 mt-1 block">Moneda configurada: Guaraníes Paraguay (G$)</span>
                      </div>

                      <div>
                        <label className="block text-xs font-semibold text-zinc-700 mb-1.5">Día Predeterminado de Vencimiento Mensual</label>
                        <input 
                          type="number" 
                          min="1" 
                          max="31"
                          name="default_due_day"
                          className="w-full h-9 px-3 text-sm rounded-md border border-zinc-200 bg-white text-zinc-950" 
                          defaultValue={settings.default_due_day || 10} 
                        />
                      </div>
                    </div>

                    <div>
                      <label className="block text-xs font-semibold text-zinc-700 mb-1.5">Texto de Pie de Página en la Hoja A4</label>
                      <textarea 
                        name="print_footer_notice"
                        className="w-full h-20 p-2.5 text-xs rounded-md border border-zinc-200 bg-white text-zinc-950"
                        defaultValue={settings.print_footer_notice || 'Estado de cuenta oficial emitido por el Sistema de Conciliación Financiera Columbia Pagos • Todos los valores expresados en Guaraníes (G$)'}
                      />
                    </div>

                    <Button type="submit" variant="default" size="sm" className="mt-2">
                      Guardar Parámetros
                    </Button>
                  </form>
                </Card>
              )}

              {/* -------------------------------------------------------------
                  SUB-PESTAÑA: BASE DE DATOS & RESPALDO
                  ------------------------------------------------------------- */}
              {settingsTab === 'backup' && (
                <div className="space-y-6">
                  <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                    <Card className="p-6 space-y-4">
                      <div className="flex items-center justify-between">
                        <div className="flex items-center gap-2.5">
                          <div className="p-2 bg-zinc-100 rounded-lg text-zinc-950">
                            <Lucide.Database size={20} />
                          </div>
                          <div>
                            <h3 className="font-semibold text-zinc-950">Archivo SQLite Local</h3>
                            <p className="text-xs text-zinc-500">financeiro.db</p>
                          </div>
                        </div>
                        <Badge variant="outline" className="font-mono text-[10px]">.DB</Badge>
                      </div>
                      <p className="text-xs text-zinc-600 leading-relaxed">
                        Archivo nativo con todas las tablas (movimientos, catálogo de etiquetas, servicios y configuraciones). Ideal para respaldo completo y copia de seguridad.
                      </p>
                      <a href="/api/backup/db" download className="inline-block">
                        <Button variant="default" size="sm">
                          <Lucide.Download size={14} />
                          <span>Descargar Base .db</span>
                        </Button>
                      </a>
                    </Card>

                    <Card className="p-6 space-y-4">
                      <div className="flex items-center justify-between">
                        <div className="flex items-center gap-2.5">
                          <div className="p-2 bg-zinc-100 rounded-lg text-zinc-950">
                            <Lucide.FileSpreadsheet size={20} />
                          </div>
                          <div>
                            <h3 className="font-semibold text-zinc-950">Extracto en Planilla</h3>
                            <p className="text-xs text-zinc-500">Excel / Google Sheets</p>
                          </div>
                        </div>
                        <Badge variant="outline" className="font-mono text-[10px]">.CSV</Badge>
                      </div>
                      <p className="text-xs text-zinc-600 leading-relaxed">
                        Planilla completa con ID, Fecha, Tipo, Título, Detalle de lo realizado, Etiquetas aplicadas, Monto en Guaraníes y Documentos.
                      </p>
                      <a href="/api/backup/csv" download className="inline-block">
                        <Button variant="secondary" size="sm">
                          <Lucide.Download size={14} />
                          <span>Exportar CSV</span>
                        </Button>
                      </a>
                    </Card>
                  </div>
                </div>
              )}
            </section>
            )
          )}

        </div>
      </main>

      {/* MODAIS & TOASTS */}
      <window.TransactionModal />
      <window.ServiceModal />
      <window.RecurringModal />
      <window.TagModal />
      <window.ConfirmModal />
      <window.ToastContainer />
      {window.CommandPalette && (
        <window.CommandPalette 
          isOpen={isCmdPaletteOpen} 
          onClose={() => setIsCmdPaletteOpen(false)} 
          onSelectTab={navigateToTab} 
          onOpenNewTx={handleOpenNewTx} 
        />
      )}
      {window.WhatsAppModal && (
        <window.WhatsAppModal 
          isOpen={isWhatsAppModalOpen} 
          onClose={() => setIsWhatsAppModalOpen(false)} 
        />
      )}
      {window.ServiceDetailModal && <window.ServiceDetailModal />}
      {window.PrintSingleServiceSheet && <window.PrintSingleServiceSheet />}
    </div>
  );
}

window.App = App;
