using Microsoft.AspNetCore.Mvc; using RobotNet10.FleetManager.Data; using RobotNet10.FleetManager.Services; using RobotNet10.FleetManager.Shared.DTOs.Robot; using RobotNet10.FleetManager.Shared.DTOs.Responses; namespace RobotNet10.FleetManager.Controllers; /// /// API controller for managing robots. /// Provides RESTful endpoints for CRUD operations on robots. /// /// /// All endpoints return appropriate HTTP status codes and error responses. /// Supports filtering by model ID and map ID. /// [ApiController] [Route("api/robots")] public class RobotController(IRobotService robotService, Services.Logger logger) : ControllerBase { private readonly IRobotService _robotService = robotService; private readonly Services.Logger _logger = logger; /// /// Get all robots with optional filters /// [HttpGet] [ProducesResponseType(typeof(List), StatusCodes.Status200OK)] public async Task>> GetAll([FromQuery] Guid? modelId, [FromQuery] Guid? mapId) { try { var robots = await _robotService.GetAllAsync(modelId, mapId); var dtos = robots.Select(r => MapToDto(r)).ToList(); return Ok(dtos); } catch (Exception ex) { _logger.Error($"Error getting all robots: {ex.Message}"); return StatusCode(500, new ErrorResponseDto { Error = "An error occurred while retrieving robots." }); } } /// /// Get robot by ID /// [HttpGet("{id}")] [ProducesResponseType(typeof(RobotDto), StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task> GetById(Guid id) { try { var robot = await _robotService.GetByIdAsync(id); if (robot == null) { return NotFound(new ErrorResponseDto { Error = $"Robot with ID {id} not found." }); } return Ok(MapToDto(robot)); } catch (Exception ex) { _logger.Error($"Error getting robot {id}: {ex.Message}"); return StatusCode(500, new ErrorResponseDto { Error = "An error occurred while retrieving the robot." }); } } /// /// Get robot by RobotId (string identifier) /// [HttpGet("robotId/{robotId}")] [ProducesResponseType(typeof(RobotDto), StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task> GetByRobotId(string robotId) { try { var robot = await _robotService.GetByRobotIdAsync(robotId); if (robot == null) { return NotFound(new ErrorResponseDto { Error = $"Robot with RobotId '{robotId}' not found." }); } return Ok(MapToDto(robot)); } catch (Exception ex) { _logger.Error($"Error getting robot with RobotId '{robotId}': {ex.Message}"); return StatusCode(500, new ErrorResponseDto { Error = "An error occurred while retrieving the robot." }); } } /// /// Search robots by query string /// [HttpGet("search")] [ProducesResponseType(typeof(List), StatusCodes.Status200OK)] public async Task>> Search([FromQuery] string query) { try { var robots = await _robotService.SearchAsync(query); var dtos = robots.Select(r => MapToDto(r)).ToList(); return Ok(dtos); } catch (Exception ex) { _logger.Error($"Error searching robots with query '{query}': {ex.Message}"); return StatusCode(500, new ErrorResponseDto { Error = "An error occurred while searching robots." }); } } /// /// Get all robots by model ID /// [HttpGet("model/{modelId}")] [ProducesResponseType(typeof(List), StatusCodes.Status200OK)] public async Task>> GetByModelId(Guid modelId) { try { var robots = await _robotService.GetByModelIdAsync(modelId); var dtos = robots.Select(r => MapToDto(r)).ToList(); return Ok(dtos); } catch (Exception ex) { _logger.Error($"Error getting robots by model {modelId}: {ex.Message}"); return StatusCode(500, new ErrorResponseDto { Error = "An error occurred while retrieving robots." }); } } /// /// Create a new robot /// [HttpPost] [ProducesResponseType(typeof(RobotDto), StatusCodes.Status201Created)] [ProducesResponseType(StatusCodes.Status400BadRequest)] public async Task> Create([FromBody] CreateRobotRequest request) { try { if (!ModelState.IsValid) { return BadRequest(new ErrorResponseDto { Error = "Validation failed", Details = ModelState.ToDictionary( kvp => kvp.Key, kvp => (object)(kvp.Value?.Errors.Select(e => e.ErrorMessage).ToArray() ?? Array.Empty())) }); } var robot = await _robotService.CreateAsync(request); var dto = MapToDto(robot); return CreatedAtAction(nameof(GetById), new { id = robot.Id }, dto); } catch (InvalidOperationException ex) { return BadRequest(new ErrorResponseDto { Error = ex.Message }); } catch (KeyNotFoundException ex) { return BadRequest(new ErrorResponseDto { Error = ex.Message }); } catch (Exception ex) { _logger.Error($"Error creating robot: {ex.Message}"); return StatusCode(500, new ErrorResponseDto { Error = "An error occurred while creating the robot." }); } } /// /// Update an existing robot /// [HttpPut("{id}")] [ProducesResponseType(typeof(RobotDto), StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status400BadRequest)] public async Task> Update(Guid id, [FromBody] UpdateRobotRequest request) { try { if (!ModelState.IsValid) { return BadRequest(new ErrorResponseDto { Error = "Validation failed", Details = ModelState.ToDictionary( kvp => kvp.Key, kvp => (object)(kvp.Value?.Errors.Select(e => e.ErrorMessage).ToArray() ?? Array.Empty())) }); } var robot = await _robotService.UpdateAsync(id, request); var dto = MapToDto(robot); return Ok(dto); } catch (KeyNotFoundException ex) { return NotFound(new ErrorResponseDto { Error = ex.Message }); } catch (InvalidOperationException ex) { return BadRequest(new ErrorResponseDto { Error = ex.Message }); } catch (Exception ex) { _logger.Error($"Error updating robot {id}: {ex.Message}"); return StatusCode(500, new ErrorResponseDto { Error = "An error occurred while updating the robot." }); } } /// /// Delete a robot /// [HttpDelete("{id}")] [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task Delete(Guid id) { try { var deleted = await _robotService.DeleteAsync(id); if (!deleted) { return NotFound(new ErrorResponseDto { Error = $"Robot with ID {id} not found." }); } return NoContent(); } catch (Exception ex) { _logger.Error($"Error deleting robot {id}: {ex.Message}"); return StatusCode(500, new ErrorResponseDto { Error = "An error occurred while deleting the robot." }); } } private static RobotDto MapToDto(Robot robot) { return new RobotDto { Id = robot.Id, RobotId = robot.RobotId, Name = robot.Name, ModelId = robot.ModelId, ModelName = robot.Model?.ModelName, MapId = robot.MapId, CreatedDate = robot.CreatedDate, UpdatedDate = robot.UpdatedDate }; } }