<?php
declare(strict_types=1);

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

function veiculo_fail(string $message, int $status = 400, array $payload = []): void
{
    json_fail($message, $status, $payload);
}

function salvar_documento_veiculo_upload(string $field, int $motoristaId): string
{
    if (!isset($_FILES[$field]) || !is_uploaded_file($_FILES[$field]['tmp_name'])) {
        veiculo_fail('Documento do veiculo nao informado.');
    }

    $uploadDir = public_upload_path('veiculos');
    $original = basename((string) $_FILES[$field]['name']);
    $safeName = preg_replace('/[^a-zA-Z0-9._-]/', '_', $original);
    $filename = 'veiculo_' . $motoristaId . '_' . time() . '_' . $safeName;
    $target = $uploadDir . '/' . $filename;

    if (!move_uploaded_file($_FILES[$field]['tmp_name'], $target)) {
        veiculo_fail('Falha ao salvar documento do veiculo.', 500);
    }

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

function normalizar_placa_veiculo(string $placa): string
{
    return strtoupper((string) preg_replace('/[^A-Za-z0-9]/', '', $placa));
}

$idMotorista = (int) ($_POST['id_motorista'] ?? 0);
$idVeiculo = (int) ($_POST['id_veiculo'] ?? 0);
$idMarcaCatalogo = (int) ($_POST['id_marca_catalogo'] ?? 0);
$idModeloCatalogo = (int) ($_POST['id_modelo_catalogo'] ?? 0);
$idCorCatalogo = (int) ($_POST['id_cor_catalogo'] ?? 0);
$marca = trim((string) ($_POST['marca'] ?? ''));
$modelo = trim((string) ($_POST['modelo'] ?? ''));
$anoFabricacao = (int) ($_POST['ano_fabricacao'] ?? 0);
$anoModelo = (int) ($_POST['ano_modelo'] ?? 0);
$cor = trim((string) ($_POST['cor'] ?? ''));
$placa = normalizar_placa_veiculo((string) ($_POST['placa'] ?? ''));

if ($idMotorista <= 0) {
    veiculo_fail('Motorista nao informado.');
}

if ($anoFabricacao <= 0 || $anoModelo <= 0) {
    veiculo_fail('Preencha os anos do veiculo.');
}

if ($placa === '') {
    veiculo_fail('Informe a placa do veiculo.');
}

if (!preg_match('/^[A-Z]{3}[0-9][A-Z0-9][0-9]{2}$/', $placa)) {
    veiculo_fail('Informe uma placa valida.', 422);
}

$anoAtual = (int) date('Y');
if ($anoFabricacao < ($anoAtual - 12) || $anoFabricacao > $anoAtual) {
    veiculo_fail('Somente veiculos com no maximo 12 anos de fabricacao podem ser cadastrados.');
}

if ($idVeiculo <= 0 && (!isset($_FILES['documento']) || !is_uploaded_file($_FILES['documento']['tmp_name']))) {
    veiculo_fail('Envie o documento do veiculo.');
}

try {
    $pdo = db();
    $promocao = usuario_garantir_motorista($idMotorista, $pdo);

    if ($idModeloCatalogo > 0) {
        $catalogoStmt = $pdo->prepare(
            'SELECT mo.id, mo.nome AS modelo, ma.id AS id_marca, ma.nome AS marca
             FROM veiculo_modelos_catalogo mo
             INNER JOIN veiculo_marcas_catalogo ma ON ma.id = mo.id_marca
             WHERE mo.id = ?
               AND mo.ativo = 1
               AND ma.ativo = 1
             LIMIT 1'
        );
        $catalogoStmt->execute([$idModeloCatalogo]);
        $catalogo = $catalogoStmt->fetch();
        if (!$catalogo) {
            veiculo_fail('Modelo de veiculo invalido.', 422);
        }

        $idModeloCatalogo = (int) $catalogo['id'];
        $idMarcaCatalogo = (int) $catalogo['id_marca'];
        $marca = (string) $catalogo['marca'];
        $modelo = (string) $catalogo['modelo'];
    }

    if ($idCorCatalogo > 0) {
        $corStmt = $pdo->prepare(
            'SELECT id, nome
             FROM veiculo_cores_catalogo
             WHERE id = ?
               AND ativo = 1
             LIMIT 1'
        );
        $corStmt->execute([$idCorCatalogo]);
        $corCatalogo = $corStmt->fetch();
        if (!$corCatalogo) {
            veiculo_fail('Cor de veiculo invalida.', 422);
        }

        $idCorCatalogo = (int) $corCatalogo['id'];
        $cor = (string) $corCatalogo['nome'];
    }

    if ($marca === '' || $modelo === '' || $cor === '') {
        veiculo_fail('Preencha marca, modelo e cor.', 422);
    }

    $placaStmt = $pdo->prepare('SELECT id FROM veiculos WHERE placa = ? AND id <> ? LIMIT 1');
    $placaStmt->execute([$placa, $idVeiculo > 0 ? $idVeiculo : 0]);
    if ($placaStmt->fetch()) {
        veiculo_fail('Ja existe um veiculo cadastrado com esta placa.', 409);
    }

    $ativoStmt = $pdo->prepare(
        'SELECT id_veiculo_ativo
         FROM usuarios
         WHERE id = ? AND tipo = "motorista"
         LIMIT 1'
    );
    $ativoStmt->execute([$idMotorista]);
    $idVeiculoAtivoAtual = (int) ($ativoStmt->fetchColumn() ?: 0);

    if ($idVeiculo <= 0) {
        $countStmt = $pdo->prepare('SELECT COUNT(*) FROM veiculos WHERE id_motorista = ?');
        $countStmt->execute([$idMotorista]);
        $totalVeiculos = (int) $countStmt->fetchColumn();
        if ($totalVeiculos >= 3) {
            veiculo_fail('O motorista pode ter no maximo 3 veiculos.');
        }
    } else {
        $existente = $pdo->prepare('SELECT id, documento_url FROM veiculos WHERE id = ? AND id_motorista = ? LIMIT 1');
        $existente->execute([$idVeiculo, $idMotorista]);
        $veiculoAtual = $existente->fetch();
        if (!$veiculoAtual) {
            veiculo_fail('Veiculo nao encontrado.', 404);
        }
    }

    $pdo->beginTransaction();

    $documentoUrl = null;
    if (isset($_FILES['documento']) && is_uploaded_file($_FILES['documento']['tmp_name'])) {
        $documentoUrl = salvar_documento_veiculo_upload('documento', $idMotorista);
    }

    if ($idVeiculo <= 0) {
        $stmt = $pdo->prepare(
            'INSERT INTO veiculos (id_motorista, id_marca_catalogo, id_modelo_catalogo, id_cor_catalogo, marca, modelo, ano_fabricacao, ano_modelo, cor, placa, documento_url, status)
             VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, "pendente")'
        );
        $stmt->execute([
            $idMotorista,
            $idMarcaCatalogo > 0 ? $idMarcaCatalogo : null,
            $idModeloCatalogo > 0 ? $idModeloCatalogo : null,
            $idCorCatalogo > 0 ? $idCorCatalogo : null,
            $marca,
            $modelo,
            $anoFabricacao,
            $anoModelo,
            $cor,
            $placa,
            $documentoUrl,
        ]);
        $idVeiculo = (int) $pdo->lastInsertId();
    } else {
        $sql = 'UPDATE veiculos SET id_marca_catalogo = ?, id_modelo_catalogo = ?, id_cor_catalogo = ?, marca = ?, modelo = ?, ano_fabricacao = ?, ano_modelo = ?, cor = ?, placa = ?, status = "pendente", observacao_revisao = NULL, aprovado_por = NULL, aprovado_em = NULL';
        $params = [
            $idMarcaCatalogo > 0 ? $idMarcaCatalogo : null,
            $idModeloCatalogo > 0 ? $idModeloCatalogo : null,
            $idCorCatalogo > 0 ? $idCorCatalogo : null,
            $marca,
            $modelo,
            $anoFabricacao,
            $anoModelo,
            $cor,
            $placa,
        ];
        if ($documentoUrl !== null) {
            $sql .= ', documento_url = ?, documento_vencimento = NULL';
            $params[] = $documentoUrl;
        }
        $sql .= ' WHERE id = ? AND id_motorista = ?';
        $params[] = $idVeiculo;
        $params[] = $idMotorista;

        $stmt = $pdo->prepare($sql);
        $stmt->execute($params);
    }

    $upMotorista = $pdo->prepare(
        'UPDATE usuarios
         SET documento_veiculo_status = "pendente",
             documento_veiculo_observacao = NULL,
             documento_veiculo_vencimento = NULL,
             documento_veiculo_aprovado_por = NULL,
             documento_veiculo_aprovado_em = NULL,
             status_verificacao = "pendente",
             observacao_verificacao = "Aguardando revisao dos documentos.",
             disponivel = "nao"'
         . ($idVeiculoAtivoAtual === $idVeiculo ? ', id_veiculo_ativo = NULL' : '') .
         ' WHERE id = ? AND tipo = "motorista"'
    );
    $upMotorista->execute([$idMotorista]);

    $pdo->commit();

    json_ok([
        'id_veiculo' => $idVeiculo,
        'tipo_convertido_motorista' => $promocao['foi_promovido'],
        'indicador_removido' => $promocao['indicador_removido'],
        'message' => 'Veiculo salvo com sucesso.',
    ]);
} catch (Throwable $e) {
    if (isset($pdo) && $pdo->inTransaction()) {
        $pdo->rollBack();
    }
    veiculo_fail('Erro ao salvar veiculo.', 500, ['error' => $e->getMessage()]);
}
