using Microsoft.AspNetCore.Mvc; using RobotNet10.FleetManager.Data; using RobotNet10.FleetManager.Services; using RobotNet10.FleetManager.Shared.DTOs.RobotModel; using RobotNet10.FleetManager.Shared.DTOs.Responses; namespace RobotNet10.FleetManager.Controllers; /// /// API controller for managing robot models. /// Provides RESTful endpoints for CRUD operations on robot models. /// /// /// All endpoints return appropriate HTTP status codes and error responses. /// Image operations are handled separately via RobotModelImagesController. /// [ApiController] [Route("api/robot-models")] public class RobotModelController(IRobotModelService robotModelService, Services.Logger logger) : ControllerBase { private readonly IRobotModelService _robotModelService = robotModelService; private readonly Services.Logger _logger = logger; /// /// Get all robot models /// [HttpGet] [ProducesResponseType(typeof(List), StatusCodes.Status200OK)] public async Task>> GetAll() { try { var models = await _robotModelService.GetAllAsync(); var dtos = models.Select(m => MapToDto(m)).ToList(); return Ok(dtos); } catch (Exception ex) { _logger.Error($"Error getting all robot models: {ex.Message}"); return StatusCode(500, new ErrorResponseDto { Error = "An error occurred while retrieving robot models." }); } } /// /// Get robot model by ID /// [HttpGet("{id}")] [ProducesResponseType(typeof(RobotModelDto), StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task> GetById(Guid id) { try { var model = await _robotModelService.GetByIdAsync(id); if (model == null) { return NotFound(new ErrorResponseDto { Error = $"Robot model with ID {id} not found." }); } return Ok(MapToDto(model)); } catch (Exception ex) { _logger.Error($"Error getting robot model {id}: {ex.Message}"); return StatusCode(500, new ErrorResponseDto { Error = "An error occurred while retrieving the robot model." }); } } /// /// Search robot models by query string /// [HttpGet("search")] [ProducesResponseType(typeof(List), StatusCodes.Status200OK)] public async Task>> Search([FromQuery] string query) { try { var models = await _robotModelService.SearchAsync(query); var dtos = models.Select(m => MapToDto(m)).ToList(); return Ok(dtos); } catch (Exception ex) { _logger.Error($"Error searching robot models with query '{query}': {ex.Message}"); return StatusCode(500, new ErrorResponseDto { Error = "An error occurred while searching robot models." }); } } /// /// Get usage information for a robot model /// [HttpGet("{id}/usage")] [ProducesResponseType(typeof(RobotModelUsageInfoDto), StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task> GetUsageInfo(Guid id) { try { var usageInfo = await _robotModelService.GetUsageInfoAsync(id); return Ok(usageInfo); } catch (KeyNotFoundException ex) { return NotFound(new ErrorResponseDto { Error = ex.Message }); } catch (Exception ex) { _logger.Error($"Error getting usage info for robot model {id}: {ex.Message}"); return StatusCode(500, new ErrorResponseDto { Error = "An error occurred while retrieving usage information." }); } } /// /// Create a new robot model /// [HttpPost] [ProducesResponseType(typeof(RobotModelDto), StatusCodes.Status201Created)] [ProducesResponseType(StatusCodes.Status400BadRequest)] public async Task> Create([FromBody] CreateRobotModelRequest 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 model = await _robotModelService.CreateAsync(request); var dto = MapToDto(model); return CreatedAtAction(nameof(GetById), new { id = model.Id }, dto); } catch (InvalidOperationException ex) { return BadRequest(new ErrorResponseDto { Error = ex.Message }); } catch (Exception ex) { _logger.Error($"Error creating robot model: {ex.Message}"); return StatusCode(500, new ErrorResponseDto { Error = "An error occurred while creating the robot model." }); } } /// /// Update an existing robot model /// [HttpPut("{id}")] [ProducesResponseType(typeof(RobotModelDto), StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status400BadRequest)] public async Task> Update(Guid id, [FromBody] UpdateRobotModelRequest 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 model = await _robotModelService.UpdateAsync(id, request); var dto = MapToDto(model); 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 model {id}: {ex.Message}"); return StatusCode(500, new ErrorResponseDto { Error = "An error occurred while updating the robot model." }); } } /// /// Delete a robot model /// [HttpDelete("{id}")] [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status400BadRequest)] public async Task Delete(Guid id) { try { var deleted = await _robotModelService.DeleteAsync(id); if (!deleted) { return NotFound(new ErrorResponseDto { Error = $"Robot model with ID {id} not found." }); } return NoContent(); } catch (InvalidOperationException ex) { return BadRequest(new ErrorResponseDto { Error = ex.Message }); } catch (Exception ex) { _logger.Error($"Error deleting robot model {id}: {ex.Message}"); return StatusCode(500, new ErrorResponseDto { Error = "An error occurred while deleting the robot model." }); } } private static RobotModelDto MapToDto(RobotModel model) { return new RobotModelDto { Id = model.Id, ModelName = model.ModelName, Length = model.Length, Width = model.Width, ImageWidth = model.ImageWidth, ImageHeight = model.ImageHeight, NavigationPointX = model.NavigationPointX, NavigationPointY = model.NavigationPointY, NavigationType = model.NavigationType, VehicleTypeId = model.VehicleTypeId, CreatedDate = model.CreatedDate, UpdatedDate = model.UpdatedDate, RobotCount = model.Robots?.Count ?? 0 }; } }