<?php

namespace ControleFrotas\Config;

use PDO;
use PDOException;

/**
 * Classe para gerenciar conexões com o banco de dados
 */
class Database
{
    private static ?PDO $connection = null;
    private static array $config = [];

    /**
     * Configura os parâmetros de conexão
     */
    public static function configure(array $config): void
    {
        self::$config = array_merge([
            'host' => 'localhost',
            'port' => 3306,
            'database' => 'pinheir3_controle_frotasV1.1',
            'username' => 'pinheir3_admin',
            'password' => '080880Gelboy',
            'charset' => 'utf8mb4',
            'options' => [
                PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
                PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
                PDO::ATTR_EMULATE_PREPARES => false,
                PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci"
            ]
        ], $config);
    }

    /**
     * Obtém a conexão com o banco (singleton)
     */
    public static function getConnection(): PDO
    {
        if (self::$connection === null) {
            self::connect();
        }

        return self::$connection;
    }

    /**
     * Estabelece a conexão com o banco
     */
    private static function connect(): void
    {
        if (empty(self::$config)) {
            throw new PDOException('Database configuration not set. Call Database::configure() first.');
        }

        $dsn = sprintf(
            'mysql:host=%s;port=%d;dbname=%s;charset=%s',
            self::$config['host'],
            self::$config['port'],
            self::$config['database'],
            self::$config['charset']
        );

        try {
            self::$connection = new PDO(
                $dsn,
                self::$config['username'],
                self::$config['password'],
                self::$config['options']
            );
        } catch (PDOException $e) {
            error_log("Database connection error: " . $e->getMessage());
            throw new PDOException('Could not connect to database: ' . $e->getMessage());
        }
    }

    /**
     * Fecha a conexão
     */
    public static function disconnect(): void
    {
        self::$connection = null;
    }

    /**
     * Inicia uma transação
     */
    public static function beginTransaction(): bool
    {
        return self::getConnection()->beginTransaction();
    }

    /**
     * Confirma uma transação
     */
    public static function commit(): bool
    {
        return self::getConnection()->commit();
    }

    /**
     * Desfaz uma transação
     */
    public static function rollback(): bool
    {
        return self::getConnection()->rollBack();
    }

    /**
     * Executa uma query e retorna o resultado
     */
    public static function query(string $sql, array $params = []): \PDOStatement
    {
        $connection = self::getConnection();
        $stmt = $connection->prepare($sql);
        $stmt->execute($params);
        return $stmt;
    }

    /**
     * Executa uma query e retorna apenas uma linha
     */
    public static function queryOne(string $sql, array $params = []): ?array
    {
        $stmt = self::query($sql, $params);
        $result = $stmt->fetch();
        return $result ?: null;
    }

    /**
     * Executa uma query e retorna todas as linhas
     */
    public static function queryAll(string $sql, array $params = []): array
    {
        $stmt = self::query($sql, $params);
        return $stmt->fetchAll();
    }

    /**
     * Executa uma query de inserção e retorna o último ID inserido
     */
    public static function insert(string $sql, array $params = []): string
    {
        self::query($sql, $params);
        return self::getConnection()->lastInsertId();
    }

    /**
     * Executa uma query de atualização/deleção e retorna o número de linhas afetadas
     */
    public static function execute(string $sql, array $params = []): int
    {
        $stmt = self::query($sql, $params);
        return $stmt->rowCount();
    }

    /**
     * Testa a conexão com o banco
     */
    public static function testConnection(): bool
    {
        try {
            $connection = self::getConnection();
            $stmt = $connection->query('SELECT 1');
            return $stmt !== false;
        } catch (PDOException $e) {
            return false;
        }
    }

    /**
     * Obtém informações sobre o banco
     */
    public static function getDatabaseInfo(): array
    {
        try {
            $connection = self::getConnection();
            
            $version = $connection->query('SELECT VERSION() as version')->fetch()['version'];
            $charset = $connection->query('SELECT @@character_set_database as charset')->fetch()['charset'];
            $collation = $connection->query('SELECT @@collation_database as collation')->fetch()['collation'];
            
            return [
                'version' => $version,
                'charset' => $charset,
                'collation' => $collation,
                'database' => self::$config['database']
            ];
        } catch (PDOException $e) {
            return ['error' => $e->getMessage()];
        }
    }
} 
