# Auto Map Location Update Feature

## Overview

This feature automatically updates map field locations when users select state and city in the Filament forms. It's implemented for both order creation forms and association location panels.

## Components

### 1. Database Changes

**Migrations:**
- `2025_01_22_000001_add_coordinates_to_states_table.php` - Adds lat/lng columns to states table
- `2025_01_22_000002_add_coordinates_to_cities_table.php` - Adds lat/lng columns to cities table

**Models Updated:**
- `app/Models/State.php` - Added lat, lng to fillable array and HasFactory trait
- `app/Models/City.php` - Added lat, lng to fillable array and HasFactory trait

### 2. Service Layer

**LocationCoordinatesService** (`app/Services/LocationCoordinatesService.php`):
- `getStateCoordinates(int $stateId)` - Retrieves coordinates for a state
- `getCityCoordinates(int $cityId)` - Retrieves coordinates for a city (with fallback to state)
- `getBestCoordinates(?int $cityId, ?int $stateId)` - Gets best available coordinates with fallbacks
- `getCenterCoordinatesForCities(array $cityIds)` - Calculates center point for multiple cities

### 3. Seeder

**CoordinatesSeeder** (`database/seeders/CoordinatesSeeder.php`):
- Contains comprehensive coordinates for Saudi Arabian states and major cities
- Populates lat/lng data for existing states/cities in the database

### 4. Filament Form Updates

**OrderResource** (`app/Filament/Resources/OrderResource.php`):
- Updated `city_id` field's `afterStateUpdated` callback to auto-update map location
- Sets location, lat, and lng fields when a city is selected

**AssociationCreateOrder** (`app/Filament/AssociationAdmin/Resources/AssociationOrderResource/Pages/AssociationCreateOrder.php`):
- Updated `city_id` field's `afterStateUpdated` callback to auto-update map location
- Sets location, lat, and lng fields when a city is selected

**AssociationMultipleForms** (`app/Filament/AssociationAdmin/Widgets/AssociationMultipleForms.php`):
- Updated `cities` field's `afterStateUpdated` callback to auto-update map location
- Calculates center point when multiple cities are selected

### 5. Testing

**Unit Tests:**
- `tests/Unit/LocationCoordinatesServiceTest.php` - Comprehensive tests for the service layer

**Feature Tests:**
- `tests/Feature/OrderLocationCoordinatesTest.php` - Integration tests for the feature

**Factories:**
- `database/factories/StateFactory.php` - Factory for creating test states
- `database/factories/CityFactory.php` - Factory for creating test cities

## How It Works

1. **User Interaction**: When a user selects a state or city in the form
2. **Trigger**: The `afterStateUpdated` callback is triggered
3. **Service Call**: LocationCoordinatesService is called to get coordinates
4. **Coordinate Lookup**: 
   - For cities: Returns city coordinates if available, otherwise falls back to state coordinates
   - For multiple cities: Calculates center point of all selected cities
5. **Map Update**: The map field location is automatically updated with the retrieved coordinates

## Installation Steps

1. Run the migrations:
   ```bash
   php artisan migrate
   ```

2. Seed the coordinates data:
   ```bash
   php artisan db:seed --class=CoordinatesSeeder
   ```

## Benefits

- **Better UX**: Users no longer need to manually search or drag the map to the correct location
- **Accuracy**: Reduces human error in location selection
- **Efficiency**: Speeds up the form filling process
- **Consistency**: Ensures consistent location data across the application

## Fallback Behavior

- If city coordinates are not available, it falls back to state coordinates
- If state coordinates are not available, it uses default Riyadh coordinates
- If multiple cities are selected, it calculates the geographic center point

## Extensibility

The service layer is designed to be extensible:
- Easy to add new coordinate sources (APIs, databases, etc.)
- Support for different coordinate calculation methods
- Configurable fallback behavior