<?php
declare(strict_types=1);

require_once __DIR__ . '/database.php';

const CORRIDA_COMPARTILHAMENTO_GRACA_MINUTOS = 10;

function corrida_compartilhamento_token_hash(string $token): string
{
    return hash('sha256', $token);
}

function corrida_compartilhamento_token_valido(string $token): bool
{
    return (bool) preg_match('/^[a-f0-9]{64}$/i', $token);
}

function corrida_compartilhamento_novo_token(): string
{
    return bin2hex(random_bytes(32));
}

function corrida_compartilhamento_public_base_url(): string
{
    $https = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off')
        || (string) ($_SERVER['SERVER_PORT'] ?? '') === '443';
    $scheme = $https ? 'https' : 'http';
    $host = (string) ($_SERVER['HTTP_HOST'] ?? 'localhost');
    $script = str_replace('\\', '/', (string) ($_SERVER['SCRIPT_NAME'] ?? '/bulo_backend/index.php'));
    $base = rtrim(dirname(dirname($script)), '/');
    if ($base === '' || $base === '.') {
        $base = '/bulo_backend';
    }

    return $scheme . '://' . $host . $base;
}

function corrida_compartilhamento_public_url(string $token): string
{
    return corrida_compartilhamento_public_base_url()
        . '/compartilhar_corrida/?t=' . rawurlencode($token);
}

function corrida_compartilhamento_primeiro_nome(?string $nome): string
{
    $nome = trim((string) $nome);
    if ($nome === '') {
        return 'Usuario';
    }

    $partes = preg_split('/\s+/', $nome);
    return (string) ($partes[0] ?? $nome);
}

function corrida_compartilhamento_status_publico(string $status): string
{
    return match ($status) {
        'pendente' => 'Buscando motorista',
        'aceita' => 'Motorista a caminho',
        'aguardando_embarque' => 'Motorista aguardando embarque',
        'em_andamento' => 'Viagem em andamento',
        'finalizada' => 'Corrida finalizada',
        'cancelada' => 'Corrida cancelada',
        default => $status,
    };
}

function corrida_compartilhamento_esta_expirado(array $row): bool
{
    if ((int) ($row['ativo'] ?? 0) !== 1) {
        return true;
    }

    $expiraEm = strtotime((string) ($row['expira_em'] ?? ''));
    if ($expiraEm !== false && $expiraEm < time()) {
        return true;
    }

    $status = (string) ($row['status'] ?? '');
    $fim = (string) (($row['finalizada_em'] ?? '') ?: ($row['cancelada_em'] ?? ''));
    $fimTs = strtotime($fim);
    if (in_array($status, ['finalizada', 'cancelada'], true) && $fimTs !== false) {
        return $fimTs + (CORRIDA_COMPARTILHAMENTO_GRACA_MINUTOS * 60) < time();
    }

    return false;
}

function corrida_compartilhamento_buscar_por_token(PDO $pdo, string $token): ?array
{
    if (!corrida_compartilhamento_token_valido($token)) {
        return null;
    }

    $stmt = $pdo->prepare(
        'SELECT cc.*, c.status, c.finalizada_em, c.cancelada_em
         FROM corrida_compartilhamentos cc
         INNER JOIN corridas c ON c.id = cc.id_corrida
         WHERE cc.token_hash = ?
         LIMIT 1'
    );
    $stmt->execute([corrida_compartilhamento_token_hash($token)]);
    $row = $stmt->fetch();
    if (!$row || corrida_compartilhamento_esta_expirado($row)) {
        return null;
    }

    return $row;
}

function corrida_compartilhamento_marcar_acesso(PDO $pdo, int $idCompartilhamento): void
{
    $stmt = $pdo->prepare(
        'UPDATE corrida_compartilhamentos
         SET ultimo_acesso_em = NOW(), acessos = acessos + 1
         WHERE id = ?'
    );
    $stmt->execute([$idCompartilhamento]);
}

function corrida_compartilhamento_dados(PDO $pdo, int $idCorrida): ?array
{
    $stmt = $pdo->prepare(
        'SELECT c.*,
                COALESCE(NULLIF(p.primeiro_nome, ""), p.nome) AS passageiro_nome,
                p.ultimo_lat AS passageiro_lat,
                p.ultimo_lng AS passageiro_lng,
                p.localizacao_atualizada_em AS passageiro_localizacao_atualizada_em,
                COALESCE(NULLIF(m.primeiro_nome, ""), m.nome) AS motorista_nome,
                m.ultimo_lat AS motorista_lat,
                m.ultimo_lng AS motorista_lng,
                m.ultimo_rumo AS motorista_rumo,
                m.localizacao_atualizada_em AS motorista_localizacao_atualizada_em,
                v.marca AS veiculo_marca,
                v.modelo AS veiculo_modelo,
                v.cor AS veiculo_cor,
                v.placa AS veiculo_placa
         FROM corridas c
         LEFT JOIN usuarios p ON p.id = c.id_passageiro
         LEFT JOIN usuarios m ON m.id = c.id_motorista
         LEFT JOIN veiculos v ON v.id = m.id_veiculo_ativo
         WHERE c.id = ?
         LIMIT 1'
    );
    $stmt->execute([$idCorrida]);
    $corrida = $stmt->fetch();
    if (!$corrida) {
        return null;
    }

    $paradasStmt = $pdo->prepare(
        'SELECT ordem, lat, lng, endereco, confirmada_em
         FROM corrida_paradas
         WHERE id_corrida = ?
         ORDER BY ordem ASC'
    );
    $paradasStmt->execute([$idCorrida]);

    $pontos = [];
    $pontosStmt = $pdo->prepare(
        'SELECT lat, lng, rumo, velocidade, registrado_em
         FROM corrida_pontos_rota
         WHERE id_corrida = ?
         ORDER BY registrado_em ASC, id ASC
         LIMIT 400'
    );
    try {
        $pontosStmt->execute([$idCorrida]);
        $pontos = $pontosStmt->fetchAll();
    } catch (Throwable) {
        $pontos = [];
    }

    $corrida['id'] = (int) $corrida['id'];
    $corrida['id_motorista'] = $corrida['id_motorista'] === null ? null : (int) $corrida['id_motorista'];
    $corrida['passageiro_nome'] = corrida_compartilhamento_primeiro_nome($corrida['passageiro_nome'] ?? null);
    $corrida['motorista_nome'] = $corrida['motorista_nome'] === null
        ? null
        : corrida_compartilhamento_primeiro_nome((string) $corrida['motorista_nome']);
    $corrida['status_label'] = corrida_compartilhamento_status_publico((string) $corrida['status']);
    $corrida['paradas'] = $paradasStmt->fetchAll();
    $corrida['pontos_rota'] = $pontos;
    $corrida['atualizado_em_servidor'] = date('Y-m-d H:i:s');

    return $corrida;
}
