# Module: Services/RegionService + RegionProcessingService + RegionRequestQueue

## Purpose
End-to-end region processing pipeline: API request handling → queue → background worker → tile download → output file generation. Three closely coupled classes form the region processing subsystem.

## Public Interface

### RegionService (implements IRegionService)
- `RequestRegionAsync(...)`: creates `RegionEntity` with status `RegionStatus.Queued`, enqueues a `RegionRequest`, returns `RegionStatusResponse`
- `GetRegionStatusAsync(Guid id)`: reads region record and maps to `RegionStatusResponse`
- `ProcessRegionAsync(Guid id, CancellationToken)`: the main processing pipeline — see Internal Logic

### RegionProcessingService (BackgroundService)
- `ExecuteAsync(CancellationToken)`: spawns `MaxConcurrentRegions` parallel worker tasks, each in an infinite dequeue loop

### RegionRequestQueue (implements IRegionRequestQueue)
- `EnqueueAsync(RegionRequest, CancellationToken)`: writes to a bounded `Channel<RegionRequest>`
- `DequeueAsync(CancellationToken)`: reads from the channel (blocks until available)
- `Count`: current queue depth

## Internal Logic

### RegionService.ProcessRegionAsync
1. Sets region status to "processing"
2. Creates a 5-minute timeout `CancellationTokenSource`
3. Queries existing tiles in the region
4. Calls `TileService.DownloadAndStoreTilesAsync` to fetch missing tiles
5. Counts downloaded vs reused tiles
6. Generates CSV file (`region_{id}_ready.csv`) listing tile coordinates + paths
7. Optionally stitches tiles into a single JPEG image (if `StitchTiles` is true)
8. Generates summary file (`region_{id}_summary.txt`)
9. Updates region status to "completed"
10. On any error: sets status to "failed", generates error summary

### Tile Stitching
Uses ImageSharp to:
1. Compute a tile grid from tile coordinates
2. Create a new image of `(gridWidth × 256) × (gridHeight × 256)` pixels
3. Place each tile image at its grid position
4. Draw a red crosshair at the center coordinates
5. Save as JPEG

### Error Handling
Comprehensive catch blocks for:
- `TaskCanceledException` (timeout vs external cancellation)
- `OperationCanceledException`
- `RateLimitException` (Google rate limiting)
- `HttpRequestException` (with status code)
- Generic `Exception`
Each sets status to "failed" and writes an error summary file.

### RegionProcessingService
- Spawns `MaxConcurrentRegions` worker tasks with staggered startup (100–500ms random delay)
- Each worker loops: dequeue → `ProcessRegionAsync` → repeat
- Graceful shutdown on cancellation

### RegionRequestQueue
- Uses `System.Threading.Channels.Channel<T>.CreateBounded` with `BoundedChannelFullMode.Wait`
- Tracks `_totalEnqueued` and `_totalDequeued` counters

## Dependencies
- `ITileService`, `IRegionRepository`, `IRegionRequestQueue`
- `StorageConfig`, `ProcessingConfig`
- `SixLabors.ImageSharp` — tile stitching
- `SatelliteProvider.Common.Utils.GeoUtils` — coordinate conversion for stitching

## Consumers
- `Program.cs` API endpoints — `RequestRegionAsync`, `GetRegionStatusAsync`
- `RouteService` — `RequestRegionAsync` (for geofence regions)
- `RouteProcessingService` — `RequestRegionAsync` (for route-point regions)

## Data Models
- Input: `RegionRequest` (queue message)
- Output: `RegionStatusResponse` (API response), CSV files, summary files, stitched images
- Persistence: `RegionEntity`

## Configuration
- `StorageConfig.ReadyDirectory` — output file location
- `ProcessingConfig.MaxConcurrentRegions` — worker count
- `ProcessingConfig.QueueCapacity` — bounded channel size

## External Integrations
- PostgreSQL (via repositories)
- File system (CSV, summary, stitched images in `./ready/`)
- Google Maps (indirectly via TileService → GoogleMapsDownloaderV2)

## Security
None.

## Tests
Integration tests in `RegionTests.cs` cover the request → poll → complete flow.
