<?php
declare(strict_types=1);

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

const CORRIDA_RAIO_CHEGADA_EMBARQUE_KM = 0.25;

$data = input_json();
require_fields($data, ['id_corrida', 'id_motorista', 'lat', 'lng']);

$idCorrida = (int) $data['id_corrida'];
$idMotorista = (int) $data['id_motorista'];
$lat = payload_float($data, ['lat', 'latitude']);
$lng = payload_float($data, ['lng', 'longitude']);

if ($idCorrida <= 0 || $idMotorista <= 0 || $lat === null || $lng === null) {
    json_fail('Dados invalidos para confirmar chegada.');
}

try {
    $pdo = db();
    $pdo->beginTransaction();

    motorista_atualizar_localizacao($idMotorista, [
        'lat' => $lat,
        'lng' => $lng,
        'rumo' => $data['rumo'] ?? $data['heading'] ?? null,
    ]);

    $stmt = $pdo->prepare(
        'SELECT id, id_motorista, status, origem_lat, origem_lng, chegou_embarque_em
         FROM corridas
         WHERE id = ?
         LIMIT 1
         FOR UPDATE'
    );
    $stmt->execute([$idCorrida]);
    $corrida = $stmt->fetch();

    if (!$corrida) {
        $pdo->rollBack();
        json_fail('Corrida nao encontrada.', 404);
    }

    if ((int) ($corrida['id_motorista'] ?? 0) !== $idMotorista) {
        $pdo->rollBack();
        json_fail('Essa corrida nao pertence a este motorista.', 403);
    }

    if (!in_array((string) ($corrida['status'] ?? ''), ['aceita', 'aguardando_embarque'], true)) {
        $pdo->rollBack();
        json_fail('A chegada ao embarque nao pode ser confirmada neste estado.', 409);
    }

    $distancia = corrida_distancia_km(
        $lat,
        $lng,
        corrida_float($corrida, 'origem_lat'),
        corrida_float($corrida, 'origem_lng')
    );

    if ($distancia === null || $distancia > CORRIDA_RAIO_CHEGADA_EMBARQUE_KM) {
        $pdo->rollBack();
        json_fail('Voce ainda esta longe do local de embarque.', 422, [
            'distancia_km' => $distancia === null ? null : round($distancia, 3),
            'raio_km' => CORRIDA_RAIO_CHEGADA_EMBARQUE_KM,
        ]);
    }

    if ((string) ($corrida['status'] ?? '') === 'aceita') {
        $up = $pdo->prepare(
            'UPDATE corridas
             SET status = "aguardando_embarque",
                 chegou_embarque_em = COALESCE(chegou_embarque_em, NOW())
             WHERE id = ?'
        );
        $up->execute([$idCorrida]);
    }

    $horaStmt = $pdo->prepare('SELECT chegou_embarque_em FROM corridas WHERE id = ? LIMIT 1');
    $horaStmt->execute([$idCorrida]);
    $chegouEm = $horaStmt->fetchColumn();

    corrida_evento_registrar($pdo, $idCorrida, 'motorista_chegou_embarque', $idMotorista, 'motorista', (string) ($corrida['status'] ?? ''), 'aguardando_embarque', null, null, [
        'distancia_km' => round($distancia, 3),
        'lat' => $lat,
        'lng' => $lng,
    ]);

    $pdo->commit();
    json_ok([
        'status' => 'aguardando_embarque',
        'chegou_embarque_em' => $chegouEm,
        'distancia_km' => round($distancia, 3),
    ]);
} catch (Throwable $e) {
    if (isset($pdo) && $pdo->inTransaction()) {
        $pdo->rollBack();
    }
    json_fail('Erro ao confirmar chegada.', 500, ['error' => $e->getMessage()]);
}
