<?php
declare(strict_types=1);

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

$method = $_SERVER['REQUEST_METHOD'] ?? 'GET';
$data = $method === 'POST' ? input_json() : $_GET;
$idUsuario = (int) ($data['id_usuario'] ?? $data['id_motorista'] ?? $data['id_passageiro'] ?? 0);
$tipoUsuario = avisos_tipo_usuario((string) ($data['tipo_usuario'] ?? $data['tipo'] ?? ''));

if ($idUsuario <= 0) {
    json_fail('Usuario nao informado.');
}

try {
    $pdo = db();
    avisos_usuario_existe($pdo, $idUsuario);

    if ($method === 'POST') {
        $acao = (string) ($data['acao'] ?? 'marcar_lido');
        if ($acao === 'marcar_todos_lidos') {
            avisos_marcar_todos_lidos($pdo, $idUsuario, $tipoUsuario);
            json_ok(['message' => 'Avisos marcados como lidos.']);
        }

        $idAviso = (int) ($data['id_aviso'] ?? $data['id'] ?? 0);
        if ($idAviso <= 0) {
            json_fail('Aviso nao informado.');
        }

        if (!avisos_visivel_para_usuario($pdo, $idAviso, $tipoUsuario)) {
            json_fail('Aviso nao encontrado para este usuario.', 404);
        }

        $stmt = $pdo->prepare(
            'INSERT INTO avisos_leituras (id_aviso, id_usuario, lido_em)
             VALUES (?, ?, NOW())
             ON DUPLICATE KEY UPDATE lido_em = VALUES(lido_em)'
        );
        $stmt->execute([$idAviso, $idUsuario]);

        json_ok(['message' => 'Aviso marcado como lido.']);
    }

    $avisos = avisos_listar_usuario($pdo, $idUsuario, $tipoUsuario);
    $naoLidos = 0;
    foreach ($avisos as $aviso) {
        if ((int) $aviso['lido'] === 0) {
            $naoLidos++;
        }
    }

    json_ok([
        'tipo_usuario' => $tipoUsuario,
        'nao_lidos' => $naoLidos,
        'avisos' => $avisos,
    ]);
} catch (Throwable $e) {
    json_fail('Erro ao processar avisos.', 500, ['error' => $e->getMessage()]);
}

function avisos_tipo_usuario(string $tipo): string
{
    return $tipo === 'passageiro' ? 'passageiro' : 'motorista';
}

function avisos_destinos_para_tipo(string $tipo): array
{
    return $tipo === 'passageiro'
        ? ['todos', 'passageiros']
        : ['todos', 'motoristas'];
}

function avisos_usuario_existe(PDO $pdo, int $idUsuario): void
{
    $stmt = $pdo->prepare('SELECT id FROM usuarios WHERE id = ? LIMIT 1');
    $stmt->execute([$idUsuario]);
    if (!$stmt->fetch()) {
        json_fail('Usuario nao encontrado.', 404);
    }
}

function avisos_visivel_para_usuario(PDO $pdo, int $idAviso, string $tipo): bool
{
    $destinos = avisos_destinos_para_tipo($tipo);
    $placeholders = implode(',', array_fill(0, count($destinos), '?'));
    $stmt = $pdo->prepare("SELECT id FROM avisos WHERE id = ? AND destino IN ($placeholders) LIMIT 1");
    $stmt->execute([$idAviso, ...$destinos]);

    return (bool) $stmt->fetch();
}

function avisos_marcar_todos_lidos(PDO $pdo, int $idUsuario, string $tipo): void
{
    $destinos = avisos_destinos_para_tipo($tipo);
    $placeholders = implode(',', array_fill(0, count($destinos), '?'));
    $stmt = $pdo->prepare(
        "INSERT INTO avisos_leituras (id_aviso, id_usuario, lido_em)
         SELECT a.id, ?, NOW()
         FROM avisos a
         WHERE a.destino IN ($placeholders)
         ON DUPLICATE KEY UPDATE lido_em = VALUES(lido_em)"
    );
    $stmt->execute([$idUsuario, ...$destinos]);
}

function avisos_listar_usuario(PDO $pdo, int $idUsuario, string $tipo): array
{
    $destinos = avisos_destinos_para_tipo($tipo);
    $placeholders = implode(',', array_fill(0, count($destinos), '?'));
    $stmt = $pdo->prepare(
        "SELECT a.id, a.destino, a.titulo, a.mensagem, a.criado_em,
                CASE WHEN al.id_usuario IS NULL THEN 0 ELSE 1 END AS lido,
                al.lido_em
         FROM avisos a
         LEFT JOIN avisos_leituras al
           ON al.id_aviso = a.id
          AND al.id_usuario = ?
         WHERE a.destino IN ($placeholders)
         ORDER BY a.criado_em DESC, a.id DESC
         LIMIT 100"
    );
    $stmt->execute([$idUsuario, ...$destinos]);

    return $stmt->fetchAll();
}
