<?php

function clamp_int($v, int $min, int $max, int $fallback): int {
    if ($v === null || $v === '') return $fallback;
    if (!is_numeric($v)) return $fallback;
    $n = (int)$v;
    if ($n < $min) return $min;
    if ($n > $max) return $max;
    return $n;
}

function str_contains_ci(string $haystack, string $needle): bool {
    if ($needle === '') return true;
    return mb_stripos($haystack, $needle) !== false;
}

function load_bid_rules(): array {
    $file = __DIR__ . '/../bid-control/bids.json';
    if (!is_file($file)) return [];

    $raw = @file_get_contents($file);
    if ($raw === false || trim($raw) === '') return [];

    $json = json_decode($raw, true);
    return is_array($json) ? $json : [];
}

function normalize_vertical_from_service_category(string $serviceCategory = '', string $fallbackVertical = ''): string {
    $serviceCategory = trim(strtolower($serviceCategory));
    $fallbackVertical = trim(strtolower($fallbackVertical));

    $map = [
        'electrician' => 'electrician',
        'plumbing' => 'plumbing',
        'waterdamagerestoration' => 'water_damage',
        'roofing' => 'roofing',
        'towingservice' => 'towingservice',
        'appliancerepair' => 'appliancerepair',
        'carpetcleaning' => 'carpetcleaning',
        'solar' => 'solar',
        'windowreplacement' => 'windowreplacement',
        'windows' => 'windowreplacement',
        'autoinsurance' => 'autoinsurance',
        'auto_insurance' => 'autoinsurance',
    ];

    if ($serviceCategory !== '' && isset($map[$serviceCategory])) {
        return $map[$serviceCategory];
    }

    if ($fallbackVertical !== '') {
        if (isset($map[$fallbackVertical])) {
            return $map[$fallbackVertical];
        }
        return $fallbackVertical;
    }

    return '';
}

function bid_rule_for_vertical(string $vertical): array {
    $vertical = normalize_vertical_from_service_category($vertical, $vertical);
    $rules = load_bid_rules();

    if ($vertical === '' || !isset($rules[$vertical]) || !is_array($rules[$vertical])) {
        return [
            'enabled' => false,
            'min_bid' => 0,
        ];
    }

    return [
        'enabled' => !empty($rules[$vertical]['enabled']),
        'min_bid' => (float)($rules[$vertical]['min_bid'] ?? 0),
    ];
}

function routing_decision_label(array $row): string {
    $event = strtoupper(trim((string)($row['event'] ?? '')));
    $bid = (float)($row['bid'] ?? 0);
    $enabled = !empty($row['_rule_enabled']);
    $minBid = (float)($row['_rule_bid'] ?? 0);

    if ($event === 'PING_REJECT') {
        if (!empty($row['raw']) && stripos((string)$row['raw'], 'LOW_BID_REJECT') !== false) {
            return 'Low Bid Rejected';
        }
        return 'Ping Rejected';
    }

    if ($event === 'PING') {
        if ($enabled && $minBid > 0 && $bid > 0 && $bid < $minBid) {
            return 'Below Threshold';
        }
        return 'Ping Received';
    }

    if ($event === 'ACCEPT') {
        return 'Routed';
    }

    return '';
}