<?php
declare(strict_types=1);

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

function fail_motorista(string $message, int $status = 400): void
{
    json_fail($message, $status);
}

function save_upload_required(string $field, string $prefix, int $userId): string
{
    if (!isset($_FILES[$field]) || !is_uploaded_file($_FILES[$field]['tmp_name'])) {
        fail_motorista("Arquivo obrigatorio ausente: {$field}");
    }

    $uploadDir = public_upload_path('motoristas');
    $original = basename((string) $_FILES[$field]['name']);
    $safeName = preg_replace('/[^a-zA-Z0-9._-]/', '_', $original);
    $filename = "{$prefix}_{$userId}_" . time() . "_{$safeName}";
    $target = $uploadDir . '/' . $filename;

    if (!move_uploaded_file($_FILES[$field]['tmp_name'], $target)) {
        fail_motorista("Falha ao salvar arquivo: {$field}", 500);
    }

    return 'uploads/motoristas/' . $filename;
}

function save_upload_optional(string $field, string $prefix, int $userId): ?string
{
    if (!isset($_FILES[$field]) || !is_uploaded_file($_FILES[$field]['tmp_name'])) {
        return null;
    }

    return save_upload_required($field, $prefix, $userId);
}

function cpf_valido(string $cpf): bool
{
    $cpf = preg_replace('/\D+/', '', $cpf);
    if (strlen($cpf) !== 11 || preg_match('/^(\d)\1{10}$/', $cpf)) {
        return false;
    }

    for ($t = 9; $t < 11; $t++) {
        $soma = 0;
        for ($i = 0; $i < $t; $i++) {
            $soma += (int) $cpf[$i] * (($t + 1) - $i);
        }
        $digito = ($soma * 10) % 11;
        if ($digito === 10) {
            $digito = 0;
        }
        if ((int) $cpf[$t] !== $digito) {
            return false;
        }
    }

    return true;
}

$data = input_json();

$primeiroNome = trim((string) ($data['primeiro_nome'] ?? $data['nome'] ?? $_POST['primeiro_nome'] ?? $_POST['nome'] ?? ''));
$sobrenome = trim((string) ($data['sobrenome'] ?? $_POST['sobrenome'] ?? ''));
$nome = trim($primeiroNome . ' ' . $sobrenome);
$cpf = preg_replace('/\D+/', '', (string) ($data['cpf'] ?? $_POST['cpf'] ?? ''));
$email = strtolower(trim((string) ($data['email'] ?? $_POST['email'] ?? '')));
$celular = preg_replace('/\D+/', '', (string) ($data['celular'] ?? $_POST['celular'] ?? ''));
$senha = (string) ($data['senha'] ?? $_POST['senha'] ?? '');
$codigoind = trim((string) ($data['codigoind'] ?? $_POST['codigoind'] ?? ''));
$indicador = trim((string) ($data['indicador'] ?? $_POST['indicador'] ?? ''));
$cep = preg_replace('/\D+/', '', (string) ($data['cep'] ?? $_POST['cep'] ?? ''));
$logradouro = trim((string) ($data['endereco_logradouro'] ?? $_POST['endereco_logradouro'] ?? ''));
$numero = trim((string) ($data['endereco_numero'] ?? $_POST['endereco_numero'] ?? ''));
$complemento = trim((string) ($data['endereco_complemento'] ?? $_POST['endereco_complemento'] ?? ''));
$bairro = trim((string) ($data['endereco_bairro'] ?? $_POST['endereco_bairro'] ?? ''));
$cidade = trim((string) ($data['endereco_cidade'] ?? $_POST['endereco_cidade'] ?? ''));
$uf = strtoupper(trim((string) ($data['endereco_uf'] ?? $_POST['endereco_uf'] ?? '')));

if ($primeiroNome === '' || strlen($primeiroNome) < 2) {
    fail_motorista('Informe o nome com pelo menos 2 caracteres.');
}
if ($sobrenome === '' || strlen($sobrenome) < 2) {
    fail_motorista('Informe o sobrenome com pelo menos 2 caracteres.');
}
if (!cpf_valido($cpf)) {
    fail_motorista('CPF invalido. Confira os numeros informados.');
}
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
    fail_motorista('E-mail invalido.');
}
if (!preg_match('/^\d{10,11}$/', $celular)) {
    fail_motorista('Celular invalido. Informe DDD + numero.');
}
if (strlen($senha) < 8) {
    fail_motorista('A senha precisa ter no minimo 8 caracteres.');
}
if ($codigoind === '') {
    fail_motorista('Nao foi possivel gerar o codigo de indicacao. Tente novamente.');
}
if (!preg_match('/^\d{8}$/', $cep)) {
    fail_motorista('CEP invalido. Informe 8 numeros.');
}
if ($logradouro === '') {
    fail_motorista('Informe o endereco.');
}
if ($numero === '') {
    fail_motorista('Informe o numero do endereco.');
}
if ($bairro === '') {
    fail_motorista('Informe o bairro.');
}
if ($cidade === '') {
    fail_motorista('Informe a cidade.');
}
if (!preg_match('/^[A-Z]{2}$/', $uf)) {
    fail_motorista('UF invalida.');
}

try {
    $pdo = db();

    $exists = $pdo->prepare('SELECT id FROM usuarios WHERE email = ? OR cpf = ? OR codigoind = ? LIMIT 1');
    $exists->execute([$email, $cpf, $codigoind]);
    if ($exists->fetch()) {
        fail_motorista('E-mail, CPF ou codigo de indicacao ja cadastrado.');
    }

    indicador_validar_para_tipo($indicador, 'motorista');

    $pdo->beginTransaction();

    $stmt = $pdo->prepare(
        'INSERT INTO usuarios (
            nome, primeiro_nome, sobrenome, cpf, email, celular, telefone_verificado,
            telefone_verificado_em, firebase_phone_uid, firebase_phone, senha_hash, tipo,
            codigoind, indicador_codigo, cep, endereco_logradouro, endereco_numero,
            endereco_complemento, endereco_bairro, endereco_cidade, endereco_uf,
            status_verificacao
         )
         VALUES (?, ?, ?, ?, ?, ?, 0, NULL, NULL, NULL, ?, "motorista", ?, ?, ?, ?, ?, ?, ?, ?, ?, "pendente")'
    );
    $stmt->execute([
        $nome,
        $primeiroNome,
        $sobrenome,
        $cpf,
        $email,
        $celular,
        password_hash($senha, PASSWORD_DEFAULT),
        $codigoind,
        $indicador === '' ? null : $indicador,
        $cep,
        $logradouro,
        $numero,
        $complemento === '' ? null : $complemento,
        $bairro,
        $cidade,
        $uf,
    ]);

    $userId = (int) $pdo->lastInsertId();

    $cnhUrl = save_upload_optional('cnh', 'cnh', $userId);
    $docUrl = save_upload_optional('documento_veiculo', 'doc_veiculo', $userId);
    $selfieUrl = save_upload_optional('selfie', 'selfie', $userId);

    $up = $pdo->prepare(
        'UPDATE usuarios
         SET cnh_url = ?, documento_veiculo_url = ?, selfie_url = ?, foto_url = ?,
             cnh_status = "pendente", documento_veiculo_status = "pendente", selfie_status = "pendente",
             status_verificacao = "pendente", observacao_verificacao = "Aguardando envio dos documentos.",
             disponivel = "nao"
         WHERE id = ?'
    );
    $up->execute([$cnhUrl, $docUrl, $selfieUrl, $selfieUrl, $userId]);

    $pdo->commit();
    json_ok([
        'id' => $userId,
        'status_verificacao' => 'pendente',
        'message' => 'Cadastro recebido. Envie os documentos depois pelo menu para revisao.',
    ]);
} catch (Throwable $e) {
    if (isset($pdo) && $pdo->inTransaction()) {
        $pdo->rollBack();
    }
    fail_motorista('Erro ao cadastrar motorista.', 500);
}
