"""IP 地理定位服务（ip-api.com，免费，无需 API Key）"""

import time
from ipaddress import ip_address, ip_network

import httpx

_cache: dict[str, tuple[dict | None, float]] = {}
_CACHE_TTL = 3600  # 1 小时
_LAN_NETS = [
    ip_network("10.0.0.0/8"),
    ip_network("172.16.0.0/12"),
    ip_network("192.168.0.0/16"),
    ip_network("127.0.0.0/8"),
]


def _is_lan(ip: str) -> bool:
    try:
        addr = ip_address(ip)
        return any(addr in net for net in _LAN_NETS)
    except ValueError:
        return True


def _is_valid_location(data: dict | None) -> bool:
    if not data:
        return False
    # ip-api 失败时 status 为 "fail"
    if data.get("status") == "fail":
        return False
    return bool(data.get("city") or data.get("regionName") or data.get("country"))


async def lookup_ip(ip: str) -> dict | None:
    """查询 IP 地理位置，返回 {country, regionName, city} 或 None"""
    if not ip or _is_lan(ip):
        return None

    now = time.time()
    cached = _cache.get(ip)
    if cached and (now - cached[1]) < _CACHE_TTL:
        return cached[0]

    try:
        async with httpx.AsyncClient(timeout=5) as cli:
            resp = await cli.get(f"http://ip-api.com/json/{ip}?fields=country,regionName,city,status")
            data = resp.json()
    except Exception:
        data = None

    result = data if _is_valid_location(data) else None
    _cache[ip] = (result, now)
    return result
