<?php
/**
 * NEXUS IT — Clasificador IA de Tickets (Groq + Llama)
 * Clasifica automáticamente: categoría, subcategoría, prioridad y genera resumen.
 */
class AIClassifier {

    private static function getApiKey(): string {
        $db = getDB();
        $stmt = $db->prepare("SELECT valor FROM configuracion WHERE clave = 'groq_api_key'");
        $stmt->execute();
        return $stmt->fetchColumn() ?: '';
    }

    /**
     * Clasificar un ticket usando IA
     */
    public static function clasificar(string $titulo, string $descripcion, ?int $ticketId = null): array {
        $apiKey = self::getApiKey();
        if (empty($apiKey)) {
            return ['ok' => false, 'error' => 'API key de Groq no configurada'];
        }

        // Obtener categorías y subcategorías existentes
        $db = getDB();
        $cats = $db->query("SELECT c.id, c.nombre, GROUP_CONCAT(s.id, ':', s.nombre SEPARATOR '|') as subs 
            FROM categorias c 
            LEFT JOIN subcategorias s ON s.categoria_id = c.id AND s.activa = 1
            WHERE c.activa = 1 
            GROUP BY c.id, c.nombre 
            ORDER BY c.nombre")->fetchAll();

        if (empty($cats)) {
            return ['ok' => false, 'error' => 'No hay categorías configuradas'];
        }

        // Construir lista de categorías para el prompt
        $catList = [];
        $catMap = [];
        $subMap = [];
        foreach ($cats as $cat) {
            $catMap[$cat['id']] = $cat['nombre'];
            $entry = "- {$cat['nombre']} (id:{$cat['id']})";
            if (!empty($cat['subs'])) {
                $subs = [];
                foreach (explode('|', $cat['subs']) as $sub) {
                    $parts = explode(':', $sub, 2);
                    if (count($parts) === 2) {
                        $subs[] = "{$parts[1]} (id:{$parts[0]})";
                        $subMap[$parts[0]] = $parts[1];
                    }
                }
                $entry .= "\n  Subcategorías: " . implode(', ', $subs);
            }
            $catList[] = $entry;
        }
        $categoriasTexto = implode("\n", $catList);

        $prompt = <<<PROMPT
Eres un asistente de mesa de ayuda IT. Analiza el siguiente ticket de soporte y clasifícalo.

CATEGORÍAS DISPONIBLES:
{$categoriasTexto}

TICKET:
Asunto: {$titulo}
Descripción: {$descripcion}

Responde SOLO con un JSON válido (sin markdown, sin explicación, sin ```), con esta estructura exacta:
{
  "categoria_id": <número>,
  "subcategoria_id": <número o null si no aplica>,
  "prioridad": "<urgente|alta|media|baja>",
  "resumen": "<resumen breve del problema en 1-2 oraciones en español>"
}

Reglas:
- Elige la categoría que mejor coincida. Si ninguna coincide, elige la más cercana.
- La prioridad debe ser: urgente (sistema caído, no pueden trabajar), alta (afecta productividad), media (problema normal), baja (consulta, mejora).
- El resumen debe ser claro y conciso en español.
- Solo devuelve el JSON, nada más.
PROMPT;

        // Llamar a Groq API
        $response = self::callGroq($apiKey, $prompt);
        
        if (!$response['ok']) {
            return $response;
        }

        // Parsear respuesta
        $text = $response['text'];
        // Limpiar posibles backticks markdown
        $text = preg_replace('/```json\s*/', '', $text);
        $text = preg_replace('/```\s*/', '', $text);
        $text = trim($text);

        $data = json_decode($text, true);
        if (!$data) {
            return ['ok' => false, 'error' => 'Respuesta IA no válida', 'raw' => $text];
        }

        // Validar que la categoría existe
        $catId = (int)($data['categoria_id'] ?? 0);
        $subId = isset($data['subcategoria_id']) ? (int)$data['subcategoria_id'] : null;
        $prioridad = $data['prioridad'] ?? 'media';
        $resumen = $data['resumen'] ?? '';

        if (!isset($catMap[$catId])) {
            $catId = array_key_first($catMap); // fallback a primera categoría
        }

        // Validar prioridad
        if (!in_array($prioridad, ['urgente', 'critica', 'alta', 'media', 'baja'])) {
            $prioridad = 'media';
        }
        // Map 'urgente' to 'critica' (ticket enum uses 'critica')
        if ($prioridad === 'urgente') $prioridad = 'critica';

        // Aplicar al ticket si se proporcionó ID
        if ($ticketId) {
            $updateFields = ['categoria_id = ?', 'prioridad = ?', 'updated_at = NOW()'];
            $updateParams = [$catId, $prioridad];
            
            if ($subId) {
                $updateFields[] = 'subcategoria_id = ?';
                $updateParams[] = $subId;
            }
            
            if (!empty($resumen)) {
                $updateFields[] = 'resumen_ia = ?';
                $updateParams[] = $resumen;
            }

            // Recalcular SLA con la nueva prioridad/categoría
            if (class_exists('SLACalculator')) {
                $stmtCreated = $db->prepare("SELECT created_at FROM tickets WHERE id = ?");
                $stmtCreated->execute([$ticketId]);
                $created = $stmtCreated->fetch();
                $slaHoras = SLACalculator::getHorasSLA($prioridad, $catId);
                $fechaVenc = SLACalculator::calcularVencimiento($slaHoras, $created ? $created['created_at'] : null);
                $updateFields[] = 'sla_horas = ?';
                $updateParams[] = $slaHoras;
                $updateFields[] = 'fecha_vencimiento = ?';
                $updateParams[] = $fechaVenc;
            }
            
            $updateParams[] = $ticketId;
            $sql = "UPDATE tickets SET " . implode(', ', $updateFields) . " WHERE id = ?";
            $db->prepare($sql)->execute($updateParams);
        }

        return [
            'ok' => true,
            'categoria_id' => $catId,
            'categoria_nombre' => $catMap[$catId] ?? 'Desconocida',
            'subcategoria_id' => $subId,
            'subcategoria_nombre' => $subId ? ($subMap[$subId] ?? null) : null,
            'prioridad' => $prioridad,
            'resumen' => $resumen
        ];
    }

    /**
     * Llamar a Groq API
     */
    private static function callGroq(string $apiKey, string $prompt): array {
        $url = 'https://api.groq.com/openai/v1/chat/completions';
        
        $payload = json_encode([
            'model' => 'llama-3.3-70b-versatile',
            'messages' => [
                ['role' => 'system', 'content' => 'Eres un clasificador de tickets IT. Responde SOLO con JSON válido.'],
                ['role' => 'user', 'content' => $prompt]
            ],
            'temperature' => 0.1,
            'max_tokens' => 300,
            'response_format' => ['type' => 'json_object']
        ]);

        $ch = curl_init($url);
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POST => true,
            CURLOPT_HTTPHEADER => [
                'Content-Type: application/json',
                'Authorization: Bearer ' . $apiKey
            ],
            CURLOPT_POSTFIELDS => $payload,
            CURLOPT_TIMEOUT => 30,
            CURLOPT_CONNECTTIMEOUT => 10
        ]);

        $result = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $error = curl_error($ch);
        curl_close($ch);

        if ($error) {
            return ['ok' => false, 'error' => "Error de conexión: $error"];
        }

        if ($httpCode !== 200) {
            $body = json_decode($result, true);
            $msg = $body['error']['message'] ?? "HTTP $httpCode";
            return ['ok' => false, 'error' => "Error Groq: $msg"];
        }

        $body = json_decode($result, true);
        $text = $body['choices'][0]['message']['content'] ?? '';

        if (empty($text)) {
            return ['ok' => false, 'error' => 'Respuesta vacía de Groq'];
        }

        return ['ok' => true, 'text' => $text];
    }

    /**
     * Test de conexión con Groq
     */
    public static function test(): array {
        $apiKey = self::getApiKey();
        if (empty($apiKey)) {
            return ['ok' => false, 'message' => 'API key no configurada'];
        }

        $response = self::callGroq($apiKey, 'Responde solo con este JSON: {"status":"ok","message":"Conexión exitosa"}');
        if (!$response['ok']) {
            return ['ok' => false, 'message' => $response['error']];
        }

        return ['ok' => true, 'message' => 'Conexión con Groq exitosa. Modelo: llama-3.3-70b-versatile'];
    }
}
