<?php

// Carregar autoloader do Composer
require_once __DIR__ . '/../vendor/autoload.php';

// Carregar variáveis de ambiente
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__ . '/..');
$dotenv->load();

use ControleFrotas\Config\Database;
use ControleFrotas\Utils\JWT;
use ControleFrotas\Utils\Logger;
use ControleFrotas\Utils\Response;

// Configurar timezone
date_default_timezone_set($_ENV['APP_TIMEZONE'] ?? 'America/Sao_Paulo');

// Configurar exibição de erros baseado no ambiente
if (($_ENV['APP_ENV'] ?? 'production') === 'development') {
    error_reporting(E_ALL);
    ini_set('display_errors', 1);
} else {
    error_reporting(0);
    ini_set('display_errors', 0);
}

// Configurar Database
Database::configure([
    'host' => $_ENV['DB_HOST'] ?? 'localhost',
    'port' => (int)($_ENV['DB_PORT'] ?? 3306),
    'database' => $_ENV['DB_NAME'] ?? 'controle_frotas',
    'username' => $_ENV['DB_USER'] ?? 'root',
    'password' => $_ENV['DB_PASS'] ?? '',
    'charset' => 'utf8mb4'
]);

// Configurar JWT
JWT::configure(
    $_ENV['JWT_SECRET'] ?? 'sua_chave_jwt_super_secreta',
    (int)($_ENV['JWT_EXPIRATION'] ?? 3600)
);

// Configurar Logger
Logger::configure(
    true, // Log para banco
    true, // Log para arquivo
    __DIR__ . '/../' . ($_ENV['LOG_PATH'] ?? 'logs/')
);

// Configurar CORS
$allowedOrigins = !empty($_ENV['CORS_ALLOWED_ORIGINS']) ? 
    explode(',', $_ENV['CORS_ALLOWED_ORIGINS']) : ['*'];

$allowedMethods = !empty($_ENV['CORS_ALLOWED_METHODS']) ? 
    explode(',', $_ENV['CORS_ALLOWED_METHODS']) : ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'];

Response::setCorsHeaders($allowedOrigins, $allowedMethods);

// Handler de erros personalizados
set_error_handler(function($severity, $message, $file, $line) {
    if (!(error_reporting() & $severity)) {
        return false;
    }
    
    Logger::error("PHP Error: $message", [
        'severity' => $severity,
        'file' => $file,
        'line' => $line,
        'trace' => debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 5)
    ]);
    
    if (($_ENV['APP_ENV'] ?? 'production') === 'development') {
        throw new ErrorException($message, 0, $severity, $file, $line);
    }
    
    return true;
});

// Handler de exceções não capturadas
set_exception_handler(function($exception) {
    Logger::critical('Uncaught Exception: ' . $exception->getMessage(), [
        'exception' => get_class($exception),
        'file' => $exception->getFile(),
        'line' => $exception->getLine(),
        'trace' => $exception->getTraceAsString()
    ]);
    
    if (($_ENV['APP_ENV'] ?? 'production') === 'development') {
        Response::error('Erro interno: ' . $exception->getMessage(), 500, [
            'file' => $exception->getFile(),
            'line' => $exception->getLine()
        ]);
    } else {
        Response::internalError();
    }
});

// Função para verificar se é uma requisição de API
function isApiRequest(): bool {
    $uri = $_SERVER['REQUEST_URI'] ?? '';
    return strpos($uri, '/api/') === 0;
}

// Função para obter usuário autenticado
function getCurrentUser(): ?array {
    $token = JWT::extractFromHeader();
    if (!$token) {
        return null;
    }
    
    return JWT::decode($token);
}

// Função para verificar autenticação
function requireAuth(): array {
    $user = getCurrentUser();
    if (!$user) {
        Response::unauthorized('Token de acesso necessário');
    }
    
    return $user;
}

// Função para verificar permissões
function requireRole(string ...$roles): array {
    $user = requireAuth();
    
    if (!in_array($user['cargo'], $roles)) {
        Response::forbidden('Permissão insuficiente');
    }
    
    return $user;
}

// Função para validar dados de entrada
function validateRequired(array $data, array $requiredFields): void {
    $errors = [];
    
    foreach ($requiredFields as $field) {
        if (!isset($data[$field]) || empty(trim($data[$field]))) {
            $errors[$field] = "Campo '$field' é obrigatório";
        }
    }
    
    if (!empty($errors)) {
        Response::validationError($errors);
    }
}

// Função para sanitizar dados
function sanitizeInput(array $data): array {
    $sanitized = [];
    
    foreach ($data as $key => $value) {
        if (is_string($value)) {
            $sanitized[$key] = htmlspecialchars(trim($value), ENT_QUOTES, 'UTF-8');
        } elseif (is_array($value)) {
            $sanitized[$key] = sanitizeInput($value);
        } else {
            $sanitized[$key] = $value;
        }
    }
    
    return $sanitized;
}

// Função para obter parâmetros de paginação
function getPaginationParams(): array {
    $page = max(1, (int)($_GET['page'] ?? 1));
    $perPage = min(100, max(1, (int)($_GET['per_page'] ?? 20)));
    $offset = ($page - 1) * $perPage;
    
    return [
        'page' => $page,
        'per_page' => $perPage,
        'offset' => $offset
    ];
}

// Teste de conexão com banco na inicialização (apenas em desenvolvimento)
if (($_ENV['APP_ENV'] ?? 'production') === 'development') {
    try {
        if (!Database::testConnection()) {
            Logger::critical('Falha na conexão com banco de dados durante inicialização');
        }
    } catch (Exception $e) {
        Logger::critical('Erro ao testar conexão com banco: ' . $e->getMessage());
    }
}

// Log de inicialização da aplicação
if (isApiRequest()) {
    Logger::info('API Request iniciada', [
        'method' => $_SERVER['REQUEST_METHOD'] ?? 'UNKNOWN',
        'uri' => $_SERVER['REQUEST_URI'] ?? 'UNKNOWN',
        'ip' => $_SERVER['REMOTE_ADDR'] ?? 'UNKNOWN',
        'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? 'UNKNOWN'
    ]);
} 
