<?php
require_once '../../core/config.php';
require_once '../../core/session.php';
require_once '../../core/database.php';
require_once '../../core/permissions.php';
require_once '../../core/format.php';
require_once '../../services/costs/CostAccess.php';

require_login();
if (!cost_can('costs.product.view')) {
    http_response_code(403);
    die('No tienes permisos para acceder al costeo de productos.');
}

$page_title = 'Costeo de productos';
$initialFrom = isset($_GET['from']) && preg_match('/^\d{4}-\d{2}-\d{2}$/', (string)$_GET['from']) ? $_GET['from'] : date('Y-01-01');
$initialTo = isset($_GET['to']) && preg_match('/^\d{4}-\d{2}-\d{2}$/', (string)$_GET['to']) ? $_GET['to'] : date('Y-m-d');
require_once '../../layouts/header.php';
require_once '../../layouts/sidebar.php';
?>

<main class="app-main" id="productCostMain" data-spa-module="costs:products">
    <?php require_once '../../layouts/topbar.php'; ?>
    <section class="content product-cost-shell">
        <header class="page-header product-cost-header">
            <div class="page-header-content">
                <span class="label">FINANZAS · FASE 2</span>
                <h1>Costeo de productos y márgenes</h1>
                <p>Versiona costos en neto, congela el costo aplicado a cada venta y controla la cobertura antes de publicar márgenes.</p>
            </div>
            <div class="product-cost-actions">
                <a class="btn btn-outline" href="/modules/costs/"><i data-lucide="arrow-left"></i><span>Gestión mensual</span></a>
                <label><span>Desde</span><input class="input" id="marginFrom" type="date" value="<?php echo safe_text($initialFrom); ?>"></label>
                <label><span>Hasta</span><input class="input" id="marginTo" type="date" value="<?php echo safe_text($initialTo); ?>"></label>
                <button class="btn btn-primary" type="button" id="refreshCostingBtn"><i data-lucide="refresh-cw"></i><span>Actualizar</span></button>
            </div>
        </header>

        <div class="product-cost-notice" id="productCostNotice" hidden></div>
        <div class="product-cost-kpis" id="productCostKpis"></div>

        <nav class="product-cost-tabs" aria-label="Secciones del costeo">
            <button class="is-active" type="button" data-product-cost-tab="catalog"><i data-lucide="package-search"></i><span>Productos</span></button>
            <button type="button" data-product-cost-tab="margins" id="marginTab"><i data-lucide="chart-no-axes-combined"></i><span>Márgenes</span></button>
            <button type="button" data-product-cost-tab="coverage"><i data-lucide="shield-check"></i><span>Cobertura y excepciones</span></button>
        </nav>

        <section class="product-cost-panel is-active" data-product-cost-panel="catalog">
            <article class="card product-cost-card">
                <header class="product-cost-card-header">
                    <div><h3>Catálogo de costo estándar</h3><p>Las versiones heredadas son provisionales hasta aprobar una receta con componentes.</p></div>
                    <input class="input" id="productCostSearch" type="search" placeholder="Buscar producto o SKU">
                </header>
                <div class="product-cost-table-scroll"><table class="product-cost-table"><thead><tr><th>Producto</th><th>Estado del costo</th><th>Vigencia</th><th class="number">Precio neto</th><th class="number">Costo unitario</th><th class="number">Margen lista</th><th></th></tr></thead><tbody id="productCostBody"></tbody></table></div>
            </article>
        </section>

        <section class="product-cost-panel" data-product-cost-panel="margins">
            <div class="margin-summary" id="marginSummary"></div>
            <div class="margin-grid">
                <article class="card product-cost-card"><header class="product-cost-card-header"><div><h3>Margen por producto</h3><p>Ingresos y costos congelados en CLP.</p></div></header><div class="product-cost-table-scroll"><table class="product-cost-table"><thead><tr><th>Producto</th><th class="number">Venta neta</th><th class="number">Costo</th><th class="number">Contribución</th><th class="number">Margen</th></tr></thead><tbody id="marginProductBody"></tbody></table></div></article>
                <article class="card product-cost-card"><header class="product-cost-card-header"><div><h3>Margen por cliente</h3><p>Solo líneas con costo identificable.</p></div></header><div class="product-cost-table-scroll"><table class="product-cost-table"><thead><tr><th>Cliente</th><th class="number">Venta neta</th><th class="number">Costo</th><th class="number">Contribución</th><th class="number">Margen</th></tr></thead><tbody id="marginCustomerBody"></tbody></table></div></article>
            </div>
        </section>

        <section class="product-cost-panel" data-product-cost-panel="coverage">
            <article class="card coverage-card">
                <header class="product-cost-card-header"><div><h3>Confiabilidad del margen</h3><p>El KPI se habilita con al menos 95% de documentos con líneas y 90% del ingreso de líneas con costo.</p></div><button class="btn btn-primary" type="button" id="rebuildSnapshotsBtn"><i data-lucide="camera"></i><span>Actualizar fotografías</span></button></header>
                <div class="coverage-grid" id="coverageGrid"></div>
                <div class="coverage-warning" id="coverageWarning"></div>
            </article>
            <article class="card coverage-card"><div class="coverage-explanation"><i data-lucide="badge-alert"></i><div><strong>Histórico protegido</strong><p>Si una factura antigua no tiene detalle de líneas en ICYLAB OS, el sistema la informa como excepción y no fabrica un margen. La actualización solo procesa líneas locales demostrables.</p></div></div></article>
        </section>
    </section>

    <div class="product-cost-modal-backdrop" id="productCostModal" aria-hidden="true">
        <div class="product-cost-modal" role="dialog" aria-modal="true" aria-labelledby="productCostModalTitle">
            <header><div><span class="label" id="productCostModalSku">PRODUCTO</span><h2 id="productCostModalTitle">Nueva versión de costo</h2><p id="productCostModalSubtitle"></p></div><button class="btn btn-outline" type="button" data-close-product-cost><i data-lucide="x"></i></button></header>
            <form id="productCostForm">
                <input type="hidden" name="action" value="save_draft"><input type="hidden" name="product_id" id="costProductId"><input type="hidden" name="version_id" id="costVersionId"><input type="hidden" name="components_json" id="costComponentsJson">
                <div class="product-cost-form-grid">
                    <label><span>Vigente desde</span><input class="input" type="date" name="effective_from" id="costEffectiveFrom" required></label>
                    <label><span>Cantidad obtenida</span><input class="input cost-calc-input" type="number" min="0.0001" step="0.0001" name="output_quantity" id="costOutputQuantity" value="1" required></label>
                    <label><span>Unidad de salida</span><input class="input" name="output_unit" id="costOutputUnit" maxlength="50" required></label>
                    <label><span>Rendimiento</span><div class="input-suffix"><input class="input cost-calc-input" type="number" min="0.01" max="100" step="0.01" name="yield_percent" id="costYield" value="100" required><span>%</span></div></label>
                    <label class="wide"><span>Notas y supuesto de costeo</span><textarea class="input" name="notes" id="costNotes" rows="2"></textarea></label>
                </div>
                <section class="component-editor">
                    <div class="component-heading"><div><strong>Componentes del costo</strong><small>Trabaja en neto recuperable y agrega la merma propia de cada insumo.</small></div><button class="btn btn-outline" type="button" id="addCostComponentBtn"><i data-lucide="plus"></i><span>Agregar componente</span></button></div>
                    <div class="component-list" id="costComponentList"></div>
                    <div class="component-totals"><span>Costo del lote <strong id="costBatchTotal">$0</strong></span><span>Costo unitario estimado <strong id="costUnitTotal">$0</strong></span></div>
                </section>
            </form>
            <footer><div><button class="btn btn-outline" type="button" data-close-product-cost>Cancelar</button></div><div class="modal-actions"><button class="btn btn-outline" type="button" id="approveCostVersionBtn" hidden><i data-lucide="badge-check"></i><span>Aprobar versión</span></button><button class="btn btn-primary" type="submit" form="productCostForm"><i data-lucide="save"></i><span>Guardar borrador</span></button></div></footer>
        </div>
    </div>

    <style>
    #productCostMain.app-main{overflow:auto!important}.product-cost-shell{max-width:none!important;width:100%!important;padding-bottom:40px}.product-cost-header{align-items:flex-end;gap:20px}.product-cost-actions{display:flex;align-items:flex-end;justify-content:flex-end;gap:10px;flex-wrap:wrap}.product-cost-actions label{display:grid;gap:5px;color:var(--text-muted);font-size:.72rem;font-weight:650}.product-cost-actions input{width:145px}.product-cost-notice{margin-bottom:14px;padding:12px 14px;border:1px solid var(--border-default);border-radius:var(--radius-md);background:var(--surface-2);font-size:.84rem}.product-cost-notice.is-error{color:var(--color-error);border-color:color-mix(in srgb,var(--color-error) 35%,var(--border-default))}.product-cost-notice.is-success{color:var(--color-success)}.product-cost-kpis,.margin-summary{display:grid;grid-template-columns:repeat(5,minmax(150px,1fr));gap:12px;margin-bottom:16px}.product-cost-kpi{padding:16px;border:1px solid var(--border-default);border-radius:var(--radius-lg);background:var(--surface-1)}.product-cost-kpi span{display:block;color:var(--text-muted);font-size:.72rem}.product-cost-kpi strong{display:block;margin-top:7px;font-size:1.42rem}.product-cost-kpi small{display:block;margin-top:4px;color:var(--text-secondary);font-size:.7rem}.product-cost-tabs{display:flex;gap:6px;margin-bottom:14px;padding:5px;border:1px solid var(--border-default);border-radius:var(--radius-lg);background:var(--surface-1);width:max-content;max-width:100%;overflow:auto}.product-cost-tabs button{display:inline-flex;align-items:center;gap:7px;padding:9px 13px;border:0;border-radius:var(--radius-md);background:transparent;color:var(--text-secondary);white-space:nowrap;cursor:pointer}.product-cost-tabs button.is-active{background:var(--surface-3);color:var(--color-primary)}.product-cost-tabs svg{width:17px}.product-cost-panel{display:none}.product-cost-panel.is-active{display:block}.product-cost-card,.coverage-card{overflow:hidden}.product-cost-card-header{display:flex;align-items:center;justify-content:space-between;gap:16px;padding:16px 18px;border-bottom:1px solid var(--border-subtle)}.product-cost-card-header h3,.product-cost-card-header p{margin:0}.product-cost-card-header p{margin-top:4px;color:var(--text-muted);font-size:.76rem}.product-cost-card-header>input{width:min(320px,40vw)}.product-cost-table-scroll{overflow:auto}.product-cost-table{width:100%;border-collapse:collapse;min-width:850px}.product-cost-table th,.product-cost-table td{padding:12px 14px;border-bottom:1px solid var(--border-subtle);text-align:left;font-size:.79rem}.product-cost-table th{color:var(--text-muted);font-size:.68rem;text-transform:uppercase;letter-spacing:.04em}.product-cost-table .number{text-align:right;font-variant-numeric:tabular-nums}.product-cost-table td strong,.product-cost-table td small{display:block}.product-cost-table td small{margin-top:3px;color:var(--text-muted)}.cost-status{display:inline-flex;padding:5px 8px;border-radius:999px;font-size:.67rem;font-weight:700}.cost-status.validated{color:var(--color-success);background:color-mix(in srgb,var(--color-success) 12%,transparent)}.cost-status.provisional{color:var(--color-warning);background:color-mix(in srgb,var(--color-warning) 12%,transparent)}.cost-status.missing{color:var(--color-error);background:color-mix(in srgb,var(--color-error) 12%,transparent)}.margin-grid{display:grid;grid-template-columns:1fr 1fr;gap:14px}.coverage-grid{display:grid;grid-template-columns:repeat(4,minmax(150px,1fr));gap:12px;padding:18px}.coverage-item{padding:14px;border:1px solid var(--border-subtle);border-radius:var(--radius-md);background:var(--surface-2)}.coverage-item span,.coverage-item small{display:block;color:var(--text-muted);font-size:.7rem}.coverage-item strong{display:block;margin:6px 0;font-size:1.25rem}.coverage-warning{margin:0 18px 18px;padding:13px;border-radius:var(--radius-md);background:var(--surface-2);font-size:.8rem}.coverage-warning.is-ready{color:var(--color-success)}.coverage-warning.is-blocked{color:var(--color-warning)}.coverage-explanation{display:flex;gap:12px;padding:18px}.coverage-explanation svg{color:var(--color-warning);flex:0 0 22px}.coverage-explanation p{margin:5px 0 0;color:var(--text-secondary);font-size:.8rem}.product-cost-modal-backdrop{position:fixed;inset:0;z-index:1100;display:none;align-items:center;justify-content:center;padding:24px;background:rgba(0,0,0,.72);backdrop-filter:blur(5px)}.product-cost-modal-backdrop.is-open{display:flex}.product-cost-modal{display:flex;flex-direction:column;width:min(1120px,calc(100vw - 48px));max-height:calc(100dvh - 48px);overflow:hidden;border:1px solid var(--border-default);border-radius:var(--radius-xl);background:var(--surface-1);box-shadow:var(--shadow-lg)}.product-cost-modal>header,.product-cost-modal>footer{display:flex;align-items:center;justify-content:space-between;gap:16px;padding:17px 20px;border-bottom:1px solid var(--border-subtle)}.product-cost-modal>header h2,.product-cost-modal>header p{margin:0}.product-cost-modal>header p{margin-top:4px;color:var(--text-muted);font-size:.75rem}.product-cost-modal>form{overflow:auto;padding:18px}.product-cost-modal>footer{border-top:1px solid var(--border-subtle);border-bottom:0}.modal-actions{display:flex;gap:10px}.product-cost-form-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px}.product-cost-form-grid label{display:grid;gap:6px;color:var(--text-secondary);font-size:.73rem}.product-cost-form-grid .wide{grid-column:1/-1}.input-suffix{position:relative}.input-suffix span{position:absolute;right:13px;top:50%;transform:translateY(-50%);color:var(--text-muted)}.input-suffix input{padding-right:34px}.component-editor{margin-top:18px;border:1px solid var(--border-default);border-radius:var(--radius-lg);overflow:hidden}.component-heading,.component-totals{display:flex;align-items:center;justify-content:space-between;gap:14px;padding:13px 15px;background:var(--surface-2)}.component-heading small{display:block;margin-top:3px;color:var(--text-muted);font-size:.69rem}.component-list{display:grid;gap:8px;padding:12px}.component-row{display:grid;grid-template-columns:150px minmax(180px,1fr) 90px 90px 110px 80px 42px;gap:8px;align-items:center}.component-row .input,.component-row .select{min-width:0}.component-row button{width:42px;height:42px;padding:0}.component-totals{justify-content:flex-end;gap:28px;font-size:.76rem}.component-totals strong{margin-left:6px;font-size:.95rem}.empty-row{padding:30px!important;text-align:center!important;color:var(--text-muted)}
    @media(max-width:1050px){.product-cost-kpis,.margin-summary{grid-template-columns:repeat(3,1fr)}.margin-grid{grid-template-columns:1fr}.product-cost-form-grid{grid-template-columns:repeat(2,1fr)}.component-row{grid-template-columns:1fr 1fr 90px 90px}.component-row>*:nth-child(n+5){grid-column:auto}.coverage-grid{grid-template-columns:repeat(2,1fr)}}
    @media(max-width:700px){.product-cost-header{align-items:stretch}.product-cost-actions{justify-content:flex-start}.product-cost-kpis,.margin-summary,.coverage-grid{grid-template-columns:1fr 1fr}.product-cost-form-grid{grid-template-columns:1fr}.product-cost-form-grid .wide{grid-column:auto}.product-cost-modal-backdrop{padding:8px}.product-cost-modal{width:calc(100vw - 16px);max-height:calc(100dvh - 16px)}.component-row{grid-template-columns:1fr 1fr}.component-totals{align-items:flex-end;flex-direction:column;gap:5px}}
    </style>
    <script>window.ICYLAB_PRODUCT_COSTING_INITIAL=<?php echo json_encode(array('from'=>$initialFrom,'to'=>$initialTo), JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES); ?>;</script>
    <script src="/modules/costs/product_costing.js?v=8.9.1"></script>
</main>

<?php require_once '../../layouts/footer.php'; ?>
