<?php
declare(strict_types=1);

/**
 * 客户区仪表盘 — 根据 IP 解析归属地（JSON）
 * GET /ip_geo.php?ip=1.2.3.4
 */

header('Content-Type: application/json; charset=utf-8');
header('Cache-Control: no-store');

$ip = trim((string) ($_GET['ip'] ?? ''));
if ($ip === '' || filter_var($ip, FILTER_VALIDATE_IP) === false) {
    echo json_encode(['ok' => false, 'text' => ''], JSON_UNESCAPED_UNICODE);
    exit;
}

if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) === false) {
    echo json_encode(['ok' => true, 'text' => '本地网络'], JSON_UNESCAPED_UNICODE);
    exit;
}

function ip_geo_cache_dir(): string
{
    $doc = rtrim((string) ($_SERVER['DOCUMENT_ROOT'] ?? ''), '/\\');
    $root = $doc !== '' ? dirname($doc) : dirname(__DIR__);
    $dir = $root . '/data/ip_geo_cache';
    if (!is_dir($dir)) {
        @mkdir($dir, 0755, true);
    }
    return $dir;
}

function ip_geo_cache_get(string $ip): ?string
{
    $file = ip_geo_cache_dir() . '/' . hash('sha256', $ip) . '.json';
    if (!is_file($file)) {
        return null;
    }
    $j = json_decode((string) file_get_contents($file), true);
    if (!is_array($j) || empty($j['text']) || (int) ($j['expires'] ?? 0) < time()) {
        @unlink($file);
        return null;
    }
    return (string) $j['text'];
}

function ip_geo_cache_set(string $ip, string $text): void
{
    $file = ip_geo_cache_dir() . '/' . hash('sha256', $ip) . '.json';
    @file_put_contents($file, json_encode([
        'text' => $text,
        'expires' => time() + 86400,
    ], JSON_UNESCAPED_UNICODE));
}

function ip_geo_lookup(string $ip): ?string
{
    $cached = ip_geo_cache_get($ip);
    if ($cached !== null) {
        return $cached;
    }

    $url = 'http://ip-api.com/json/' . rawurlencode($ip) . '?lang=zh-CN&fields=status,country,regionName,city';
    $ctx = stream_context_create([
        'http' => ['timeout' => 4, 'ignore_errors' => true],
    ]);
    $raw = @file_get_contents($url, false, $ctx);
    if ($raw === false) {
        return null;
    }
    $j = json_decode($raw, true);
    if (!is_array($j) || ($j['status'] ?? '') !== 'success') {
        return null;
    }
    $parts = array_filter([
        (string) ($j['country'] ?? ''),
        (string) ($j['regionName'] ?? ''),
        (string) ($j['city'] ?? ''),
    ], static fn ($v) => $v !== '');
    $text = implode(' ', array_unique($parts));
    if ($text === '') {
        return null;
    }
    ip_geo_cache_set($ip, $text);
    return $text;
}

$text = ip_geo_lookup($ip);
if ($text === null) {
    echo json_encode(['ok' => false, 'text' => ''], JSON_UNESCAPED_UNICODE);
    exit;
}

echo json_encode(['ok' => true, 'text' => $text], JSON_UNESCAPED_UNICODE);
