# GeocodeService Documentation

## Overview
The GeocodeService provides geocoding functionality through OpenStreetMap's Nominatim API, offering address lookup, reverse geocoding, and result caching capabilities.

## Features

### 1. Address to Coordinates
- Forward geocoding (address to coordinates)
- Address normalization and validation
- Result confidence scoring
- Batch processing support

### 2. Coordinates to Address
- Reverse geocoding (coordinates to address)
- Multiple result handling
- Address component extraction
- Location type detection

### 3. Cache Management
- 24-hour TTL for results
- Cache invalidation strategy
- Memory optimization
- Cache warming support

### 4. Error Handling
- Rate limit management
- API error handling
- Validation failures
- Network timeouts

## Implementation Details

### Service Structure
```php
class GeocodeService
{
    public function geocode(string $address): ?array
    public function reverseGeocode(float $lat, float $lon): ?array
    public function batchGeocode(array $addresses): array
    public function validateCoordinates(float $lat, float $lon): bool
    public function clearCache(?string $key = null): void
    public function warmCache(array $addresses): void
}
```

### Cache Keys
- Forward geocoding: `geocode:{normalized_address}`
- Reverse geocoding: `reverse:{lat},{lon}`
- TTL: 24 hours (configurable)

### API Integration
- Base URL: https://nominatim.openstreetmap.org
- Rate Limiting: Max 1 request per second
- User-Agent Required: "ThrillWiki Geocoder"
- Response Format: JSON

### Validation Rules
- Latitude: -90 to 90
- Longitude: -180 to 180
- Address length: 5 to 200 characters
- Required fields: street or city + country

## Usage Examples

### Forward Geocoding
```php
$geocoder = app(GeocodeService::class);
$result = $geocoder->geocode('123 Main St, City, Country');
// Returns: ['lat' => 12.34, 'lon' => 56.78, 'display_name' => '...', ...]
```

### Reverse Geocoding
```php
$geocoder = app(GeocodeService::class);
$result = $geocoder->reverseGeocode(12.34, 56.78);
// Returns: ['address' => [...], 'display_name' => '...', ...]
```

### Batch Processing
```php
$geocoder = app(GeocodeService::class);
$results = $geocoder->batchGeocode(['address1', 'address2']);
// Returns: ['address1' => [...], 'address2' => [...]]
```

## Error Handling

### Exception Types
1. GeocodingException
   - Invalid input
   - API errors
   - Rate limiting
2. ValidationException
   - Invalid coordinates
   - Invalid address format
3. CacheException
   - Cache access errors
   - Invalid cache data

### Error Responses
```php
try {
    $result = $geocoder->geocode($address);
} catch (GeocodingException $e) {
    // Handle geocoding errors
} catch (ValidationException $e) {
    // Handle validation errors
}
```

## Performance Optimization

### Cache Strategy
1. Cache all successful results
2. Implement cache warming for common addresses
3. Use cache tags for better management
4. Regular cache cleanup

### Batch Processing
1. Group requests when possible
2. Respect rate limits
3. Parallel processing for large batches
4. Error handling per item

## Integration Points

### 1. Location Model
- Automatic geocoding on address changes
- Cache management for stored locations
- Coordinate validation

### 2. HasLocation Trait
- Geocoding helpers
- Address formatting
- Location type handling

### 3. Components
- Address search interface
- Map display
- Location selection

## Testing Strategy

### Unit Tests
- [ ] Address validation
- [ ] Coordinate validation
- [ ] Cache management
- [ ] Error handling

### Integration Tests
- [ ] API communication
- [ ] Cache interaction
- [ ] Batch processing
- [ ] Rate limiting

### Performance Tests
- [ ] Cache efficiency
- [ ] Memory usage
- [ ] Response times
- [ ] Batch processing speed