<?php
/**
 * Server-side IP geolocation: uses the real client IP seen by this host, then looks up geo via HTTPS.
 * Called same-origin from shop-core.js (fetchGeoFromProviders) before browser ipapi/ipwho fallbacks.
 */
header('Content-Type: application/json; charset=UTF-8');
header('Cache-Control: no-store');

require_once __DIR__ . '/geoip-client-ip.inc.php';

if (!in_array($_SERVER['REQUEST_METHOD'] ?? '', ['GET', 'POST'], true)) {
    http_response_code(405);
    echo json_encode(['status' => 'error', 'message' => 'Method not allowed']);
    exit;
}

$ip = sb_geoip_client_ip();
if ($ip === '') {
    http_response_code(200);
    echo json_encode(['status' => 'error', 'message' => 'Could not determine client IP']);
    exit;
}

/**
 * @return array|null [city, region, country, isp] or null on failure
 */
function sb_geoip_lookup_ipapi($ip) {
    $url = 'https://ipapi.co/' . rawurlencode($ip) . '/json/';
    $body = sb_geoip_http_get($url);
    if ($body === null || $body === '') {
        return null;
    }
    $d = json_decode($body, true);
    if (!is_array($d) || !empty($d['error']) || isset($d['reason'])) {
        return null;
    }
    $city = isset($d['city']) ? trim((string) $d['city']) : '';
    $region = isset($d['region']) ? trim((string) $d['region']) : '';
    $country = isset($d['country_name']) ? trim((string) $d['country_name']) : '';
    $isp = isset($d['org']) ? trim((string) $d['org']) : '';
    if (strtolower($city) === 'unknown') {
        $city = '';
    }
    if (strtolower($region) === 'unknown') {
        $region = '';
    }
    return [
        'city' => $city,
        'region' => $region,
        'country' => $country,
        'isp' => $isp !== '' ? $isp : 'Unknown',
    ];
}

/**
 * @return array|null
 */
function sb_geoip_lookup_ipwho($ip) {
    $url = 'https://ipwho.is/' . rawurlencode($ip);
    $body = sb_geoip_http_get($url);
    if ($body === null || $body === '') {
        return null;
    }
    $d = json_decode($body, true);
    if (!is_array($d) || (isset($d['success']) && $d['success'] === false)) {
        return null;
    }
    $city = isset($d['city']) ? trim((string) $d['city']) : '';
    $region = isset($d['region']) ? trim((string) $d['region']) : '';
    $country = isset($d['country']) ? trim((string) $d['country']) : '';
    $isp = '';
    if (isset($d['connection']['isp'])) {
        $isp = trim((string) $d['connection']['isp']);
    } elseif (isset($d['isp'])) {
        $isp = trim((string) $d['isp']);
    }
    if (strtolower($city) === 'unknown') {
        $city = '';
    }
    if (strtolower($region) === 'unknown') {
        $region = '';
    }
    return [
        'city' => $city,
        'region' => $region,
        'country' => $country,
        'isp' => $isp !== '' ? $isp : 'Unknown',
    ];
}

function sb_geoip_http_get($url) {
    if (function_exists('curl_init')) {
        $ch = curl_init($url);
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_TIMEOUT => 8,
            CURLOPT_USERAGENT => 'StoreBuilderGeo/1.0',
        ]);
        $response = curl_exec($ch);
        $errno = curl_errno($ch);
        $code = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);
        if ($errno !== 0 || $response === false || $code < 200 || $code >= 300) {
            return null;
        }
        return $response;
    }
    $ctx = stream_context_create([
        'http' => [
            'timeout' => 8,
            'header' => "User-Agent: StoreBuilderGeo/1.0\r\n",
        ],
    ]);
    $response = @file_get_contents($url, false, $ctx);
    return $response !== false ? $response : null;
}

$geo = sb_geoip_lookup_ipapi($ip);
if ($geo === null) {
    $geo = sb_geoip_lookup_ipwho($ip);
}

if ($geo === null) {
    http_response_code(200);
    echo json_encode([
        'status' => 'error',
        'message' => 'Geo lookup failed',
        'ip' => $ip,
    ], JSON_UNESCAPED_UNICODE);
    exit;
}

echo json_encode([
    'status' => 'ok',
    'ip' => $ip,
    'city' => $geo['city'] !== '' ? $geo['city'] : 'Unknown',
    'region' => $geo['region'],
    'country' => $geo['country'],
    'isp' => $geo['isp'],
], JSON_UNESCAPED_UNICODE);
