<?php

namespace Gestoreasy\Core\Database;

use PDO;
use Exception;

/**
 * Logger de queries para monitoramento de performance
 */
class QueryLogger {
    private static array $queries = [];
    private static bool $enabled = false;
    private static int $slowQueryThreshold = 1000; // ms
    private static array $slowQueries = [];

    /**
     * Habilita o logging de queries
     */
    public static function enable(int $slowQueryThreshold = 1000): void {
        self::$enabled = true;
        self::$slowQueryThreshold = $slowQueryThreshold;
    }

    /**
     * Desabilita o logging de queries
     */
    public static function disable(): void {
        self::$enabled = false;
    }

    /**
     * Verifica se está habilitado
     */
    public static function isEnabled(): bool {
        return self::$enabled;
    }

    /**
     * Registra uma query executada
     */
    public static function log(string $sql, array $params, float $durationMs, ?string $error = null): void {
        if (!self::$enabled) {
            return;
        }

        $query = [
            'sql' => $sql,
            'params' => $params,
            'duration_ms' => $durationMs,
            'timestamp' => microtime(true),
            'error' => $error,
        ];

        self::$queries[] = $query;

        // Registrar queries lentas
        if ($durationMs > self::$slowQueryThreshold) {
            self::$slowQueries[] = $query;
            error_log(sprintf(
                'SLOW QUERY (%.2fms): %s | Params: %s',
                $durationMs,
                $sql,
                json_encode($params)
            ));
        }

        // Limitar tamanho do array (manter últimas 1000 queries)
        if (count(self::$queries) > 1000) {
            self::$queries = array_slice(self::$queries, -1000);
        }
    }

    /**
     * Obtém todas as queries registradas
     */
    public static function getQueries(): array {
        return self::$queries;
    }

    /**
     * Obtém queries lentas
     */
    public static function getSlowQueries(): array {
        return self::$slowQueries;
    }

    /**
     * Obtém estatísticas de queries
     */
    public static function getStats(): array {
        if (empty(self::$queries)) {
            return [
                'total' => 0,
                'slow' => 0,
                'avg_duration' => 0,
                'max_duration' => 0,
                'min_duration' => 0,
            ];
        }

        $durations = array_column(self::$queries, 'duration_ms');
        $slowCount = count(self::$slowQueries);

        return [
            'total' => count(self::$queries),
            'slow' => $slowCount,
            'avg_duration' => round(array_sum($durations) / count($durations), 2),
            'max_duration' => round(max($durations), 2),
            'min_duration' => round(min($durations), 2),
            'slow_threshold' => self::$slowQueryThreshold,
        ];
    }

    /**
     * Limpa queries registradas
     */
    public static function clear(): void {
        self::$queries = [];
        self::$slowQueries = [];
    }

    /**
     * Obtém queries agrupadas por SQL (para identificar queries duplicadas)
     */
    public static function getQueriesBySql(): array {
        $grouped = [];
        
        foreach (self::$queries as $query) {
            $sql = $query['sql'];
            if (!isset($grouped[$sql])) {
                $grouped[$sql] = [
                    'sql' => $sql,
                    'count' => 0,
                    'total_duration' => 0,
                    'avg_duration' => 0,
                    'max_duration' => 0,
                ];
            }
            
            $grouped[$sql]['count']++;
            $grouped[$sql]['total_duration'] += $query['duration_ms'];
            $grouped[$sql]['max_duration'] = max($grouped[$sql]['max_duration'], $query['duration_ms']);
        }

        // Calcular média
        foreach ($grouped as &$group) {
            $group['avg_duration'] = round($group['total_duration'] / $group['count'], 2);
        }

        // Ordenar por total_duration (desc)
        uasort($grouped, fn($a, $b) => $b['total_duration'] <=> $a['total_duration']);

        return $grouped;
    }
}

