<?php
declare(strict_types=1);

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

const CORRIDA_RAIO_INICIAR_VIAGEM_KM = 0.30;

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

$idCorrida = (int) $data['id_corrida'];
$idMotorista = (int) $data['id_motorista'];
$lat = payload_float($data, ['lat', 'latitude']);
$lng = payload_float($data, ['lng', 'longitude']);
$codigoInformado = preg_replace('/\D+/', '', (string) ($data['codigo_embarque'] ?? ''));

if ($idCorrida <= 0 || $idMotorista <= 0 || $lat === null || $lng === null || strlen($codigoInformado) !== 4) {
    json_fail('Dados invalidos para iniciar viagem.');
}

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

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

    $selectCodigo = corrida_schema_column_exists($pdo, 'corridas', 'codigo_embarque')
        ? 'c.codigo_embarque'
        : 'NULL AS codigo_embarque';
    $stmt = $pdo->prepare(
        'SELECT c.id, c.id_motorista, c.status, c.origem_lat, c.origem_lng,
                ' . $selectCodigo . ',
                p.celular AS passageiro_celular
         FROM corridas c
         INNER JOIN usuarios p ON p.id = c.id_passageiro
         WHERE c.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 ((string) ($corrida['status'] ?? '') !== 'aguardando_embarque') {
        $pdo->rollBack();
        json_fail('Confirme chegada ao embarque antes de iniciar a viagem.', 409);
    }

    $codigoEsperado = preg_replace('/\D+/', '', (string) ($corrida['codigo_embarque'] ?? ''));
    if (strlen($codigoEsperado) < 4) {
        $celular = preg_replace('/\D+/', '', (string) ($corrida['passageiro_celular'] ?? ''));
        $codigoEsperado = $celular === '' ? '' : str_pad(substr($celular, -4), 4, '0', STR_PAD_LEFT);
    }
    if ($codigoEsperado === '' || $codigoInformado !== $codigoEsperado) {
        $pdo->rollBack();
        json_fail('Codigo do passageiro incorreto.', 422);
    }

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

    if ($distancia === null || $distancia > CORRIDA_RAIO_INICIAR_VIAGEM_KM) {
        $pdo->rollBack();
        json_fail('Voce precisa estar proximo do embarque para iniciar.', 422, [
            'distancia_km' => $distancia === null ? null : round($distancia, 3),
            'raio_km' => CORRIDA_RAIO_INICIAR_VIAGEM_KM,
        ]);
    }

    $up = $pdo->prepare(
        'UPDATE corridas
         SET status = "em_andamento",
             iniciou_viagem_em = COALESCE(iniciou_viagem_em, NOW())
         WHERE id = ?'
    );
    $up->execute([$idCorrida]);

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

    corrida_evento_registrar($pdo, $idCorrida, 'viagem_iniciada', $idMotorista, 'motorista', 'aguardando_embarque', 'em_andamento', null, null, [
        'codigo_validado' => true,
    ]);

    $pdo->commit();
    json_ok([
        'status' => 'em_andamento',
        'iniciou_viagem_em' => $iniciouEm,
        'distancia_km' => round($distancia, 3),
    ]);
} catch (Throwable $e) {
    if (isset($pdo) && $pdo->inTransaction()) {
        $pdo->rollBack();
    }
    json_fail('Erro ao iniciar viagem.', 500, ['error' => $e->getMessage()]);
}
