<?php
declare(strict_types=1);

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

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

try {
    $pdo = db();
    $idCorrida = (int) $data['id_corrida'];
    $idMotorista = (int) $data['id_motorista'];

    $pdo->beginTransaction();

    corrida_ofertas_expirar($pdo, $idCorrida);

    $listaLiberada = 1;
    if (corrida_schema_column_exists($pdo, 'corridas', 'oferta_lista_liberada')) {
        $listaStmt = $pdo->prepare('SELECT oferta_lista_liberada FROM corridas WHERE id = ? LIMIT 1');
        $listaStmt->execute([$idCorrida]);
        $listaLiberada = (int) ($listaStmt->fetchColumn() ?: 0);
    }

    $ofertaId = null;
    if (corrida_ofertas_ativas($pdo) && $listaLiberada !== 1) {
        $ofertaStmt = $pdo->prepare(
            'SELECT id
             FROM corrida_ofertas
             WHERE id_corrida = ?
               AND id_motorista = ?
               AND status = "pendente"
               AND expira_em > NOW()
             ORDER BY expira_em ASC
             LIMIT 1'
        );
        $ofertaStmt->execute([$idCorrida, $idMotorista]);
        $ofertaId = $ofertaStmt->fetchColumn();
        if (!$ofertaId) {
            $pdo->rollBack();
            json_fail('Essa chamada expirou ou ja foi enviada para outro motorista.', 409);
        }
        $ofertaId = (int) $ofertaId;
    }

    $distanciaAceiteKm = null;
    $tempoAceiteMin = null;
    if (corrida_schema_column_exists($pdo, 'corridas', 'distancia_motorista_aceite_km')) {
        $distanciaStmt = $pdo->prepare(
            'SELECT c.origem_lat, c.origem_lng, u.ultimo_lat, u.ultimo_lng
             FROM corridas c
             INNER JOIN usuarios u ON u.id = ?
             WHERE c.id = ?
             LIMIT 1'
        );
        $distanciaStmt->execute([$idMotorista, $idCorrida]);
        $distanciaBase = $distanciaStmt->fetch();
        if ($distanciaBase) {
            $distanciaAceiteKm = corrida_distancia_km(
                corrida_float($distanciaBase, 'ultimo_lat'),
                corrida_float($distanciaBase, 'ultimo_lng'),
                corrida_float($distanciaBase, 'origem_lat'),
                corrida_float($distanciaBase, 'origem_lng')
            );
            if ($distanciaAceiteKm !== null) {
                $distanciaAceiteKm = round($distanciaAceiteKm, 3);
                $tempoAceiteMin = round(($distanciaAceiteKm / 30) * 60, 2);
            }
        }
    }

    $set = ['status = "aceita"', 'id_motorista = ?', 'aceita_em = NOW()'];
    $params = [$idMotorista];
    if (corrida_schema_column_exists($pdo, 'corridas', 'distancia_motorista_aceite_km')) {
        $set[] = 'distancia_motorista_aceite_km = ?';
        $params[] = $distanciaAceiteKm;
    }
    if (corrida_schema_column_exists($pdo, 'corridas', 'tempo_motorista_aceite_min')) {
        $set[] = 'tempo_motorista_aceite_min = ?';
        $params[] = $tempoAceiteMin;
    }
    $params[] = $idCorrida;

    $stmt = $pdo->prepare(
        'UPDATE corridas
         SET ' . implode(', ', $set) . '
         WHERE id = ? AND status = "pendente"'
    );
    $stmt->execute($params);

    if ($stmt->rowCount() === 0) {
        $pdo->rollBack();
        json_fail('Corrida ja foi aceita ou nao existe.', 409);
    }

    if (corrida_table_exists($pdo, 'corrida_ofertas')) {
        if ($ofertaId === null) {
            $listaOferta = $pdo->prepare(
                'INSERT INTO corrida_ofertas
                  (id_corrida, id_motorista, rodada, ordem, status, distancia_ate_origem_km, expira_em, respondido_em)
                 VALUES (?, ?, 99, 1, "aceita", ?, NOW(), NOW())
                 ON DUPLICATE KEY UPDATE
                   status = "aceita",
                   distancia_ate_origem_km = VALUES(distancia_ate_origem_km),
                   respondido_em = NOW()'
            );
            $listaOferta->execute([$idCorrida, $idMotorista, $distanciaAceiteKm]);

            $listaOfertaId = $pdo->prepare(
                'SELECT id
                 FROM corrida_ofertas
                 WHERE id_corrida = ?
                   AND id_motorista = ?
                   AND rodada = 99
                 LIMIT 1'
            );
            $listaOfertaId->execute([$idCorrida, $idMotorista]);
            $ofertaId = (int) ($listaOfertaId->fetchColumn() ?: 0);
            if ($ofertaId <= 0) {
                $ofertaId = null;
            }
        }

        if ($ofertaId !== null) {
            $aceita = $pdo->prepare(
                'UPDATE corrida_ofertas
                 SET status = "aceita", respondido_em = NOW()
                 WHERE id = ?'
            );
            $aceita->execute([$ofertaId]);
        }

        $cancelar = $pdo->prepare(
            'UPDATE corrida_ofertas
             SET status = "cancelada", respondido_em = COALESCE(respondido_em, NOW())
             WHERE id_corrida = ?
               AND status = "pendente"'
        );
        $cancelar->execute([$idCorrida]);
    }
    motorista_metricas_corridas_recalcular($pdo, $idMotorista);

    corrida_evento_registrar($pdo, $idCorrida, 'motorista_aceitou', $idMotorista, 'motorista', 'pendente', 'aceita', null, null, [
        'id_oferta' => $ofertaId,
        'distancia_motorista_aceite_km' => $distanciaAceiteKm,
        'tempo_motorista_aceite_min' => $tempoAceiteMin,
    ]);

    $corrida = corrida_formatar_para_motorista($pdo, $idCorrida, $ofertaId, null);
    $pdo->commit();
    json_ok(['corrida' => $corrida]);
} catch (Throwable $e) {
    if (isset($pdo) && $pdo->inTransaction()) {
        $pdo->rollBack();
    }
    json_fail('Erro ao aceitar corrida.', 500, ['error' => $e->getMessage()]);
}
