<?php
declare(strict_types=1);

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

$data = input_json();
$idPassageiro = (int) ($data['id_passageiro'] ?? $data['id_usuario'] ?? 0);
$apelido = trim((string) ($data['apelido'] ?? ''));
$bandeira = trim((string) ($data['bandeira'] ?? ''));
$ultimos4 = preg_replace('/\D+/', '', (string) ($data['ultimos4'] ?? ''));
$validadeMes = (int) ($data['validade_mes'] ?? 0);
$validadeAno = (int) ($data['validade_ano'] ?? 0);
$mpCustomerId = trim((string) ($data['mp_customer_id'] ?? ''));
$mpCardId = trim((string) ($data['mp_card_id'] ?? ''));
$mpPaymentMethodId = trim((string) ($data['mp_payment_method_id'] ?? ''));
$tokenGateway = trim((string) ($data['token_gateway'] ?? $data['card_token'] ?? ''));

if ($idPassageiro <= 0) {
    json_fail('Passageiro nao informado.');
}
if ($tokenGateway === '' && !preg_match('/^\d{4}$/', $ultimos4)) {
    json_fail('Informe os 4 ultimos digitos do cartao.');
}
if ($tokenGateway === '' && ($validadeMes < 1 || $validadeMes > 12)) {
    json_fail('Mes de validade invalido.');
}
if ($validadeAno > 0 && $validadeAno < (int) date('Y')) {
    json_fail('Ano de validade invalido.');
}

function carteira_passageiro_mp_email(array $usuario, int $idPassageiro): string
{
    $email = trim((string) ($usuario['email'] ?? ''));
    return $email !== '' ? $email : 'passageiro' . $idPassageiro . '@bulo.local';
}

function carteira_passageiro_mp_customer(PDO $pdo, array $usuario, int $idPassageiro): string
{
    $email = carteira_passageiro_mp_email($usuario, $idPassageiro);
    $accessToken = mp_access_token_plataforma($pdo);

    $search = mp_http_json_request(
        'GET',
        'https://api.mercadopago.com/v1/customers/search?email=' . rawurlencode($email),
        ['Authorization: Bearer ' . $accessToken]
    );
    $results = $search['results'] ?? [];
    if (is_array($results) && isset($results[0]['id']) && trim((string) $results[0]['id']) !== '') {
        return (string) $results[0]['id'];
    }

    $nome = trim((string) ($usuario['nome'] ?? 'Passageiro'));
    $cpf = preg_replace('/\D+/', '', (string) ($usuario['cpf'] ?? ''));
    $payload = [
        'email' => $email,
        'first_name' => $nome !== '' ? $nome : 'Passageiro',
    ];
    if ($cpf !== '') {
        $payload['identification'] = [
            'type' => 'CPF',
            'number' => $cpf,
        ];
    }

    $created = mp_http_json_request(
        'POST',
        'https://api.mercadopago.com/v1/customers',
        ['Authorization: Bearer ' . $accessToken],
        $payload,
        'bulo-passenger-customer-' . $idPassageiro
    );
    $customerId = trim((string) ($created['id'] ?? ''));
    if ($customerId === '') {
        throw new RuntimeException('O provedor de pagamento nao retornou o cliente do passageiro.');
    }

    return $customerId;
}

try {
    $pdo = db();
    $userStmt = $pdo->prepare('SELECT id, nome, email, cpf FROM usuarios WHERE id = ? LIMIT 1');
    $userStmt->execute([$idPassageiro]);
    $usuario = $userStmt->fetch();
    if (!$usuario) {
        json_fail('Passageiro nao encontrado.', 404);
    }

    if ($tokenGateway !== '') {
        $mpCustomerId = carteira_passageiro_mp_customer($pdo, $usuario, $idPassageiro);
        $card = mp_http_json_request(
            'POST',
            'https://api.mercadopago.com/v1/customers/' . rawurlencode($mpCustomerId) . '/cards',
            ['Authorization: Bearer ' . mp_access_token_plataforma($pdo)],
            ['token' => $tokenGateway],
            'bulo-passenger-card-' . $idPassageiro . '-' . substr(hash('sha256', $tokenGateway), 0, 16)
        );

        $mpCardId = trim((string) ($card['id'] ?? $mpCardId));
        $mpPaymentMethodId = trim((string) (
            $card['payment_method']['id']
            ?? $card['payment_method_id']
            ?? $mpPaymentMethodId
        ));
        $bandeira = trim((string) (
            $card['payment_method']['name']
            ?? $card['payment_method']['id']
            ?? $mpPaymentMethodId
            ?? $bandeira
        ));
        $ultimos4 = preg_replace('/\D+/', '', (string) ($card['last_four_digits'] ?? $ultimos4));
        $validadeMes = (int) ($card['expiration_month'] ?? $validadeMes);
        $validadeAno = (int) ($card['expiration_year'] ?? $validadeAno);

        if ($mpCardId === '' || !preg_match('/^\d{4}$/', $ultimos4)) {
            json_fail('Nao foi possivel salvar o cartao no provedor de pagamento.', 502, ['gateway' => $card]);
        }
    }

    if (!preg_match('/^\d{4}$/', $ultimos4)) {
        json_fail('Informe os 4 ultimos digitos do cartao.');
    }
    if ($validadeMes < 1 || $validadeMes > 12) {
        json_fail('Mes de validade invalido.');
    }

    $columns = ['id_passageiro', 'apelido', 'bandeira', 'ultimos4', 'validade_mes', 'validade_ano', 'ativo'];
    $placeholders = ['?', '?', '?', '?', '?', '?', '1'];
    $params = [
        $idPassageiro,
        $apelido === '' ? null : $apelido,
        $bandeira === '' ? null : $bandeira,
        $ultimos4,
        $validadeMes,
        $validadeAno <= 0 ? null : $validadeAno,
    ];

    if (mp_column_exists($pdo, 'passageiro_cartoes', 'token_gateway')) {
        $columns[] = 'token_gateway';
        $placeholders[] = '?';
        $params[] = null;
    }
    if (mp_column_exists($pdo, 'passageiro_cartoes', 'mp_customer_id')) {
        $columns[] = 'mp_customer_id';
        $placeholders[] = '?';
        $params[] = $mpCustomerId !== '' ? $mpCustomerId : null;
    }
    if (mp_column_exists($pdo, 'passageiro_cartoes', 'mp_card_id')) {
        $columns[] = 'mp_card_id';
        $placeholders[] = '?';
        $params[] = $mpCardId !== '' ? $mpCardId : null;
    }
    if (mp_column_exists($pdo, 'passageiro_cartoes', 'mp_payment_method_id')) {
        $columns[] = 'mp_payment_method_id';
        $placeholders[] = '?';
        $params[] = $mpPaymentMethodId !== '' ? $mpPaymentMethodId : null;
    }
    if (mp_column_exists($pdo, 'passageiro_cartoes', 'token_status')) {
        $columns[] = 'token_status';
        $placeholders[] = '?';
        $params[] = ($mpCardId !== '' || $tokenGateway !== '') ? 'tokenizado' : 'referencia';
    }
    if (mp_column_exists($pdo, 'passageiro_cartoes', 'observacao_gateway')) {
        $columns[] = 'observacao_gateway';
        $placeholders[] = '?';
        $params[] = ($mpCardId !== '' || $tokenGateway !== '')
            ? 'Cartao preparado para cobranca online.'
            : 'Cartao salvo como referencia local.';
    }

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

    json_ok([
        'id_cartao' => (int) $pdo->lastInsertId(),
        'tokenizado' => $mpCardId !== '' || $tokenGateway !== '',
        'message' => $mpCardId !== ''
            ? 'Cartao salvo para proximas corridas.'
            : 'Cartao salvo como referencia local.',
    ]);
} catch (Throwable $e) {
    json_fail(
        mp_gateway_exception_message($e, 'Erro ao salvar cartao.'),
        $e instanceof MercadoPagoApiException ? 422 : 500,
        mp_gateway_exception_payload($e)
    );
}
