using LogisticsApp.Server.Data; using LogisticsApp.Server.DTOs; using LogisticsApp.Server.Models; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; namespace LogisticsApp.Server.Controllers { [ApiController] [Route("api/[controller]")] public class OrdersController : ControllerBase { private readonly ApplicationDbContext _context; public OrdersController(ApplicationDbContext context) { _context = context; } // GET: api/orders [Authorize] [HttpGet] public async Task>>> GetOrders([FromQuery] OrderFilters filters) { try { var query = _context.Orders.AsQueryable(); if (!string.IsNullOrEmpty(filters.ClientName)) { query = query.Where(o => o.ClientName.ToLower().Contains(filters.ClientName.ToLower())); } if (filters.MinCost.HasValue) { query = query.Where(o => o.OrderCost >= filters.MinCost.Value); } if (filters.MaxCost.HasValue) { query = query.Where(o => o.OrderCost <= filters.MaxCost.Value); } if (filters.OrderDate.HasValue) { query = query.Where(o => o.OrderDate.Date == filters.OrderDate.Value.Date); } if (!string.IsNullOrEmpty(filters.Status)) { query = query.Where(o => o.Status == filters.Status); } var totalCount = await query.CountAsync(); var orders = await query .OrderByDescending(o => o.OrderDate) .Skip((filters.Page - 1) * filters.PageSize) .Take(filters.PageSize) .ToListAsync(); var result = new PagedResult { Items = orders, TotalCount = totalCount, Page = filters.Page, PageSize = filters.PageSize, TotalPages = (int)Math.Ceiling(totalCount / (double)filters.PageSize) }; return Ok(new ApiResponse>(true, "Orders retrieved successfully", result)); } catch (Exception ex) { return StatusCode(500, new ApiResponse(false, $"Internal server error: {ex.Message}")); } } // GET: api/orders/5 [Authorize] [HttpGet("{id}")] public async Task>> GetOrder(int id) { var order = await _context.Orders.FindAsync(id); if (order == null) { return NotFound(new ApiResponse(false, "Order not found")); } return Ok(new ApiResponse(true, "Order retrieved successfully", order)); } // PUT: api/orders/5 [Authorize] [HttpPut("{id}")] public async Task>> PutOrder(int id, Order order) { if (id != order.Id) { return BadRequest(new ApiResponse(false, "ID mismatch")); } var validStatuses = new[] { "pending", "in_progress", "completed", "cancelled" }; if (!validStatuses.Contains(order.Status)) { return BadRequest(new ApiResponse(false, "Invalid status")); } if (order.OrderCost <= 0) { return BadRequest(new ApiResponse(false, "Order cost must be positive")); } _context.Entry(order).State = EntityState.Modified; try { await _context.SaveChangesAsync(); } catch (DbUpdateConcurrencyException) { if (!OrderExists(id)) { return NotFound(new ApiResponse(false, "Order not found")); } else { throw; } } return Ok(new ApiResponse(true, "Order updated successfully", order)); } // POST: api/orders [Authorize] [HttpPost] public async Task>> PostOrder(Order order) { if (string.IsNullOrEmpty(order.ClientName) || order.ClientName.Length > 200) { return BadRequest(new ApiResponse(false, "Client name is required and must be less than 200 characters")); } if (order.OrderCost <= 0) { return BadRequest(new ApiResponse(false, "Order cost must be positive")); } if (string.IsNullOrEmpty(order.Address) || order.Address.Length > 500) { return BadRequest(new ApiResponse(false, "Address is required and must be less than 500 characters")); } var validStatuses = new[] { "pending", "in_progress", "completed", "cancelled" }; if (!validStatuses.Contains(order.Status)) { return BadRequest(new ApiResponse(false, "Invalid status")); } _context.Orders.Add(order); await _context.SaveChangesAsync(); return CreatedAtAction("GetOrder", new { id = order.Id }, new ApiResponse(true, "Order created successfully", order)); } // DELETE: api/orders/5 [Authorize] [HttpDelete("{id}")] public async Task>> DeleteOrder(int id) { try { var order = await _context.Orders.FindAsync(id); if (order == null) { return NotFound(new ApiResponse(false, "Order not found")); } _context.Orders.Remove(order); await _context.SaveChangesAsync(); return Ok(new ApiResponse(true, "Order deleted successfully")); } catch (Exception ex) { return StatusCode(500, new ApiResponse(false, $"Internal server error: {ex.Message}")); } } private bool OrderExists(int id) { return _context.Orders.Any(e => e.Id == id); } } }