<?php
declare(strict_types=1);

function tarifas_defaults(): array
{
    return [
        'preco_base' => 5.00,
        'preco_por_km' => 2.50,
        'preco_por_minuto' => 0.35,
        'taxa_servico' => 0.00,
        'valor_minimo' => 5.00,
    ];
}

function tarifas_defaults_por_categoria(): array
{
    $base = tarifas_defaults();

    return [
        'economica' => $base,
        'plus' => $base,
        'pro' => $base,
    ];
}

function tarifas_chaves_preco(): array
{
    return ['preco_base', 'preco_por_km', 'preco_por_minuto', 'taxa_servico', 'valor_minimo'];
}

function tarifas_categorias_defaults(): array
{
    return [
        'economica' => true,
        'plus' => true,
        'pro' => true,
    ];
}

function tarifas_categorias_indisponiveis(): array
{
    return [
        'economica' => false,
        'plus' => false,
        'pro' => false,
    ];
}

function tarifas_mensagem_indisponivel(): string
{
    return 'Ainda nao estamos disponiveis nessa regiao. Estamos trabalhando para atender em breve.';
}

function tarifas_table_exists(PDO $pdo, string $table): bool
{
    $stmt = $pdo->prepare(
        'SELECT COUNT(*)
         FROM INFORMATION_SCHEMA.TABLES
         WHERE TABLE_SCHEMA = DATABASE()
           AND TABLE_NAME = ?'
    );
    $stmt->execute([$table]);

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

function tarifas_column_exists(PDO $pdo, string $table, string $column): bool
{
    static $cache = [];
    $key = $table . '.' . $column;
    if (array_key_exists($key, $cache)) {
        return $cache[$key];
    }

    $stmt = $pdo->prepare(
        'SELECT COUNT(*)
         FROM INFORMATION_SCHEMA.COLUMNS
         WHERE TABLE_SCHEMA = DATABASE()
           AND TABLE_NAME = ?
           AND COLUMN_NAME = ?'
    );
    $stmt->execute([$table, $column]);
    $cache[$key] = (int) $stmt->fetchColumn() > 0;

    return $cache[$key];
}

function tarifas_config_global(PDO $pdo): array
{
    $config = tarifas_defaults();
    $stmt = $pdo->query('SELECT chave, valor FROM configuracoes');

    foreach ($stmt->fetchAll() as $row) {
        if (array_key_exists((string) $row['chave'], $config)) {
            $config[(string) $row['chave']] = (float) $row['valor'];
        }
    }

    return $config;
}

function tarifas_config_global_por_categoria(PDO $pdo): array
{
    $tarifas = [
        'economica' => tarifas_defaults(),
        'plus' => [],
        'pro' => [],
    ];
    $stmt = $pdo->query('SELECT chave, valor FROM configuracoes');

    foreach ($stmt->fetchAll() as $row) {
        $chave = (string) $row['chave'];
        $valor = (float) $row['valor'];

        if (in_array($chave, tarifas_chaves_preco(), true)) {
            $tarifas['economica'][$chave] = $valor;
            continue;
        }

        foreach (['plus', 'pro'] as $categoria) {
            $prefixo = $categoria . '_';
            if (strncmp($chave, $prefixo, strlen($prefixo)) === 0) {
                $chavePreco = substr($chave, strlen($prefixo));
                if (in_array($chavePreco, tarifas_chaves_preco(), true)) {
                    $tarifas[$categoria][$chavePreco] = $valor;
                }
            }
        }
    }

    foreach (['plus', 'pro'] as $categoria) {
        foreach (tarifas_chaves_preco() as $chave) {
            if (!array_key_exists($chave, $tarifas[$categoria])) {
                $tarifas[$categoria][$chave] = $tarifas['economica'][$chave];
            }
        }
    }

    return $tarifas;
}

function tarifas_decode_geocerca(?string $json): array
{
    if ($json === null || trim($json) === '') {
        return [];
    }

    $decoded = json_decode($json, true);
    if (!is_array($decoded)) {
        return [];
    }

    $pontos = [];
    foreach ($decoded as $ponto) {
        if (!is_array($ponto)) {
            continue;
        }

        $lat = isset($ponto['lat']) ? (float) $ponto['lat'] : null;
        $lng = isset($ponto['lng']) ? (float) $ponto['lng'] : null;
        if ($lat === null || $lng === null) {
            continue;
        }

        $pontos[] = ['lat' => $lat, 'lng' => $lng];
    }

    return count($pontos) >= 3 ? $pontos : [];
}

function tarifas_point_in_polygon(float $lat, float $lng, array $polygon): bool
{
    $inside = false;
    $count = count($polygon);
    if ($count < 3) {
        return false;
    }

    for ($i = 0, $j = $count - 1; $i < $count; $j = $i++) {
        $latI = (float) $polygon[$i]['lat'];
        $lngI = (float) $polygon[$i]['lng'];
        $latJ = (float) $polygon[$j]['lat'];
        $lngJ = (float) $polygon[$j]['lng'];

        $intersects = (($lngI > $lng) !== ($lngJ > $lng))
            && ($lat < ($latJ - $latI) * ($lng - $lngI) / (($lngJ - $lngI) ?: 0.0000001) + $latI);

        if ($intersects) {
            $inside = !$inside;
        }
    }

    return $inside;
}

function tarifas_categoria_normalizar(string $categoria): string
{
    $categoria = strtolower(trim($categoria));
    return in_array($categoria, ['economica', 'plus', 'pro'], true) ? $categoria : 'economica';
}

function tarifas_dinamica_regiao_config(array $row): array
{
    $max = (float) ($row['dinamica_multiplicador_max'] ?? 1.80);
    $max = max(1.00, min(3.00, $max));

    $sensibilidade = strtolower(trim((string) ($row['dinamica_sensibilidade'] ?? 'media')));
    if (!in_array($sensibilidade, ['baixa', 'media', 'alta'], true)) {
        $sensibilidade = 'media';
    }

    $celulaKm = (float) ($row['dinamica_celula_km'] ?? 2.00);
    $celulaKm = max(0.80, min(8.00, $celulaKm));

    $janelaMinutos = (int) ($row['dinamica_janela_minutos'] ?? 12);
    $janelaMinutos = max(1, min(60, $janelaMinutos));

    return [
        'ativa' => (int) ($row['dinamica_ativa'] ?? 0) === 1,
        'multiplicador_max' => round($max, 2),
        'sensibilidade' => $sensibilidade,
        'celula_km' => round($celulaKm, 2),
        'janela_minutos' => $janelaMinutos,
    ];
}

function tarifas_dinamica_celula(float $lat, float $lng, float $celulaKm): array
{
    $latStep = $celulaKm / 110.574;
    $row = (int) floor(($lat + 90.0) / $latStep);
    $centroLat = -90.0 + ($row * $latStep) + ($latStep / 2);
    $lngKm = 111.320 * max(0.20, cos(deg2rad($centroLat)));
    $lngStep = $celulaKm / $lngKm;
    $col = (int) floor(($lng + 180.0) / $lngStep);
    $centroLng = -180.0 + ($col * $lngStep) + ($lngStep / 2);

    return [
        'row' => $row,
        'col' => $col,
        'id' => $row . ':' . $col,
        'lat' => round($centroLat, 7),
        'lng' => round($centroLng, 7),
        'celula_km' => round($celulaKm, 2),
    ];
}

function tarifas_dinamica_poligono_octogonal(float $lat, float $lng, float $celulaKm): array
{
    $raioKm = $celulaKm * 0.58;
    $lngKm = 111.320 * max(0.20, cos(deg2rad($lat)));
    $pontos = [];

    for ($i = 0; $i < 8; $i++) {
        $angulo = deg2rad(22.5 + ($i * 45.0));
        $pontos[] = [
            'lat' => round($lat + (cos($angulo) * $raioKm / 110.574), 7),
            'lng' => round($lng + (sin($angulo) * $raioKm / $lngKm), 7),
        ];
    }

    return $pontos;
}

function tarifas_dinamica_ponto_mesma_celula(float $lat, float $lng, array $celula): bool
{
    $outra = tarifas_dinamica_celula($lat, $lng, (float) $celula['celula_km']);
    return $outra['id'] === $celula['id'];
}

function tarifas_dinamica_demanda_celula(PDO $pdo, int $idRegiao, string $categoria, array $celula, array $polygon, int $janelaMinutos = 12): int
{
    if (!tarifas_table_exists($pdo, 'corridas') || !tarifas_column_exists($pdo, 'corridas', 'id_tarifa_regiao')) {
        return 0;
    }

    $janelaMinutos = max(1, min(60, $janelaMinutos));
    $stmt = $pdo->prepare(
        'SELECT origem_lat, origem_lng
         FROM corridas
         WHERE status = "pendente"
           AND id_tarifa_regiao = ?
           AND COALESCE(categoria_veiculo, "economica") = ?
           AND origem_lat IS NOT NULL
           AND origem_lng IS NOT NULL
           AND criada_em >= DATE_SUB(NOW(), INTERVAL ' . $janelaMinutos . ' MINUTE)'
    );
    $stmt->execute([$idRegiao, $categoria]);

    $total = 0;
    foreach ($stmt->fetchAll() as $row) {
        $lat = (float) $row['origem_lat'];
        $lng = (float) $row['origem_lng'];
        if (
            tarifas_dinamica_ponto_mesma_celula($lat, $lng, $celula)
            && (!$polygon || tarifas_point_in_polygon($lat, $lng, $polygon))
        ) {
            $total++;
        }
    }

    return $total;
}

function tarifas_dinamica_motoristas_celula(PDO $pdo, string $categoria, array $celula, array $polygon): int
{
    if (!tarifas_table_exists($pdo, 'usuarios') || !tarifas_table_exists($pdo, 'veiculos')) {
        return 0;
    }

    $stmt = $pdo->prepare(
        'SELECT u.ultimo_lat, u.ultimo_lng
         FROM usuarios u
         INNER JOIN veiculos v
           ON v.id = u.id_veiculo_ativo
          AND v.id_motorista = u.id
          AND v.status = "aprovado"
         LEFT JOIN veiculo_modelos_catalogo vm ON vm.id = v.id_modelo_catalogo
         WHERE u.tipo = "motorista"
           AND u.disponivel = "sim"
           AND u.cnh_status = "aprovado"
           AND u.selfie_status = "aprovado"
           AND u.ultimo_lat IS NOT NULL
           AND u.ultimo_lng IS NOT NULL
           AND u.localizacao_atualizada_em >= DATE_SUB(NOW(), INTERVAL 3 MINUTE)
           AND (
             ? = "economica"
             OR (? = "plus" AND COALESCE(vm.categoria_plus, 0) = 1)
             OR (? = "pro" AND COALESCE(vm.categoria_pro, 0) = 1)
           )'
    );
    $stmt->execute([$categoria, $categoria, $categoria]);

    $total = 0;
    foreach ($stmt->fetchAll() as $row) {
        $lat = (float) $row['ultimo_lat'];
        $lng = (float) $row['ultimo_lng'];
        if (
            tarifas_dinamica_ponto_mesma_celula($lat, $lng, $celula)
            && (!$polygon || tarifas_point_in_polygon($lat, $lng, $polygon))
        ) {
            $total++;
        }
    }

    return $total;
}

function tarifas_dinamica_calcular_categoria(
    PDO $pdo,
    array $row,
    string $categoria,
    float $lat,
    float $lng,
    bool $incluirSolicitacao = false
): array {
    $categoria = tarifas_categoria_normalizar($categoria);
    $config = tarifas_dinamica_regiao_config($row);
    $polygon = tarifas_decode_geocerca($row['geocerca_json'] ?? null);
    $celula = tarifas_dinamica_celula($lat, $lng, (float) $config['celula_km']);
    $celulaId = (int) ($row['id'] ?? 0) . ':' . $categoria . ':' . $celula['id'];

    $base = [
        'ativa' => $config['ativa'],
        'categoria' => $categoria,
        'multiplicador' => 1.00,
        'multiplicador_max' => $config['multiplicador_max'],
        'sensibilidade' => $config['sensibilidade'],
        'celula_id' => $celulaId,
        'celula_km' => $config['celula_km'],
        'janela_minutos' => $config['janela_minutos'],
        'celula_centro' => ['lat' => $celula['lat'], 'lng' => $celula['lng']],
        'celula_poligono' => [],
        'demanda' => 0,
        'motoristas' => 0,
        'motivo' => null,
    ];

    if (!$config['ativa']) {
        return $base;
    }

    $demanda = tarifas_dinamica_demanda_celula(
        $pdo,
        (int) $row['id'],
        $categoria,
        $celula,
        $polygon,
        (int) $config['janela_minutos']
    );
    if ($incluirSolicitacao) {
        $demanda++;
    }
    $motoristas = tarifas_dinamica_motoristas_celula($pdo, $categoria, $celula, $polygon);

    $base['demanda'] = $demanda;
    $base['motoristas'] = $motoristas;

    if ($demanda < 2 || ($motoristas > 0 && $demanda <= $motoristas)) {
        return $base;
    }

    switch ($config['sensibilidade']) {
        case 'alta':
            $limiar = 1.00;
            $fatorPressao = 0.14;
            $bonusDeficit = 0.03;
            break;
        case 'baixa':
            $limiar = 1.70;
            $fatorPressao = 0.10;
            $bonusDeficit = 0.02;
            break;
        default:
            $limiar = 1.25;
            $fatorPressao = 0.12;
            $bonusDeficit = 0.025;
            break;
    }

    $ofertaReferencia = max(1, $motoristas);
    $pressao = $motoristas === 0 ? ($demanda + 1.0) : ($demanda / $ofertaReferencia);
    if ($pressao <= $limiar) {
        return $base;
    }

    $deficit = max(0, $demanda - $motoristas);
    $multiplicador = 1.00 + (($pressao - $limiar) * $fatorPressao) + ($deficit * $bonusDeficit);
    $multiplicador = min((float) $config['multiplicador_max'], max(1.00, $multiplicador));
    $multiplicador = ceil($multiplicador * 10.0) / 10.0;
    $multiplicador = min((float) $config['multiplicador_max'], max(1.20, $multiplicador));
    $multiplicador = round($multiplicador, 1);

    if ($multiplicador <= 1.00) {
        return $base;
    }

    $base['multiplicador'] = $multiplicador;
    $base['celula_poligono'] = tarifas_dinamica_poligono_octogonal(
        (float) $celula['lat'],
        (float) $celula['lng'],
        (float) $config['celula_km']
    );
    $base['motivo'] = sprintf(
        'Alta demanda: %d chamada(s) e %d motorista(s) disponivel(is) na celula.',
        $demanda,
        $motoristas
    );

    return $base;
}

function tarifas_dinamica_calcular_regiao(
    PDO $pdo,
    array $row,
    ?float $lat,
    ?float $lng,
    bool $incluirSolicitacao = false
): array {
    $categorias = [
        'economica' => ['multiplicador' => 1.00],
        'plus' => ['multiplicador' => 1.00],
        'pro' => ['multiplicador' => 1.00],
    ];
    $celulas = [];
    $ativa = false;
    $mensagem = null;

    if ($lat === null || $lng === null) {
        return [
            'ativa' => false,
            'mensagem' => null,
            'categorias' => $categorias,
            'celulas' => [],
        ];
    }

    foreach (array_keys($categorias) as $categoria) {
        $calc = tarifas_dinamica_calcular_categoria($pdo, $row, $categoria, $lat, $lng, $incluirSolicitacao);
        $categorias[$categoria] = $calc;
        if ((float) ($calc['multiplicador'] ?? 1.00) > 1.00) {
            $ativa = true;
            $mensagem ??= 'Alta demanda nesta regiao.';
            $celulas[] = [
                'id' => $calc['celula_id'],
                'categoria' => $categoria,
                'multiplicador' => $calc['multiplicador'],
                'demanda' => $calc['demanda'],
                'motoristas' => $calc['motoristas'],
                'motivo' => $calc['motivo'],
                'centro' => $calc['celula_centro'],
                'poligono' => $calc['celula_poligono'],
            ];
        }
    }

    return [
        'ativa' => $ativa,
        'mensagem' => $mensagem,
        'categorias' => $categorias,
        'celulas' => $celulas,
    ];
}

function tarifas_dinamicas_ativas(PDO $pdo): array
{
    if (
        !tarifas_table_exists($pdo, 'tarifa_regioes')
        || !tarifas_column_exists($pdo, 'tarifa_regioes', 'dinamica_ativa')
        || !tarifas_table_exists($pdo, 'corridas')
        || !tarifas_column_exists($pdo, 'corridas', 'id_tarifa_regiao')
    ) {
        return [];
    }

    $regioesStmt = $pdo->query(
        'SELECT *
         FROM tarifa_regioes
         WHERE ativo = 1 AND dinamica_ativa = 1'
    );
    $regioes = [];
    foreach ($regioesStmt->fetchAll() as $row) {
        $regioes[(int) $row['id']] = $row;
    }
    if (!$regioes) {
        return [];
    }

    $janelaMaxima = 12;
    foreach ($regioes as $regiao) {
        $janelaMaxima = max(
            $janelaMaxima,
            (int) tarifas_dinamica_regiao_config($regiao)['janela_minutos']
        );
    }

    $corridasStmt = $pdo->query(
        'SELECT DISTINCT id_tarifa_regiao, COALESCE(categoria_veiculo, "economica") AS categoria_veiculo,
                origem_lat, origem_lng
         FROM corridas
         WHERE status = "pendente"
           AND id_tarifa_regiao IS NOT NULL
           AND origem_lat IS NOT NULL
           AND origem_lng IS NOT NULL
           AND criada_em >= DATE_SUB(NOW(), INTERVAL ' . $janelaMaxima . ' MINUTE)'
    );

    $celulas = [];
    foreach ($corridasStmt->fetchAll() as $corrida) {
        $idRegiao = (int) $corrida['id_tarifa_regiao'];
        if (!isset($regioes[$idRegiao])) {
            continue;
        }

        $calc = tarifas_dinamica_calcular_categoria(
            $pdo,
            $regioes[$idRegiao],
            (string) $corrida['categoria_veiculo'],
            (float) $corrida['origem_lat'],
            (float) $corrida['origem_lng'],
            false
        );

        if ((float) ($calc['multiplicador'] ?? 1.00) <= 1.00) {
            continue;
        }

        $key = (string) $calc['celula_id'];
        $celulas[$key] = [
            'id' => $key,
            'id_regiao' => $idRegiao,
            'regiao' => (string) $regioes[$idRegiao]['nome'],
            'categoria' => (string) $calc['categoria'],
            'multiplicador' => (float) $calc['multiplicador'],
            'demanda' => (int) $calc['demanda'],
            'motoristas' => (int) $calc['motoristas'],
            'janela_minutos' => (int) ($calc['janela_minutos'] ?? 12),
            'motivo' => $calc['motivo'],
            'centro' => $calc['celula_centro'],
            'poligono' => $calc['celula_poligono'],
        ];
    }

    return array_values($celulas);
}

function tarifas_regiao_to_payload(array $row): array
{
    $economica = [
        'preco_base' => (float) $row['preco_base'],
        'preco_por_km' => (float) $row['preco_por_km'],
        'preco_por_minuto' => (float) $row['preco_por_minuto'],
        'taxa_servico' => (float) $row['taxa_servico'],
        'valor_minimo' => isset($row['valor_minimo']) ? (float) $row['valor_minimo'] : (float) $row['preco_base'],
    ];
    $plus = [
        'preco_base' => isset($row['plus_preco_base']) ? (float) $row['plus_preco_base'] : $economica['preco_base'],
        'preco_por_km' => isset($row['plus_preco_por_km']) ? (float) $row['plus_preco_por_km'] : $economica['preco_por_km'],
        'preco_por_minuto' => isset($row['plus_preco_por_minuto']) ? (float) $row['plus_preco_por_minuto'] : $economica['preco_por_minuto'],
        'taxa_servico' => isset($row['plus_taxa_servico']) ? (float) $row['plus_taxa_servico'] : $economica['taxa_servico'],
        'valor_minimo' => isset($row['plus_valor_minimo']) ? (float) $row['plus_valor_minimo'] : $economica['valor_minimo'],
    ];
    $pro = [
        'preco_base' => isset($row['pro_preco_base']) ? (float) $row['pro_preco_base'] : $economica['preco_base'],
        'preco_por_km' => isset($row['pro_preco_por_km']) ? (float) $row['pro_preco_por_km'] : $economica['preco_por_km'],
        'preco_por_minuto' => isset($row['pro_preco_por_minuto']) ? (float) $row['pro_preco_por_minuto'] : $economica['preco_por_minuto'],
        'taxa_servico' => isset($row['pro_taxa_servico']) ? (float) $row['pro_taxa_servico'] : $economica['taxa_servico'],
        'valor_minimo' => isset($row['pro_valor_minimo']) ? (float) $row['pro_valor_minimo'] : $economica['valor_minimo'],
    ];

    $dinamicaConfig = tarifas_dinamica_regiao_config($row);

    return [
        'id' => (int) $row['id'],
        'nome' => (string) $row['nome'],
        'ativo' => (int) $row['ativo'] === 1,
        'dinamica_ativa' => $dinamicaConfig['ativa'],
        'dinamica_multiplicador_max' => $dinamicaConfig['multiplicador_max'],
        'dinamica_sensibilidade' => $dinamicaConfig['sensibilidade'],
        'dinamica_celula_km' => $dinamicaConfig['celula_km'],
        'dinamica_janela_minutos' => $dinamicaConfig['janela_minutos'],
        'configuracoes' => $economica,
        'tarifas' => [
            'economica' => $economica,
            'plus' => $plus,
            'pro' => $pro,
        ],
        'categorias' => [
            'economica' => (int) $row['economica_ativo'] === 1,
            'plus' => (int) $row['plus_ativo'] === 1,
            'pro' => (int) $row['pro_ativo'] === 1,
        ],
        'geocerca' => tarifas_decode_geocerca($row['geocerca_json'] ?? null),
    ];
}

function tarifas_resolver_por_ponto(PDO $pdo, ?float $lat, ?float $lng, bool $incluirSolicitacaoDinamica = false): array
{
    $global = tarifas_config_global($pdo);
    $globalPorCategoria = tarifas_config_global_por_categoria($pdo);
    $fallback = [
        'configuracoes' => $global,
        'tarifas' => $globalPorCategoria,
        'categorias' => tarifas_categorias_defaults(),
        'regiao' => null,
        'disponivel' => true,
        'mensagem_indisponivel' => null,
        'dinamica' => [
            'ativa' => false,
            'mensagem' => null,
            'categorias' => [
                'economica' => ['multiplicador' => 1.00],
                'plus' => ['multiplicador' => 1.00],
                'pro' => ['multiplicador' => 1.00],
            ],
            'celulas' => [],
        ],
    ];

    if ($lat === null || $lng === null) {
        return $fallback;
    }

    $indisponivel = [
        'configuracoes' => $global,
        'tarifas' => $globalPorCategoria,
        'categorias' => tarifas_categorias_indisponiveis(),
        'regiao' => null,
        'disponivel' => false,
        'mensagem_indisponivel' => tarifas_mensagem_indisponivel(),
        'dinamica' => $fallback['dinamica'],
    ];

    if (!tarifas_table_exists($pdo, 'tarifa_regioes')) {
        return $indisponivel;
    }

    $stmt = $pdo->query(
        'SELECT *
         FROM tarifa_regioes
         ORDER BY ordem ASC, id ASC'
    );

    foreach ($stmt->fetchAll() as $row) {
        $polygon = tarifas_decode_geocerca($row['geocerca_json'] ?? null);
        if (!$polygon || !tarifas_point_in_polygon($lat, $lng, $polygon)) {
            continue;
        }

        if ((int) $row['ativo'] !== 1) {
            $indisponivel['regiao'] = [
                'id' => (int) $row['id'],
                'nome' => (string) $row['nome'],
            ];
            return $indisponivel;
        }

        $regiao = tarifas_regiao_to_payload($row);

        $dinamica = tarifas_dinamica_calcular_regiao($pdo, $row, $lat, $lng, $incluirSolicitacaoDinamica);

        return [
            'configuracoes' => $regiao['configuracoes'],
            'tarifas' => $regiao['tarifas'],
            'categorias' => $regiao['categorias'],
            'regiao' => [
                'id' => $regiao['id'],
                'nome' => $regiao['nome'],
            ],
            'disponivel' => true,
            'mensagem_indisponivel' => null,
            'dinamica' => $dinamica,
        ];
    }

    return $indisponivel;
}

function tarifas_calcular_valor(array $config, float $distanciaKm, float $duracaoMinutos): float
{
    $precoBase = (float) ($config['preco_base'] ?? 0);
    $valorMinimo = (float) ($config['valor_minimo'] ?? $precoBase);
    $valor = $precoBase
        + ($distanciaKm * (float) ($config['preco_por_km'] ?? 0))
        + ($duracaoMinutos * (float) ($config['preco_por_minuto'] ?? 0))
        + (float) ($config['taxa_servico'] ?? 0);

    return round(max($valorMinimo, $valor), 2);
}
