<?php

namespace App\Services;

use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Http;

class GeoIpService
{
    public function locate(?string $ip): array
    {
        $ip = $ip ?: '';
        if ($ip === '' || $this->isPrivate($ip)) {
            return [];
        }

        $ttl = (int) config('analytics.geo_cache_ttl', 86400);
        $key = 'geoip:'.md5($ip);
        return Cache::remember($key, $ttl, function () use ($ip) {
            $provider = config('analytics.geo_provider', 'ip-api');
            $timeout = (int) config('analytics.geo_timeout', 5);

            if ($provider === 'ipapi') {
                // ipapi.co JSON (no key for basic usage)
                $url = 'https://ipapi.co/'.$ip.'/json/';
                $res = Http::timeout($timeout)->get($url);
                if ($res->ok()) {
                    $j = $res->json();
                    return [
                        'country' => Arr::get($j, 'country_name'),
                        'city' => Arr::get($j, 'city'),
                        'lat' => Arr::get($j, 'latitude') ?? Arr::get($j, 'lat'),
                        'lon' => Arr::get($j, 'longitude') ?? Arr::get($j, 'lon'),
                    ];
                }
            }

            // Default to ip-api.com
            $fields = 'status,message,country,city,lat,lon';
            $url = 'http://ip-api.com/json/'.urlencode($ip).'?fields='.$fields;
            $res = Http::timeout($timeout)->get($url);
            if ($res->ok()) {
                $j = $res->json();
                if (Arr::get($j, 'status') === 'success') {
                    return [
                        'country' => Arr::get($j, 'country'),
                        'city' => Arr::get($j, 'city'),
                        'lat' => Arr::get($j, 'lat'),
                        'lon' => Arr::get($j, 'lon'),
                    ];
                }
            }

            return [];
        });
    }

    private function isPrivate(string $ip): bool
    {
        if ($ip === '127.0.0.1' || $ip === '::1') return true;
        // Basic check for RFC1918 ranges
        return preg_match('/^(10\.|192\.168\.|172\.(1[6-9]|2[0-9]|3[0-1])\.)/', $ip) === 1;
    }
}
