<?php
$pageTitle = "Gráficas Levey-Jennings";
require_once __DIR__ . '/../../config/config.php';
requirePermiso('control_calidad');

$db = Database::getInstance()->getConnection();
$lote_id = $_GET['lote_id'] ?? null;
$parametro_id = $_GET['parametro_id'] ?? null;
$fecha_inicio = $_GET['fecha_inicio'] ?? date('Y-m-01');
$fecha_fin = $_GET['fecha_fin'] ?? date('Y-m-d');

// Obtener lotes activos
$lotes = $db->query("SELECT * FROM cc_lotes WHERE estado = 'Activo' ORDER BY codigo")->fetchAll(PDO::FETCH_ASSOC);

// Obtener parámetros del lote seleccionado
$parametrosLote = [];
if ($lote_id) {
    $stmt = $db->prepare("SELECT lp.*, pe.nombre as parametro_nombre, e.nombre as examen_nombre
                          FROM cc_lote_parametros lp
                          JOIN parametros_examen pe ON lp.parametro_id = pe.id
                          JOIN examenes e ON pe.examen_id = e.id
                          WHERE lp.lote_id = ? AND lp.tipo_resultado = 'numerico'
                          ORDER BY e.nombre, pe.orden");
    $stmt->execute([$lote_id]);
    $parametrosLote = $stmt->fetchAll(PDO::FETCH_ASSOC);
}

// Datos para la gráfica
$datosGrafica = [];
$estadisticas = [];
$loteParamInfo = null;

if ($parametro_id && $lote_id) {
    // Obtener info del parámetro
    $stmt = $db->prepare("SELECT lp.*, pe.nombre, pe.unidad, e.nombre as examen
                          FROM cc_lote_parametros lp
                          JOIN parametros_examen pe ON lp.parametro_id = pe.id
                          JOIN examenes e ON pe.examen_id = e.id
                          WHERE lp.id = ?");
    $stmt->execute([$parametro_id]);
    $loteParamInfo = $stmt->fetch(PDO::FETCH_ASSOC);
    
    // Obtener resultados
    $stmt = $db->prepare("SELECT r.*, u.nombre as analista
                          FROM cc_resultados r
                          LEFT JOIN usuarios u ON r.analista_id = u.id
                          WHERE r.lote_parametro_id = ? 
                          AND DATE(r.fecha_analisis) BETWEEN ? AND ?
                          ORDER BY r.fecha_analisis ASC");
    $stmt->execute([$parametro_id, $fecha_inicio, $fecha_fin]);
    $resultados = $stmt->fetchAll(PDO::FETCH_ASSOC);
    
    foreach ($resultados as $r) {
        $datosGrafica[] = [
            'fecha' => $r['fecha_analisis'],
            'valor' => floatval($r['valor_obtenido']),
            'z_score' => floatval($r['z_score']),
            'estado' => $r['estado'],
            'reglas' => $r['reglas_violadas'],
            'analista' => $r['analista']
        ];
    }
    
    // Calcular estadísticas
    if (!empty($datosGrafica)) {
        $valores = array_column($datosGrafica, 'valor');
        $estadisticas = [
            'n' => count($valores),
            'media_obtenida' => array_sum($valores) / count($valores),
            'media_asignada' => floatval($loteParamInfo['valor_asignado']),
            'de_asignada' => floatval($loteParamInfo['desviacion_estandar']),
            'min' => min($valores),
            'max' => max($valores),
            'aceptados' => count(array_filter($datosGrafica, function ($d) { return $d['estado'] == 'Aceptado'; })),
            'rechazados' => count(array_filter($datosGrafica, function ($d) { return $d['estado'] == 'Rechazado'; })),
            'alertas' => count(array_filter($datosGrafica, function ($d) { return $d['estado'] == 'Alerta'; }))
        ];
        
        // Calcular DE observada
        $varianza = 0;
        foreach ($valores as $v) {
            $varianza += pow($v - $estadisticas['media_obtenida'], 2);
        }
        $estadisticas['de_obtenida'] = sqrt($varianza / count($valores));
        $estadisticas['cv'] = ($estadisticas['de_obtenida'] / $estadisticas['media_obtenida']) * 100;
        $estadisticas['sesgo'] = $estadisticas['media_obtenida'] - $estadisticas['media_asignada'];
        $estadisticas['sesgo_pct'] = ($estadisticas['sesgo'] / $estadisticas['media_asignada']) * 100;
    }
}

require_once __DIR__ . '/../../includes/header.php';
?>

<div class="row mb-4">
    <div class="col-12">
        <nav aria-label="breadcrumb">
            <ol class="breadcrumb">
                <li class="breadcrumb-item"><a href="list.php">Control de Calidad</a></li>
                <li class="breadcrumb-item active">Gráficas Levey-Jennings</li>
            </ol>
        </nav>
        <h2><i class="bi bi-graph-up me-2"></i>Gráficas de Control Levey-Jennings</h2>
    </div>
</div>

<!-- Filtros -->
<div class="card mb-4">
    <div class="card-body">
        <form method="GET" class="row g-3 align-items-end">
            <div class="col-md-3">
                <label class="form-label">Lote de Control</label>
                <select name="lote_id" class="form-select" onchange="this.form.submit()">
                    <option value="">-- Seleccione lote --</option>
                    <?php foreach ($lotes as $l): ?>
                    <option value="<?= $l['id'] ?>" <?= $lote_id == $l['id'] ? 'selected' : '' ?>>
                        <?= htmlspecialchars($l['codigo']) ?> - <?= htmlspecialchars($l['nombre']) ?>
                    </option>
                    <?php endforeach; ?>
                </select>
            </div>
            <div class="col-md-3">
                <label class="form-label">Parámetro</label>
                <select name="parametro_id" class="form-select" <?= empty($parametrosLote) ? 'disabled' : '' ?>>
                    <option value="">-- Seleccione parámetro --</option>
                    <?php foreach ($parametrosLote as $p): ?>
                    <option value="<?= $p['id'] ?>" <?= $parametro_id == $p['id'] ? 'selected' : '' ?>>
                        <?= htmlspecialchars($p['examen_nombre']) ?> - <?= htmlspecialchars($p['parametro_nombre']) ?>
                    </option>
                    <?php endforeach; ?>
                </select>
            </div>
            <div class="col-md-2">
                <label class="form-label">Fecha Inicio</label>
                <input type="date" name="fecha_inicio" class="form-control" value="<?= $fecha_inicio ?>">
            </div>
            <div class="col-md-2">
                <label class="form-label">Fecha Fin</label>
                <input type="date" name="fecha_fin" class="form-control" value="<?= $fecha_fin ?>">
            </div>
            <div class="col-md-2">
                <button type="submit" class="btn btn-primary w-100">
                    <i class="bi bi-search me-1"></i> Ver Gráfica
                </button>
            </div>
        </form>
    </div>
</div>

<?php if ($loteParamInfo && !empty($datosGrafica)): ?>
<!-- Información del parámetro -->
<div class="row mb-4">
    <div class="col-md-8">
        <div class="card">
            <div class="card-header bg-primary text-white">
                <h5 class="mb-0">
                    <i class="bi bi-graph-up me-2"></i>
                    <?= htmlspecialchars($loteParamInfo['examen']) ?> - <?= htmlspecialchars($loteParamInfo['nombre']) ?>
                    (<?= htmlspecialchars($loteParamInfo['unidad']) ?>)
                </h5>
            </div>
            <div class="card-body">
                <!-- Canvas para la gráfica -->
                <canvas id="chartLJ" height="300"></canvas>
            </div>
        </div>
    </div>
    
    <div class="col-md-4">
        <!-- Estadísticas -->
        <div class="card mb-3">
            <div class="card-header">
                <h6 class="mb-0"><i class="bi bi-calculator me-2"></i>Estadísticas</h6>
            </div>
            <div class="card-body">
                <table class="table table-sm mb-0">
                    <tr class="table-danger">
                        <td>Límite Superior (+2DE)</td>
                        <td class="text-end"><strong><?= number_format($estadisticas['media_asignada'] + 2 * $estadisticas['de_asignada'], 2) ?></strong></td>
                    </tr>
                    <tr class="table-warning">
                        <td>+1DE</td>
                        <td class="text-end"><?= number_format($estadisticas['media_asignada'] + $estadisticas['de_asignada'], 2) ?></td>
                    </tr>
                    <tr class="table-success">
                        <td>Media (Centro)</td>
                        <td class="text-end"><strong><?= number_format($estadisticas['media_asignada'], 2) ?></strong></td>
                    </tr>
                    <tr class="table-warning">
                        <td>-1DE</td>
                        <td class="text-end"><?= number_format($estadisticas['media_asignada'] - $estadisticas['de_asignada'], 2) ?></td>
                    </tr>
                    <tr class="table-danger">
                        <td>Límite Inferior (-2DE)</td>
                        <td class="text-end"><strong><?= number_format($estadisticas['media_asignada'] - 2 * $estadisticas['de_asignada'], 2) ?></strong></td>
                    </tr>
                    <tr><td colspan="2"><hr class="my-1"></td></tr>
                    <tr>
                        <td>N (controles)</td>
                        <td class="text-end"><strong><?= $estadisticas['n'] ?></strong></td>
                    </tr>
                    <tr>
                        <td>DE Calculada</td>
                        <td class="text-end"><?= number_format($estadisticas['de_asignada'], 4) ?></td>
                    </tr>
                    <tr>
                        <td>DE Obtenida</td>
                        <td class="text-end"><?= number_format($estadisticas['de_obtenida'], 4) ?></td>
                    </tr>
                    <tr>
                        <td>Media Obtenida</td>
                        <td class="text-end"><?= number_format($estadisticas['media_obtenida'], 2) ?></td>
                    </tr>
                    <tr>
                        <td>CV%</td>
                        <td class="text-end"><strong><?= number_format($estadisticas['cv'], 2) ?>%</strong></td>
                    </tr>
                    <tr>
                        <td>Sesgo</td>
                        <td class="text-end <?= abs($estadisticas['sesgo_pct']) > 5 ? 'text-danger' : '' ?>">
                            <?= number_format($estadisticas['sesgo'], 2) ?> (<?= number_format($estadisticas['sesgo_pct'], 2) ?>%)
                        </td>
                    </tr>
                    <tr>
                        <td>Mín / Máx</td>
                        <td class="text-end"><?= number_format($estadisticas['min'], 2) ?> / <?= number_format($estadisticas['max'], 2) ?></td>
                    </tr>
                </table>
            </div>
        </div>
        
        <!-- Resumen de estados -->
        <div class="card">
            <div class="card-header">
                <h6 class="mb-0"><i class="bi bi-pie-chart me-2"></i>Resultados</h6>
            </div>
            <div class="card-body">
                <div class="d-flex justify-content-around text-center">
                    <div>
                        <div class="fs-3 text-success"><?= $estadisticas['aceptados'] ?></div>
                        <small class="text-muted">Aceptados</small>
                    </div>
                    <div>
                        <div class="fs-3 text-warning"><?= $estadisticas['alertas'] ?></div>
                        <small class="text-muted">Alertas</small>
                    </div>
                    <div>
                        <div class="fs-3 text-danger"><?= $estadisticas['rechazados'] ?></div>
                        <small class="text-muted">Rechazados</small>
                    </div>
                </div>
                
                <?php 
                $pctAceptado = ($estadisticas['aceptados'] / $estadisticas['n']) * 100;
                ?>
                <div class="progress mt-3" style="height: 25px;">
                    <div class="progress-bar bg-success" style="width: <?= ($estadisticas['aceptados']/$estadisticas['n'])*100 ?>%">
                        <?= round(($estadisticas['aceptados']/$estadisticas['n'])*100) ?>%
                    </div>
                    <div class="progress-bar bg-warning" style="width: <?= ($estadisticas['alertas']/$estadisticas['n'])*100 ?>%"></div>
                    <div class="progress-bar bg-danger" style="width: <?= ($estadisticas['rechazados']/$estadisticas['n'])*100 ?>%"></div>
                </div>
                <div class="text-center mt-2">
                    <span class="badge bg-<?= $pctAceptado >= 90 ? 'success' : ($pctAceptado >= 80 ? 'warning' : 'danger') ?>">
                        <?= number_format($pctAceptado, 1) ?>% Aceptación
                    </span>
                </div>
            </div>
        </div>
    </div>
</div>

<!-- Tabla de datos -->
<div class="card">
    <div class="card-header d-flex justify-content-between align-items-center">
        <h6 class="mb-0"><i class="bi bi-table me-2"></i>Datos del Control</h6>
        <button class="btn btn-sm btn-outline-primary" onclick="exportarDatos()">
            <i class="bi bi-download me-1"></i> Exportar
        </button>
    </div>
    <div class="card-body">
        <div class="table-responsive">
            <table class="table table-sm table-hover" id="tablaDatos">
                <thead>
                    <tr>
                        <th>#</th>
                        <th>Fecha/Hora</th>
                        <th>Valor</th>
                        <th>Z-Score</th>
                        <th>Estado</th>
                        <th>Reglas</th>
                        <th>Analista</th>
                    </tr>
                </thead>
                <tbody>
                    <?php foreach ($datosGrafica as $i => $d): ?>
                    <tr>
                        <td><?= $i + 1 ?></td>
                        <td><?= date('d/m/Y H:i', strtotime($d['fecha'])) ?></td>
                        <td><strong><?= number_format($d['valor'], 2) ?></strong></td>
                        <td>
                            <span class="badge bg-<?= abs($d['z_score']) > 2 ? 'danger' : (abs($d['z_score']) > 1 ? 'warning' : 'success') ?>">
                                <?= number_format($d['z_score'], 2) ?>
                            </span>
                        </td>
                        <td>
                            <span class="badge bg-<?= $d['estado'] == 'Aceptado' ? 'success' : ($d['estado'] == 'Rechazado' ? 'danger' : 'warning') ?>">
                                <?= $d['estado'] ?>
                            </span>
                        </td>
                        <td><small class="text-danger"><?= $d['reglas'] ?: '-' ?></small></td>
                        <td><small><?= htmlspecialchars($d['analista'] ?? '-') ?></small></td>
                    </tr>
                    <?php endforeach; ?>
                </tbody>
            </table>
        </div>
    </div>
</div>

<!-- Include Chart.js -->
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-annotation@3.0.1/dist/chartjs-plugin-annotation.min.js"></script>

<script>
const datosGrafica = <?= json_encode($datosGrafica) ?>;
const media = <?= $estadisticas['media_asignada'] ?? 0 ?>;
const de = <?= $estadisticas['de_asignada'] ?? 0 ?>;
const limInf = <?= $loteParamInfo['rango_min'] ?? 0 ?>;
const limSup = <?= $loteParamInfo['rango_max'] ?? 0 ?>;

const ctx = document.getElementById('chartLJ').getContext('2d');

// Preparar datos
const labels = datosGrafica.map((d, i) => i + 1);
const valores = datosGrafica.map(d => d.valor);
const colores = datosGrafica.map(d => {
    if (d.estado === 'Rechazado') return '#dc3545';
    if (d.estado === 'Alerta') return '#ffc107';
    return '#198754';
});

// Rango del eje Y: un poco más allá de los límites para dar margen visual
const margen = de > 0 ? de * 0.5 : 1;
const yMin = de > 0 ? limInf - margen : Math.min(...valores) - 1;
const yMax = de > 0 ? limSup + margen : Math.max(...valores) + 1;

// Construir anotaciones
const annotations = {};

// Siempre mostrar la línea de la media (centro)
annotations.media = {
    type: 'line',
    yMin: media,
    yMax: media,
    borderColor: '#000000',
    borderWidth: 2,
    label: {
        display: true,
        content: 'Media: ' + media.toFixed(2),
        position: 'start',
        backgroundColor: '#000000',
        color: '#ffffff',
        font: { size: 11, weight: 'bold' },
        padding: 4
    }
};

if (de > 0) {
    // +1DE (primera desviación positiva)
    annotations.plus1de = {
        type: 'line',
        yMin: media + de,
        yMax: media + de,
        borderColor: '#ffc107',
        borderWidth: 1.5,
        borderDash: [6, 4],
        label: {
            display: true,
            content: '+1DE: ' + (media + de).toFixed(2),
            position: 'start',
            backgroundColor: 'rgba(255, 193, 7, 0.9)',
            color: '#000000',
            font: { size: 10 },
            padding: 3
        }
    };
    // -1DE (primera desviación negativa)
    annotations.minus1de = {
        type: 'line',
        yMin: media - de,
        yMax: media - de,
        borderColor: '#ffc107',
        borderWidth: 1.5,
        borderDash: [6, 4],
        label: {
            display: true,
            content: '-1DE: ' + (media - de).toFixed(2),
            position: 'start',
            backgroundColor: 'rgba(255, 193, 7, 0.9)',
            color: '#000000',
            font: { size: 10 },
            padding: 3
        }
    };
    // +2DE = Límite Superior (segunda desviación positiva)
    annotations.plus2de = {
        type: 'line',
        yMin: media + 2*de,
        yMax: media + 2*de,
        borderColor: '#dc3545',
        borderWidth: 2.5,
        label: {
            display: true,
            content: 'Lím. Superior (+2DE): ' + (media + 2*de).toFixed(2),
            position: 'end',
            backgroundColor: '#dc3545',
            color: '#ffffff',
            font: { size: 11, weight: 'bold' },
            padding: 4
        }
    };
    // -2DE = Límite Inferior (segunda desviación negativa)
    annotations.minus2de = {
        type: 'line',
        yMin: media - 2*de,
        yMax: media - 2*de,
        borderColor: '#dc3545',
        borderWidth: 2.5,
        label: {
            display: true,
            content: 'Lím. Inferior (-2DE): ' + (media - 2*de).toFixed(2),
            position: 'end',
            backgroundColor: '#dc3545',
            color: '#ffffff',
            font: { size: 11, weight: 'bold' },
            padding: 4
        }
    };
    
    // ===== Zonas de color =====
    // Zona verde central: entre -1DE y +1DE (aceptable)
    annotations.zonaOk = {
        type: 'box',
        yMin: media - de,
        yMax: media + de,
        backgroundColor: 'rgba(40, 167, 69, 0.08)',
        borderWidth: 0
    };
    // Zona amarilla superior: entre +1DE y +2DE (alerta)
    annotations.zonaAlerta1 = {
        type: 'box',
        yMin: media + de,
        yMax: media + 2*de,
        backgroundColor: 'rgba(255, 193, 7, 0.08)',
        borderWidth: 0
    };
    // Zona amarilla inferior: entre -2DE y -1DE (alerta)
    annotations.zonaAlerta2 = {
        type: 'box',
        yMin: media - 2*de,
        yMax: media - de,
        backgroundColor: 'rgba(255, 193, 7, 0.08)',
        borderWidth: 0
    };
    // Zona roja superior: fuera de +2DE (rechazado)
    annotations.zonaRechazo1 = {
        type: 'box',
        yMin: media + 2*de,
        yMax: yMax,
        backgroundColor: 'rgba(220, 53, 69, 0.08)',
        borderWidth: 0
    };
    // Zona roja inferior: fuera de -2DE (rechazado)
    annotations.zonaRechazo2 = {
        type: 'box',
        yMin: yMin,
        yMax: media - 2*de,
        backgroundColor: 'rgba(220, 53, 69, 0.08)',
        borderWidth: 0
    };
}

new Chart(ctx, {
    type: 'line',
    data: {
        labels: labels,
        datasets: [{
            label: 'Valor Obtenido',
            data: valores,
            borderColor: '#0d6efd',
            backgroundColor: colores,
            pointBackgroundColor: colores,
            pointBorderColor: colores,
            pointRadius: 6,
            pointHoverRadius: 8,
            fill: false,
            tension: 0
        }]
    },
    options: {
        responsive: true,
        maintainAspectRatio: false,
        scales: {
            y: {
                min: yMin,
                max: yMax,
                title: {
                    display: true,
                    text: 'Valor (<?= addslashes($loteParamInfo['unidad'] ?? '') ?>)'
                },
                ticks: {
                    callback: function(value) {
                        // Marcar en el eje los valores clave
                        if (de > 0) {
                            const vals = [media - 2*de, media - de, media, media + de, media + 2*de];
                            for (let v of vals) {
                                if (Math.abs(value - v) < de * 0.01) {
                                    return value.toFixed(2) + ' ◄';
                                }
                            }
                        }
                        return value.toFixed(2);
                    }
                }
            },
            x: {
                title: {
                    display: true,
                    text: 'Número de Control'
                }
            }
        },
        plugins: {
            legend: {
                display: true,
                labels: {
                    generateLabels: function() {
                        const items = [
                            { text: 'Valor Obtenido', fillStyle: '#0d6efd', strokeStyle: '#0d6efd', lineWidth: 2 },
                            { text: 'Aceptado', fillStyle: '#198754', strokeStyle: '#198754', lineWidth: 0 },
                            { text: 'Alerta', fillStyle: '#ffc107', strokeStyle: '#ffc107', lineWidth: 0 },
                            { text: 'Rechazado', fillStyle: '#dc3545', strokeStyle: '#dc3545', lineWidth: 0 }
                        ];
                        if (de > 0) {
                            items.push(
                                { text: '±1DE (Alerta)', fillStyle: 'rgba(255,193,7,0.15)', strokeStyle: '#ffc107', lineWidth: 1.5, lineDash: [6,4] },
                                { text: '±2DE (Límite)', fillStyle: 'rgba(220,53,69,0.15)', strokeStyle: '#dc3545', lineWidth: 2.5 }
                            );
                        }
                        return items;
                    }
                }
            },
            tooltip: {
                callbacks: {
                    afterLabel: function(context) {
                        const d = datosGrafica[context.dataIndex];
                        return [
                            'Z-Score: ' + (d.z_score ? d.z_score.toFixed(2) : 'N/A'),
                            'Estado: ' + d.estado,
                            d.reglas ? 'Reglas: ' + d.reglas : '',
                            'Fecha: ' + d.fecha,
                            'Límites: ' + limInf.toFixed(2) + ' - ' + limSup.toFixed(2)
                        ].filter(Boolean);
                    }
                }
            },
            annotation: {
                annotations: annotations
            }
        }
    }
});

function exportarDatos() {
    let csv = 'Numero,Fecha,Valor,Z-Score,Estado,Reglas,Analista\n';
    datosGrafica.forEach((d, i) => {
        csv += `${i+1},"${d.fecha}",${d.valor},${d.z_score},"${d.estado}","${d.reglas || ''}","${d.analista || ''}"\n`;
    });
    
    const blob = new Blob([csv], { type: 'text/csv' });
    const url = window.URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = 'control_calidad_<?= date('Y-m-d') ?>.csv';
    a.click();
}
</script>

<?php elseif ($loteParamInfo && empty($datosGrafica)): ?>
<div class="alert alert-info">
    <i class="bi bi-info-circle me-2"></i>
    No hay resultados para el período seleccionado.
</div>
<?php else: ?>
<div class="card">
    <div class="card-body text-center py-5">
        <i class="bi bi-graph-up fs-1 text-muted"></i>
        <p class="text-muted mt-3">Seleccione un lote y parámetro para ver la gráfica de Levey-Jennings</p>
    </div>
</div>
<?php endif; ?>

<?php require_once __DIR__ . '/../../includes/footer.php'; ?>
