<?php
/**
 * NEXUS IT — Escalamiento Automático de SLA
 * 
 * Ejecutar cada 15 minutos vía cron:
 *   */15 * * * * php /path/to/cron/sla_escalation.php
 * 
 * Qué hace:
 * 1. Tickets sin respuesta por X horas → Notifica al técnico asignado
 * 2. Tickets vencidos (fecha_vencimiento < ahora) → Escala al admin/supervisor
 * 3. Tickets sin técnico asignado por más de 1 hora → Auto-asigna si está habilitado
 */

require_once __DIR__ . '/../api/config/app.php';
require_once __DIR__ . '/../api/config/database.php';
if (file_exists(__DIR__ . '/../api/helpers/EmailService.php')) require_once __DIR__ . '/../api/helpers/EmailService.php';

$db = getDB();
$ahora = date('Y-m-d H:i:s');
$log = [];

// ============================================================
// 1. TICKETS VENCIDOS → Notificar admin/supervisor
// ============================================================
$vencidos = $db->prepare("
    SELECT t.id, t.numero_ticket, t.titulo, t.prioridad, t.estado, t.sla_horas,
           t.fecha_vencimiento, t.tecnico_asignado_id, t.created_at,
           s.nombre_completo as solicitante_nombre,
           tec.nombre_completo as tecnico_nombre, tec.email as tecnico_email
    FROM tickets t
    LEFT JOIN usuarios s ON t.solicitante_id = s.id
    LEFT JOIN usuarios tec ON t.tecnico_asignado_id = tec.id
    WHERE t.estado IN ('abierto', 'en_progreso')
      AND t.fecha_vencimiento IS NOT NULL
      AND t.fecha_vencimiento < ?
");
$vencidos->execute([$ahora]);
$ticketsVencidos = $vencidos->fetchAll();

foreach ($ticketsVencidos as $t) {
    $ticketId = $t['id'];

    // Verificar si ya se notificó esta escalación (evitar spam)
    $yaNotificado = $db->prepare("
        SELECT COUNT(*) FROM notificaciones 
        WHERE referencia_tipo = 'escalacion' 
          AND referencia_id = ? 
          AND created_at > DATE_SUB(NOW(), INTERVAL 4 HOUR)
    ");
    $yaNotificado->execute([$ticketId]);
    if ((int)$yaNotificado->fetchColumn() > 0) continue;

    // Crear notificación para todos los admins
    $admins = $db->query("SELECT id, email, nombre_completo FROM usuarios WHERE rol = 'admin' AND activo = 1")->fetchAll();

    foreach ($admins as $admin) {
        // Notificación in-app
        $db->prepare("INSERT INTO notificaciones (usuario_id, titulo, mensaje, tipo, url_accion, referencia_tipo, referencia_id) VALUES (?,?,?,?,?,?,?)")
            ->execute([
                $admin['id'],
                "SLA vencido: {$t['numero_ticket']}",
                "El ticket \"{$t['titulo']}\" ha superado su SLA de {$t['sla_horas']}h hábiles. " .
                ($t['tecnico_nombre'] ? "Asignado a: {$t['tecnico_nombre']}" : "Sin técnico asignado"),
                'alerta',
                "/admin/ticket-detalle.html?id={$ticketId}",
                'escalacion',
                $ticketId
            ]);

        // Email al admin
        if (class_exists('EmailService')) {
            try {
                $html = EmailService::template(
                    "SLA Vencido — {$t['numero_ticket']}",
                    "<p>El ticket <strong>{$t['numero_ticket']}: {$t['titulo']}</strong> ha superado su SLA.</p>" .
                    "<p><strong>Prioridad:</strong> {$t['prioridad']}<br>" .
                    "<strong>SLA:</strong> {$t['sla_horas']}h hábiles<br>" .
                    "<strong>Vencimiento:</strong> {$t['fecha_vencimiento']}<br>" .
                    "<strong>Técnico:</strong> " . ($t['tecnico_nombre'] ?: 'Sin asignar') . "<br>" .
                    "<strong>Solicitante:</strong> {$t['solicitante_nombre']}</p>" .
                    "<p style='color:#ef4444;font-weight:bold'>Este ticket requiere atención inmediata.</p>",
                    "/admin/ticket-detalle.html?id={$ticketId}",
                    'Ver Ticket'
                );
                EmailService::enviar($admin['email'], "SLA Vencido: {$t['numero_ticket']}", $html);
            } catch (\Exception $e) {
                error_log("Escalation email error: " . $e->getMessage());
            }
        }
    }

    // También notificar al técnico asignado
    if ($t['tecnico_asignado_id'] && $t['tecnico_email']) {
        $db->prepare("INSERT INTO notificaciones (usuario_id, titulo, mensaje, tipo, url_accion, referencia_tipo, referencia_id) VALUES (?,?,?,?,?,?,?)")
            ->execute([
                $t['tecnico_asignado_id'],
                "SLA vencido en tu ticket: {$t['numero_ticket']}",
                "El ticket \"{$t['titulo']}\" ha superado su tiempo de respuesta.",
                'alerta',
                "/admin/ticket-detalle.html?id={$ticketId}",
                'escalacion',
                $ticketId
            ]);
    }

    $log[] = "VENCIDO: {$t['numero_ticket']} — SLA {$t['sla_horas']}h, vencía {$t['fecha_vencimiento']}";
}

// ============================================================
// 2. TICKETS SIN RESPUESTA por más de 2 horas → Recordatorio al técnico
// ============================================================
$sinRespuesta = $db->prepare("
    SELECT t.id, t.numero_ticket, t.titulo, t.tecnico_asignado_id,
           tec.nombre_completo as tecnico_nombre
    FROM tickets t
    LEFT JOIN usuarios tec ON t.tecnico_asignado_id = tec.id
    WHERE t.estado IN ('abierto', 'en_progreso')
      AND t.tecnico_asignado_id IS NOT NULL
      AND t.primera_respuesta_at IS NULL
      AND t.created_at < DATE_SUB(NOW(), INTERVAL 2 HOUR)
");
$sinRespuesta->execute();
$ticketsSinRespuesta = $sinRespuesta->fetchAll();

foreach ($ticketsSinRespuesta as $t) {
    // Verificar si ya se recordó (cada 4 horas máximo)
    $yaRecordado = $db->prepare("
        SELECT COUNT(*) FROM notificaciones 
        WHERE referencia_tipo = 'recordatorio_respuesta' 
          AND referencia_id = ? 
          AND created_at > DATE_SUB(NOW(), INTERVAL 4 HOUR)
    ");
    $yaRecordado->execute([$t['id']]);
    if ((int)$yaRecordado->fetchColumn() > 0) continue;

    $db->prepare("INSERT INTO notificaciones (usuario_id, titulo, mensaje, tipo, url_accion, referencia_tipo, referencia_id) VALUES (?,?,?,?,?,?,?)")
        ->execute([
            $t['tecnico_asignado_id'],
            "Ticket sin respuesta: {$t['numero_ticket']}",
            "El ticket \"{$t['titulo']}\" lleva más de 2 horas sin respuesta.",
            'ticket',
            "/admin/ticket-detalle.html?id={$t['id']}",
            'recordatorio_respuesta',
            $t['id']
        ]);

    $log[] = "SIN RESPUESTA: {$t['numero_ticket']} — asignado a {$t['tecnico_nombre']}";
}

// ============================================================
// 3. TICKETS SIN ASIGNAR por más de 1 hora → Auto-asignar (si habilitado)
// ============================================================
$autoStmt = $db->prepare("SELECT valor FROM configuracion WHERE clave = 'ticket_autoasignar'");
$autoStmt->execute();
$autoAsignar = $autoStmt->fetchColumn();

if ($autoAsignar === 'true' || $autoAsignar === '1') {
    $sinAsignar = $db->prepare("
        SELECT t.id, t.numero_ticket, t.titulo
        FROM tickets t
        WHERE t.estado = 'abierto'
          AND t.tecnico_asignado_id IS NULL
          AND t.created_at < DATE_SUB(NOW(), INTERVAL 1 HOUR)
    ");
    $sinAsignar->execute();
    $ticketsSinAsignar = $sinAsignar->fetchAll();

    if (count($ticketsSinAsignar) > 0) {
        // Obtener técnico con menos carga
        $tecnicos = $db->query("
            SELECT u.id, u.nombre_completo,
                (SELECT COUNT(*) FROM tickets t WHERE t.tecnico_asignado_id = u.id AND t.estado IN ('abierto','en_progreso')) as tickets_abiertos
            FROM usuarios u 
            WHERE u.activo = 1 AND u.rol = 'tecnico'
            ORDER BY tickets_abiertos ASC, u.id ASC
        ")->fetchAll();

        // Fallback a admins si no hay técnicos
        if (count($tecnicos) === 0) {
            $tecnicos = $db->query("
                SELECT u.id, u.nombre_completo,
                    (SELECT COUNT(*) FROM tickets t WHERE t.tecnico_asignado_id = u.id AND t.estado IN ('abierto','en_progreso')) as tickets_abiertos
                FROM usuarios u 
                WHERE u.activo = 1 AND u.rol = 'admin'
                ORDER BY tickets_abiertos ASC, u.id ASC
            ")->fetchAll();
        }

        if (count($tecnicos) > 0) {
            $tecnico = $tecnicos[0];

            foreach ($ticketsSinAsignar as $t) {
                $db->prepare("UPDATE tickets SET tecnico_asignado_id = ?, estado = 'en_progreso', updated_at = NOW() WHERE id = ?")
                    ->execute([$tecnico['id'], $t['id']]);

                // Notificar al técnico
                $db->prepare("INSERT INTO notificaciones (usuario_id, titulo, mensaje, tipo, url_accion, referencia_tipo, referencia_id) VALUES (?,?,?,?,?,?,?)")
                    ->execute([
                        $tecnico['id'],
                        "Ticket auto-asignado: {$t['numero_ticket']}",
                        "El ticket \"{$t['titulo']}\" te fue asignado automáticamente.",
                        'ticket',
                        "/admin/ticket-detalle.html?id={$t['id']}",
                        'auto_asignacion',
                        $t['id']
                    ]);

                $log[] = "AUTO-ASIGNADO: {$t['numero_ticket']} → {$tecnico['nombre_completo']}";
            }
        }
    }
}

// ============================================================
// LOG
// ============================================================
if (!empty($log)) {
    echo date('Y-m-d H:i:s') . " — SLA Escalation:\n" . implode("\n", $log) . "\n";
    error_log("SLA Escalation: " . implode(" | ", $log));
} else {
    echo date('Y-m-d H:i:s') . " — SLA Escalation: Sin acciones pendientes\n";
}
