using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using OneForMe.Data; using OneForMe.Models; using System.IO; namespace OneForMe.Controllers; [Authorize] public class OrderController : Controller { private readonly ApplicationDbContext _context; public OrderController(ApplicationDbContext context) { _context = context; } // GET: Order/Create public IActionResult Create() { return View(); } // POST: Order/Create [HttpPost] public async Task Create(Order order, string[] itemNames, string[] itemPrices, IFormFile? ImageFile) { if (!ModelState.IsValid) return View(); order.OrderCode = GenerateOrderCode(); order.CreatorName = User.Identity?.Name ?? "Unknown"; // Handle image upload if (ImageFile != null && ImageFile.Length > 0) { try { var uploadsFolder = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "uploads", "orders"); if (!Directory.Exists(uploadsFolder)) { Directory.CreateDirectory(uploadsFolder); } var uniqueFileName = $"{order.OrderCode}_{Guid.NewGuid()}_{Path.GetFileName(ImageFile.FileName)}"; var filePath = Path.Combine(uploadsFolder, uniqueFileName); using (var fileStream = new FileStream(filePath, FileMode.Create)) { await ImageFile.CopyToAsync(fileStream); } order.ImagePath = $"/uploads/orders/{uniqueFileName}"; } catch (Exception ex) { ModelState.AddModelError("ImageFile", $"Error uploading file: {ex.Message}"); return View(); } } _context.Orders.Add(order); await _context.SaveChangesAsync(); // Add menu items for (int i = 0; i < itemNames.Length; i++) { itemPrices[i] = itemPrices[i].Replace(".", ","); if (!string.IsNullOrEmpty(itemNames[i]) && decimal.TryParse(itemPrices[i], out var price) && price > 0) { _context.MenuItems.Add(new MenuItem { OrderId = order.Id, Name = itemNames[i], Price = price }); } } await _context.SaveChangesAsync(); return RedirectToAction("Details", new { code = order.OrderCode }); } // GET: Order/Join public async Task Join(string code) { var order = await _context.Orders .Include(o => o.MenuItems) .Include(o => o.OrderItems) .FirstOrDefaultAsync(o => o.OrderCode == code); if (order == null) return NotFound("Order not found"); if (order.IsClosed || order.IsCompleted) return BadRequest("This order cannot be joined"); return View(order); } // POST: Order/AddItem [HttpPost] public async Task AddItem(int orderId, int menuItemId, int quantity) { var order = await _context.Orders.FindAsync(orderId); if (order == null || order.IsClosed) return BadRequest("Order not found or is closed"); var menuItem = await _context.MenuItems.FindAsync(menuItemId); if (menuItem == null) return BadRequest("Menu item not found"); var orderItem = new OrderItem { OrderId = orderId, MenuItemId = menuItemId, Quantity = quantity, ParticipantName = User.Identity?.Name ?? "", ParticipantEmail = User.Identity?.Name }; _context.OrderItems.Add(orderItem); await _context.SaveChangesAsync(); return RedirectToAction("Join", new { code = order.OrderCode }); } // GET: Order/Details/{code} public async Task Details(string code) { var order = await _context.Orders .Include(o => o.MenuItems) .Include(o => o.OrderItems) .FirstOrDefaultAsync(o => o.OrderCode == code); if (order == null) return NotFound(); return View(order); } // GET: Order/Close/{code} public async Task Close(string code) { var order = await _context.Orders.FirstOrDefaultAsync(o => o.OrderCode == code); if (order == null) return NotFound("Order not found"); if (order.IsClosed) return BadRequest("Order is already closed"); if (order.CreatorName != User.Identity?.Name) return Forbid("Only the order creator can close this order"); order.IsClosed = true; order.ClosedAt = DateTime.UtcNow; _context.Orders.Update(order); await _context.SaveChangesAsync(); return RedirectToAction("Details", new { code = order.OrderCode }); } // GET: Order/Complete/{code} public async Task Complete(string code) { var order = await _context.Orders.FirstOrDefaultAsync(o => o.OrderCode == code); if (order == null) return NotFound("Order not found"); // Only the creator can complete an order if (order.CreatorName != User.Identity?.Name) return Forbid("Only the order creator can mark this as completed"); if (!order.IsClosed) return BadRequest("Order must be closed before marking as completed"); if (order.IsCompleted) return BadRequest("Order is already marked as completed"); order.IsCompleted = true; order.CompletedAt = DateTime.UtcNow; _context.Orders.Update(order); await _context.SaveChangesAsync(); return RedirectToAction("Details", new { code = order.OrderCode }); } private string GenerateOrderCode() { return Guid.NewGuid().ToString().Substring(0, 8).ToUpper(); } }