<?php
declare(strict_types=1);

require_once __DIR__ . '/database.php';

header('Content-Type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Headers: Content-Type, Authorization');
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');

if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    http_response_code(204);
    exit;
}

function input_json(): array
{
    $raw = file_get_contents('php://input');
    if ($raw === false || trim($raw) === '') {
        return $_POST;
    }

    $data = json_decode($raw, true);
    return is_array($data) ? $data : [];
}

function json_ok(array $payload = []): void
{
    echo json_encode(['success' => true] + $payload, JSON_UNESCAPED_UNICODE);
    exit;
}

function json_fail(string $message, int $status = 400, array $payload = []): void
{
    http_response_code($status);
    echo json_encode(['success' => false, 'message' => $message] + $payload, JSON_UNESCAPED_UNICODE);
    exit;
}

function require_fields(array $data, array $fields): void
{
    foreach ($fields as $field) {
        if (!isset($data[$field]) || trim((string) $data[$field]) === '') {
            json_fail("Campo obrigatorio ausente: {$field}");
        }
    }
}

function public_upload_path(string $folder): string
{
    $path = dirname(__DIR__) . '/uploads/' . trim($folder, '/');
    if (!is_dir($path)) {
        mkdir($path, 0775, true);
    }
    return $path;
}

function motorista_status_documento(array $motorista, string $campo): string
{
    return (string) ($motorista[$campo] ?? 'pendente');
}

function motorista_documentos_aprovados(array $motorista): bool
{
    return motorista_status_documento($motorista, 'cnh_status') === 'aprovado'
        && motorista_status_documento($motorista, 'selfie_status') === 'aprovado';
}

function motorista_status_geral(array $motorista): string
{
    if (motorista_documentos_aprovados($motorista)) {
        return 'aprovado';
    }

    if (
        motorista_status_documento($motorista, 'cnh_status') === 'reprovado'
        || motorista_status_documento($motorista, 'documento_veiculo_status') === 'reprovado'
        || motorista_status_documento($motorista, 'selfie_status') === 'reprovado'
    ) {
        return 'reprovado';
    }

    return 'pendente';
}

function motorista_status_operacional(array $motorista, bool $temVeiculoAprovado): string
{
    if (
        motorista_status_documento($motorista, 'cnh_status') === 'reprovado'
        || motorista_status_documento($motorista, 'selfie_status') === 'reprovado'
    ) {
        return 'reprovado';
    }

    if (motorista_documentos_aprovados($motorista) && $temVeiculoAprovado) {
        return 'aprovado';
    }

    return 'pendente';
}

function motorista_pode_ficar_online(array $motorista): bool
{
    $temVeiculo = isset($motorista['tem_veiculo_aprovado'])
        ? (bool) $motorista['tem_veiculo_aprovado']
        : true;

    return motorista_documentos_aprovados($motorista) && $temVeiculo;
}

function payload_float(array $data, array $keys): ?float
{
    foreach ($keys as $key) {
        if (isset($data[$key]) && trim((string) $data[$key]) !== '') {
            return (float) str_replace(',', '.', (string) $data[$key]);
        }
    }

    return null;
}

function motorista_atualizar_localizacao(int $idMotorista, array $data): void
{
    if ($idMotorista <= 0) {
        return;
    }

    $lat = payload_float($data, ['lat', 'latitude', 'ultimo_lat']);
    $lng = payload_float($data, ['lng', 'longitude', 'ultimo_lng']);
    if ($lat === null || $lng === null) {
        return;
    }

    if ($lat < -90 || $lat > 90 || $lng < -180 || $lng > 180) {
        return;
    }

    $rumo = payload_float($data, ['rumo', 'heading', 'ultimo_rumo']);
    if ($rumo !== null) {
        $rumo = fmod(($rumo + 360), 360);
    }

    $stmt = db()->prepare(
        'UPDATE usuarios
         SET ultimo_lat = ?, ultimo_lng = ?, ultimo_rumo = ?, localizacao_atualizada_em = NOW()
         WHERE id = ? AND tipo = "motorista"'
    );
    $stmt->execute([$lat, $lng, $rumo, $idMotorista]);
}

function motorista_status_documento_real(array $motorista): string
{
    $aprovados = (int) ($motorista['veiculos_aprovados'] ?? 0);
    $reprovados = (int) ($motorista['veiculos_reprovados'] ?? 0);
    $total = (int) ($motorista['total_veiculos'] ?? 0);

    if ($aprovados > 0) {
        return 'aprovado';
    }

    if ($reprovados > 0) {
        return 'reprovado';
    }

    if ($total > 0) {
        return 'pendente';
    }

    return (string) ($motorista['documento_veiculo_status'] ?? 'pendente');
}

function indicador_validar_para_tipo(string $codigo, string $tipoIndicado): ?array
{
    $codigo = trim($codigo);
    if ($codigo === '') {
        return null;
    }

    $stmt = db()->prepare('SELECT id, nome, tipo, codigoind FROM usuarios WHERE codigoind = ? LIMIT 1');
    $stmt->execute([$codigo]);
    $indicador = $stmt->fetch();
    if (!$indicador) {
        json_fail('Codigo de indicacao nao encontrado.');
    }

    if ($tipoIndicado === 'motorista' && $indicador['tipo'] !== 'motorista') {
        json_fail('Motoristas so podem ser indicados por motoristas.');
    }

    return $indicador;
}

function indicador_codigo_valido_para_tipo(PDO $pdo, string $codigo, string $tipoIndicado, int $idIndicado = 0): bool
{
    $codigo = trim($codigo);
    if ($codigo === '') {
        return true;
    }

    $stmt = $pdo->prepare('SELECT id, tipo FROM usuarios WHERE codigoind = ? LIMIT 1');
    $stmt->execute([$codigo]);
    $indicador = $stmt->fetch();
    if (!$indicador) {
        return false;
    }

    if ($idIndicado > 0 && (int) $indicador['id'] === $idIndicado) {
        return false;
    }

    if ($tipoIndicado === 'motorista' && (string) $indicador['tipo'] !== 'motorista') {
        return false;
    }

    return true;
}

function usuario_limpar_indicador_invalido_para_tipo(PDO $pdo, array $usuario, string $tipoIndicado): bool
{
    $codigo = trim((string) ($usuario['indicador_codigo'] ?? ''));
    if ($codigo === '') {
        return false;
    }

    if (indicador_codigo_valido_para_tipo($pdo, $codigo, $tipoIndicado, (int) $usuario['id'])) {
        return false;
    }

    $up = $pdo->prepare('UPDATE usuarios SET indicador_codigo = NULL WHERE id = ?');
    $up->execute([(int) $usuario['id']]);

    return true;
}

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

    $indicadorRemovido = usuario_limpar_indicador_invalido_para_tipo($pdo, $usuario, 'motorista');
    $foiPromovido = (string) $usuario['tipo'] !== 'motorista';

    if ($foiPromovido) {
        $up = $pdo->prepare(
            'UPDATE usuarios
             SET tipo = "motorista",
                 status_verificacao = "pendente",
                 observacao_verificacao = "Aguardando envio dos documentos.",
                 disponivel = "nao"
             WHERE id = ?'
        );
        $up->execute([$idUsuario]);
    }

    return [
        'id' => $idUsuario,
        'foi_promovido' => $foiPromovido,
        'indicador_removido' => $indicadorRemovido,
    ];
}
