<?php

require_once '../../core/config.php';
require_once '../../core/session.php';
require_once '../../core/permissions.php';
require_once '../../core/format.php';
require_once '../../core/database.php';
require_once '../../services/crm/CrmService.php';
require_once '../../services/crm/PaymentStatusService.php';
require_once '../../services/crm/OpportunityAccessService.php';

require_login();
require_permission('module.crm');

$id = isset($_GET['id']) ? (int) $_GET['id'] : 0;
$isModal = isset($_GET['modal']) && $_GET['modal'] == '1';

$pdo = db();
PaymentStatusService::processOverdueOpportunities($pdo);
$crm = new CrmService();
$opportunity = $crm->getOpportunity($id);

if (!$opportunity) {
    die('Oportunidad no encontrada.');
}

$opportunityDisplayName = trim((string)($opportunity['customer_display_name'] ?? $opportunity['customer_name'] ?? ''));
$opportunityLegalName = trim((string)($opportunity['customer_legal_name'] ?? ''));
if ($opportunityLegalName === '') {
    $opportunityLegalName = $opportunityDisplayName;
}
$opportunityTaxId = trim((string)($opportunity['customer_current_tax_id'] ?? $opportunity['customer_tax_id'] ?? ''));

$isClosedOpportunity = !empty($opportunity['archived_at']);
$canDeleteOpportunity = OpportunityAccessService::canDelete(current_user() ?: array());
$hasBillingAccess = function_exists('user_can') && user_can('module.billing');
$archiveHoldActive = !empty($opportunity['archive_hold_reason']);
$canManageArchiveHold = !$isClosedOpportunity && ($opportunity['stage'] ?? '') === 'facturada' && OpportunityAccessService::canManage($opportunity, current_user() ?: array());
$closureOutcomeLabels = array(
    'won' => 'Ganada',
    'lost' => 'Perdida',
    'invoiced' => 'Facturada',
    'cancelled' => 'Cancelada',
    'no_decision' => 'Sin decisión',
);
$closureOutcomeLabel = $closureOutcomeLabels[$opportunity['closure_outcome'] ?? ''] ?? 'Cerrada';

$activities = $crm->getActivities($id);
$documents = $crm->getDocuments($id);

if (!function_exists('opportunity_format_currency')) {
    function opportunity_format_currency($amount, $currencyCode)
    {
        $currencyCode = strtoupper(trim((string)$currencyCode)) ?: 'CLP';
        $decimals = $currencyCode === 'CLP' ? 0 : 2;
        return $currencyCode . ' ' . number_format((float)$amount, $decimals, ',', '.');
    }
}

// =========================================================================
// 🚀 NUEVO: Pre-carga de datos de Cotizaciones para el SPA
// =========================================================================
$hasQuoteDeletedAt = false;
try {
    $stmtQuoteCol = $pdo->prepare("SHOW COLUMNS FROM `crm_quotes` LIKE ?");
    $stmtQuoteCol->execute(array('deleted_at'));
    $hasQuoteDeletedAt = (bool)$stmtQuoteCol->fetch(PDO::FETCH_ASSOC);
} catch (Throwable $e) {
    $hasQuoteDeletedAt = false;
}
$stmtQuotes = $pdo->prepare("SELECT * FROM crm_quotes WHERE opportunity_id = ?" . ($hasQuoteDeletedAt ? " AND deleted_at IS NULL" : ""));
$stmtQuotes->execute(array($id));
$oppQuotes = $stmtQuotes->fetchAll(PDO::FETCH_ASSOC);

$oppQuoteItems = array();
if (!empty($oppQuotes)) {
    $qIds = array_column($oppQuotes, 'id');
    $inQuery = implode(',', array_fill(0, count($qIds), '?'));
    $stmtItems = $pdo->prepare("SELECT * FROM crm_quote_items WHERE quote_id IN ($inQuery)");
    $stmtItems->execute($qIds);
    foreach ($stmtItems->fetchAll(PDO::FETCH_ASSOC) as $it) {
        $oppQuoteItems[$it['quote_id']][] = $it;
    }
}

// Rescatar Teléfono/Email real del cliente
$stmtCust = $pdo->prepare("SELECT email, phone FROM crm_customers WHERE id = ?");
$stmtCust->execute(array($opportunity['customer_id']));
$custData = $stmtCust->fetch();
$custPhone = preg_replace('/[^0-9]/', '', $custData['phone'] ?? '');
if ($custPhone && strpos($custPhone, '56') !== 0) $custPhone = '56' . $custPhone;
$custEmail = $custData['email'] ?? '';
$systemSettings = $pdo->query("SELECT * FROM system_settings WHERE id = 1 LIMIT 1")->fetch(PDO::FETCH_ASSOC) ?: array();
$quoteDefaultConditions = trim((string)($systemSettings['quote_default_conditions'] ?? ''));
// =========================================================================

$customers = $crm->getCustomers();
$assignableUsers = $crm->getAssignableUsers();

$sourceOptions = ['Instagram' => 'Instagram', 'Web' => 'Web', 'OpenLab' => 'OpenLab', 'Recomendación' => 'Recomendación', 'Email' => 'Email', 'Llamada' => 'Llamada', 'Distribuidor' => 'Distribuidor', 'Reposicion predictiva' => 'Reposición predictiva', 'Otro' => 'Otro'];
$stageOptions = ['nuevo' => 'Nuevo', 'contactado' => 'Contactado', 'cotizando' => 'Cotizando', 'negociacion' => 'Negociación', 'ganada' => 'Ganada', 'perdida' => 'Perdida', 'facturada' => 'Facturada'];
$paymentStatusOptions = ['no_facturado' => 'No facturado', 'por_cobrar' => 'Por cobrar', 'pagado' => 'Pagado', 'atrasado' => 'Atrasado', 'incobrable' => 'Incobrable'];
$competitorOptions = ['' => 'No identificado', 'Abstrax' => 'Abstrax', 'HopBurst' => 'HopBurst', 'Pellets' => 'Pellets', 'Proveedor tradicional' => 'Proveedor tradicional', 'Otro' => 'Otro'];
$nextActionOptions = ['' => 'Sin acción', 'Llamar' => 'Llamar', 'Enviar cotización' => 'Enviar cotización', 'Enviar muestra' => 'Enviar muestra', 'Agendar reunión' => 'Agendar reunión', 'Despachar' => 'Despachar', 'Hacer seguimiento' => 'Hacer seguimiento', 'Esperar respuesta' => 'Esperar respuesta'];

ob_start(); ?>
<form id="form-edit-opportunity" action="/modules/crm/opportunity_update.php" method="POST" data-no-spa="true" style="margin:0;">
    <input type="hidden" name="id" value="<?php echo (int) $opportunity['id']; ?>">
    <input type="hidden" name="customer_id" value="<?php echo (int) $opportunity['customer_id']; ?>">
    
    <div class="form-grid form-grid-2 mb-4">
        <div class="form-field">
            <label class="label">Cliente</label>
            <input class="input" type="text" value="<?php echo safe_text($opportunityDisplayName); ?>" disabled style="background: var(--surface-2);">
            <?php if ($opportunityLegalName !== '' && $opportunityLegalName !== $opportunityDisplayName): ?>
                <small class="text-secondary">Razón social: <?php echo safe_text($opportunityLegalName); ?></small>
            <?php endif; ?>
        </div>
        <div class="form-field is-required">
            <label class="label">Título de la oportunidad</label>
            <input class="input" type="text" name="title" required value="<?php echo safe_text($opportunity['title']); ?>">
        </div>
    </div>

    <div class="form-grid form-grid-4">
        <div class="form-field is-required"><label class="label">Etapa inicial</label><select class="select" name="stage" required><?php foreach ($stageOptions as $value => $label): ?><option value="<?php echo safe_text($value); ?>" <?php echo $opportunity['stage'] === $value ? 'selected' : ''; ?>><?php echo safe_text($label); ?></option><?php endforeach; ?></select></div>
        <div class="form-field"><label class="label">Estado de cobranza</label><select class="select" name="payment_status"><?php foreach ($paymentStatusOptions as $value => $label): ?><option value="<?php echo safe_text($value); ?>" <?php echo ($opportunity['payment_status'] ?? 'no_facturado') === $value ? 'selected' : ''; ?>><?php echo safe_text($label); ?></option><?php endforeach; ?></select></div>
        <div class="form-field"><label class="label">Fecha vencimiento pago</label><input class="input" type="date" name="payment_due_date" value="<?php echo safe_text($opportunity['payment_due_date']); ?>"></div>
        <div class="form-field"><label class="label">Fecha de pago</label><input class="input" type="date" name="payment_paid_date" value="<?php echo safe_text($opportunity['payment_paid_date']); ?>"></div>
        <div class="form-field">
            <label class="label">Responsable comercial</label>
            <select class="select" name="owner_user_id" onchange="this.nextElementSibling.value = this.options[this.selectedIndex].getAttribute('data-name') || '';">
                <option value="">Sin responsable</option>
                <?php foreach ($assignableUsers as $user): ?>
                    <?php 
                        $isSelected = false;
                        if (!empty($opportunity['owner_user_id']) && (int)$opportunity['owner_user_id'] === (int)$user['id']) $isSelected = true;
                        elseif (!empty($opportunity['owner_name']) && $user['name'] === $opportunity['owner_name']) $isSelected = true;
                    ?>
                    <option value="<?php echo (int)$user['id']; ?>" data-name="<?php echo safe_text($user['name']); ?>" <?php echo $isSelected ? 'selected' : ''; ?>>
                        <?php echo safe_text($user['name']); ?>
                    </option>
                <?php endforeach; ?>
            </select>
            <input type="hidden" name="owner_name" value="<?php echo safe_text($opportunity['owner_name'] ?? ''); ?>">
        </div>
        <div class="form-field is-required"><label class="label">Origen</label><select class="select" name="source" required><option value="" disabled <?php echo empty($opportunity['source']) ? 'selected' : ''; ?>>Seleccionar origen</option><?php foreach ($sourceOptions as $value => $label): ?><option value="<?php echo safe_text($value); ?>" <?php echo $opportunity['source'] === $value ? 'selected' : ''; ?>><?php echo safe_text($label); ?></option><?php endforeach; ?></select></div>
        <div class="form-field"><label class="label">Competidor / Alternativa</label><select class="select" name="competitor"><?php foreach ($competitorOptions as $value => $label): ?><option value="<?php echo safe_text($value); ?>" <?php echo $opportunity['competitor'] === $value ? 'selected' : ''; ?>><?php echo safe_text($label); ?></option><?php endforeach; ?></select></div>
        <div class="form-field"><label class="label">Valor esperado ($)</label><input class="input" type="number" name="expected_value" min="0" step="1" value="<?php echo (float) $opportunity['expected_value']; ?>"></div>
        <div class="form-field"><label class="label">Probabilidad (%)</label><input class="input" type="number" name="probability" min="0" max="100" value="<?php echo (int) $opportunity['probability']; ?>"></div>
        <div class="form-field is-required"><label class="label">Fecha est. de cierre</label><input class="input" type="date" name="expected_close_date" required value="<?php echo safe_text($opportunity['expected_close_date']); ?>"></div>
        <div class="form-field is-required"><label class="label">Próxima acción</label><select class="select" name="next_action" required><?php foreach ($nextActionOptions as $value => $label): ?><option value="<?php echo safe_text($value); ?>" <?php echo $opportunity['next_action'] === $value ? 'selected' : ''; ?>><?php echo safe_text($label); ?></option><?php endforeach; ?></select></div>
        <div class="form-field is-required"><label class="label">Fecha próxima acción</label><input class="input" type="date" name="next_action_date" required value="<?php echo safe_text($opportunity['next_action_date']); ?>"></div>
        <div class="form-field form-field-full"><label class="label">Notas/ Comentarios</label><textarea class="textarea" name="notes" placeholder="Escribe aquí..."><?php echo safe_text($opportunity['notes']); ?></textarea></div>
    </div>
</form>
<?php $formEditHtml = ob_get_clean();

ob_start(); ?>
<form id="form-document" action="/modules/crm/document_store.php" method="POST" enctype="multipart/form-data" data-no-spa="true" style="margin:0;">
    <input type="hidden" name="_csrf_token" value="<?php echo safe_text(csrf_token()); ?>">
    <input type="hidden" name="opportunity_id" value="<?php echo (int) $opportunity['id']; ?>">
    <input type="hidden" name="customer_id" value="<?php echo (int) $opportunity['customer_id']; ?>">
    <div class="form-grid form-grid-2">
        <div class="form-field is-required"><label class="label">Tipo documento</label><select class="select" name="document_type" required><option value="cotizacion">Cotización (Externa)</option><option value="orden_compra">Orden de compra</option><option value="factura">Factura</option><option value="nota_credito">Nota de crédito</option><option value="nota_debito">Nota de débito</option><option value="otro">Otro</option></select></div>
        <div class="form-field is-required"><label class="label">Nombre documento</label><input class="input" type="text" name="document_name" required placeholder="Ej: OC 1421"></div>
        <div class="form-field"><label class="label">Número / Folio</label><input class="input" type="text" name="document_number" placeholder="Ej: 1421"></div>
        <div class="form-field"><label class="label">Fecha</label><input class="input" type="date" name="document_date" value="<?php echo date('Y-m-d'); ?>"></div>
        <div class="form-field"><label class="label">Monto neto ($)</label><input class="input" type="number" name="net_amount" min="0" step="1" placeholder="Opcional"></div>
        <div class="form-field"><label class="label">Monto total ($)</label><input class="input" type="number" name="total_amount" min="0" step="1" placeholder="Opcional"></div>
        <div class="form-field form-field-full is-required"><label class="label">Archivo PDF</label><input class="input file-input" type="file" name="document_file" accept="application/pdf" required></div>
        <div class="form-field form-field-full"><label class="label">Notas</label><textarea class="textarea" name="notes" placeholder="Observaciones del documento..."></textarea></div>
    </div>
</form>
<?php $formDocHtml = ob_get_clean();

ob_start(); ?>
<form id="form-activity" action="/modules/crm/activity_store.php" method="POST" data-no-spa="true" style="margin:0;">
    <input type="hidden" name="opportunity_id" value="<?php echo (int) $opportunity['id']; ?>">
    <input type="hidden" name="customer_id" value="<?php echo (int) $opportunity['customer_id']; ?>">
    <input type="hidden" name="customer_name" value="<?php echo safe_text($opportunityDisplayName); ?>">
    <div class="form-grid form-grid-2">
        <div class="form-field is-required"><label class="label">Tipo de actividad</label><select class="select" name="activity_type" required><option value="nota">Nota</option><option value="llamada">Llamada</option><option value="correo">Correo</option><option value="reunion">Reunión</option><option value="despachar">Despachar</option><option value="seguimiento">Seguimiento</option></select></div>
        <div class="form-field is-required"><label class="label">Fecha</label><input class="input" type="datetime-local" name="activity_date" value="<?php echo date('Y-m-d\TH:i'); ?>" required></div>
        <div class="form-field is-required form-field-full"><label class="label">Título</label><input class="input" type="text" name="title" required placeholder="Ej: Llamada de seguimiento"></div>
        <div class="form-field form-field-full"><label class="label">Descripción</label><textarea class="textarea" name="description" placeholder="Describe los detalles de la actividad..."></textarea></div>
        <div class="form-field form-field-full"><label class="label">Responsable</label><input class="input" type="text" name="owner_name" value="<?php echo safe_text($opportunity['owner_name']); ?>" placeholder="Nombre del responsable"></div>
    </div>
</form>
<?php $formActHtml = ob_get_clean();

// ======================================================================
// MODAL DE COTIZACIÓN (CREAR/EDITAR) HOMOLOGADO (SIN TABLAS, CSS GRID)
// ======================================================================
ob_start(); ?>
<form id="form-quote-modal" action="/modules/crm/quote_store.php" method="POST" data-no-spa="true" style="margin:0;">
    <input type="hidden" name="opportunity_id" value="<?php echo $opportunity['id']; ?>">
    <input type="hidden" name="customer_id" value="<?php echo $opportunity['customer_id']; ?>">
    <input type="hidden" name="quote_id" id="modalQuoteId" value="0">
    
    <div class="mobile-hidden" style="display: grid; grid-template-columns: 2.5fr 1fr 0.8fr 1fr 1.2fr 1.2fr 40px; gap: 12px; padding: 0 14px 8px; border-bottom: 1px solid var(--border-subtle); margin-bottom: 12px; font-size: 0.75rem; font-weight: 700; color: var(--text-muted); text-transform: uppercase;">
        <div>Buscar Producto (Facto)</div>
        <div>SKU</div>
        <div>Cant.</div>
        <div>Precio U. Neto</div>
        <div>Total Fila</div>
        <div style="text-align: right;"></div>
    </div>

    <div id="modalItemsContainer" style="display: flex; flex-direction: column; gap: 12px;"></div>
    
    <div class="mt-4 mb-6" style="padding-left: 14px;">
        <button type="button" class="btn btn-outline btn-sm" id="modalAddRowBtn" style="width: auto;">
            <i data-lucide="plus"></i> <span>Añadir Fila</span>
        </button>
    </div>

    <div class="grid grid-2 mt-6 responsive-grid">
        <div class="card" style="box-shadow: none; border-color: var(--border-subtle);">
            <div class="card-body">
                <div class="form-field mb-4"><label class="label">Estado</label><select class="select" name="status" id="modalQuoteStatus"><option value="Borrador">Borrador</option><option value="Enviada">Enviada</option><option value="Aceptada">Aceptada</option><option value="Rechazada">Rechazada</option></select></div>
                <div class="form-field"><label class="label">Condiciones comerciales</label><textarea class="textarea" name="notes" rows="4" placeholder="Ej: Precios válidos por 15 días..."><?php echo safe_text($quoteDefaultConditions); ?></textarea></div>
            </div>
        </div>
        <div class="card" style="box-shadow: none; border-color: var(--border-subtle);">
            <div class="card-body">
                <div class="metric-row"><span>Subtotal Neto</span><strong id="modalSummarySubtotal">$ 0</strong></div>
                <div class="metric-row align-items-center my-2" style="margin: 10px 0;"><span>Descto. (%)</span><input type="number" name="discount_percent" id="modalDiscountPercent" class="input" value="0" min="0" max="100" step="0.1" style="width: 80px; text-align: right; padding: 4px 8px;"></div>
                <div class="metric-row text-muted" id="modalDiscountRow" style="display: none; font-size: 0.9rem;"><span>Monto</span><strong id="modalSummaryDiscount">$ 0</strong></div>
                <div class="metric-row"><span>IVA (19%)</span><strong id="modalSummaryIva">$ 0</strong></div>
                <hr class="my-4" style="border: 0; border-top: 1px solid var(--border-default);">
                <div class="metric-row" style="font-size: 1.25rem;"><span>Total General</span><strong id="modalSummaryTotal" class="text-primary" style="color: var(--color-success);">$ 0</strong></div>
            </div>
        </div>
    </div>
</form>
<?php $formQuoteHtml = ob_get_clean();

ob_start(); ?>
<div id="oppQuotePreviewDocument"></div>
<?php $formQuoteViewHtml = ob_get_clean();

$page_title = 'Oportunidad';

if (!$isModal) {
    require_once '../../layouts/header.php';
    require_once '../../layouts/sidebar.php';
}
?>

<style>
/* CSS NATIVO RESPONSIVO PARA LA VISTA DE COTIZACIÓN BLANCA */
@media (max-width: 768px) {
    .vq-info-grid { grid-template-columns: 1fr !important; }
    .vq-info-grid > div { border-right: none !important; }

    .vq-items-table, .vq-items-table tbody, .vq-items-table tr, .vq-items-table td {
        display: block !important;
        width: 100% !important;
        box-sizing: border-box;
    }
    .vq-items-table thead { display: none !important; }
    .vq-items-table tr {
        margin-bottom: 16px;
        border: 1px solid #e2e8f0;
        border-radius: 8px;
        overflow: hidden;
        background: #ffffff;
    }
    .vq-items-table td {
        display: flex !important;
        justify-content: space-between;
        align-items: center;
        padding: 10px 14px !important;
        border-bottom: 1px solid #e2e8f0 !important;
        text-align: right;
    }
    .vq-items-table td:last-child { border-bottom: none !important; }
    .vq-items-table td::before {
        content: attr(data-label);
        font-size: 0.7rem;
        font-weight: 700;
        color: #64748b;
        text-transform: uppercase;
        padding-right: 12px;
        text-align: left;
    }
    .vq-items-table td > div { flex: 1; word-break: break-word; text-align: right; }
    
    .vq-items-table td[data-label="Glosa / Descripción"] {
        flex-direction: column;
        align-items: flex-start;
        background: #f8fafc;
        border-bottom: 2px solid #e2e8f0 !important;
    }
    .vq-items-table td[data-label="Glosa / Descripción"]::before { display: none; }
    .vq-items-table td[data-label="Glosa / Descripción"] > div { text-align: left; width: 100%; }

    .vq-footer-grid { grid-template-columns: 1fr !important; }
    .vq-totals { width: 100% !important; box-sizing: border-box; }
    .quote-preview-card { padding: 16px !important; }
}

.action-square-btn { height: 40px !important; width: 40px !important; min-width: 40px !important; max-width: 40px !important; padding: 0 !important; margin: 0 !important; display: flex !important; align-items: center !important; justify-content: center !important; flex-shrink: 0 !important; border-radius: var(--radius-md) !important; }
@media (min-width: 769px) { .mobile-label { display: none !important; } }
.text-truncate { display: inline-block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; vertical-align: middle; }
.top-actions-cluster { display: flex; flex-wrap: nowrap !important; align-items: center; gap: 8px; }
.btn-icon-mobile { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
.inline-quick-actions { display: flex; gap: 12px; flex-wrap: nowrap; width: 100%; }
.inline-quick-actions .action-btn { flex: 1; justify-content: center; white-space: nowrap; }
.opportunity-layout { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-4); align-items: start; }
.layout-detalle { order: 1; margin-bottom: 0; }
.layout-timeline { order: 2; margin-bottom: 0; }
.layout-docs { order: 3; grid-column: 1 / -1; margin-bottom: 0; }
.card-scroll-container { max-height: 360px; overflow-y: auto; overflow-x: hidden; padding-right: 6px; }
.card-scroll-container::-webkit-scrollbar { width: 5px; }
.card-scroll-container::-webkit-scrollbar-track { background: transparent; }
.card-scroll-container::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 4px; }
.table-wrap { overflow-x: auto; width: 100%; }
.mobile-table-collapsible table { table-layout: fixed; width: 100% !important; min-width: 100% !important; }
.actions-btn-group { display: flex !important; flex-direction: row !important; gap: 6px !important; justify-content: flex-end !important; flex-wrap: nowrap !important; align-items: center !important; }
.action-icon-btn { padding: 0 !important; display: inline-flex !important; align-items: center !important; justify-content: center !important; height: 32px !important; width: 32px !important; min-width: 32px !important; border-radius: var(--radius-md) !important; border: 1px solid var(--border-default) !important; background-color: var(--surface-2) !important; color: var(--text-primary) !important; }
.action-icon-btn:hover { background-color: var(--surface-3) !important; }
.approve-btn { border-color: var(--color-success) !important; color: var(--color-success) !important; }
.approve-btn:hover { background-color: var(--color-primary-soft) !important; color: var(--color-success) !important; }
.crm-timeline-dot.despachar { background: #0ea5e9; } 
.responsive-kpis .kpi-value { font-size: clamp(1.1rem, 2.5vw, 1.8rem) !important; word-break: break-all; white-space: normal; line-height: 1.1; }

/* MODALES */
.product-modal-backdrop { position: fixed; inset: 0; background: rgba(0,0,0,0.6); backdrop-filter: blur(4px); z-index: 1050; display: none; align-items: center; justify-content: center; opacity: 0; transition: opacity 0.2s ease; }
.product-modal-backdrop.show { opacity: 1; }
.product-modal-box { background: var(--surface-1); width: 860px; max-width: 95%; max-height: 90vh; border: 1px solid var(--border-default); border-radius: var(--radius-xl); box-shadow: var(--shadow-lg); display: flex; flex-direction: column; transform: translateY(20px); transition: transform 0.2s ease; }
.product-modal-backdrop.show .product-modal-box { transform: translateY(0); }
.product-modal-header { padding: var(--space-5); border-bottom: 1px solid var(--border-subtle); display: flex; justify-content: space-between; align-items: center; }
.product-modal-body { padding: var(--space-5); overflow-y: auto; flex: 1; }

/* CAPAS DEL MODAL (SPA Multi-View) */
.opp-view-layer { display: none; flex-direction: column; flex: 1; min-height: 0; width: 100%; }
.opp-view-layer.active { display: flex; }

.search-results-box { position: absolute; width: 100%; z-index: 1060; box-shadow: var(--shadow-lg); border: 1px solid var(--border-default); background: var(--surface-1); max-height: 220px; overflow-y: auto; border-radius: var(--radius-lg); top: 100%; left: 0; display: none; }
.search-result-item { width: 100%; background: transparent; border: none; padding: 10px 12px; text-align: left; cursor: pointer; color: var(--text-secondary); border-bottom: 1px solid var(--border-subtle); display: flex; flex-direction: column; }
.search-result-item:hover { background: var(--surface-2); }
.search-result-item strong { color: var(--text-primary); font-size: 0.9rem; }
.search-result-item span { color: var(--text-muted); font-size: 0.75rem; margin-top: 2px; }
.search-result-item-empty { padding: 12px; color: var(--text-muted); font-size: 0.85rem; text-align: center; }
.remove-action-cell { text-align: center; vertical-align: middle; }
.remove-action-cell .remove-row-btn { padding: 6px; display: inline-flex; align-items: center; justify-content: center; }

@media (max-width: 768px) {
    .header-responsive { flex-direction: row !important; flex-wrap: nowrap !important; align-items: center !important; justify-content: space-between !important; }
    .page-header-content { flex: 1; min-width: 0; padding-right: 12px; }
    .page-header-content h1 { font-size: 1.35rem !important; margin-bottom: 4px !important; }
    .top-actions-cluster { width: auto !important; justify-content: flex-end !important; }
    
    .mobile-hidden { display: none !important; }
    
    .btn-icon-mobile { padding: 0 !important; width: 42px !important; height: 42px !important; display: flex; align-items: center; justify-content: center; }
    .responsive-kpis { grid-template-columns: repeat(2, 1fr) !important; gap: 12px !important; }
    .inline-quick-actions { gap: 8px; flex-wrap: wrap !important; }
    .inline-quick-actions .action-btn { padding: 0 4px; font-size: 0.8rem; flex: 1 1 auto; }
    .opportunity-layout { display: flex !important; flex-direction: column !important; gap: 16px !important; align-items: stretch !important; width: 100% !important; }
    .layout-detalle { order: 1; width: 100% !important; }
    .layout-docs { order: 2; width: 100% !important; }
    .layout-timeline { order: 3; width: 100% !important; }
    
    .mobile-table-collapsible { border: none !important; background: transparent !important; border-radius: 0 !important; box-shadow: none !important; padding: 0 !important; }
    .mobile-table-collapsible::after { display: none !important; }
    .mobile-table-collapsible table, .mobile-table-collapsible tbody, .mobile-table-collapsible tr, .mobile-table-collapsible td { display: block !important; width: 100% !important; min-width: 0 !important; max-width: 100% !important; box-sizing: border-box !important; }
    .mobile-table-collapsible thead { display: none !important; } 
    .mobile-table-collapsible tr { border: 1px solid var(--border-default) !important; border-radius: var(--radius-xl) !important; padding: 16px !important; margin-bottom: 16px !important; background: var(--surface-2) !important; }
    
    .mobile-table-collapsible td:not(.actions-cell-align) { display: flex !important; justify-content: space-between !important; align-items: center !important; padding: 8px 0 !important; border: none !important; }
    .mobile-table-collapsible td[data-label]:not(.actions-cell-align)::before { content: attr(data-label); font-size: 11px !important; font-weight: 600 !important; text-transform: uppercase !important; color: var(--text-muted) !important; }
    .mobile-table-collapsible .cell-value { text-align: right !important; margin-left: auto !important; }
    .mobile-table-collapsible td.actions-cell-align { border-top: 1px solid var(--border-subtle) !important; padding-top: 14px !important; margin-top: 8px !important; text-align: left !important; }
    .mobile-table-collapsible td.actions-cell-align::before { content: attr(data-label); display: block !important; font-size: 11px !important; font-weight: 600 !important; text-transform: uppercase !important; color: var(--text-muted) !important; margin-bottom: 10px !important; }
    .mobile-table-collapsible td.actions-cell-align .actions-btn-group { justify-content: space-between !important; gap: 10px !important; width: 100% !important; }
    .mobile-table-collapsible td.actions-cell-align .action-icon-btn { flex: 1 1 0% !important; width: auto !important; max-width: none !important; height: 40px !important; }
    .mobile-table-collapsible tr.empty-state-row { background: transparent !important; border: 1px dashed var(--border-strong) !important; display: flex !important; align-items: center !important; justify-content: center !important; padding: 24px 16px !important; }
    .mobile-table-collapsible tr.empty-state-row td { width: 100% !important; justify-content: center !important; text-align: center !important; border: none !important; }
    .mobile-table-collapsible tr.empty-state-row td::before { display: none !important; }

    /* Estilos de Cotizador Movil (Divs Flexibles) HOMOLOGADO */
    .eq-row { display: flex !important; flex-wrap: wrap !important; gap: 16px 4% !important; padding: 16px !important; border: 1px solid var(--border-default) !important; border-radius: var(--radius-xl) !important; background: var(--surface-2) !important; margin-bottom: 0 !important; }
    .eq-row > div { display: flex !important; flex-direction: column !important; align-items: flex-start !important; justify-content: flex-end !important; box-sizing: border-box !important; padding: 0 !important; border: none !important; }
    .eq-row .mobile-label { display: block !important; width: 100% !important; text-align: left !important; font-size: 11px !important; font-weight: 600 !important; text-transform: uppercase !important; color: var(--text-muted) !important; margin-bottom: 6px !important; }
    
    .eq-col-prod { flex: 0 0 100% !important; max-width: 100% !important; order: 1; }
    .eq-col-sku { flex: 0 0 48% !important; max-width: 48% !important; order: 2; }
    .eq-col-qty { flex: 0 0 48% !important; max-width: 48% !important; order: 3; }
    .eq-col-price { flex: 0 0 48% !important; max-width: 48% !important; order: 4; }
    .eq-col-total { flex: 0 0 48% !important; max-width: 48% !important; order: 5; align-items: flex-start !important; }
    .eq-col-del { flex: 0 0 100% !important; max-width: 100% !important; order: 6; margin-top: 8px; text-align: right; }
    
    .eq-col-del .remove-row-btn { width: 100% !important; max-width: none !important; height: 42px !important; }
    .eq-row .it-total-text { font-size: 1.15rem !important; line-height: 42px !important; color: var(--text-primary) !important; font-weight: 700 !important; width: 100% !important; text-align: left !important; padding: 0 10px !important; border: 1px solid var(--border-default) !important; border-radius: var(--radius-md) !important; background: var(--surface-0) !important; }
    .eq-row .input { width: 100% !important; max-width: 100% !important; }
}

/* FOOTER MODALES HOMOLOGADO */
.product-modal-footer {
    display: flex !important;
    flex-direction: row !important;
    justify-content: space-between !important;
    align-items: center !important;
    gap: 8px !important;
    flex-wrap: nowrap !important;
    min-height: 68px !important;
    padding: var(--space-3) var(--space-4) !important;
    background: var(--surface-0);
    border-top: 1px solid var(--border-subtle);
    border-radius: 0 0 var(--radius-xl) var(--radius-xl);
    overflow: hidden !important;
    flex-shrink: 0 !important;
}

#quote-delete-container {
    display: flex !important;
    align-items: center !important;
    justify-content: flex-start !important;
    flex: 0 0 auto !important;
    min-width: 42px !important;
    max-width: 42px !important;
    overflow: hidden !important;
}

.btn-delete-mobile,
.quote-delete-icon-btn {
    padding: 0 !important;
    width: 42px !important;
    height: 42px !important;
    min-width: 42px !important;
    max-width: 42px !important;
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    border-radius: var(--radius-md) !important;
    flex: 0 0 42px !important;
    overflow: hidden !important;
}

.btn-delete-mobile span,
.quote-delete-icon-btn span,
#quote-delete-container .mobile-hidden {
    display: none !important;
}

.modal-footer-actions-right {
    display: flex !important;
    flex-direction: row !important;
    align-items: center !important;
    justify-content: flex-end !important;
    gap: 8px !important;
    flex: 1 1 auto !important;
    min-width: 0 !important;
    overflow: hidden !important;
}

.modal-footer-actions-right .btn {
    padding: 0 var(--space-3) !important;
    height: 42px !important;
    min-height: 42px !important;
    font-size: 1rem !important;
    white-space: nowrap !important;
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    gap: 6px !important;
    width: auto !important;
    min-width: 42px !important;
    max-width: 100% !important;
    flex: 0 1 auto !important;
    overflow: hidden !important;
}

.modal-footer-actions-right .btn svg {
    margin: 0 !important;
    flex-shrink: 0 !important;
}

/* HOTFIX MOBILE MODAL OPPORTUNITY / QUOTES */
@media (max-width: 768px) {
    .product-modal-backdrop {
        align-items: stretch !important;
        justify-content: center !important;
        padding: 10px !important;
        overflow: hidden !important;
    }

    .product-modal-box {
        width: 100% !important;
        max-width: 100% !important;
        height: calc(100dvh - 100px) !important;
        max-height: calc(100dvh - 100px) !important;
        border-radius: var(--radius-xl) !important;
        overflow: hidden !important;
        display: flex !important;
        flex-direction: column !important;
    }

    #oppViewModalBackdrop .product-modal-box {
        width: 100% !important;
        max-width: 100% !important;
        height: calc(100dvh - 100px) !important;
        max-height: calc(100dvh - 100px) !important;
    }

    .opp-view-layer {
        min-height: 0 !important;
        height: 100% !important;
        overflow: hidden !important;
    }

    .opp-view-layer.active {
        display: flex !important;
        flex-direction: column !important;
    }

    .product-modal-header {
        flex-shrink: 0 !important;
        min-height: 74px !important;
        padding: 16px !important;
        gap: 10px !important;
    }

    .product-modal-header .h3 {
        font-size: 1.05rem !important;
        line-height: 1.2 !important;
    }

    .product-modal-header .text-sm {
        font-size: 0.9rem !important;
        line-height: 1.25 !important;
    }

    .product-modal-body {
        flex: 1 1 auto !important;
        min-height: 0 !important;
        overflow-y: auto !important;
        overflow-x: hidden !important;
        -webkit-overflow-scrolling: touch;
        padding: 16px !important;
    }

    .product-modal-footer {
        flex-shrink: 0 !important;
        flex-wrap: nowrap !important;
        min-height: 68px !important;
        max-height: 68px !important;
        padding: 12px !important;
        gap: 8px !important;
        overflow: hidden !important;
    }

    #quote-delete-container {
        flex: 0 0 42px !important;
        width: 42px !important;
        min-width: 42px !important;
        max-width: 42px !important;
        overflow: hidden !important;
    }

    .btn-delete-mobile,
    .quote-delete-icon-btn {
        width: 42px !important;
        height: 42px !important;
        min-width: 42px !important;
        max-width: 42px !important;
        padding: 0 !important;
    }

    .modal-footer-actions-right {
        flex: 1 1 auto !important;
        min-width: 0 !important;
        justify-content: flex-end !important;
        gap: 8px !important;
        overflow: hidden !important;
    }

    .modal-footer-actions-right .btn {
        width: 42px !important;
        min-width: 42px !important;
        max-width: 42px !important;
        height: 42px !important;
        padding: 0 !important;
        flex: 0 0 42px !important;
    }

    .modal-footer-actions-right .btn span {
        display: none !important;
    }

    #modalDirectSaveBtn {
        width: 46px !important;
        min-width: 46px !important;
        max-width: 46px !important;
        flex-basis: 46px !important;
    }

    .grid.grid-2.responsive-grid {
        display: grid !important;
        grid-template-columns: 1fr !important;
        gap: 16px !important;
    }

    #form-quote-modal {
        width: 100% !important;
        max-width: 100% !important;
        overflow-x: hidden !important;
    }

    #modalItemsContainer {
        width: 100% !important;
        max-width: 100% !important;
        overflow-x: hidden !important;
    }

    .eq-row {
        width: 100% !important;
        max-width: 100% !important;
        min-width: 0 !important;
        box-sizing: border-box !important;
        overflow: hidden !important;
    }

    .eq-row input,
    .eq-row select,
    .eq-row textarea,
    .eq-row .input,
    .eq-row .select,
    .eq-row .textarea {
        width: 100% !important;
        max-width: 100% !important;
        min-width: 0 !important;
        box-sizing: border-box !important;
    }

    .search-results-box {
        left: 0 !important;
        right: 0 !important;
        width: 100% !important;
        max-width: 100% !important;
        box-sizing: border-box !important;
    }
}



/* P0.1 OPPORTUNITY MODAL - geometría estable y preview homologado con Cotizaciones */
.product-modal-backdrop {
    padding: 24px !important;
    overflow: hidden !important;
}

.product-modal-box {
    height: min(700px, calc(100vh - 100px)) !important;
    height: min(700px, calc(100dvh - 100px)) !important;
    max-height: calc(100vh - 100px) !important;
    max-height: calc(100dvh - 100px) !important;
    min-height: min(620px, calc(100vh - 100px)) !important;
    min-height: min(620px, calc(100dvh - 100px)) !important;
    display: flex !important;
    flex-direction: column !important;
    overflow: hidden !important;
}

#oppViewModalBackdrop .product-modal-box {
    width: min(1050px, calc(100vw - 48px)) !important;
    max-width: calc(100vw - 48px) !important;
}

.opp-view-layer,
.opp-view-layer.active {
    flex: 1 1 auto !important;
    min-height: 0 !important;
    overflow: hidden !important;
}

.opp-view-layer.active {
    display: flex !important;
    flex-direction: column !important;
}

.product-modal-body {
    flex: 1 1 auto !important;
    min-height: 0 !important;
    overflow-y: auto !important;
    overflow-x: hidden !important;
    -webkit-overflow-scrolling: touch !important;
}

.product-modal-footer {
    flex: 0 0 auto !important;
    min-height: 72px !important;
    height: auto !important;
    max-height: none !important;
    overflow: visible !important;
}

.quote-doc {
    color: #00122f;
    background: #fff;
    padding: 42px 52px 28px;
    font-family: var(--font-sans);
}

.quote-doc-head { display: flex; justify-content: space-between; gap: 24px; margin-bottom: 28px; align-items: flex-start; }
.quote-doc h2 { color: #00122f; font-size: 1.55rem; letter-spacing: -0.03em; margin: 0; }
.quote-doc-grid { display: grid; grid-template-columns: 1fr 1fr; border: 1px solid #dbe3ef; border-radius: 8px; overflow: hidden; margin-bottom: 34px; }
.quote-doc-cell { padding: 14px 18px; border-bottom: 1px solid #dbe3ef; min-height: 74px; }
.quote-doc-cell:nth-child(odd) { border-right: 1px solid #dbe3ef; }
.quote-doc-cell:nth-last-child(-n+2) { border-bottom: 0; }
.quote-doc-label { display: block; color: #536b8f; font-size: 0.76rem; font-weight: 800; text-transform: uppercase; margin-bottom: 8px; }
.quote-doc-value { color: #00122f; font-size: 1rem; }
.quote-doc-table { width: 100%; border-collapse: collapse; margin-bottom: 28px; }
.quote-doc-table th { color: #536b8f; font-size: 0.76rem; text-transform: uppercase; text-align: left; padding: 10px 14px; border-bottom: 2px solid #dbe3ef; }
.quote-doc-table td { color: #00122f; padding: 14px; border-bottom: 1px solid #dbe3ef; }
.quote-doc-table .text-right { text-align: right; }
.quote-doc-bottom { display: grid; grid-template-columns: minmax(0, 1fr) 380px; gap: 30px; align-items: start; }
.quote-doc-conditions { border: 1px solid #dbe3ef; border-radius: 8px; min-height: 118px; padding: 18px; background: #f8fafc; white-space: pre-line; }
.quote-doc-totalbox { border: 1px solid #dbe3ef; border-radius: 8px; padding: 18px 22px; display: grid; gap: 12px; }
.quote-doc-totalbox div { display: flex; justify-content: space-between; gap: 16px; }
.quote-doc-totalbox hr { border: 0; border-top: 1px solid #dbe3ef; width: 100%; }
.quote-doc-totalbox .grand { font-size: 1.25rem; font-weight: 800; }

@media (max-width: 768px) {
    .product-modal-backdrop {
        padding: 8px !important;
    }

    .product-modal-box,
    #oppViewModalBackdrop .product-modal-box {
        width: 100% !important;
        max-width: 100% !important;
        height: calc(100vh - 100px) !important;
        height: calc(100dvh - 100px) !important;
        max-height: calc(100vh - 100px) !important;
        max-height: calc(100dvh - 100px) !important;
        min-height: 0 !important;
    }

    .product-modal-footer {
        min-height: 68px !important;
        height: 68px !important;
        max-height: 68px !important;
        overflow: hidden !important;
    }

    .quote-doc { padding: 22px 16px !important; }
    .quote-doc-head, .quote-doc-grid { display: block !important; }
    .quote-doc-cell { border-right: 0 !important; border-bottom: 1px solid #dbe3ef !important; }
    .quote-doc-table th:nth-child(1), .quote-doc-table td:nth-child(1) { display: none !important; }
    .quote-doc-bottom { grid-template-columns: 1fr !important; }
}



/* P15 - Oportunidad: alto de capas y footers homologados con Crear Cliente */
#oppViewModalBackdrop.product-modal-backdrop,
#opportunityEditModal.product-modal-backdrop,
#documentModal.product-modal-backdrop,
#activityModal.product-modal-backdrop,
#quoteModal.product-modal-backdrop,
#quoteViewModal.product-modal-backdrop {
    align-items: center !important;
    justify-content: center !important;
    padding: 24px !important;
    overflow: hidden !important;
}

#oppViewModalBackdrop .product-modal-box,
#opportunityEditModal .product-modal-box,
#documentModal .product-modal-box,
#activityModal .product-modal-box,
#quoteModal .product-modal-box,
#quoteViewModal .product-modal-box {
    width: min(1050px, calc(100vw - 48px)) !important;
    max-width: calc(100vw - 48px) !important;
    height: min(700px, calc(100dvh - 100px)) !important;
    min-height: min(560px, calc(100dvh - 100px)) !important;
    max-height: calc(100dvh - 100px) !important;
    display: flex !important;
    flex-direction: column !important;
    overflow: hidden !important;
}

#oppViewModalBackdrop .opp-view-layer,
#oppViewModalBackdrop .opp-view-layer.active {
    flex: 1 1 auto !important;
    min-height: 0 !important;
    overflow: hidden !important;
}

#oppViewModalBackdrop .opp-view-layer.active {
    display: flex !important;
    flex-direction: column !important;
}

#oppViewModalBackdrop .product-modal-header,
#opportunityEditModal .product-modal-header,
#documentModal .product-modal-header,
#activityModal .product-modal-header,
#quoteModal .product-modal-header,
#quoteViewModal .product-modal-header,
#oppViewModalBackdrop .product-modal-footer,
#opportunityEditModal .product-modal-footer,
#documentModal .product-modal-footer,
#activityModal .product-modal-footer,
#quoteModal .product-modal-footer,
#quoteViewModal .product-modal-footer {
    flex: 0 0 auto !important;
}

#oppViewModalBackdrop .product-modal-body,
#opportunityEditModal .product-modal-body,
#documentModal .product-modal-body,
#activityModal .product-modal-body,
#quoteModal .product-modal-body,
#quoteViewModal .product-modal-body {
    flex: 1 1 auto !important;
    min-height: 0 !important;
    overflow-y: auto !important;
    overflow-x: hidden !important;
    -webkit-overflow-scrolling: touch !important;
}

#oppViewModalBackdrop .product-modal-footer,
#opportunityEditModal .product-modal-footer,
#documentModal .product-modal-footer,
#activityModal .product-modal-footer,
#quoteModal .product-modal-footer,
#quoteViewModal .product-modal-footer {
    min-height: 72px !important;
    height: auto !important;
    max-height: none !important;
    display: flex !important;
    align-items: center !important;
    justify-content: flex-end !important;
    gap: 12px !important;
    flex-wrap: nowrap !important;
    padding: var(--space-4) var(--space-5) !important;
    background: var(--surface-0) !important;
    border-top: 1px solid var(--border-subtle) !important;
    border-radius: 0 0 var(--radius-xl) var(--radius-xl) !important;
    overflow: visible !important;
}

#oppViewModalBackdrop .product-modal-footer:has(.modal-footer-actions-left),
#opportunityEditModal .product-modal-footer:has(.modal-footer-actions-left),
#quoteModal .product-modal-footer:has(.modal-footer-actions-left) {
    justify-content: space-between !important;
}

#oppViewModalBackdrop .modal-footer-actions-left,
#opportunityEditModal .modal-footer-actions-left,
#quoteModal .modal-footer-actions-left,
#quoteViewModal .modal-footer-actions-left {
    display: flex !important;
    align-items: center !important;
    justify-content: flex-start !important;
    gap: 10px !important;
    margin-right: auto !important;
    flex: 0 0 auto !important;
    min-width: 0 !important;
    overflow: visible !important;
}

#oppViewModalBackdrop .modal-footer-actions-right,
#opportunityEditModal .modal-footer-actions-right,
#documentModal .modal-footer-actions-right,
#activityModal .modal-footer-actions-right,
#quoteModal .modal-footer-actions-right,
#quoteViewModal .modal-footer-actions-right {
    width: auto !important;
    min-width: 0 !important;
    margin-left: auto !important;
    display: flex !important;
    align-items: center !important;
    justify-content: flex-end !important;
    gap: 12px !important;
    flex: 0 1 auto !important;
    overflow: visible !important;
    flex-wrap: nowrap !important;
}

#oppViewModalBackdrop .product-modal-footer .btn,
#opportunityEditModal .product-modal-footer .btn,
#documentModal .product-modal-footer .btn,
#activityModal .product-modal-footer .btn,
#quoteModal .product-modal-footer .btn,
#quoteViewModal .product-modal-footer .btn {
    width: auto !important;
    min-width: 118px !important;
    max-width: none !important;
    height: 48px !important;
    min-height: 48px !important;
    padding: 0 18px !important;
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    gap: 8px !important;
    flex: 0 0 auto !important;
    white-space: nowrap !important;
    border-radius: var(--radius-lg) !important;
}

#oppViewModalBackdrop .btn-delete-mobile,
#opportunityEditModal .btn-delete-mobile,
#quoteModal .btn-delete-mobile,
#oppViewModalBackdrop .quote-delete-icon-btn,
#opportunityEditModal .quote-delete-icon-btn,
#quoteModal .quote-delete-icon-btn {
    width: 48px !important;
    min-width: 48px !important;
    max-width: 48px !important;
    padding: 0 !important;
    flex: 0 0 48px !important;
    color: var(--color-error) !important;
    border-color: rgba(255, 77, 79, 0.58) !important;
    background: rgba(255, 77, 79, 0.06) !important;
}

#oppViewModalBackdrop .product-modal-footer .btn span,
#opportunityEditModal .product-modal-footer .btn span,
#documentModal .product-modal-footer .btn span,
#activityModal .product-modal-footer .btn span,
#quoteModal .product-modal-footer .btn span,
#quoteViewModal .product-modal-footer .btn span {
    display: inline-block !important;
    max-width: 18ch !important;
    overflow: hidden !important;
    text-overflow: ellipsis !important;
    white-space: nowrap !important;
}

#oppViewModalBackdrop .btn-delete-mobile span,
#opportunityEditModal .btn-delete-mobile span,
#quoteModal .btn-delete-mobile span,
#oppViewModalBackdrop .quote-delete-icon-btn span,
#opportunityEditModal .quote-delete-icon-btn span,
#quoteModal .quote-delete-icon-btn span {
    display: none !important;
}

@media (max-width: 760px) {
    #oppViewModalBackdrop.product-modal-backdrop,
    #opportunityEditModal.product-modal-backdrop,
    #documentModal.product-modal-backdrop,
    #activityModal.product-modal-backdrop,
    #quoteModal.product-modal-backdrop,
    #quoteViewModal.product-modal-backdrop {
        padding: 8px !important;
        align-items: center !important;
    }

    #oppViewModalBackdrop .product-modal-box,
    #opportunityEditModal .product-modal-box,
    #documentModal .product-modal-box,
    #activityModal .product-modal-box,
    #quoteModal .product-modal-box,
    #quoteViewModal .product-modal-box {
        width: calc(100vw - 16px) !important;
        max-width: calc(100vw - 16px) !important;
        height: calc(100dvh - 100px) !important;
        min-height: 0 !important;
        max-height: calc(100dvh - 100px) !important;
        border-radius: var(--radius-xl) !important;
    }

    #oppViewModalBackdrop .product-modal-header,
    #opportunityEditModal .product-modal-header,
    #documentModal .product-modal-header,
    #activityModal .product-modal-header,
    #quoteModal .product-modal-header,
    #quoteViewModal .product-modal-header {
        min-height: 0 !important;
        padding: 16px 18px !important;
    }

    #oppViewModalBackdrop .product-modal-body,
    #opportunityEditModal .product-modal-body,
    #documentModal .product-modal-body,
    #activityModal .product-modal-body,
    #quoteModal .product-modal-body,
    #quoteViewModal .product-modal-body {
        padding: 16px 18px 18px !important;
    }

    #oppViewModalBackdrop .product-modal-footer,
    #opportunityEditModal .product-modal-footer,
    #documentModal .product-modal-footer,
    #activityModal .product-modal-footer,
    #quoteModal .product-modal-footer,
    #quoteViewModal .product-modal-footer {
        min-height: 68px !important;
        height: auto !important;
        max-height: none !important;
        padding: 10px 18px calc(10px + env(safe-area-inset-bottom)) !important;
        gap: 10px !important;
        overflow: visible !important;
    }

    #oppViewModalBackdrop .modal-footer-actions-left,
    #opportunityEditModal .modal-footer-actions-left,
    #quoteModal .modal-footer-actions-left {
        gap: 10px !important;
    }

    #oppViewModalBackdrop .modal-footer-actions-right,
    #opportunityEditModal .modal-footer-actions-right,
    #documentModal .modal-footer-actions-right,
    #activityModal .modal-footer-actions-right,
    #quoteModal .modal-footer-actions-right,
    #quoteViewModal .modal-footer-actions-right {
        gap: 10px !important;
        flex: 1 1 auto !important;
    }

    #oppViewModalBackdrop .product-modal-footer .btn,
    #opportunityEditModal .product-modal-footer .btn,
    #documentModal .product-modal-footer .btn,
    #activityModal .product-modal-footer .btn,
    #quoteModal .product-modal-footer .btn {
        width: auto !important;
        min-width: 104px !important;
        max-width: calc((100vw - 122px) / 2) !important;
        height: 48px !important;
        min-height: 48px !important;
        padding: 0 14px !important;
        flex: 0 1 auto !important;
    }

    #oppViewModalBackdrop .btn-delete-mobile,
    #opportunityEditModal .btn-delete-mobile,
    #quoteModal .btn-delete-mobile,
    #oppViewModalBackdrop .quote-delete-icon-btn,
    #opportunityEditModal .quote-delete-icon-btn,
    #quoteModal .quote-delete-icon-btn {
        width: 48px !important;
        min-width: 48px !important;
        max-width: 48px !important;
        padding: 0 !important;
        flex: 0 0 48px !important;
    }

    #quoteViewModal .product-modal-footer .btn,
    #oppViewModalBackdrop #layer-quote-view .product-modal-footer .btn {
        width: 48px !important;
        min-width: 48px !important;
        max-width: 48px !important;
        padding: 0 !important;
        flex: 0 0 48px !important;
    }

    #quoteViewModal .product-modal-footer .btn span,
    #oppViewModalBackdrop #layer-quote-view .product-modal-footer .btn span {
        display: none !important;
    }

    #oppViewModalBackdrop .product-modal-footer .btn span,
    #opportunityEditModal .product-modal-footer .btn span,
    #documentModal .product-modal-footer .btn span,
    #activityModal .product-modal-footer .btn span,
    #quoteModal .product-modal-footer .btn span {
        display: inline-block !important;
        max-width: 12ch !important;
        overflow: hidden !important;
        text-overflow: ellipsis !important;
        white-space: nowrap !important;
    }
}



/* =========================================================
   P20 - Opportunity modals: mobile/desktop final normalization
   Homologa detalle, editar, documentos, actividades y cotizaciones.
   Header/footer fijos; body con scroll interno; botones sin desplazamiento.
   ========================================================= */
#oppViewModalBackdrop.product-modal-backdrop,
#opportunityEditModal.product-modal-backdrop,
#documentModal.product-modal-backdrop,
#activityModal.product-modal-backdrop,
#quoteModal.product-modal-backdrop,
#quoteViewModal.product-modal-backdrop {
    position: fixed !important;
    inset: 0 !important;
    padding: 24px !important;
    align-items: center !important;
    justify-content: center !important;
    overflow: hidden !important;
    background: rgba(0, 0, 0, 0.68) !important;
    backdrop-filter: blur(5px) !important;
    z-index: 1050 !important;
}

#oppViewModalBackdrop > .product-modal-box {
    width: min(1050px, calc(100vw - 48px)) !important;
    max-width: calc(100vw - 48px) !important;
    height: min(700px, calc(100dvh - 100px)) !important;
    min-height: min(560px, calc(100dvh - 100px)) !important;
    max-height: calc(100dvh - 100px) !important;
    display: flex !important;
    flex-direction: column !important;
    overflow: hidden !important;
    border-radius: var(--radius-xl) !important;
}

#opportunityEditModal > .product-modal-box,
#quoteModal > .product-modal-box {
    width: min(900px, calc(100vw - 48px)) !important;
    max-width: calc(100vw - 48px) !important;
    height: min(700px, calc(100dvh - 100px)) !important;
    min-height: min(560px, calc(100dvh - 100px)) !important;
    max-height: calc(100dvh - 48px) !important;
    display: flex !important;
    flex-direction: column !important;
    overflow: hidden !important;
    border-radius: var(--radius-xl) !important;
}

#documentModal > .product-modal-box,
#activityModal > .product-modal-box,
#quoteViewModal > .product-modal-box {
    width: min(860px, calc(100vw - 48px)) !important;
    max-width: calc(100vw - 100px) !important;
    max-height: calc(100dvh - 100px) !important;
    display: flex !important;
    flex-direction: column !important;
    overflow: hidden !important;
    border-radius: var(--radius-xl) !important;
}

#oppViewModalBackdrop .opp-view-layer {
    flex: 1 1 auto !important;
    width: 100% !important;
    min-height: 0 !important;
    height: 100% !important;
    overflow: hidden !important;
}

#oppViewModalBackdrop .opp-view-layer.active {
    display: flex !important;
    flex-direction: column !important;
}

#oppViewModalBackdrop .product-modal-header,
#opportunityEditModal .product-modal-header,
#documentModal .product-modal-header,
#activityModal .product-modal-header,
#quoteModal .product-modal-header,
#quoteViewModal .product-modal-header {
    flex: 0 0 auto !important;
    min-height: 78px !important;
    padding: 20px 24px !important;
    display: flex !important;
    flex-direction: row !important;
    align-items: flex-start !important;
    justify-content: space-between !important;
    gap: 14px !important;
    border-bottom: 1px solid var(--border-subtle) !important;
    background: var(--surface-1) !important;
}

#oppViewModalBackdrop .product-modal-header .h3,
#opportunityEditModal .product-modal-header .h3,
#documentModal .product-modal-header .h3,
#activityModal .product-modal-header .h3,
#quoteModal .product-modal-header .h3,
#quoteViewModal .product-modal-header .h3 {
    line-height: 1.14 !important;
    margin-bottom: 3px !important;
}

#oppViewModalBackdrop .product-modal-body,
#opportunityEditModal .product-modal-body,
#documentModal .product-modal-body,
#activityModal .product-modal-body,
#quoteModal .product-modal-body,
#quoteViewModal .product-modal-body {
    flex: 1 1 auto !important;
    min-height: 0 !important;
    max-height: none !important;
    padding: 20px 24px !important;
    overflow-y: auto !important;
    overflow-x: hidden !important;
    -webkit-overflow-scrolling: touch !important;
    overscroll-behavior: contain !important;
}

#oppViewModalBackdrop #layer-main > .product-modal-body {
    padding-bottom: 24px !important;
}

#oppViewModalBackdrop .product-modal-footer,
#opportunityEditModal .product-modal-footer,
#documentModal .product-modal-footer,
#activityModal .product-modal-footer,
#quoteModal .product-modal-footer,
#quoteViewModal .product-modal-footer {
    flex: 0 0 auto !important;
    min-height: 76px !important;
    height: auto !important;
    max-height: none !important;
    padding: 14px 20px !important;
    display: flex !important;
    flex-direction: row !important;
    align-items: center !important;
    justify-content: flex-end !important;
    gap: 12px !important;
    flex-wrap: nowrap !important;
    background: var(--surface-0) !important;
    border-top: 1px solid var(--border-subtle) !important;
    border-radius: 0 0 var(--radius-xl) var(--radius-xl) !important;
    overflow: visible !important;
}

#oppViewModalBackdrop .product-modal-footer:has(.modal-footer-actions-left),
#opportunityEditModal .product-modal-footer:has(.modal-footer-actions-left),
#quoteModal .product-modal-footer:has(.modal-footer-actions-left) {
    justify-content: space-between !important;
}

#oppViewModalBackdrop .modal-footer-actions-left,
#opportunityEditModal .modal-footer-actions-left,
#quoteModal .modal-footer-actions-left,
#quoteViewModal .modal-footer-actions-left {
    display: flex !important;
    align-items: center !important;
    justify-content: flex-start !important;
    gap: 10px !important;
    margin-right: auto !important;
    flex: 0 0 auto !important;
    min-width: 48px !important;
    overflow: visible !important;
}

#oppViewModalBackdrop .modal-footer-actions-right,
#opportunityEditModal .modal-footer-actions-right,
#documentModal .modal-footer-actions-right,
#activityModal .modal-footer-actions-right,
#quoteModal .modal-footer-actions-right,
#quoteViewModal .modal-footer-actions-right {
    width: auto !important;
    min-width: 0 !important;
    margin-left: auto !important;
    display: flex !important;
    align-items: center !important;
    justify-content: flex-end !important;
    gap: 12px !important;
    flex: 1 1 auto !important;
    overflow: visible !important;
    flex-wrap: nowrap !important;
}

#oppViewModalBackdrop .product-modal-footer .btn,
#opportunityEditModal .product-modal-footer .btn,
#documentModal .product-modal-footer .btn,
#activityModal .product-modal-footer .btn,
#quoteModal .product-modal-footer .btn,
#quoteViewModal .product-modal-footer .btn {
    width: auto !important;
    min-width: 118px !important;
    max-width: none !important;
    height: 48px !important;
    min-height: 48px !important;
    padding: 0 18px !important;
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    gap: 8px !important;
    flex: 0 0 auto !important;
    white-space: nowrap !important;
    text-align: center !important;
    border-radius: var(--radius-lg) !important;
    overflow: visible !important;
    text-overflow: clip !important;
}

#oppViewModalBackdrop .product-modal-footer .btn-primary,
#opportunityEditModal .product-modal-footer .btn-primary,
#documentModal .product-modal-footer .btn-primary,
#activityModal .product-modal-footer .btn-primary,
#quoteModal .product-modal-footer .btn-primary,
#quoteViewModal .product-modal-footer .btn-primary {
    min-width: 154px !important;
}

#oppViewModalBackdrop .product-modal-footer .btn span,
#opportunityEditModal .product-modal-footer .btn span,
#documentModal .product-modal-footer .btn span,
#activityModal .product-modal-footer .btn span,
#quoteModal .product-modal-footer .btn span,
#quoteViewModal .product-modal-footer .btn span {
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    max-width: none !important;
    overflow: visible !important;
    text-overflow: clip !important;
    white-space: nowrap !important;
    text-align: center !important;
}

#oppViewModalBackdrop .btn-delete-mobile,
#opportunityEditModal .btn-delete-mobile,
#quoteModal .btn-delete-mobile,
#oppViewModalBackdrop .quote-delete-icon-btn,
#opportunityEditModal .quote-delete-icon-btn,
#quoteModal .quote-delete-icon-btn {
    width: 48px !important;
    min-width: 48px !important;
    max-width: 48px !important;
    height: 48px !important;
    min-height: 48px !important;
    padding: 0 !important;
    flex: 0 0 48px !important;
    color: var(--color-error) !important;
    border-color: rgba(255, 77, 79, 0.58) !important;
    background: rgba(255, 77, 79, 0.06) !important;
}

#oppViewModalBackdrop .btn-delete-mobile span,
#opportunityEditModal .btn-delete-mobile span,
#quoteModal .btn-delete-mobile span,
#oppViewModalBackdrop .quote-delete-icon-btn span,
#opportunityEditModal .quote-delete-icon-btn span,
#quoteModal .quote-delete-icon-btn span {
    display: none !important;
}

#quoteViewModal .product-modal-footer .modal-footer-actions-right,
#oppViewModalBackdrop #layer-quote-view .product-modal-footer .modal-footer-actions-right {
    flex: 1 1 auto !important;
    justify-content: flex-end !important;
}

@media (max-width: 760px) {
    #oppViewModalBackdrop.product-modal-backdrop,
    #opportunityEditModal.product-modal-backdrop,
    #documentModal.product-modal-backdrop,
    #activityModal.product-modal-backdrop,
    #quoteModal.product-modal-backdrop,
    #quoteViewModal.product-modal-backdrop {
        padding: 12px !important;
        align-items: center !important;
        justify-content: center !important;
    }

    #oppViewModalBackdrop > .product-modal-box,
    #opportunityEditModal > .product-modal-box,
    #documentModal > .product-modal-box,
    #activityModal > .product-modal-box,
    #quoteModal > .product-modal-box,
    #quoteViewModal > .product-modal-box {
        width: calc(100vw - 24px) !important;
        max-width: calc(100vw - 24px) !important;
        height: calc(100dvh - 200px) !important;
        min-height: 0 !important;
        max-height: calc(100dvh - 200px) !important;
        border-radius: 18px !important;
    }

    #oppViewModalBackdrop .product-modal-header,
    #opportunityEditModal .product-modal-header,
    #documentModal .product-modal-header,
    #activityModal .product-modal-header,
    #quoteModal .product-modal-header,
    #quoteViewModal .product-modal-header {
        min-height: 72px !important;
        padding: 16px !important;
        gap: 10px !important;
    }

    #oppViewModalBackdrop .product-modal-header .h3,
    #opportunityEditModal .product-modal-header .h3,
    #documentModal .product-modal-header .h3,
    #activityModal .product-modal-header .h3,
    #quoteModal .product-modal-header .h3,
    #quoteViewModal .product-modal-header .h3 {
        font-size: 1.05rem !important;
        line-height: 1.16 !important;
    }

    #oppViewModalBackdrop .product-modal-header .text-sm,
    #opportunityEditModal .product-modal-header .text-sm,
    #documentModal .product-modal-header .text-sm,
    #activityModal .product-modal-header .text-sm,
    #quoteModal .product-modal-header .text-sm,
    #quoteViewModal .product-modal-header .text-sm {
        font-size: 0.86rem !important;
        line-height: 1.22 !important;
    }

    #oppViewModalBackdrop .product-modal-body,
    #opportunityEditModal .product-modal-body,
    #documentModal .product-modal-body,
    #activityModal .product-modal-body,
    #quoteModal .product-modal-body,
    #quoteViewModal .product-modal-body {
        padding: 16px !important;
    }

    #oppViewModalBackdrop .product-modal-footer,
    #opportunityEditModal .product-modal-footer,
    #documentModal .product-modal-footer,
    #activityModal .product-modal-footer,
    #quoteModal .product-modal-footer,
    #quoteViewModal .product-modal-footer {
        min-height: 68px !important;
        height: auto !important;
        max-height: none !important;
        padding: 10px 12px calc(10px + env(safe-area-inset-bottom)) !important;
        gap: 10px !important;
        overflow: visible !important;
    }

    #oppViewModalBackdrop .modal-footer-actions-left,
    #opportunityEditModal .modal-footer-actions-left,
    #quoteModal .modal-footer-actions-left {
        min-width: 44px !important;
        gap: 8px !important;
    }

    #oppViewModalBackdrop .modal-footer-actions-right,
    #opportunityEditModal .modal-footer-actions-right,
    #documentModal .modal-footer-actions-right,
    #activityModal .modal-footer-actions-right,
    #quoteModal .modal-footer-actions-right,
    #quoteViewModal .modal-footer-actions-right {
        gap: 10px !important;
        flex: 1 1 auto !important;
    }

    #oppViewModalBackdrop .product-modal-footer .btn,
    #opportunityEditModal .product-modal-footer .btn,
    #documentModal .product-modal-footer .btn,
    #activityModal .product-modal-footer .btn,
    #quoteModal .product-modal-footer .btn {
        height: 44px !important;
        min-height: 44px !important;
        min-width: 98px !important;
        max-width: none !important;
        padding: 0 12px !important;
        font-size: 0.9rem !important;
        flex: 0 1 auto !important;
    }

    #oppViewModalBackdrop .product-modal-footer .btn-primary,
    #opportunityEditModal .product-modal-footer .btn-primary,
    #documentModal .product-modal-footer .btn-primary,
    #activityModal .product-modal-footer .btn-primary,
    #quoteModal .product-modal-footer .btn-primary {
        min-width: 138px !important;
    }

    #oppViewModalBackdrop .btn-delete-mobile,
    #opportunityEditModal .btn-delete-mobile,
    #quoteModal .btn-delete-mobile,
    #oppViewModalBackdrop .quote-delete-icon-btn,
    #opportunityEditModal .quote-delete-icon-btn,
    #quoteModal .quote-delete-icon-btn {
        width: 44px !important;
        min-width: 44px !important;
        max-width: 44px !important;
        height: 44px !important;
        min-height: 44px !important;
        padding: 0 !important;
        flex: 0 0 44px !important;
    }

    #quoteViewModal .product-modal-footer .btn,
    #oppViewModalBackdrop #layer-quote-view .product-modal-footer .btn {
        width: 44px !important;
        min-width: 44px !important;
        max-width: 44px !important;
        height: 44px !important;
        min-height: 44px !important;
        padding: 0 !important;
        flex: 0 0 44px !important;
    }

    #quoteViewModal .product-modal-footer .btn span,
    #oppViewModalBackdrop #layer-quote-view .product-modal-footer .btn span {
        display: none !important;
    }
}


/* =========================================================
   P21 - Edit opportunity footer homologado a Crear oportunidad
   Mantiene la acción destructiva a la izquierda y normaliza
   Cancelar/Guardar con el mismo patrón visual de creación.
   ========================================================= */
#opportunityEditModal .product-modal-footer,
#oppViewModalBackdrop #layer-edit .product-modal-footer {
    min-height: 76px !important;
    height: auto !important;
    max-height: none !important;
    display: flex !important;
    flex-direction: row !important;
    align-items: center !important;
    justify-content: flex-end !important;
    gap: 12px !important;
    flex-wrap: nowrap !important;
    padding: 14px 20px !important;
    background: var(--surface-0) !important;
    border-top: 1px solid var(--border-subtle) !important;
    border-radius: 0 0 var(--radius-xl) var(--radius-xl) !important;
    overflow: visible !important;
}

#opportunityEditModal .modal-footer-actions-left,
#oppViewModalBackdrop #layer-edit .modal-footer-actions-left {
    flex: 0 0 auto !important;
    min-width: 48px !important;
    margin-right: auto !important;
    display: flex !important;
    align-items: center !important;
    justify-content: flex-start !important;
    gap: 8px !important;
}

#opportunityEditModal .modal-footer-actions-right,
#oppViewModalBackdrop #layer-edit .modal-footer-actions-right {
    flex: 0 0 auto !important;
    width: auto !important;
    margin-left: auto !important;
    display: flex !important;
    align-items: center !important;
    justify-content: flex-end !important;
    gap: 12px !important;
    min-width: 0 !important;
}

#opportunityEditModal .product-modal-footer .btn,
#oppViewModalBackdrop #layer-edit .product-modal-footer .btn {
    width: auto !important;
    min-width: 118px !important;
    max-width: none !important;
    height: 48px !important;
    min-height: 48px !important;
    padding: 0 18px !important;
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    gap: 8px !important;
    flex: 0 0 auto !important;
    white-space: nowrap !important;
    text-align: center !important;
    overflow: visible !important;
    text-overflow: clip !important;
}

#opportunityEditModal .modal-footer-actions-right .btn-primary,
#oppViewModalBackdrop #layer-edit .modal-footer-actions-right .btn-primary {
    min-width: 178px !important;
}

#opportunityEditModal .product-modal-footer .btn span,
#oppViewModalBackdrop #layer-edit .product-modal-footer .btn span {
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    min-width: 0 !important;
    max-width: none !important;
    overflow: visible !important;
    text-overflow: clip !important;
    white-space: nowrap !important;
    text-align: center !important;
}

#opportunityEditModal .modal-footer-actions-left .btn-delete-mobile,
#opportunityEditModal .modal-footer-actions-left .quote-delete-icon-btn,
#oppViewModalBackdrop #layer-edit .modal-footer-actions-left .btn-delete-mobile,
#oppViewModalBackdrop #layer-edit .modal-footer-actions-left .quote-delete-icon-btn {
    width: 48px !important;
    min-width: 48px !important;
    max-width: 48px !important;
    height: 48px !important;
    min-height: 48px !important;
    padding: 0 !important;
    flex: 0 0 48px !important;
}

#opportunityEditModal .modal-footer-actions-left .btn-delete-mobile span,
#opportunityEditModal .modal-footer-actions-left .quote-delete-icon-btn span,
#oppViewModalBackdrop #layer-edit .modal-footer-actions-left .btn-delete-mobile span,
#oppViewModalBackdrop #layer-edit .modal-footer-actions-left .quote-delete-icon-btn span {
    display: none !important;
}

@media (max-width: 760px) {
    #opportunityEditModal .product-modal-footer,
    #oppViewModalBackdrop #layer-edit .product-modal-footer {
        min-height: 68px !important;
        padding: 10px 12px calc(10px + env(safe-area-inset-bottom)) !important;
        gap: 10px !important;
    }

    #opportunityEditModal .modal-footer-actions-left,
    #oppViewModalBackdrop #layer-edit .modal-footer-actions-left {
        min-width: 44px !important;
        gap: 8px !important;
    }

    #opportunityEditModal .modal-footer-actions-right,
    #oppViewModalBackdrop #layer-edit .modal-footer-actions-right {
        gap: 10px !important;
        flex: 0 1 auto !important;
        min-width: 0 !important;
    }

    #opportunityEditModal .product-modal-footer .btn,
    #oppViewModalBackdrop #layer-edit .product-modal-footer .btn {
        height: 44px !important;
        min-height: 44px !important;
        min-width: 106px !important;
        max-width: none !important;
        padding: 0 14px !important;
        font-size: 0.94rem !important;
        flex: 0 0 auto !important;
    }

    #opportunityEditModal .modal-footer-actions-right .btn-primary,
    #oppViewModalBackdrop #layer-edit .modal-footer-actions-right .btn-primary {
        min-width: 124px !important;
    }

    #opportunityEditModal .modal-footer-actions-right .btn-primary .mobile-hidden,
    #oppViewModalBackdrop #layer-edit .modal-footer-actions-right .btn-primary .mobile-hidden {
        display: none !important;
    }

    #opportunityEditModal .modal-footer-actions-left .btn-delete-mobile,
    #opportunityEditModal .modal-footer-actions-left .quote-delete-icon-btn,
    #oppViewModalBackdrop #layer-edit .modal-footer-actions-left .btn-delete-mobile,
    #oppViewModalBackdrop #layer-edit .modal-footer-actions-left .quote-delete-icon-btn {
        width: 44px !important;
        min-width: 44px !important;
        max-width: 44px !important;
        height: 44px !important;
        min-height: 44px !important;
        padding: 0 !important;
        flex: 0 0 44px !important;
    }
}

</style>

<?php if (!$isModal): ?>
<main class="app-main">
    <section class="content">
        <div class="page-header header-responsive">
            <div class="page-header-content">
                <span class="label">CRM</span>
                <h1><?php echo safe_text($opportunity['title']); ?></h1>
                <p class="text-secondary text-truncate" style="max-width: 100%;">
                    <?php echo safe_text($opportunityDisplayName); ?>
                    <?php if ($opportunityLegalName !== '' && $opportunityLegalName !== $opportunityDisplayName): ?> · <?php echo safe_text($opportunityLegalName); ?><?php endif; ?>
                    <?php if ($opportunityTaxId !== ''): ?> · <?php echo safe_text(format_rut($opportunityTaxId)); ?><?php endif; ?>
                </p>
            </div>
            <div class="cluster top-actions-cluster">
                <a class="btn btn-outline btn-icon-mobile" href="/modules/crm/" title="Volver al CRM"><i data-lucide="arrow-left"></i><span class="mobile-hidden">Volver</span></a>
                <a class="btn btn-outline btn-icon-mobile" href="/modules/crm/embudo.php" title="Ver embudo"><i data-lucide="kanban-square"></i><span class="mobile-hidden">Embudo</span></a>
                <?php if (!$isClosedOpportunity): ?>
                    <a class="btn btn-outline btn-icon-mobile" href="/modules/crm/embudo.php?close_id=<?php echo (int)$opportunity['id']; ?>" title="Cerrar oportunidad"><i data-lucide="archive"></i><span class="mobile-hidden">Cerrar</span></a>
                    <?php if ($canManageArchiveHold): ?>
                        <button type="button" class="btn btn-outline btn-icon-mobile" onclick="window.toggleOpportunityArchiveHold(<?php echo (int)$opportunity['id']; ?>, <?php echo $archiveHoldActive ? 'true' : 'false'; ?>)" title="<?php echo $archiveHoldActive ? 'Reactivar archivo mensual' : 'Pausar archivo mensual'; ?>"><i data-lucide="<?php echo $archiveHoldActive ? 'shield-check' : 'shield-alert'; ?>"></i><span class="mobile-hidden"><?php echo $archiveHoldActive ? 'Reactivar archivo' : 'Pausar archivo'; ?></span></button>
                    <?php endif; ?>
                    <button type="button" class="btn btn-primary btn-icon-mobile" onclick="openStandardModal('opportunityEditModal')" title="Editar oportunidad"><i data-lucide="pencil"></i><span class="mobile-hidden">Editar</span></button>
                <?php else: ?>
                    <a class="btn btn-primary btn-icon-mobile" href="/modules/crm/closed_opportunities.php?q=<?php echo urlencode((string)$opportunity['title']); ?>" title="Ver archivo de cerradas"><i data-lucide="archive"></i><span class="mobile-hidden">Archivada</span></a>
                <?php endif; ?>
            </div>
        </div>
<?php else: ?>
<div class="product-modal-backdrop show" style="display: flex; z-index: 1040;" id="oppViewModalBackdrop">
    <div class="product-modal-box" style="width: 1050px; max-width: 95%; max-height: 95dvh; overflow: hidden; position: relative;">
        <div id="layer-main" class="opp-view-layer active">
            
            <div class="product-modal-header" style="flex-shrink: 0; display: flex; flex-wrap: nowrap; align-items: flex-start; gap: 12px;">
                <div style="flex: 1; min-width: 0;">
                    <h2 class="h3" style="font-size: 1.3rem; margin-bottom: 2px; word-break: break-word;"><?php echo safe_text($opportunity['title']); ?></h2>
                    <span class="text-secondary text-sm" style="display: block; word-break: break-word;">
                        <?php echo safe_text($opportunityDisplayName); ?>
                        <?php if ($opportunityLegalName !== '' && $opportunityLegalName !== $opportunityDisplayName): ?> · <?php echo safe_text($opportunityLegalName); ?><?php endif; ?>
                        <?php if ($opportunityTaxId !== ''): ?> · <?php echo safe_text(format_rut($opportunityTaxId)); ?><?php endif; ?>
                    </span>
                </div>
                <div class="cluster actions-cluster" style="display: flex; flex-direction: row !important; flex-wrap: nowrap !important; gap: 8px; flex-shrink: 0; align-items: center;">
                    <?php if (!$isClosedOpportunity): ?>
                        <button type="button" class="btn btn-outline action-square-btn" onclick="window.openCloseOpportunityModal(event, <?php echo (int)$opportunity['id']; ?>, <?php echo htmlspecialchars(json_encode($opportunity['title'], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), ENT_QUOTES, 'UTF-8'); ?>)" title="Cerrar oportunidad">
                            <i data-lucide="archive" style="width: 18px; height: 18px;"></i>
                        </button>
                        <?php if ($canManageArchiveHold): ?>
                            <button type="button" class="btn btn-outline action-square-btn" onclick="window.toggleOpportunityArchiveHold(<?php echo (int)$opportunity['id']; ?>, <?php echo $archiveHoldActive ? 'true' : 'false'; ?>)" title="<?php echo $archiveHoldActive ? 'Reactivar archivo mensual' : 'Pausar archivo mensual'; ?>">
                                <i data-lucide="<?php echo $archiveHoldActive ? 'shield-check' : 'shield-alert'; ?>" style="width:18px;height:18px;"></i>
                            </button>
                        <?php endif; ?>
                        <button type="button" class="btn btn-outline action-square-btn" onclick="window.switchOppLayer('layer-edit')" title="Editar oportunidad">
                            <i data-lucide="pencil" style="width: 18px; height: 18px;"></i>
                        </button>
                    <?php else: ?>
                        <a class="btn btn-outline action-square-btn" href="/modules/crm/closed_opportunities.php?q=<?php echo urlencode((string)$opportunity['title']); ?>" title="Ver archivo de cerradas">
                            <i data-lucide="archive" style="width: 18px; height: 18px;"></i>
                        </a>
                    <?php endif; ?>
                    <button type="button" class="btn btn-outline action-square-btn" onclick="document.getElementById('oppViewModalBackdrop').remove()" title="Cerrar">
                        <i data-lucide="x" style="width: 18px; height: 18px;"></i>
                    </button>
                </div>
            </div>
            
            <div class="product-modal-body" style="padding-bottom: 40px;">
<?php endif; ?>

        <?php if ($isClosedOpportunity): ?>
            <aside style="display:flex;align-items:flex-start;justify-content:space-between;gap:14px;padding:14px 16px;margin-bottom:16px;border:1px solid var(--border-default);border-radius:14px;background:var(--surface-2);">
                <div style="display:flex;align-items:flex-start;gap:10px;min-width:0;">
                    <i data-lucide="archive" style="width:19px;height:19px;flex:0 0 auto;color:var(--text-muted);"></i>
                    <div style="min-width:0;">
                        <strong>Oportunidad archivada · <?php echo safe_text($closureOutcomeLabel); ?></strong>
                        <p class="text-secondary text-sm" style="margin:4px 0 0;">
                            Cerrada el <?php echo safe_text(date('d-m-Y', strtotime($opportunity['archived_at']))); ?>
                            <?php if (!empty($opportunity['closure_reason'])): ?> · <?php echo safe_text($opportunity['closure_reason']); ?><?php endif; ?>
                        </p>
                    </div>
                </div>
                <a class="btn btn-sm btn-outline" href="/modules/crm/closed_opportunities.php?q=<?php echo urlencode((string)$opportunity['title']); ?>"><i data-lucide="rotate-ccw"></i><span>Gestionar</span></a>
            </aside>
        <?php endif; ?>

        <section class="grid grid-4 responsive-kpis">
            <article class="kpi-card"><div class="kpi-label">Valor esperado</div><div class="kpi-main"><div class="kpi-value"><?php echo clp($opportunity['expected_value']); ?></div></div></article>
            <article class="kpi-card"><div class="kpi-label">Probabilidad</div><div class="kpi-main"><div class="kpi-value"><?php echo (int) $opportunity['probability']; ?>%</div></div></article>
            <article class="kpi-card"><div class="kpi-label">Cierre estimado</div><div class="kpi-main"><div class="kpi-value"><?php echo !empty($opportunity['expected_close_date']) ? safe_text($opportunity['expected_close_date']) : 'Sin fecha'; ?></div></div></article>
            <article class="kpi-card">
                <div class="kpi-label">Próxima acción</div>
                <div class="kpi-main"><div class="kpi-value text-truncate" style="max-width: 100%;"><?php echo !empty($opportunity['next_action']) ? safe_text($opportunity['next_action']) : 'Sin acción'; ?></div></div>
                <p class="kpi-context"><?php echo !empty($opportunity['next_action_date']) ? safe_text($opportunity['next_action_date']) : 'Sin fecha'; ?></p>
            </article>
        </section>

        <div class="mt-6"></div>

        <section class="inline-quick-actions">
            <button type="button" class="btn btn-outline action-btn" onclick="<?php echo $isModal ? "window.switchOppLayer('layer-doc')" : "openStandardModal('documentModal')"; ?>">
                <i data-lucide="file-text"></i> <span>Documento</span>
            </button>
            <button type="button" class="btn btn-outline action-btn" onclick="<?php echo $isModal ? "window.switchOppLayer('layer-act')" : "openStandardModal('activityModal')"; ?>">
                <i data-lucide="check-square"></i> <span>Actividad</span>
            </button>
            <?php if (!$isClosedOpportunity): ?>
                <button type="button" class="btn btn-primary action-btn" onclick="<?php echo $isModal ? "window.openQuoteCreateLayer()" : "window.ICY_SPA_GO ? window.ICY_SPA_GO('/modules/crm/quote_create.php?opportunity_id={$id}') : (window.location.href='/modules/crm/quote_create.php?opportunity_id={$id}');"; ?>">
                    <i data-lucide="file-spreadsheet"></i> <span>Cotización</span>
                </button>
                <?php if ($isModal): ?>
                    <button type="button" class="btn btn-outline action-btn" onclick="window.openCloseOpportunityModal(event, <?php echo (int)$opportunity['id']; ?>, <?php echo htmlspecialchars(json_encode($opportunity['title'], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), ENT_QUOTES, 'UTF-8'); ?>)">
                        <i data-lucide="archive"></i> <span>Cerrar</span>
                    </button>
                <?php else: ?>
                    <a class="btn btn-outline action-btn" href="/modules/crm/embudo.php?close_id=<?php echo (int)$opportunity['id']; ?>"><i data-lucide="archive"></i><span>Cerrar</span></a>
                <?php endif; ?>
            <?php else: ?>
                <a class="btn btn-primary action-btn" href="/modules/crm/closed_opportunities.php?q=<?php echo urlencode((string)$opportunity['title']); ?>"><i data-lucide="archive"></i><span>Ver cierre</span></a>
            <?php endif; ?>
        </section>

        <div class="mt-6"></div>

        <div class="opportunity-layout">
            <article class="card layout-detalle">
                <div class="card-header">
                    <div>
                        <span class="label">Información comercial</span>
                        <div style="display: flex; align-items: center; gap: 8px;">
                            <h3>Detalle de oportunidad</h3>
                            <span class="badge"><?php echo safe_text($opportunity['stage']); ?></span>
                        </div>
                    </div>
                </div>
                <div class="card-body">
                    <?php $paymentStatus = $opportunity['payment_status'] ?? 'no_facturado'; $paymentLabel = $paymentStatusOptions[$paymentStatus] ?? $paymentStatus; ?>
                    <div class="metric-row"><span>Responsable</span><strong class="metric-value"><?php echo !empty($opportunity['owner_name']) ? safe_text($opportunity['owner_name']) : 'Sistema'; ?></strong></div>
                    <div class="metric-row"><span>Origen</span><strong class="metric-value"><?php echo !empty($opportunity['source']) ? safe_text($opportunity['source']) : 'Sin origen'; ?></strong></div>
                    <div class="metric-row"><span>Competidor</span><strong class="metric-value"><?php echo !empty($opportunity['competitor']) ? safe_text($opportunity['competitor']) : 'No identificado'; ?></strong></div>
                    <div class="metric-row"><span>Creada</span><strong class="metric-value"><?php echo safe_text($opportunity['created_at']); ?></strong></div>
                    <div class="metric-row"><span>Cobranza</span><strong class="metric-value"><span class="badge payment-badge payment-<?php echo safe_text($paymentStatus); ?>"><?php echo safe_text($paymentLabel); ?></span></strong></div>
                    <div class="metric-row"><span>Vencimiento pago</span><strong class="metric-value"><?php echo !empty($opportunity['payment_due_date']) ? safe_text($opportunity['payment_due_date']) : 'Sin fecha'; ?></strong></div>
                    <div class="metric-row"><span>Fecha de pago</span><strong class="metric-value"><?php echo !empty($opportunity['payment_paid_date']) ? safe_text($opportunity['payment_paid_date']) : 'Sin pago'; ?></strong></div>
                    <?php if (!empty($opportunity['notes'])): ?>
                        <div class="mt-5"><span class="label">Notas</span><p class="text-secondary" style="font-size: 0.9rem;"><?php echo nl2br(safe_text($opportunity['notes'])); ?></p></div>
                    <?php endif; ?>
                </div>
            </article>

            <article class="card layout-timeline">
                <div class="card-header">
                    <div><span class="label">Historial</span><h3>Actividad comercial</h3></div>
                </div>
                <div class="card-body">
                    <div class="card-scroll-container">
                        <div class="crm-timeline">
                            <?php foreach ($activities as $activity): ?>
                                <div class="crm-timeline-item">
                                    <span class="crm-timeline-dot <?php echo safe_text($activity['activity_type']); ?>"></span>
                                    <div>
                                        <strong><?php echo safe_text($activity['title']); ?></strong>
                                        <?php if (!empty($activity['description'])): ?><p class="text-secondary text-sm" style="margin-top: 4px;"><?php echo nl2br(safe_text($activity['description'])); ?></p><?php endif; ?>
                                        <span class="text-muted text-sm" style="margin-top: 4px; display: block;"><?php echo safe_text($activity['activity_date']); ?><?php if (!empty($activity['owner_name'])): ?> · <?php echo safe_text($activity['owner_name']); ?><?php endif; ?></span>
                                    </div>
                                </div>
                            <?php endforeach; ?>
                            <?php if (empty($activities)): ?><p class="text-secondary" style="text-align: center; padding: 20px;">Sin actividad registrada.</p><?php endif; ?>
                        </div>
                    </div>
                </div>
            </article>

            <article class="card layout-docs">
                <div class="card-header">
                    <div><span class="label">Adjuntos</span><h3>Documentos asociados</h3></div>
                </div>
                <div class="card-body">
                    <div class="card-scroll-container">
                        <div class="table-wrap mobile-table-collapsible">
                            <table class="table">
                                <thead><tr><th style="width: 30%;">Detalle</th><th style="width: 15%;">Estado</th><th style="width: 15%;">Fecha</th><th style="width: 15%;">Total</th><th style="width: 25%; text-align: right;">Acciones</th></tr></thead>
                                <tbody>
                                    <?php foreach ($documents as $document): 
                                        $docTypeLower = isset($document['document_type']) ? mb_strtolower(trim($document['document_type']), 'UTF-8') : '';
                                        $isQuote = ($docTypeLower === 'cotización' || $docTypeLower === 'cotizacion');
                                        $qId = 0; $quoteStatus = '—'; $badgeClass = '';
                                        if (!empty($document['file_path']) && preg_match('/id=(\d+)/', $document['file_path'], $matches)) { $qId = (int)$matches[1]; }
                                        if ($isQuote && $qId > 0) {
                                            $quoteRef = array_filter($oppQuotes, function($q) use ($qId) { return $q['id'] == $qId; });
                                            $quoteRef = !empty($quoteRef) ? array_values($quoteRef)[0] : null;
                                            $quoteStatus = $quoteRef ? ($quoteRef['status'] ?: 'Borrador') : 'Borrador';
                                            
                                            if ($quoteStatus === 'Aceptada') $badgeClass = 'badge-success';
                                            elseif ($quoteStatus === 'Enviada') $badgeClass = 'badge-warning';
                                            elseif ($quoteStatus === 'Rechazada') $badgeClass = 'badge-error';
                                        }
                                    ?>
                                        <tr>
                                            <td data-label="Documento">
                                                <div class="cell-value"><div class="doc-main-title" style="font-weight: 600; color: var(--text-primary);"><?php echo safe_text($document['document_name']); ?></div><?php if (!$isQuote): ?><small class="text-secondary" style="font-size: 0.75rem; display: block; margin-top: 2px;"><?php echo safe_text($document['document_type']); ?> <?php echo !empty($document['document_number']) ? 'Nº ' . safe_text($document['document_number']) : ''; ?></small><?php endif; ?></div>
                                            </td>
                                            <td data-label="Estado"><div class="cell-value"><?php if ($isQuote): ?><span class="badge <?php echo $badgeClass; ?>"><?php echo safe_text($quoteStatus); ?></span><?php else: ?><span class="text-muted">—</span><?php endif; ?></div></td>
                                            <td data-label="Fecha"><div class="cell-value"><span class="text-sm"><?php echo date('d-m-Y', strtotime($document['document_date'])); ?></span></div></td>
                                            <td data-label="Total"><div class="cell-value">
                                                <?php
                                                    $docCurrency = strtoupper(trim((string)($document['linked_currency_code'] ?? 'CLP'))) ?: 'CLP';
                                                    $docOriginalTotal = isset($document['linked_foreign_total_amount']) && $document['linked_foreign_total_amount'] !== null
                                                        ? (float)$document['linked_foreign_total_amount']
                                                        : (float)($document['total_amount'] ?? 0);
                                                    $docRate = (float)($document['linked_exchange_rate_value'] ?? 0);
                                                    $docTotalClp = isset($document['linked_total_amount_clp']) && $document['linked_total_amount_clp'] !== null
                                                        ? (float)$document['linked_total_amount_clp']
                                                        : ($docCurrency !== 'CLP' && $docRate > 0 ? round($docOriginalTotal * $docRate, 2) : (float)($document['total_amount'] ?? 0));
                                                ?>
                                                <?php if ($docCurrency !== 'CLP'): ?>
                                                    <strong style="color: var(--color-success); font-size: 14px; display:block;"><?php echo safe_text(opportunity_format_currency($docOriginalTotal, $docCurrency)); ?></strong>
                                                    <small class="text-secondary" style="display:block; margin-top:2px; line-height:1.35;">
                                                        Equiv. <?php echo safe_text(clp($docTotalClp)); ?>
                                                        <?php if ($docRate > 0): ?> · TC <?php echo safe_text(number_format($docRate, 2, ',', '.')); ?><?php endif; ?>
                                                        <?php if (!empty($document['linked_exchange_rate_date'])): ?> · <?php echo safe_text(date('d-m-Y', strtotime($document['linked_exchange_rate_date']))); ?><?php endif; ?>
                                                    </small>
                                                <?php else: ?>
                                                    <strong style="color: var(--color-success); font-size: 14px;"><?php echo clp($docTotalClp); ?></strong>
                                                <?php endif; ?>
                                            </div></td>
                                            <td class="actions-cell-align" data-label="Acciones">
                                                <div class="cluster actions-btn-group">
                                                    <?php if ($isQuote && $qId > 0): ?>
                                                        <button type="button" class="btn btn-sm btn-outline action-icon-btn" onclick="window.openQuoteViewLayer(<?php echo $qId; ?>)" title="Ver Detalle Cotización"><i data-lucide="eye"></i></button>
                                                        <button type="button" class="btn btn-sm btn-outline action-icon-btn" onclick="window.openQuoteEditLayer(<?php echo $qId; ?>)" style="border-color: var(--color-warning); color: var(--color-warning);" title="Editar Cotización"><i data-lucide="pencil"></i></button>
                                                        <button type="button" class="btn btn-sm btn-outline action-icon-btn approve-btn" onclick="window.approveQuote(<?php echo $qId; ?>, this)" title="Aprobar Cotización"><i data-lucide="check"></i></button>
                                                    <?php elseif (!empty($document['file_path']) || !empty($document['facto_document_id'])): ?>
                                                        <a class="btn btn-sm btn-outline action-icon-btn" href="/modules/crm/document_file.php?id=<?php echo (int)$document['id']; ?>&amp;kind=pdf" target="_blank" rel="noopener" data-no-spa="true" title="Ver documento"><i data-lucide="eye"></i></a>
                                                    <?php else: ?>
                                                        <span class="text-muted">—</span>
                                                    <?php endif; ?>
                                                </div>
                                            </td>
                                        </tr>
                                    <?php endforeach; ?>
                                    <?php if (empty($documents)): ?>
                                        <tr class="empty-state-row"><td colspan="5" class="text-secondary">Sin documentos asociados.</td></tr>
                                    <?php endif; ?>
                                </tbody>
                            </table>
                        </div>
                    </div>
                </div>
            </article>
        </div> 

<?php if ($isModal): ?>
            </div> </div> <?php else: ?>
    </section>
<?php endif; ?>

<?php 
// ==============================================================================
// RENDERIZADO DE LAS CAPAS MODALES 
// ==============================================================================
function render_form_layer($id, $title, $subtitle, $formHtml, $footerHtml, $isModal) {
    if ($isModal) {
        echo '
        <div id="' . $id . '" class="opp-view-layer">
            <div class="product-modal-header" style="flex-shrink: 0; display: flex; flex-wrap: nowrap; align-items: flex-start; gap: 12px;">
                <div style="display:flex; align-items:flex-start; gap:12px; flex: 1; min-width: 0;">
                    <button type="button" class="btn btn-outline action-square-btn" onclick="window.switchOppLayer(\'layer-main\')"><i data-lucide="arrow-left" style="width: 18px; height: 18px;"></i></button>
                    <div style="flex: 1; min-width: 0;"><h2 class="h3" style="font-size: 1.15rem; margin-bottom: 2px; word-break: break-word;">' . $title . '</h2><span class="text-secondary text-sm" style="display: block; word-break: break-word;">' . $subtitle . '</span></div>
                </div>
                <button type="button" class="btn btn-outline action-square-btn" onclick="document.getElementById(\'oppViewModalBackdrop\').remove()"><i data-lucide="x" style="width: 18px; height: 18px;"></i></button>
            </div>
            <div class="product-modal-body">' . $formHtml . '</div>
            <div class="product-modal-footer" style="flex-shrink: 0; justify-content: space-between; gap: 12px; flex-wrap: nowrap;">' . $footerHtml . '</div>
        </div>';
    } else {
        echo '
        <div id="' . $id . '" class="product-modal-backdrop">
            <div class="product-modal-box" style="max-width: 860px;">
                <div class="product-modal-header" style="display: flex; flex-wrap: nowrap; align-items: flex-start; gap: 12px;">
                    <div style="flex: 1; min-width: 0;">
                        <h2 class="h3" style="margin-bottom: 2px; word-break: break-word;">' . $title . '</h2>
                        <span class="text-secondary text-sm" style="display: block; word-break: break-word;">' . $subtitle . '</span>
                    </div>
                    <button type="button" class="btn btn-outline action-square-btn" onclick="window.closeStandardModal(\'' . $id . '\')"><i data-lucide="x" style="width: 18px; height: 18px;"></i></button>
                </div>
                <div class="product-modal-body">' . $formHtml . '</div>
                <div class="product-modal-footer" style="justify-content: space-between; gap: 12px; flex-wrap: nowrap;">' . $footerHtml . '</div>
            </div>
        </div>';
    }
}

// 1. LAYER EDITAR OP.
$deleteOpportunityFooter = '';
if ($canDeleteOpportunity) {
    $deleteOpportunityFooter = '
<div class="modal-footer-actions-left" style="display: flex; align-items: center;">
    <form id="form-delete-opportunity" action="/modules/crm/opportunity_delete.php" method="POST" data-no-spa="true" style="margin:0;">
        <input type="hidden" name="_csrf_token" value="' . safe_text(csrf_token()) . '">
        <input type="hidden" name="id" value="' . (int)$opportunity['id'] . '">
        <button type="submit" class="btn btn-outline btn-delete-mobile quote-delete-icon-btn" style="color: var(--color-error); border-color: var(--color-error);" title="Eliminar oportunidad" aria-label="Eliminar oportunidad">
            <i data-lucide="trash-2"></i>
        </button>
    </form>
</div>';
}

$footerEdit = $deleteOpportunityFooter . '
<div class="modal-footer-actions-right" style="flex: 1;">
    <button type="button" class="btn btn-outline" onclick="' . ($isModal ? "window.switchOppLayer('layer-main')" : "window.closeStandardModal('opportunityEditModal')") . '"><i data-lucide="x"></i><span>Cancelar</span></button>
    <button type="submit" form="form-edit-opportunity" class="btn btn-primary"><i data-lucide="save"></i><span>Guardar<span class="mobile-hidden"> Cambios</span></span></button>
</div>';
render_form_layer($isModal ? 'layer-edit' : 'opportunityEditModal', 'Editar Oportunidad', 'Actualiza los datos comerciales de la cuenta', $formEditHtml, $footerEdit, $isModal);

// 2. LAYER DOCUMENTO
$footerDoc = '
<div class="modal-footer-actions-right" style="width: 100%; justify-content: flex-end;">
    <button type="button" class="btn btn-outline" onclick="' . ($isModal ? "window.switchOppLayer('layer-main')" : "window.closeStandardModal('documentModal')") . '"><i data-lucide="x"></i><span>Cancelar</span></button>
    <button type="submit" form="form-document" class="btn btn-primary"><i data-lucide="upload"></i><span>Subir<span class="mobile-hidden"> Documento</span></span></button>
</div>';
render_form_layer($isModal ? 'layer-doc' : 'documentModal', 'Adjuntar Documento', 'Sube PDFs relacionados a la oportunidad', $formDocHtml, $footerDoc, $isModal);

// 3. LAYER ACTIVIDAD
$footerAct = '
<div class="modal-footer-actions-right" style="width: 100%; justify-content: flex-end;">
    <button type="button" class="btn btn-outline" onclick="' . ($isModal ? "window.switchOppLayer('layer-main')" : "window.closeStandardModal('activityModal')") . '"><i data-lucide="x"></i><span>Cancelar</span></button>
    <button type="submit" form="form-activity" class="btn btn-primary"><i data-lucide="save"></i><span>Guardar<span class="mobile-hidden"> Actividad</span></span></button>
</div>';
render_form_layer($isModal ? 'layer-act' : 'activityModal', 'Agregar Actividad', 'Registra una interacción o estado', $formActHtml, $footerAct, $isModal);

// 4. LAYER COTIZACION (CREAR Y EDITAR) - Homologado al nuevo footer
$footerQuote = '
<div class="modal-footer-actions-left" style="display: flex; align-items: center;" id="quote-delete-container">
    <form id="form-delete-quote" action="/modules/crm/quote_delete.php" method="POST" data-no-spa="true" style="margin:0;">
        <input type="hidden" name="id" id="delete-quote-id" value="">
        <button type="submit" class="btn btn-outline btn-delete-mobile" style="color: var(--color-error); border-color: var(--color-error);" title="Eliminar Cotización">
            <i data-lucide="trash-2"></i> <span class="mobile-hidden" style="margin-left: 6px;">Eliminar</span>
        </button>
    </form>
</div>
<div class="modal-footer-actions-right" style="flex: 1; justify-content: flex-end;">
    <button type="button" class="btn btn-outline" onclick="' . ($isModal ? "window.switchOppLayer('layer-main')" : "window.closeStandardModal('quoteModal')") . '"><i data-lucide="x"></i><span>Cancelar</span></button>
    <button type="button" class="btn btn-primary" id="modalDirectSaveBtn" onclick="window.submitQuoteDirect()" disabled><i data-lucide="save"></i><span id="modalDirectSaveBtnText" style="margin-left:6px;">Guardar</span></button>
</div>';
render_form_layer($isModal ? 'layer-quote' : 'quoteModal', 'Generar Cotización Oficial', 'Construye una propuesta formal', $formQuoteHtml, $footerQuote, $isModal);

// 5. LAYER VISTA COTIZACION
$footerQuoteView = '
<div class="modal-footer-actions-right" style="width: 100%; justify-content: flex-end;">
    <a href="#" id="viewQuotePdfBtn" target="_blank" class="btn btn-outline"><i data-lucide="file-text"></i><span>Ver PDF</span></a>
    <a href="#" id="viewQuoteWaBtn" target="_blank" class="btn btn-outline" style="color: #25D366; border-color: #25D366;"><i data-lucide="message-circle"></i><span>WhatsApp</span></a>
    <a href="#" id="viewQuoteMailBtn" target="_blank" class="btn btn-outline"><i data-lucide="mail"></i><span>Email</span></a>
    <button type="button" class="btn btn-primary" id="viewQuoteBillingBtn" style="display:none;"><i data-lucide="receipt"></i><span>Facturar</span></button>
    <button type="button" class="btn btn-outline" id="viewQuoteEditBtn"><i data-lucide="pencil"></i><span>Editar</span></button>
</div>';
render_form_layer($isModal ? 'layer-quote-view' : 'quoteViewModal', 'Detalle de Cotización', 'Visualiza y comparte el documento', $formQuoteViewHtml, $footerQuoteView, $isModal);
?>

<script>
(function() {
    if(window.lucide) window.lucide.createIcons();
    
    // =========================================================================
    // INYECCIÓN DE DATOS PHP PARA EL SPA
    // =========================================================================
    window.oppQuotesData = <?php echo json_encode($oppQuotes); ?>;
    window.oppCanUseBilling = <?php echo $hasBillingAccess ? 'true' : 'false'; ?>;
    window.oppQuoteItemsData = <?php echo json_encode($oppQuoteItems); ?>;
    
    window.oppContext = {
        customerName: <?php echo json_encode($opportunityLegalName, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); ?>,
        customerDisplayName: <?php echo json_encode($opportunityDisplayName, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); ?>,
        customerTaxId: <?php echo json_encode(format_rut($opportunityTaxId), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); ?>,
        ownerName: <?php echo json_encode($opportunity['owner_name'], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); ?>,
        email: <?php echo json_encode($custEmail, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); ?>,
        phone: <?php echo json_encode($custPhone, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); ?>
    };


    window.toggleOpportunityArchiveHold = function(opportunityId, isHeld) {
        var holdAction = isHeld ? 'release' : 'hold';
        var reason = '';
        var until = '';
        if (isHeld) {
            if (!window.confirm('¿Reactivar el archivo automático de esta oportunidad facturada?')) return;
        } else {
            reason = window.prompt('Motivo para pausar el archivo mensual (reclamo, nota de crédito, corrección u otro):', '') || '';
            reason = reason.trim();
            if (!reason) return;
            until = window.prompt('Fecha de revisión opcional (AAAA-MM-DD). Déjalo vacío para mantener la pausa hasta liberarla manualmente:', '') || '';
            until = until.trim();
        }
        var formData = new FormData();
        formData.append('_csrf_token', <?php echo json_encode(csrf_token(), JSON_UNESCAPED_SLASHES); ?>);
        formData.append('id', opportunityId);
        formData.append('hold_action', holdAction);
        formData.append('reason', reason);
        formData.append('until', until);
        fetch('/modules/crm/opportunity_archive_hold.php', { method: 'POST', body: formData })
            .then(function(response) { return response.json().then(function(data) { return { ok: response.ok, data: data }; }); })
            .then(function(result) {
                if (!result.ok || !result.data.success) throw new Error(result.data.error || 'No fue posible actualizar el archivo mensual.');
                if (window.ICY_SPA_CLEAR_CACHE) window.ICY_SPA_CLEAR_CACHE();
                var modal = document.getElementById('oppViewModalBackdrop');
                if (modal) {
                    modal.remove();
                    window.ICY_OPEN_OPPORTUNITY_MODAL(null, opportunityId);
                } else if (window.ICY_SPA_RELOAD) {
                    window.ICY_SPA_RELOAD({ force: true });
                } else {
                    window.location.reload();
                }
            })
            .catch(function(error) { window.alert(error.message); });
    };

    // 🔥 FIX: Interceptamos la eliminación con un Listener ultra-específico y deteniendo la propagación
    const deleteForm = document.getElementById('form-delete-opportunity');
    if (deleteForm && !deleteForm.dataset.customDeleteAttached) {
        deleteForm.addEventListener('submit', function(e) {
            e.preventDefault();
            e.stopImmediatePropagation(); 
            
            if (!confirm('¿Estás seguro de eliminar esta oportunidad y todo su historial?')) return;
            
            const btn = deleteForm.querySelector('button[type="submit"]');
            const originalHtml = btn ? btn.innerHTML : '';
            if(btn) {
                btn.disabled = true;
                btn.innerHTML = '<i data-lucide="loader" class="spin-icon"></i>';
                if(window.lucide) window.lucide.createIcons();
            }

            const formData = new FormData(this);
            formData.append('ajax', '1'); 

            fetch(this.action, {
                method: 'POST',
                body: formData
            })
            .then(res => res.json())
            .then(data => {
                if (data.success) {
                    if (window.ICY_SPA_CLEAR_CACHE) window.ICY_SPA_CLEAR_CACHE();
                    const backdrop = document.getElementById('oppViewModalBackdrop');
                    if (backdrop) backdrop.remove();
                    
                    const oppId = formData.get('id');
                    const card = document.querySelector(`.crm-opportunity-card[data-id="${oppId}"]`);
                    if (card) {
                        card.remove();
                        if (typeof window.updateColumnCounts === 'function') {
                            window.updateColumnCounts();
                        }
                    } else {
                        (window.ICY_SPA_RELOAD ? window.ICY_SPA_RELOAD({ force: true }) : window.location.reload());
                    }
                } else {
                    alert('Error: ' + (data.error || 'Desconocido'));
                    if(btn) { btn.disabled = false; btn.innerHTML = originalHtml; if(window.lucide) window.lucide.createIcons(); }
                }
            })
            .catch(err => { 
                alert('Error al eliminar: ' + err); 
                if(btn) { btn.disabled = false; btn.innerHTML = originalHtml; if(window.lucide) window.lucide.createIcons(); }
            });
        });
        deleteForm.dataset.customDeleteAttached = 'true';
    }

    // 🔥 Interceptamos el formulario de Edición para guardado silencioso y actualización en tiempo real (SPA)
    const editForm = document.getElementById('form-edit-opportunity');
    if (editForm && !editForm.dataset.customEditAttached) {
        editForm.addEventListener('submit', function(e) {
            e.preventDefault();
            e.stopImmediatePropagation();
            
            const btn = editForm.querySelector('button[type="submit"]');
            const originalHtml = btn ? btn.innerHTML : '';
            if(btn) {
                btn.disabled = true;
                btn.innerHTML = '<i data-lucide="loader" class="spin-icon"></i>';
                if(window.lucide) window.lucide.createIcons();
            }

            const formData = new FormData(this);
            formData.append('ajax', '1'); 

            fetch(this.action, {
                method: 'POST',
                body: formData
            })
            .then(res => res.json())
            .then(data => {
                if (data.success) {
                    if (window.ICY_SPA_CLEAR_CACHE) window.ICY_SPA_CLEAR_CACHE();
                    const oppId = formData.get('id');
                    const titleVal = formData.get('title');
                    const stageVal = formData.get('stage');
                    const paymentStatusVal = formData.get('payment_status');
                    const paymentDueDateVal = formData.get('payment_due_date');
                    const paymentPaidDateVal = formData.get('payment_paid_date');
                    const ownerNameVal = formData.get('owner_name') || 'Sistema';
                    const sourceVal = formData.get('source') || 'Sin origen';
                    const competitorVal = formData.get('competitor') || 'No identificado';
                    const expectedValueVal = parseFloat(formData.get('expected_value')) || 0;
                    const probabilityVal = parseInt(formData.get('probability')) || 0;
                    const expectedCloseDateVal = formData.get('expected_close_date');
                    const nextActionVal = formData.get('next_action');
                    const nextActionDateVal = formData.get('next_action_date');
                    const notesVal = formData.get('notes');

                    const stageLabels = { 'nuevo': 'Nuevo', 'contactado': 'Contactado', 'cotizando': 'Cotizando', 'negociacion': 'Negociación', 'ganada': 'Ganada', 'perdida': 'Perdida', 'facturada': 'Facturada' };
                    const paymentLabels = { 'no_facturado': 'No facturado', 'por_cobrar': 'Por cobrar', 'pagado': 'Pagado', 'atrasado': 'Atrasado', 'incobrable': 'Incobrable' };
                    const fmtDate = (d) => { if (!d) return 'Sin fecha'; const parts = d.split('-'); return parts.length === 3 ? `${parts[2]}-${parts[1]}-${parts[0]}` : d; };

                    const isModalView = document.getElementById('oppViewModalBackdrop') !== null;
                    
                    if (isModalView) {
                        const h2ModalTitle = document.querySelector('#oppViewModalBackdrop #layer-main .product-modal-header h2');
                        if (h2ModalTitle) h2ModalTitle.innerText = titleVal;
                        
                        const embudoCardTitle = document.querySelector(`.crm-opportunity-card[data-id="${oppId}"] strong, .crm-opportunity-card[data-id="${oppId}"] h4`);
                        if (embudoCardTitle) embudoCardTitle.innerText = titleVal;
                    } else {
                        const h1Title = document.querySelector('.page-header-content h1');
                        if (h1Title) h1Title.innerText = titleVal;
                    }

                    if (data.new_activity_html) {
                        const timelineContainer = isModalView 
                            ? document.querySelector('#oppViewModalBackdrop .crm-timeline') 
                            : document.querySelector('.layout-timeline .crm-timeline');
                            
                        if (timelineContainer) {
                            const emptyState = timelineContainer.querySelector('p.text-secondary');
                            if (emptyState && emptyState.innerText.includes('Sin actividad')) emptyState.remove();
                            timelineContainer.insertAdjacentHTML('afterbegin', data.new_activity_html);
                        }
                    }

                    const updateMetricRow = (label, htmlContent) => {
                        const rows = document.querySelectorAll('.layout-detalle .metric-row');
                        for (let row of rows) {
                            const span = row.querySelector('span');
                            if (span && span.innerText.trim().toLowerCase() === label.toLowerCase()) {
                                const strong = row.querySelector('.metric-value');
                                if (strong) strong.innerHTML = htmlContent;
                                return;
                            }
                        }
                    };

                    const kpiValues = document.querySelectorAll('.responsive-kpis .kpi-value');
                    if (kpiValues.length >= 4) {
                        kpiValues[0].innerText = window.fmtCLP ? window.fmtCLP(expectedValueVal) : '$ ' + Math.round(expectedValueVal);
                        kpiValues[1].innerText = probabilityVal + '%';
                        kpiValues[2].innerText = fmtDate(expectedCloseDateVal);
                        kpiValues[3].innerText = nextActionVal || 'Sin acción';
                    }
                    const kpiContext = document.querySelector('.responsive-kpis .kpi-context');
                    if (kpiContext) kpiContext.innerText = fmtDate(nextActionDateVal);

                    updateMetricRow('Responsable', ownerNameVal);
                    updateMetricRow('Origen', sourceVal);
                    updateMetricRow('Competidor', competitorVal);
                    updateMetricRow('Vencimiento pago', fmtDate(paymentDueDateVal));
                    updateMetricRow('Fecha de pago', paymentPaidDateVal ? fmtDate(paymentPaidDateVal) : 'Sin pago');

                    const stageBadge = document.querySelector('.layout-detalle .card-header .badge');
                    if (stageBadge) stageBadge.innerText = stageLabels[stageVal] || stageVal;

                    updateMetricRow('Cobranza', `<span class="badge payment-badge payment-${paymentStatusVal}">${paymentLabels[paymentStatusVal] || paymentStatusVal}</span>`);

                    window.switchOppLayer('layer-main');
                } else {
                    let errorMsg = 'Error al procesar la oportunidad.';
                    if (data.errors) {
                        errorMsg = Object.values(data.errors).join('\n');
                    }
                    alert(errorMsg);
                }
            })
            .catch(err => { 
                alert('Ocurrió un error de conexión con el servidor.'); 
                console.error(err);
            })
            .finally(() => {
                if(btn) { 
                    btn.disabled = false; 
                    btn.innerHTML = originalHtml; 
                    if(window.lucide) window.lucide.createIcons(); 
                }
            });
        });
        editForm.dataset.customEditAttached = 'true';
    }
    
    // 🔥 NUEVO: Interceptar formulario de Actividad para guardado por AJAX
    const activityForm = document.getElementById('form-activity');
    if (activityForm && !activityForm.dataset.customAttached) {
        activityForm.addEventListener('submit', function(e) {
            e.preventDefault();
            e.stopImmediatePropagation();
            
            const btn = this.querySelector('button[type="submit"]');
            const originalHtml = btn ? btn.innerHTML : '';
            if(btn) {
                btn.disabled = true;
                btn.innerHTML = '<i data-lucide="loader" class="spin-icon"></i>';
                if(window.lucide) window.lucide.createIcons();
            }

            const formData = new FormData(this);
            formData.append('ajax', '1');

            fetch(this.action, {
                method: 'POST',
                body: formData
            })
            .then(res => res.json())
            .then(data => {
                if (data.success) {
                    if (window.ICY_SPA_CLEAR_CACHE) window.ICY_SPA_CLEAR_CACHE();
                    const isModalView = document.getElementById('oppViewModalBackdrop') !== null;
                    const timelineContainer = isModalView 
                        ? document.querySelector('#oppViewModalBackdrop .crm-timeline') 
                        : document.querySelector('.layout-timeline .crm-timeline');
                        
                    if (timelineContainer) {
                        const emptyState = timelineContainer.querySelector('p.text-secondary');
                        if (emptyState && emptyState.innerText.includes('Sin actividad')) emptyState.remove();

                        if (data.new_activity_html) {
                            timelineContainer.insertAdjacentHTML('afterbegin', data.new_activity_html);
                        } else {
                            const aType = formData.get('activity_type');
                            const aTitle = formData.get('title');
                            const aDesc = formData.get('description');
                            const aDateRaw = formData.get('activity_date');
                            const aDate = aDateRaw ? aDateRaw.replace('T', ' ') : 'Recién';
                            const aOwner = formData.get('owner_name');
                            
                            const fallbackHtml = `
                                <div class="crm-timeline-item">
                                    <span class="crm-timeline-dot ${aType}"></span>
                                    <div>
                                        <strong>${aTitle}</strong>
                                        ${aDesc ? `<p class="text-secondary text-sm" style="margin-top: 4px;">${aDesc.replace(/\\n/g, '<br>')}</p>` : ''}
                                        <span class="text-muted text-sm" style="margin-top: 4px; display: block;">${aDate}${aOwner ? ' · ' + aOwner : ''}</span>
                                    </div>
                                </div>`;
                            timelineContainer.insertAdjacentHTML('afterbegin', fallbackHtml);
                        }
                    }
                    
                    this.reset(); 
                    if (isModalView) {
                        window.switchOppLayer('layer-main');
                    } else {
                        window.closeStandardModal('activityModal');
                    }
                } else {
                    let errorMsg = 'Error al guardar la actividad.';
                    if (data.errors) errorMsg = Object.values(data.errors).join('\\n');
                    alert(errorMsg);
                }
            })
            .catch(err => { 
                console.error(err); 
                alert('Error de conexión al guardar la actividad.'); 
            })
            .finally(() => {
                if(btn) { btn.disabled = false; btn.innerHTML = originalHtml; if(window.lucide) window.lucide.createIcons(); }
            });
        });
        activityForm.dataset.customAttached = 'true';
    }

    // 🔥 NUEVO: Interceptar formulario de Documento para guardado por AJAX
    const docForm = document.getElementById('form-document');
    if (docForm && !docForm.dataset.customAttached) {
        docForm.addEventListener('submit', function(e) {
            e.preventDefault();
            e.stopImmediatePropagation();
            
            const btn = this.querySelector('button[type="submit"]');
            const originalHtml = btn ? btn.innerHTML : '';
            if(btn) {
                btn.disabled = true;
                btn.innerHTML = '<i data-lucide="loader" class="spin-icon"></i>';
                if(window.lucide) window.lucide.createIcons();
            }

            const formData = new FormData(this);
            formData.append('ajax', '1');

            fetch(this.action, {
                method: 'POST',
                body: formData
            })
            .then(res => res.json())
            .then(data => {
                if (data.success) {
                    if (window.ICY_SPA_CLEAR_CACHE) window.ICY_SPA_CLEAR_CACHE();
                    const tbody = document.querySelector('.layout-docs table tbody');
                    if (tbody) {
                        const emptyState = tbody.querySelector('.empty-state-row');
                        if (emptyState) emptyState.remove();

                        if (data.new_document_html) {
                            tbody.insertAdjacentHTML('afterbegin', data.new_document_html);
                        } else {
                            const dName = formData.get('document_name');
                            const dType = formData.get('document_type');
                            const dNum = formData.get('document_number');
                            const dTotal = parseFloat(formData.get('total_amount') || 0);
                            const fTotal = dTotal > 0 ? '$ ' + Math.round(dTotal).toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ".") : '$ 0';
                            
                            const dDateRaw = formData.get('document_date');
                            const dDate = dDateRaw ? dDateRaw.split('-').reverse().join('-') : 'Hoy';
                            
                            const linkHtml = data.file_path
                                ? `<a class="btn btn-sm btn-outline action-icon-btn" href="${data.file_path}" target="_blank" rel="noopener" data-no-spa="true" title="Ver documento"><i data-lucide="eye"></i></a>`
                                : '<span class="text-muted">—</span>';
                                
                            const tr = document.createElement('tr');
                            tr.innerHTML = `
                                <td data-label="Documento">
                                    <div class="cell-value">
                                        <div class="doc-main-title" style="font-weight: 600; color: var(--text-primary);">${dName}</div>
                                        <small class="text-secondary" style="font-size: 0.75rem; display: block; margin-top: 2px;">${dType.toUpperCase()} ${dNum ? 'Nº ' + dNum : ''}</small>
                                    </div>
                                </td>
                                <td data-label="Estado"><div class="cell-value"><span class="text-muted">—</span></div></td>
                                <td data-label="Fecha"><div class="cell-value"><span class="text-sm">${dDate}</span></div></td>
                                <td data-label="Total"><div class="cell-value"><strong style="color: var(--color-success); font-size: 14px;">${fTotal}</strong></div></td>
                                <td class="actions-cell-align" data-label="Acciones">
                                    <div class="cluster actions-btn-group">${linkHtml}</div>
                                </td>
                            `;
                            tbody.insertBefore(tr, tbody.firstChild);
                        }
                    }
                    
                    this.reset();
                    
                    const isModalView = document.getElementById('oppViewModalBackdrop') !== null;
                    if (isModalView) {
                        window.switchOppLayer('layer-main');
                    } else {
                        window.closeStandardModal('documentModal');
                    }
                } else {
                    let errorMsg = 'Error al subir el documento.';
                    if (data.errors) errorMsg = Object.values(data.errors).join('\\n');
                    alert(errorMsg);
                }
            })
            .catch(err => { 
                console.error(err); 
                alert('Error de conexión al subir el documento.'); 
            })
            .finally(() => {
                if(btn) { btn.disabled = false; btn.innerHTML = originalHtml; if(window.lucide) window.lucide.createIcons(); }
            });
        });
        docForm.dataset.customAttached = 'true';
    }

    window.approveQuote = function(quoteId, buttonElement) {
        if (!confirm('¿Confirmas que deseas marcar esta cotización como ACEPTADA?')) return;
        buttonElement.disabled = true;
        var formData = new FormData();
        formData.append('quote_id', quoteId);
        formData.append('status', 'Aceptada');
        formData.append('opportunity_id', '<?php echo $id; ?>');
        formData.append('customer_id', '<?php echo (int)$opportunity['customer_id']; ?>');
        formData.append('items', 'dummy'); 
        fetch('/modules/crm/quote_store.php', { method: 'POST', body: formData })
        .then(() => (window.ICY_SPA_RELOAD ? window.ICY_SPA_RELOAD({ force: true }) : window.location.reload()))
        .catch(err => { alert('Error: ' + err); buttonElement.disabled = false; });
    };

    window.switchOppLayer = function(layerId) {
        document.querySelectorAll('.opp-view-layer').forEach(el => el.classList.remove('active'));
    
        const target = document.getElementById(layerId);
    
        if (target) {
            target.classList.add('active');
    
            const body = target.querySelector('.product-modal-body');
            if (body) body.scrollTop = 0;
        }
    
        if (window.lucide) window.lucide.createIcons();
    };

    window.openStandardModal = function(modalId) {
        var m = document.getElementById(modalId);
        if(m) { 
            if (modalId === 'documentModal') document.getElementById('form-document').reset();
            if (modalId === 'activityModal') document.getElementById('form-activity').reset();
            m.style.display = 'flex'; 
            setTimeout(() => m.classList.add('show'), 10); 
        }
    };
    
    window.closeStandardModal = function(modalId) {
        var m = document.getElementById(modalId);
        if(m) { m.classList.remove('show'); setTimeout(() => m.style.display = 'none', 200); }
    };

    if (!window.__oppModalListenerAttached) {
        document.addEventListener('click', (e) => { 
            if(e.target.classList.contains('product-modal-backdrop')) {
                if(e.target.id === 'oppViewModalBackdrop') e.target.remove();
                else window.closeStandardModal(e.target.id);
            }
        });
        window.__oppModalListenerAttached = true;
    }

    // =========================================================================
    // LÓGICA DE CONTROL DE COTIZACIONES (HOMOLOGADA)
    // =========================================================================
    
    window.openQuoteCreateLayer = function() {
        document.getElementById('form-quote-modal').reset();
        document.getElementById('modalQuoteId').value = "0";
        document.getElementById('modalDiscountPercent').value = 0;
        document.getElementById('modalDirectSaveBtnText').innerText = "Crear";
        
        var delContainer = document.getElementById('quote-delete-container');
        if(delContainer) delContainer.style.display = 'none';

        window.initQuoteBuilder(null);
        window.switchOppLayer('layer-quote');
    };

    window.openQuoteEditLayer = function(qId) {
        const quote = window.oppQuotesData.find(q => q.id == qId);
        const items = window.oppQuoteItemsData[qId] || [];
        
        if(!quote) return;
        
        document.getElementById('modalQuoteId').value = quote.id;
        document.getElementById('modalQuoteStatus').value = quote.status || 'Borrador';
        document.querySelector('#form-quote-modal textarea[name="notes"]').value = quote.notes || '';
        document.getElementById('modalDiscountPercent').value = quote.discount_percent || 0;
        document.getElementById('modalDirectSaveBtnText').innerText = "Guardar";
        
        var delQuoteInput = document.getElementById('delete-quote-id');
        if(delQuoteInput) delQuoteInput.value = quote.id;
        
        var delContainer = document.getElementById('quote-delete-container');
        if(delContainer) delContainer.style.display = 'flex';
        
        window.initQuoteBuilder(items);
        window.switchOppLayer('layer-quote');
    };

    window.submitQuoteDirect = function() {
        const form = document.getElementById('form-quote-modal');
        const btn = document.getElementById('modalDirectSaveBtn');
        const originalHtml = btn.innerHTML;
        
        btn.disabled = true;
        btn.innerHTML = '<i data-lucide="loader" class="spin-icon"></i>';
        if(window.lucide) lucide.createIcons();

        const fd = new FormData(form);
        fd.append('ajax', '1');

        fetch('/modules/crm/quote_store.php', {
            method: 'POST',
            body: fd
        })
        .then(res => res.json())
        .then(data => {
            if(data.success) {
                (window.ICY_SPA_RELOAD ? window.ICY_SPA_RELOAD({ force: true }) : window.location.reload()); 
            } else {
                alert('Error: ' + (data.error || 'Ocurrió un problema en la base de datos.'));
                btn.disabled = false; btn.innerHTML = originalHtml;
                if(window.lucide) window.lucide.createIcons();
            }
        })
        .catch(err => {
            console.error(err);
            alert('Error de conexión al servidor.');
            btn.disabled = false; btn.innerHTML = originalHtml;
            if(window.lucide) window.lucide.createIcons();
        });
    };

    function oppEsc(value) {
        return String(value ?? '').replace(/[&<>"']/g, function (m) {
            return {'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#039;'}[m];
        });
    }

    function oppBadgeClass(status) {
        if (['Aceptada', 'Pagada'].includes(status)) return 'badge-success';
        if (['Enviada', 'Facturada', 'Esperando pago'].includes(status)) return 'badge-warning';
        if (['Rechazada', 'Vencida', 'Anulada'].includes(status)) return 'badge-error';
        return '';
    }

    function oppNetAmount(quote) {
        return Number(quote.subtotal || 0) - Number(quote.discount_amount || 0);
    }

    function oppFormatDate(value) {
        const raw = String(value || '').split(' ')[0];
        return raw ? raw.split('-').reverse().join('-') : '—';
    }

    function oppCleanItem(item) {
        let name = String(item.name || '');
        let sku = item.sku || '';
        const match = name.match(/\s*\(SKU:\s*([^)]*)\)\s*$/i);
        if (match) {
            sku = match[1];
            name = name.replace(/\s*\(SKU:\s*[^)]*\)\s*$/i, '');
        }
        return { name: name, sku: sku || '—' };
    }

    function renderOppQuotePreviewDoc(quote, items) {
        const rows = (items || []).map(function (item) {
            const clean = oppCleanItem(item);
            return `<tr>
                <td class="quote-doc-sku"><span class="mono">${oppEsc(clean.sku)}</span></td>
                <td class="quote-doc-product"><strong>${oppEsc(clean.name)}</strong><small>${oppEsc(clean.sku)}</small></td>
                <td class="text-right quote-doc-qty">${oppEsc(item.quantity || 1)}${item.unit ? ' ' + oppEsc(item.unit) : ''}</td>
                <td class="text-right quote-doc-price">${window.fmtCLP(item.price_unit || 0)}</td>
                <td class="text-right quote-doc-total"><strong>${window.fmtCLP(item.total_item || (Number(item.quantity || 0) * Number(item.price_unit || 0)))}</strong></td>
            </tr>`;
        }).join('');

        return `<article class="quote-doc">
            <div class="quote-doc-head">
                <h2>Cotización ${oppEsc(quote.quote_number || 'S/N')}</h2>
                <span class="badge ${oppBadgeClass(quote.status)}">${oppEsc(String(quote.status || 'Borrador').toUpperCase())}</span>
            </div>
            <div class="quote-doc-grid">
                <div class="quote-doc-cell"><span class="quote-doc-label">Razón social</span><strong class="quote-doc-value">${oppEsc(window.oppContext.customerName || '')}</strong></div>
                <div class="quote-doc-cell"><span class="quote-doc-label">Fecha</span><span class="quote-doc-value">${oppEsc(oppFormatDate(quote.created_at))}</span></div>
                <div class="quote-doc-cell"><span class="quote-doc-label">R.U.T.</span><span class="quote-doc-value">${oppEsc(window.oppContext.customerTaxId || '—')}</span></div>
                <div class="quote-doc-cell"><span class="quote-doc-label">Email cliente</span><span class="quote-doc-value">${oppEsc(window.oppContext.email || 'Sin email')}</span></div>
                <div class="quote-doc-cell"><span class="quote-doc-label">Teléfono</span><span class="quote-doc-value">${oppEsc(window.oppContext.phone || 'Sin teléfono')}</span></div>
                <div class="quote-doc-cell"><span class="quote-doc-label">Vendedor</span><span class="quote-doc-value">${oppEsc(window.oppContext.ownerName || 'Sistema')}</span></div>
            </div>
            <table class="quote-doc-table">
                <thead><tr><th class="quote-doc-sku-head">SKU</th><th>Glosa / Descripción</th><th class="text-right">Cant.</th><th class="text-right">Prc. Unit</th><th class="text-right">Monto</th></tr></thead>
                <tbody>${rows || '<tr><td colspan="5">Sin productos asociados.</td></tr>'}</tbody>
            </table>
            <div class="quote-doc-bottom">
                <div><span class="quote-doc-label">Condiciones comerciales</span><div class="quote-doc-conditions">${oppEsc(quote.notes || 'Sin condiciones comerciales adicionales especificadas.')}</div></div>
                <div class="quote-doc-totalbox">
                    <div><span>Subtotal Bruto:</span><strong>${window.fmtCLP(quote.subtotal || 0)}</strong></div>
                    <div><span>Monto Neto:</span><strong>${window.fmtCLP(oppNetAmount(quote))}</strong></div>
                    <div><span>Monto Exento:</span><strong>${window.fmtCLP(0)}</strong></div>
                    <div><span>IVA (19%):</span><strong>${window.fmtCLP(quote.iva || 0)}</strong></div>
                    <hr>
                    <div class="grand"><span>Total General:</span><strong>${window.fmtCLP(quote.total || 0)}</strong></div>
                </div>
            </div>
        </article>`;
    }

    window.openQuoteViewLayer = function(qId) {
        const quote = window.oppQuotesData.find(q => q.id == qId);
        const items = window.oppQuoteItemsData[qId] || [];
        if(!quote) return;

        const target = document.getElementById('oppQuotePreviewDocument');
        if (target) target.innerHTML = renderOppQuotePreviewDoc(quote, items);

        const publicUrl = `${window.location.origin}/modules/crm/quote_view.php?id=${qId}`;
        const pdfBtn = document.getElementById('viewQuotePdfBtn');
        if (pdfBtn) pdfBtn.href = publicUrl;

        const editBtn = document.getElementById('viewQuoteEditBtn');
        if (editBtn) editBtn.onclick = () => window.openQuoteEditLayer(qId);

        const billingBtn = document.getElementById('viewQuoteBillingBtn');
        if (billingBtn) {
            const billingStatuses = ['Aceptada', 'Facturada', 'Esperando pago', 'Pagada'];
            const canBill = window.oppCanUseBilling && billingStatuses.includes(String(quote.status || ''));
            billingBtn.style.display = canBill ? 'inline-flex' : 'none';
            const billingLabel = billingBtn.querySelector('span');
            if (billingLabel) billingLabel.textContent = String(quote.facto_document_id || quote.invoice_number || '').trim() ? 'Ver facturaciÃ³n' : 'Facturar';
            billingBtn.onclick = canBill ? function () {
                const billingUrl = '/modules/crm/quotes.php?billing_quote_id=' + encodeURIComponent(qId) + '&from=opportunity';
                if (typeof window.ICY_SPA_GO === 'function') window.ICY_SPA_GO(billingUrl, { force: true });
                else window.location.href = billingUrl;
            } : null;
        }

        const waBtn = document.getElementById('viewQuoteWaBtn');
        if (waBtn) {
            if (window.oppContext.phone) {
                waBtn.href = `https://wa.me/${window.oppContext.phone}?text=${encodeURIComponent('Hola, te comparto la cotización ' + (quote.quote_number || '') + ' de ICYLAB por ' + window.fmtCLP(quote.total || 0) + ': ' + publicUrl)}`;
                waBtn.style.display = 'inline-flex';
            } else {
                waBtn.style.display = 'none';
            }
        }

        const mailBtn = document.getElementById('viewQuoteMailBtn');
        if (mailBtn) {
            if (window.oppContext.email) {
                mailBtn.href = `mailto:${window.oppContext.email}?subject=${encodeURIComponent('Cotización ICYLAB ' + (quote.quote_number || ''))}&body=${encodeURIComponent('Hola, te comparto la cotización correspondiente: ' + publicUrl)}`;
                mailBtn.style.display = 'inline-flex';
            } else {
                mailBtn.style.display = 'none';
            }
        }

        window.switchOppLayer('layer-quote-view');
    };

    // =========================================================================
    // MOTOR DE ELIMINACIÓN DE COTIZACIÓN (AJAX)
    // =========================================================================
    const deleteQuoteForm = document.getElementById('form-delete-quote');
    if (deleteQuoteForm) {
        deleteQuoteForm.onsubmit = function(e) {
            e.preventDefault();
            e.stopImmediatePropagation();
            
            if (!confirm('⚠️ ATENCIÓN:\n\n¿Estás seguro de eliminar esta cotización?\nEsta acción ocultará la cotización, conservando cabecera, productos e historial.')) return;
            
            const btn = this.querySelector('button[type="submit"]');
            const originalHtml = btn.innerHTML;
            btn.disabled = true; 
            btn.innerHTML = '<i data-lucide="loader" class="spin-icon"></i>';
            if(window.lucide) lucide.createIcons();

            const fd = new FormData(this);
            fd.append('ajax', '1');

            fetch(this.action, { method: 'POST', body: fd })
            .then(r => r.json())
            .then(d => {
                if(d.success) {
                    (window.ICY_SPA_RELOAD ? window.ICY_SPA_RELOAD({ force: true }) : window.location.reload()); 
                } else {
                    alert('Error: ' + (d.error || 'Desconocido'));
                    btn.disabled = false; btn.innerHTML = originalHtml;
                    if(window.lucide) lucide.createIcons();
                }
            })
            .catch(err => {
                alert('Error de conexión al intentar eliminar.');
                btn.disabled = false; btn.innerHTML = originalHtml;
                if(window.lucide) lucide.createIcons();
            });
        };
    }

    // =========================================================================
    // CONSTRUCTOR INTELIGENTE DE FILAS DEL COTIZADOR (HOMOLOGADO A QUOTES.PHP)
    // =========================================================================
    window.fmtCLP = function(value) { return '$ ' + Math.round(value).toString().replace(/\B(?=(\d{3})+(?!\d))/g, "."); }

    window.initQuoteBuilder = function(preloadItems) {
        var mContainer = document.getElementById('modalItemsContainer');
        var mAddBtn = document.getElementById('modalAddRowBtn');
        var mDiscountInput = document.getElementById('modalDiscountPercent');
        
        if(!mContainer || !mAddBtn) return;
        
        window.__mRowIndex = 0;
        mContainer.innerHTML = '';

        function calcTotals() {
            var sub = 0;
            mContainer.querySelectorAll('.eq-row').forEach(function(row) {
                var q = parseFloat(row.querySelector('.it-qty').value) || 0;
                var p = parseFloat(row.querySelector('.it-price').value) || 0;
                var tot = q * p;
                row.querySelector('.it-total-text').innerText = window.fmtCLP(tot);
                sub += tot;
            });
            var dp = parseFloat(mDiscountInput ? mDiscountInput.value : 0) || 0;
            var da = sub * (dp / 100);
            var net = sub - da;
            
            var discRow = document.getElementById('modalDiscountRow');
            if(discRow) discRow.style.display = da > 0 ? 'flex' : 'none';
            
            var sumDisc = document.getElementById('modalSummaryDiscount');
            if(sumDisc) sumDisc.innerText = '- ' + window.fmtCLP(da);
            
            var sumSub = document.getElementById('modalSummarySubtotal');
            if(sumSub) sumSub.innerText = window.fmtCLP(sub);
            
            var sumIva = document.getElementById('modalSummaryIva');
            if(sumIva) sumIva.innerText = window.fmtCLP(net * 0.19);
            
            var sumTot = document.getElementById('modalSummaryTotal');
            if(sumTot) sumTot.innerText = window.fmtCLP(net * 1.19);
            
            var directBtn = document.getElementById('modalDirectSaveBtn');
            if(directBtn) directBtn.disabled = (sub <= 0);
        }

        var modalQuoteUnitOptions = ['unidad', 'mL', 'L', 'g', 'kg', 'pack', 'caja', 'servicio'];
        function modalCleanQuoteUnit(value) { return modalQuoteUnitOptions.indexOf(String(value || '').trim()) !== -1 ? String(value).trim() : 'unidad'; }
        function modalUnitSelectHtml(index, value) {
            var current = modalCleanQuoteUnit(value);
            return '<select name="items[' + index + '][unit]" class="input it-unit" style="width:100% !important;">' + modalQuoteUnitOptions.map(function(unit) {
                return '<option value="' + unit + '"' + (unit === current ? ' selected' : '') + '>' + unit + '</option>';
            }).join('') + '</select>';
        }

        function mAddRow(data) {
            var row = document.createElement('div');
            row.className = 'eq-row';
            row.style.cssText = "display: grid; grid-template-columns: 2.5fr 1fr 0.8fr 1fr 1.2fr 1.2fr 40px; gap: 12px; align-items: center;";
            
            row.innerHTML = `
                <div class="eq-col-prod"><span class="mobile-label">Buscar Producto</span><div style="position:relative; width:100%; display:block;"><input type="text" class="input it-name" placeholder="Escribe para buscar..." value="${data ? data.name : ''}" autocomplete="off" style="width:100% !important;"><input type="hidden" name="items[${window.__mRowIndex}][product_id]" value="${data ? data.product_id : ''}"><input type="hidden" name="items[${window.__mRowIndex}][name]" class="it-hidden-name" value="${data ? data.name : ''}"><input type="hidden" name="items[${window.__mRowIndex}][sku]" class="it-sku" value="${data ? data.sku : ''}"><div class="search-results-box" style="display:none;"></div></div></div>
                <div class="eq-col-sku"><span class="mobile-label">SKU</span><input type="text" class="input it-display-sku" readonly style="background:rgba(255,255,255,0.03); color:var(--text-muted); width:100% !important;" value="${data ? data.sku : ''}"></div>
                <div class="eq-col-qty"><span class="mobile-label">Cant.</span><input type="number" name="items[${window.__mRowIndex}][quantity]" class="input it-qty" value="${data ? data.quantity : 1}" style="width:100% !important;" min="0.001" step="0.001" inputmode="decimal"></div>
                <div class="eq-col-unit"><span class="mobile-label">Unidad</span>${modalUnitSelectHtml(window.__mRowIndex, data ? data.unit : 'unidad')}</div>
                <div class="eq-col-price"><span class="mobile-label">Precio U. Neto</span><input type="number" name="items[${window.__mRowIndex}][price_unit]" class="input it-price" value="${data ? data.price_unit : 0}" style="width:100% !important;" min="0"></div>
                <div class="eq-col-total"><span class="mobile-label">Total Fila</span><strong class="it-total-text" style="display:block; padding:0 12px; font-size:1rem;">$ 0</strong></div>
                <div class="eq-col-del" style="text-align: right;"><span class="mobile-label" style="display:none;">Borrar</span><button type="button" class="btn btn-danger btn-sm remove-row-btn" style="padding: 0; width: 36px; min-width: 36px; height: 36px; display: inline-flex; justify-content: center; align-items: center;"><i data-lucide="trash-2" style="width: 16px; height: 16px;"></i></button></div>
            `;
            mContainer.appendChild(row);
            
            var sInput = row.querySelector('.it-name');
            var rBox = row.querySelector('.search-results-box');
            var qInp = row.querySelector('.it-qty');
            var pInp = row.querySelector('.it-price');
            
            qInp.addEventListener('input', calcTotals);
            pInp.addEventListener('input', calcTotals);
            row.querySelector('.remove-row-btn').addEventListener('click', function() { row.remove(); calcTotals(); });

            var tOut = null;
            sInput.addEventListener('input', function() {
                clearTimeout(tOut);
                var q = sInput.value.trim();
                if (q.length < 2) { rBox.style.display = 'none'; return; }
                tOut = setTimeout(function() {
                    fetch('/modules/crm/api_products.php?q=' + encodeURIComponent(q))
                        .then(r => r.json())
                        .then(d => {
                            rBox.innerHTML = '';
                            if (!d.length) { rBox.innerHTML = '<div class="search-result-item-empty">Sin resultados</div>'; rBox.style.display = 'block'; return; }
                            d.forEach(p => {
                                var btn = document.createElement('button');
                                btn.type = 'button'; btn.className = 'search-result-item';
                                btn.innerHTML = `<strong>${p.name}</strong><span>SKU: ${p.sku} · ${window.fmtCLP(p.price)} · ${p.unit || 'unidad'}</span>`;
                                btn.onclick = function() {
                                    sInput.value = p.name;
                                    row.querySelector('input[type="hidden"]').value = p.id;
                                    row.querySelector('.it-hidden-name').value = p.name;
                                    row.querySelector('.it-sku').value = p.sku;
                                    row.querySelector('.it-display-sku').value = p.sku;
                                    var unitSelect = row.querySelector('.it-unit'); if (unitSelect) unitSelect.value = modalCleanQuoteUnit(p.unit || 'unidad');
                                    pInp.value = p.price;
                                    rBox.style.display = 'none';
                                    calcTotals();
                                };
                                rBox.appendChild(btn);
                            });
                            rBox.style.display = 'block';
                        });
                }, 300);
            });
            
            document.addEventListener('click', function(e) { if (!row.contains(e.target)) rBox.style.display = 'none'; });
            window.__mRowIndex++;
            if (window.lucide) window.lucide.createIcons();
        }
        
        var oldAddBtn = mAddBtn;
        var newAddBtn = oldAddBtn.cloneNode(true);
        oldAddBtn.parentNode.replaceChild(newAddBtn, oldAddBtn);
        newAddBtn.addEventListener('click', () => mAddRow(null));
        
        if (mDiscountInput) {
            var newDisc = mDiscountInput.cloneNode(true);
            mDiscountInput.parentNode.replaceChild(newDisc, mDiscountInput);
            newDisc.addEventListener('input', calcTotals);
        }

        if (preloadItems && preloadItems.length > 0) {
            preloadItems.forEach(item => {
                let itemName = item.name || '';
                let itemSku = item.sku || '';
                const match = itemName.match(/ \(SKU: (.*)\)$/);
                if (match) {
                    itemSku = match[1];
                    itemName = itemName.replace(/ \(SKU: .*\)$/, '');
                }
                mAddRow({
                    product_id: item.product_id,
                    name: itemName,
                    sku: itemSku,
                    quantity: item.quantity,
                    unit: item.unit || 'unidad',
                    price_unit: item.price_unit
                });
            });
        } else {
            mAddRow(null); 
        }
        calcTotals();
    };
    
    <?php if (!$isModal): ?>
    window.initQuoteBuilder(null);
    <?php endif; ?>
    
})();

</script>

<?php if ($isModal): ?>
    </div> </div> <?php else: ?>
</main>
<?php require_once '../../layouts/footer.php'; ?>
<?php endif; ?>
