using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using RobotNet10.RobotApp.Data; using RobotNet10.RobotApp.Shared.DockStation; using RobotNet10.Shared.Enum; using RobotNet10.Shared.Numbers; using System.Text.Json; namespace RobotNet10.RobotApp.Controllers; [Route("api/dock-station-config")] [ApiController] [Authorize] public class DockStationConfigController(ApplicationDbContext dbContext) : ControllerBase { [HttpGet] public async Task>> GetAll() { var configs = await dbContext.DockStationConfigs .Include(d => d.MarkerEntries) .OrderByDescending(d => d.UpdatedAt) .ToListAsync(); return Ok(configs.Select(MapToSummaryDto).ToList()); } [HttpGet("{id:guid}")] public async Task> GetById(Guid id) { var config = await dbContext.DockStationConfigs .Include(d => d.MarkerEntries) .FirstOrDefaultAsync(d => d.Id == id); if (config is null) return NotFound(); return Ok(MapToDto(config)); } [HttpGet("station/{stationId}")] public async Task> GetByStationId(string stationId) { var config = await dbContext.DockStationConfigs .Include(d => d.MarkerEntries) .FirstOrDefaultAsync(d => d.StationId == stationId); if (config is null) return NotFound(); return Ok(MapToDto(config)); } [HttpPost] public async Task> Create( [FromBody] CreateDockStationConfigRequest request) { if (await dbContext.DockStationConfigs.AnyAsync(d => d.StationId == request.StationId)) return BadRequest($"StationId '{request.StationId}' already exists."); var entity = new DockStationConfig { StationId = request.StationId, ConfigName = request.ConfigName ?? string.Empty, Description = request.Description ?? string.Empty, X = request.X, Y = request.Y, Yaw = request.Yaw, Width = request.Width, Length = request.Length, IsActive = request.IsActive, CreatedAt = DateTime.UtcNow, UpdatedAt = DateTime.UtcNow, MarkerEntries = request.MarkerEntries.Select(MapFromEntryDto).ToList() }; dbContext.DockStationConfigs.Add(entity); await dbContext.SaveChangesAsync(); return CreatedAtAction(nameof(GetById), new { id = entity.Id }, MapToDto(entity)); } [HttpPut("{id:guid}")] public async Task> Update( Guid id, [FromBody] UpdateDockStationConfigRequest request) { var entity = await dbContext.DockStationConfigs .Include(d => d.MarkerEntries) .FirstOrDefaultAsync(d => d.Id == id); if (entity is null) return NotFound(); if (request.StationId is not null) { if (request.StationId != entity.StationId && await dbContext.DockStationConfigs.AnyAsync(d => d.StationId == request.StationId)) return BadRequest($"StationId '{request.StationId}' already exists."); entity.StationId = request.StationId; } if (request.ConfigName is not null) entity.ConfigName = request.ConfigName; if (request.Description is not null) entity.Description = request.Description; if (request.X.HasValue) entity.X = request.X.Value; if (request.Y.HasValue) entity.Y = request.Y.Value; if (request.Yaw.HasValue) entity.Yaw = request.Yaw.Value; if (request.Width.HasValue) entity.Width = request.Width.Value; if (request.Length.HasValue) entity.Length = request.Length.Value; if (request.IsActive.HasValue) entity.IsActive = request.IsActive.Value; entity.UpdatedAt = DateTime.UtcNow; if (request.MarkerEntries is not null) { dbContext.DockStationMarkerEntries.RemoveRange(entity.MarkerEntries); entity.MarkerEntries = request.MarkerEntries.Select(MapFromEntryDto).ToList(); } await dbContext.SaveChangesAsync(); return Ok(MapToDto(entity)); } [HttpDelete("{id:guid}")] public async Task Delete(Guid id) { var entity = await dbContext.DockStationConfigs.FindAsync(id); if (entity is null) return NotFound(); dbContext.DockStationConfigs.Remove(entity); await dbContext.SaveChangesAsync(); return NoContent(); } #region Mapping Helpers private static DockStationConfigDto MapToDto(DockStationConfig entity) => new() { Id = entity.Id, StationId = entity.StationId, ConfigName = entity.ConfigName, Description = entity.Description, X = entity.X, Y = entity.Y, Yaw = entity.Yaw, Width = entity.Width, Length = entity.Length, CreatedAt = entity.CreatedAt, UpdatedAt = entity.UpdatedAt, IsActive = entity.IsActive, MarkerEntries = entity.MarkerEntries?.Select(MapToEntryDto).ToList() ?? [] }; private static DockStationConfigSummaryDto MapToSummaryDto(DockStationConfig entity) => new() { Id = entity.Id, StationId = entity.StationId, ConfigName = entity.ConfigName, Description = entity.Description, IsActive = entity.IsActive, MarkerEntryCount = entity.MarkerEntries?.Count ?? 0, CreatedAt = entity.CreatedAt, UpdatedAt = entity.UpdatedAt }; private static DockStationMarkerEntryDto MapToEntryDto(DockStationMarkerEntry entity) => new() { Id = entity.Id, MarkerId = entity.MarkerId, Type = (MarkerType)entity.Type, Priority = entity.Priority, DeviceId = entity.DeviceId, Code = entity.Code, ReferencePoints = DeserializeReferencePoints(entity.ReferencePointsJson) }; private static DockStationMarkerEntry MapFromEntryDto(DockStationMarkerEntryDto dto) => new() { MarkerId = dto.MarkerId, Type = (int)dto.Type, Priority = dto.Priority, DeviceId = dto.DeviceId ?? string.Empty, Code = dto.Code ?? string.Empty, ReferencePointsJson = JsonSerializer.Serialize(dto.ReferencePoints ?? []) }; private static List DeserializeReferencePoints(string? json) { if (string.IsNullOrWhiteSpace(json)) return []; try { return JsonSerializer.Deserialize>(json) ?? []; } catch { return []; } } #endregion }