# IP Geolocation Service

This document describes how to use the IP Geolocation service in the QuitSure application.

## Overview

The IP Geolocation service provides a way to determine a user's country based on their IP address. This can be useful for:

- Localizing content
- Applying region-specific rules
- Analytics and reporting
- Compliance with regional regulations

## Configuration

The service uses the [ipgeolocation.io](https://ipgeolocation.io/) API as the primary source and [ip.circl.lu](https://ip.circl.lu/) as a fallback.

### Environment Variables

Add the following variables to your `.env` file:

```
# IP Geolocation API
IP_GEOLOCATION_KEY=your_api_key_here
GEOLOCATION_USE_CACHE=true
GEOLOCATION_CACHE_TTL=1440
```

You can obtain an API key by signing up at [ipgeolocation.io](https://ipgeolocation.io/).

## Usage Options

There are three ways to use the IP Geolocation service:

1. Global Helper Function
2. Service Class
3. Facade

### Option 1: Global Helper Function

The service is implemented as a global helper function that can be used anywhere in your application.

#### Basic Usage

```php
$country = getCountryFromIP();
```

This will return the country name for the current user's IP address, or `null` if the country could not be determined.

#### Advanced Usage

```php
// Get country for a specific IP address
$country = getCountryFromIP('8.8.8.8');

// Disable caching
$country = getCountryFromIP(null, false);

// Set custom cache TTL (in minutes)
$country = getCountryFromIP(null, true, 60); // Cache for 1 hour
```

#### Parameters

- `$ipAddress` (string|null): The IP address to look up. If null, uses the current user's IP.
- `$useCache` (bool): Whether to use caching. Default is true.
- `$cacheTtl` (int): Cache time-to-live in minutes. Default is 1440 (24 hours).

### Option 2: Service Class

For more object-oriented usage, you can use the `GeoLocationService` class directly:

```php
use App\Services\GeoLocationService;

class MyController extends Controller
{
    protected $geoService;
    
    public function __construct(GeoLocationService $geoService)
    {
        $this->geoService = $geoService;
    }
    
    public function index()
    {
        $country = $this->geoService->getCountryFromIP();
        
        // Get full geolocation data
        $geoData = $this->geoService->getGeoDataFromIP();
        
        // Configure the service
        $this->geoService->setUseCache(false)
                         ->setCacheTtl(60);
                         
        return view('welcome', [
            'country' => $country,
            'geoData' => $geoData,
        ]);
    }
}
```

### Option 3: Facade

For a cleaner syntax, you can use the `GeoLocation` facade:

```php
use App\Facades\GeoLocation;

class MyController extends Controller
{
    public function index()
    {
        $country = GeoLocation::getCountryFromIP();
        
        // Get full geolocation data
        $geoData = GeoLocation::getGeoDataFromIP();
        
        // Configure the service
        GeoLocation::setUseCache(false)
                  ->setCacheTtl(60);
                  
        return view('welcome', [
            'country' => $country,
            'geoData' => $geoData,
        ]);
    }
}
```

## Return Values

- `getCountryFromIP()`: Returns a string with the country name, or `null` if the country could not be determined.
- `getGeoDataFromIP()`: Returns an object with full geolocation data, or `null` if the data could not be retrieved.

## Caching

By default, results are cached for 24 hours to reduce API calls and improve performance. You can disable caching or adjust the cache duration as needed.

## Error Handling

The service handles errors gracefully and logs them using Laravel's logging system. If the primary service fails, it automatically tries the fallback service.

## Examples

### Example 1: Basic Usage in a Controller

```php
public function welcome(Request $request)
{
    $country = getCountryFromIP();
    
    return view('welcome', [
        'country' => $country,
    ]);
}
```

### Example 2: Using in a Middleware

```php
public function handle($request, Closure $next)
{
    $country = getCountryFromIP();
    
    if ($country === 'United States') {
        // Apply US-specific logic
    }
    
    return $next($request);
}
```

### Example 3: Using with a Specific IP

```php
public function getUserInfo($userId)
{
    $user = User::find($userId);
    $lastIp = $user->last_login_ip;
    
    $country = getCountryFromIP($lastIp);
    
    return [
        'user' => $user,
        'country' => $country,
    ];
}
```

### Example 4: Using the Facade with Full Geolocation Data

```php
use App\Facades\GeoLocation;

public function showUserLocation()
{
    $geoData = GeoLocation::getGeoDataFromIP();
    
    return view('location', [
        'country' => $geoData->country_name ?? 'Unknown',
        'city' => $geoData->city ?? 'Unknown',
        'latitude' => $geoData->latitude ?? 0,
        'longitude' => $geoData->longitude ?? 0,
        'timezone' => $geoData->time_zone->name ?? 'UTC',
    ]);
}
```

## API Routes

The package includes example API routes for testing the geolocation service:

- `GET /api/geo` - Get country for the current user's IP (using helper function)
- `GET /api/geo/ip/{ip}` - Get country for a specific IP address (using service)
- `GET /api/geo/no-cache` - Test without caching (using facade)
- `GET /api/geo/full` - Get full geolocation data (using facade)
