using Dapper; using Npgsql; using SatelliteProvider.DataAccess.Models; namespace SatelliteProvider.DataAccess.Repositories; public class RouteRepository : IRouteRepository { private readonly string _connectionString; public RouteRepository(string connectionString) { _connectionString = connectionString; } public async Task GetByIdAsync(Guid id) { using var connection = new NpgsqlConnection(_connectionString); const string sql = @" SELECT id, name, description, region_size_meters as RegionSizeMeters, zoom_level as ZoomLevel, total_distance_meters as TotalDistanceMeters, total_points as TotalPoints, request_maps as RequestMaps, maps_ready as MapsReady, csv_file_path as CsvFilePath, summary_file_path as SummaryFilePath, stitched_image_path as StitchedImagePath, created_at as CreatedAt, updated_at as UpdatedAt FROM routes WHERE id = @Id"; return await connection.QuerySingleOrDefaultAsync(sql, new { Id = id }); } public async Task> GetRoutePointsAsync(Guid routeId) { using var connection = new NpgsqlConnection(_connectionString); const string sql = @" SELECT id, route_id as RouteId, sequence_number as SequenceNumber, latitude, longitude, point_type as PointType, segment_index as SegmentIndex, distance_from_previous as DistanceFromPrevious, created_at as CreatedAt FROM route_points WHERE route_id = @RouteId ORDER BY sequence_number"; return await connection.QueryAsync(sql, new { RouteId = routeId }); } public async Task InsertRouteAsync(RouteEntity route) { using var connection = new NpgsqlConnection(_connectionString); const string sql = @" INSERT INTO routes (id, name, description, region_size_meters, zoom_level, total_distance_meters, total_points, request_maps, maps_ready, csv_file_path, summary_file_path, stitched_image_path, created_at, updated_at) VALUES (@Id, @Name, @Description, @RegionSizeMeters, @ZoomLevel, @TotalDistanceMeters, @TotalPoints, @RequestMaps, @MapsReady, @CsvFilePath, @SummaryFilePath, @StitchedImagePath, @CreatedAt, @UpdatedAt) RETURNING id"; return await connection.ExecuteScalarAsync(sql, route); } public async Task InsertRoutePointsAsync(IEnumerable points) { using var connection = new NpgsqlConnection(_connectionString); const string sql = @" INSERT INTO route_points (id, route_id, sequence_number, latitude, longitude, point_type, segment_index, distance_from_previous, created_at) VALUES (@Id, @RouteId, @SequenceNumber, @Latitude, @Longitude, @PointType, @SegmentIndex, @DistanceFromPrevious, @CreatedAt)"; await connection.ExecuteAsync(sql, points); } public async Task UpdateRouteAsync(RouteEntity route) { using var connection = new NpgsqlConnection(_connectionString); const string sql = @" UPDATE routes SET name = @Name, description = @Description, region_size_meters = @RegionSizeMeters, zoom_level = @ZoomLevel, total_distance_meters = @TotalDistanceMeters, total_points = @TotalPoints, request_maps = @RequestMaps, maps_ready = @MapsReady, csv_file_path = @CsvFilePath, summary_file_path = @SummaryFilePath, stitched_image_path = @StitchedImagePath, updated_at = @UpdatedAt WHERE id = @Id"; return await connection.ExecuteAsync(sql, route); } public async Task DeleteRouteAsync(Guid id) { using var connection = new NpgsqlConnection(_connectionString); const string sql = "DELETE FROM routes WHERE id = @Id"; return await connection.ExecuteAsync(sql, new { Id = id }); } public async Task LinkRouteToRegionAsync(Guid routeId, Guid regionId) { using var connection = new NpgsqlConnection(_connectionString); const string sql = @" INSERT INTO route_regions (route_id, region_id, created_at) VALUES (@RouteId, @RegionId, @CreatedAt) ON CONFLICT (route_id, region_id) DO NOTHING"; await connection.ExecuteAsync(sql, new { RouteId = routeId, RegionId = regionId, CreatedAt = DateTime.UtcNow }); } public async Task> GetRegionIdsByRouteAsync(Guid routeId) { using var connection = new NpgsqlConnection(_connectionString); const string sql = @" SELECT region_id FROM route_regions WHERE route_id = @RouteId"; return await connection.QueryAsync(sql, new { RouteId = routeId }); } public async Task> GetRoutesWithPendingMapsAsync() { using var connection = new NpgsqlConnection(_connectionString); const string sql = @" SELECT id, name, description, region_size_meters as RegionSizeMeters, zoom_level as ZoomLevel, total_distance_meters as TotalDistanceMeters, total_points as TotalPoints, request_maps as RequestMaps, maps_ready as MapsReady, csv_file_path as CsvFilePath, summary_file_path as SummaryFilePath, stitched_image_path as StitchedImagePath, created_at as CreatedAt, updated_at as UpdatedAt FROM routes WHERE request_maps = true AND maps_ready = false"; return await connection.QueryAsync(sql); } }