# Area Organization System

## Overview
The Area Organization system provides a flexible way to structure and order areas within a park. It supports both flat and nested hierarchies, with drag-and-drop reordering capabilities and efficient position management.

## Database Structure

### Park Areas Table
```sql
CREATE TABLE park_areas (
    id bigint unsigned NOT NULL AUTO_INCREMENT,
    park_id bigint unsigned NOT NULL,
    parent_id bigint unsigned NULL,
    name varchar(255) NOT NULL,
    slug varchar(255) NOT NULL,
    description text NULL,
    opening_date date NULL,
    closing_date date NULL,
    position integer NOT NULL DEFAULT 0,
    created_at timestamp NULL,
    updated_at timestamp NULL,
    PRIMARY KEY (id),
    FOREIGN KEY (park_id) REFERENCES parks(id),
    FOREIGN KEY (parent_id) REFERENCES park_areas(id),
    INDEX idx_ordering (park_id, position),
    INDEX idx_hierarchy (park_id, parent_id)
);
```

## Key Features

### 1. Position Management
- Automatic position assignment for new areas
- Zero-based position indexing
- Position maintenance during reordering
- Efficient batch updates for position changes

### 2. Hierarchical Structure
- Parent-child relationships between areas
- Unlimited nesting depth
- Separate position sequences per parent
- Cascading deletion options

### 3. Query Optimization
- Compound indexes for efficient ordering
- Optimized parent-child lookups
- Position-based sorting
- Scoped uniqueness constraints

## Implementation Details

### Position Management
1. New Area Creation
   ```php
   protected static function boot()
   {
       parent::boot();
       static::creating(function (ParkArea $area) {
           if (is_null($area->position)) {
               $area->position = $area->getNextPosition();
           }
       });
   }
   ```

2. Position Calculation
   ```php
   public function getNextPosition(): int
   {
       $maxPosition = static::where('park_id', $this->park_id)
           ->where('parent_id', $this->parent_id)
           ->max('position');

       return ($maxPosition ?? -1) + 1;
   }
   ```

3. Position Updates
   ```php
   public function moveToPosition(int $newPosition): void
   {
       if ($newPosition === $this->position) {
           return;
       }

       $oldPosition = $this->position;

       if ($newPosition > $oldPosition) {
           // Moving down: decrement positions of items in between
           static::where('park_id', $this->park_id)
               ->where('parent_id', $this->parent_id)
               ->whereBetween('position', [$oldPosition + 1, $newPosition])
               ->decrement('position');
       } else {
           // Moving up: increment positions of items in between
           static::where('park_id', $this->park_id)
               ->where('parent_id', $this->parent_id)
               ->whereBetween('position', [$newPosition, $oldPosition - 1])
               ->increment('position');
       }

       $this->update(['position' => $newPosition]);
   }
   ```

### Hierarchical Relationships
1. Parent Relationship
   ```php
   public function parent(): BelongsTo
   {
       return $this->belongsTo(ParkArea::class, 'parent_id');
   }
   ```

2. Children Relationship
   ```php
   public function children(): HasMany
   {
       return $this->hasMany(ParkArea::class, 'parent_id')
           ->orderBy('position');
   }
   ```

3. Helper Methods
   ```php
   public function hasChildren(): bool
   {
       return $this->children()->exists();
   }

   public function isTopLevel(): bool
   {
       return is_null($this->parent_id);
   }
   ```

## Usage Examples

### Creating a New Area
```php
$area = new ParkArea([
    'name' => 'Adventure Zone',
    'description' => 'Thrilling rides area',
]);
$park->areas()->save($area);
```

### Moving an Area
```php
$area->moveToPosition(5);
```

### Adding a Sub-Area
```php
$subArea = new ParkArea([
    'name' => 'Coaster Corner',
    'parent_id' => $area->id,
]);
$park->areas()->save($subArea);
```

## Future Enhancements
1. [ ] Add drag-and-drop reordering UI
2. [ ] Implement position validation
3. [ ] Add move restrictions
4. [ ] Implement area statistics
5. [ ] Add bulk reordering
6. [ ] Implement depth limits
7. [ ] Add position caching
8. [ ] Implement move history

## Security Considerations
1. Position Validation
   - Prevent out-of-bounds positions
   - Validate parent-child relationships
   - Check for circular references

2. Access Control
   - Restrict reordering permissions
   - Validate park ownership
   - Log position changes

## Performance Optimization
1. Batch Updates
   - Use transactions for moves
   - Minimize position updates
   - Cache position values

2. Query Optimization
   - Use compound indexes
   - Minimize nested queries
   - Efficient position calculations

## Testing Strategy
1. Unit Tests
   - [ ] Position calculation
   - [ ] Move operations
   - [ ] Parent-child relationships

2. Integration Tests
   - [ ] Reordering flows
   - [ ] Nested operations
   - [ ] Position maintenance

3. Performance Tests
   - [ ] Large-scale reordering
   - [ ] Nested structure queries
   - [ ] Position update efficiency