<?php
declare(strict_types=1);

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

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

function corrida_column_exists(PDO $pdo, string $column): bool
{
    $stmt = $pdo->prepare(
        'SELECT COUNT(*)
         FROM INFORMATION_SCHEMA.COLUMNS
         WHERE TABLE_SCHEMA = DATABASE()
           AND TABLE_NAME = "corridas"
           AND COLUMN_NAME = ?'
    );
    $stmt->execute([$column]);

    return (int) $stmt->fetchColumn() > 0;
}

function corrida_saldo_passageiro(PDO $pdo, int $idPassageiro): float
{
    if (!corrida_table_exists($pdo, 'passageiro_carteira_movimentos')) {
        return 0.0;
    }

    $stmt = $pdo->prepare(
        'SELECT COALESCE(SUM(
            CASE
              WHEN status <> "confirmado" THEN 0
              WHEN tipo = "debito" THEN -valor
              ELSE valor
            END
        ), 0) AS saldo
         FROM passageiro_carteira_movimentos
         WHERE id_passageiro = ?'
    );
    $stmt->execute([$idPassageiro]);

    return round((float) $stmt->fetchColumn(), 2);
}

function corrida_codigo_embarque(PDO $pdo, int $idPassageiro): ?string
{
    $stmt = $pdo->prepare('SELECT celular FROM usuarios WHERE id = ? LIMIT 1');
    $stmt->execute([$idPassageiro]);
    $celular = preg_replace('/\D+/', '', (string) $stmt->fetchColumn());

    if ($celular === '') {
        return null;
    }

    return str_pad(substr($celular, -4), 4, '0', STR_PAD_LEFT);
}

function corrida_normalizar_pagamento(array $data): array
{
    $detalhe = strtolower(trim((string) ($data['forma_pagamento_detalhe'] ?? $data['forma_pagamento'] ?? 'dinheiro_pix')));
    $aliases = [
        'dinheiro' => 'dinheiro_pix',
        'pix' => 'dinheiro_pix',
        'dinheiro/pix' => 'dinheiro_pix',
        'pix_presencial' => 'dinheiro_pix',
        'online' => 'pix_online',
        'cartao' => 'cartao_credito',
        'cartao_credito' => 'cartao_credito',
        'cartão de credito' => 'cartao_credito',
        'cartão de crédito' => 'cartao_credito',
    ];
    $detalhe = $aliases[$detalhe] ?? $detalhe;
    if (!in_array($detalhe, ['dinheiro_pix', 'pix_online', 'cartao_credito'], true)) {
        $detalhe = 'dinheiro_pix';
    }

    return [
        'forma' => $detalhe === 'dinheiro_pix' ? 'dinheiro' : 'online',
        'detalhe' => $detalhe,
    ];
}

function corrida_normalizar_paradas(array $data): array
{
    $paradasInput = $data['paradas'] ?? [];
    if (is_string($paradasInput)) {
        $decoded = json_decode($paradasInput, true);
        $paradasInput = is_array($decoded) ? $decoded : [];
    }
    if (!is_array($paradasInput)) {
        return [];
    }

    $paradas = [];
    foreach ($paradasInput as $parada) {
        if (!is_array($parada)) {
            continue;
        }
        $lat = $parada['lat'] ?? $parada['latitude'] ?? null;
        $lng = $parada['lng'] ?? $parada['longitude'] ?? null;
        if ($lat === null || $lng === null) {
            continue;
        }
        $lat = (float) str_replace(',', '.', (string) $lat);
        $lng = (float) str_replace(',', '.', (string) $lng);
        if ($lat < -90 || $lat > 90 || $lng < -180 || $lng > 180) {
            continue;
        }

        $paradas[] = [
            'ordem' => count($paradas) + 1,
            'lat' => $lat,
            'lng' => $lng,
            'endereco' => trim((string) ($parada['endereco'] ?? $parada['descricao'] ?? '')),
        ];

        if (count($paradas) >= 3) {
            break;
        }
    }

    return $paradas;
}

try {
    $pdo = db();
    $idPassageiro = (int) $data['id_passageiro'];
    $pagamento = corrida_normalizar_pagamento($data);
    $paradas = corrida_normalizar_paradas($data);
    $formaPagamento = $pagamento['forma'];
    $formaPagamentoDetalhe = $pagamento['detalhe'];

    $categoriaVeiculo = strtolower(trim((string) ($data['categoria_veiculo'] ?? 'economica')));
    if (!in_array($categoriaVeiculo, ['economica', 'plus', 'pro'], true)) {
        $categoriaVeiculo = 'economica';
    }

    $origemLat = isset($data['origem_lat']) ? (float) $data['origem_lat'] : null;
    $origemLng = isset($data['origem_lng']) ? (float) $data['origem_lng'] : null;
    $origemEndereco = trim((string) ($data['origem_endereco'] ?? ''));
    $destinoEndereco = trim((string) ($data['destino_endereco'] ?? ''));
    $distancia = isset($data['distancia']) ? (float) $data['distancia'] : null;
    $duracaoMinutos = isset($data['duracao_minutos']) ? (float) $data['duracao_minutos'] : null;

    $tarifa = tarifas_resolver_por_ponto($pdo, $origemLat, $origemLng, true);
    if (($tarifa['disponivel'] ?? true) !== true) {
        json_fail(
            (string) ($tarifa['mensagem_indisponivel'] ?? tarifas_mensagem_indisponivel()),
            422,
            [
                'disponivel' => false,
                'regiao' => $tarifa['regiao'],
            ]
        );
    }

    if (!(bool) ($tarifa['categorias'][$categoriaVeiculo] ?? false)) {
        json_fail('Categoria indisponivel nessa regiao.', 422, [
            'categorias' => $tarifa['categorias'],
            'regiao' => $tarifa['regiao'],
        ]);
    }

    $valorBase = null;
    $multiplicadorDinamico = 1.00;
    $valorDinamicoAdicional = 0.00;
    $dinamicaCelulaId = null;
    $dinamicaMotivo = null;
    $dinamicaDados = null;

    if ($distancia !== null && $duracaoMinutos !== null) {
        $configCategoria = $tarifa['tarifas'][$categoriaVeiculo] ?? $tarifa['configuracoes'];
        $valorBase = tarifas_calcular_valor($configCategoria, $distancia, $duracaoMinutos);
        $dinamicaCategoria = $tarifa['dinamica']['categorias'][$categoriaVeiculo] ?? ['multiplicador' => 1.00];
        $multiplicadorDinamico = max(1.00, round((float) ($dinamicaCategoria['multiplicador'] ?? 1.00), 2));
        $valorDinamicoAdicional = $multiplicadorDinamico > 1.00
            ? round($valorBase * ($multiplicadorDinamico - 1.00), 2)
            : 0.00;
        $valor = round($valorBase + $valorDinamicoAdicional, 2);
        $dinamicaCelulaId = $multiplicadorDinamico > 1.00 ? ($dinamicaCategoria['celula_id'] ?? null) : null;
        $dinamicaMotivo = $multiplicadorDinamico > 1.00 ? ($dinamicaCategoria['motivo'] ?? null) : null;
        $dinamicaDados = $multiplicadorDinamico > 1.00 ? $dinamicaCategoria : null;
    } else {
        $valor = isset($data['valor']) ? round((float) $data['valor'], 2) : null;
        $valorBase = $valor;
    }
    if ($valor !== null && $paradas) {
        $valor = round($valor + count($paradas), 2);
    }

    $columns = [
        'id_passageiro',
        'origem_lat',
        'origem_lng',
        'destino_lat',
        'destino_lng',
        'distancia',
        'tempo_estimado',
        'valor',
    ];
    $placeholders = array_fill(0, count($columns), '?');
    $params = [
        $idPassageiro,
        $origemLat,
        $origemLng,
        isset($data['destino_lat']) ? (float) $data['destino_lat'] : null,
        isset($data['destino_lng']) ? (float) $data['destino_lng'] : null,
        $distancia,
        $data['tempo_estimado'] ?? null,
        $valor,
    ];

    if (corrida_column_exists($pdo, 'categoria_veiculo')) {
        $columns[] = 'categoria_veiculo';
        $placeholders[] = '?';
        $params[] = $categoriaVeiculo;
    }

    if (corrida_column_exists($pdo, 'origem_endereco')) {
        $columns[] = 'origem_endereco';
        $placeholders[] = '?';
        $params[] = $origemEndereco !== '' ? $origemEndereco : null;
    }

    if (corrida_column_exists($pdo, 'destino_endereco')) {
        $columns[] = 'destino_endereco';
        $placeholders[] = '?';
        $params[] = $destinoEndereco !== '' ? $destinoEndereco : null;
    }

    if (corrida_column_exists($pdo, 'id_tarifa_regiao')) {
        $columns[] = 'id_tarifa_regiao';
        $placeholders[] = '?';
        $params[] = $tarifa['regiao']['id'] ?? null;
    }

    if (corrida_column_exists($pdo, 'valor_base')) {
        $columns[] = 'valor_base';
        $placeholders[] = '?';
        $params[] = $valorBase;
    }

    if (corrida_column_exists($pdo, 'multiplicador_dinamico')) {
        $columns[] = 'multiplicador_dinamico';
        $placeholders[] = '?';
        $params[] = $multiplicadorDinamico;
    }

    if (corrida_column_exists($pdo, 'valor_dinamico_adicional')) {
        $columns[] = 'valor_dinamico_adicional';
        $placeholders[] = '?';
        $params[] = $valorDinamicoAdicional;
    }

    if (corrida_column_exists($pdo, 'dinamica_celula_id')) {
        $columns[] = 'dinamica_celula_id';
        $placeholders[] = '?';
        $params[] = $dinamicaCelulaId;
    }

    if (corrida_column_exists($pdo, 'dinamica_motivo')) {
        $columns[] = 'dinamica_motivo';
        $placeholders[] = '?';
        $params[] = $dinamicaMotivo;
    }

    if (corrida_column_exists($pdo, 'dinamica_dados_json')) {
        $columns[] = 'dinamica_dados_json';
        $placeholders[] = '?';
        $params[] = $dinamicaDados ? json_encode($dinamicaDados, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) : null;
    }

    $saldoNegativoCobrado = 0.0;
    if ($valor !== null && corrida_column_exists($pdo, 'saldo_negativo_cobrado')) {
        $saldoPassageiro = corrida_saldo_passageiro($pdo, $idPassageiro);
        if ($saldoPassageiro < 0) {
            $saldoNegativoCobrado = round(abs($saldoPassageiro), 2);
            $valor = round($valor + $saldoNegativoCobrado, 2);
            $valorIndex = array_search('valor', $columns, true);
            if ($valorIndex !== false) {
                $params[$valorIndex] = $valor;
            }
        }

        $columns[] = 'saldo_negativo_cobrado';
        $placeholders[] = '?';
        $params[] = $saldoNegativoCobrado;
    }

    $columns[] = 'forma_pagamento';
    $placeholders[] = '?';
    $params[] = $formaPagamento;

    if (corrida_column_exists($pdo, 'forma_pagamento_detalhe')) {
        $columns[] = 'forma_pagamento_detalhe';
        $placeholders[] = '?';
        $params[] = $formaPagamentoDetalhe;
    }

    if (corrida_column_exists($pdo, 'codigo_embarque')) {
        $columns[] = 'codigo_embarque';
        $placeholders[] = '?';
        $params[] = corrida_codigo_embarque($pdo, $idPassageiro);
    }

    $columns[] = 'status';
    $placeholders[] = '?';
    $params[] = 'pendente';

    $stmt = $pdo->prepare(
        'INSERT INTO corridas (' . implode(', ', $columns) . ')
         VALUES (' . implode(', ', $placeholders) . ')'
    );

    $stmt->execute($params);
    $idCorrida = (int) $pdo->lastInsertId();

    if ($paradas && corrida_table_exists($pdo, 'corrida_paradas')) {
        $paradaStmt = $pdo->prepare(
            'INSERT INTO corrida_paradas (id_corrida, ordem, lat, lng, endereco)
             VALUES (?, ?, ?, ?, ?)'
        );
        foreach ($paradas as $parada) {
            $paradaStmt->execute([
                $idCorrida,
                $parada['ordem'],
                $parada['lat'],
                $parada['lng'],
                $parada['endereco'] !== '' ? $parada['endereco'] : null,
            ]);
        }
    }

    corrida_evento_registrar($pdo, $idCorrida, 'corrida_criada', $idPassageiro, 'passageiro', null, 'pendente', null, null, [
        'categoria_veiculo' => $categoriaVeiculo,
        'forma_pagamento' => $formaPagamento,
        'forma_pagamento_detalhe' => $formaPagamentoDetalhe,
        'valor' => $valor,
        'valor_base' => $valorBase,
        'multiplicador_dinamico' => $multiplicadorDinamico,
        'valor_dinamico_adicional' => $valorDinamicoAdicional,
        'dinamica_celula_id' => $dinamicaCelulaId,
        'dinamica_motivo' => $dinamicaMotivo,
        'distancia' => $distancia,
        'total_paradas' => count($paradas),
        'regiao' => $tarifa['regiao']['nome'] ?? null,
    ]);

    $idPagamentoGateway = mp_registrar_pagamento_corrida($pdo, [
        'id' => $idCorrida,
        'id_passageiro' => $idPassageiro,
        'id_motorista' => null,
        'valor' => $valor ?? 0,
        'saldo_negativo_cobrado' => $saldoNegativoCobrado,
        'forma_pagamento' => $formaPagamento,
        'forma_pagamento_detalhe' => $formaPagamentoDetalhe,
    ]);

    $pagamentoAntesDaBusca = $formaPagamento === 'online';
    if (!$pagamentoAntesDaBusca) {
        corrida_ofertas_despachar($pdo, $idCorrida);
    }

    json_ok([
        'id_corrida' => $idCorrida,
        'id_pagamento_gateway' => $idPagamentoGateway,
        'valor' => $valor,
        'forma_pagamento' => $formaPagamento,
        'forma_pagamento_detalhe' => $formaPagamentoDetalhe,
        'pagamento_requerido' => $pagamentoAntesDaBusca,
        'saldo_negativo_cobrado' => $saldoNegativoCobrado,
        'total_paradas' => count($paradas),
        'regiao' => $tarifa['regiao'],
        'dinamica' => [
            'multiplicador' => $multiplicadorDinamico,
            'valor_base' => $valorBase,
            'valor_dinamico_adicional' => $valorDinamicoAdicional,
            'celula_id' => $dinamicaCelulaId,
            'motivo' => $dinamicaMotivo,
        ],
    ]);
} catch (Throwable $e) {
    json_fail('Erro ao criar corrida.', 500, ['error' => $e->getMessage()]);
}
