<?php
declare(strict_types=1);

require_once __DIR__ . '/../config/helpers.php';
require_once __DIR__ . '/../config/push.php';

$method = $_SERVER['REQUEST_METHOD'] ?? 'GET';
$data = $method === 'POST' ? input_json() : $_GET;

$idCorrida = (int) ($data['id_corrida'] ?? $data['id'] ?? 0);
$idUsuario = (int) ($data['id_usuario'] ?? 0);
$tipoUsuario = trim((string) ($data['tipo_usuario'] ?? ''));

if ($idCorrida <= 0 || $idUsuario <= 0 || !in_array($tipoUsuario, ['motorista', 'passageiro'], true)) {
    json_fail('Corrida ou usuario nao informado.');
}

function chat_buscar_corrida(PDO $pdo, int $idCorrida, int $idUsuario, string $tipoUsuario): array
{
    $stmt = $pdo->prepare(
        'SELECT id, id_passageiro, id_motorista, status
         FROM corridas
         WHERE id = ?
         LIMIT 1'
    );
    $stmt->execute([$idCorrida]);
    $corrida = $stmt->fetch();
    if (!$corrida) {
        json_fail('Corrida nao encontrada.', 404);
    }

    if ((int) ($corrida['id_motorista'] ?? 0) <= 0 || (string) $corrida['status'] === 'pendente') {
        json_fail('Chat disponivel somente depois que o motorista aceitar a corrida.', 403);
    }

    if (in_array((string) $corrida['status'], ['finalizada', 'cancelada'], true)) {
        json_fail('Chat encerrado para esta corrida.', 403);
    }

    if ($tipoUsuario === 'passageiro' && (int) $corrida['id_passageiro'] !== $idUsuario) {
        json_fail('Voce nao tem acesso a este chat.', 403);
    }

    if ($tipoUsuario === 'motorista' && (int) $corrida['id_motorista'] !== $idUsuario) {
        json_fail('Voce nao tem acesso a este chat.', 403);
    }

    return $corrida;
}

function chat_nome_usuario(PDO $pdo, int $idUsuario, string $tipoUsuario): string
{
    $stmt = $pdo->prepare('SELECT nome FROM usuarios WHERE id = ? LIMIT 1');
    $stmt->execute([$idUsuario]);
    $nome = trim((string) ($stmt->fetchColumn() ?: ''));
    if ($nome === '') {
        return $tipoUsuario === 'motorista' ? 'Motorista' : 'Passageiro';
    }

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

function chat_notificar_destinatario(
    array $corrida,
    string $remetenteTipo,
    string $nome,
    string $mensagem
): void {
    if (!function_exists('push_enviar_chat_corrida_usuario')) {
        return;
    }

    $destinatarioTipo = $remetenteTipo === 'motorista' ? 'passageiro' : 'motorista';
    $idDestinatario = (int) (
        $destinatarioTipo === 'passageiro'
            ? ($corrida['id_passageiro'] ?? 0)
            : ($corrida['id_motorista'] ?? 0)
    );
    if ($idDestinatario <= 0) {
        return;
    }

    $app = $destinatarioTipo === 'passageiro' ? 'bulo_passageiro' : 'bulo_motorista';
    $titulo = $remetenteTipo === 'motorista'
        ? 'Nova mensagem do motorista'
        : 'Nova mensagem do passageiro';
    $texto = trim($mensagem);
    if (mb_strlen($texto) > 120) {
        $texto = mb_substr($texto, 0, 117) . '...';
    }
    if ($texto === '') {
        $texto = 'Toque para abrir o chat da corrida.';
    }

    try {
        push_enviar_chat_corrida_usuario(
            $idDestinatario,
            $destinatarioTipo,
            $app,
            (int) ($corrida['id'] ?? 0),
            $titulo,
            $texto
        );
    } catch (Throwable $e) {
        // A mensagem ja foi salva; falha no push nao pode quebrar o chat.
    }
}

try {
    $pdo = db();
    $corridaAtual = chat_buscar_corrida($pdo, $idCorrida, $idUsuario, $tipoUsuario);

    if ($method === 'POST') {
        $mensagem = trim((string) ($data['mensagem'] ?? ''));
        if ($mensagem === '') {
            json_fail('Digite uma mensagem.');
        }

        if (mb_strlen($mensagem) > 1000) {
            json_fail('Mensagem muito longa.');
        }

        $nome = chat_nome_usuario($pdo, $idUsuario, $tipoUsuario);
        $lidaMotorista = $tipoUsuario === 'motorista' ? 1 : 0;
        $lidaPassageiro = $tipoUsuario === 'passageiro' ? 1 : 0;

        $stmt = $pdo->prepare(
            'INSERT INTO corrida_mensagens
             (id_corrida, remetente_tipo, id_remetente, nome_remetente, mensagem, lida_motorista, lida_passageiro)
             VALUES (?, ?, ?, ?, ?, ?, ?)'
        );
        $stmt->execute([$idCorrida, $tipoUsuario, $idUsuario, $nome, $mensagem, $lidaMotorista, $lidaPassageiro]);
        chat_notificar_destinatario($corridaAtual, $tipoUsuario, $nome, $mensagem);
    }

    if ($tipoUsuario === 'motorista') {
        $read = $pdo->prepare(
            'UPDATE corrida_mensagens
             SET lida_motorista = 1
             WHERE id_corrida = ? AND remetente_tipo <> "motorista"'
        );
    } else {
        $read = $pdo->prepare(
            'UPDATE corrida_mensagens
             SET lida_passageiro = 1
             WHERE id_corrida = ? AND remetente_tipo <> "passageiro"'
        );
    }
    $marcarLidas = !isset($data['marcar_lidas'])
        || !in_array(strtolower((string) $data['marcar_lidas']), ['0', 'false', 'nao', 'não'], true);
    if ($marcarLidas) {
        $read->execute([$idCorrida]);
    }

    $ultimoId = (int) ($data['ultimo_id'] ?? 0);
    if ($ultimoId > 0) {
        $mensagensStmt = $pdo->prepare(
            'SELECT id, id_corrida, remetente_tipo, id_remetente, nome_remetente, mensagem,
                    lida_motorista, lida_passageiro, criado_em
             FROM corrida_mensagens
             WHERE id_corrida = ? AND id > ?
             ORDER BY criado_em ASC, id ASC'
        );
        $mensagensStmt->execute([$idCorrida, $ultimoId]);
    } else {
        $mensagensStmt = $pdo->prepare(
            'SELECT id, id_corrida, remetente_tipo, id_remetente, nome_remetente, mensagem,
                    lida_motorista, lida_passageiro, criado_em
             FROM corrida_mensagens
             WHERE id_corrida = ?
             ORDER BY criado_em ASC, id ASC'
        );
        $mensagensStmt->execute([$idCorrida]);
    }

    $naoLidasColuna = $tipoUsuario === 'motorista' ? 'lida_motorista' : 'lida_passageiro';
    $naoLidasStmt = $pdo->prepare(
        "SELECT COUNT(*)
         FROM corrida_mensagens
         WHERE id_corrida = ? AND remetente_tipo <> ? AND {$naoLidasColuna} = 0"
    );
    $naoLidasStmt->execute([$idCorrida, $tipoUsuario]);

    json_ok([
        'mensagens' => $mensagensStmt->fetchAll(),
        'nao_lidas' => (int) $naoLidasStmt->fetchColumn(),
        'message' => $method === 'POST' ? 'Mensagem enviada.' : 'Chat carregado.',
    ]);
} catch (Throwable $e) {
    json_fail('Erro ao carregar chat da corrida.', 500, ['error' => $e->getMessage()]);
}
