import SwiftUI import SwiftData @MainActor final class DishViewModel: ObservableObject { @Published var name: String = "" @Published var descriptionText: String = "" @Published var selectedTagIds: Set = [] @Published var isPriority: Bool = false @Published var showTagSelector: Bool = false @Published var showDeleteAlert: Bool = false @Published var showAssignedDeleteAlert: Bool = false var editingDish: Dish? var isEditing: Bool { editingDish != nil } var isValid: Bool { !name.trimmingCharacters(in: .whitespaces).isEmpty } func loadDish(_ dish: Dish) { editingDish = dish name = dish.name descriptionText = dish.descriptionText ?? "" selectedTagIds = Set(dish.tagIds) isPriority = dish.isPriority } func reset() { editingDish = nil name = "" descriptionText = "" selectedTagIds = [] isPriority = false } func save(context: ModelContext) { let trimmedName = name.trimmingCharacters(in: .whitespaces) guard !trimmedName.isEmpty else { return } if let dish = editingDish { dish.name = trimmedName dish.descriptionText = descriptionText.isEmpty ? nil : descriptionText dish.tagIds = Array(selectedTagIds) dish.isPriority = isPriority } else { let dish = Dish( name: trimmedName, descriptionText: descriptionText.isEmpty ? nil : descriptionText, tagIds: Array(selectedTagIds), isPriority: isPriority ) context.insert(dish) AnalyticsService.logDishAdded(tagCount: selectedTagIds.count) } try? context.save() reset() } func deleteDish(context: ModelContext) -> Bool { guard let dish = editingDish else { return false } if isDishAssignedInCurrentWeek(dishId: dish.id, context: context) { showAssignedDeleteAlert = true return false } context.delete(dish) try? context.save() AnalyticsService.logDishDeleted() reset() return true } func canDelete(currentPlan: WeekPlan?) -> Bool { guard let dish = editingDish, let plan = currentPlan else { return true } return !plan.slots.contains { $0.dishId == dish.id } } private func isDishAssignedInCurrentWeek(dishId: UUID, context: ModelContext) -> Bool { let currentWeekStart = Date().startOfWeek() let descriptor = FetchDescriptor( predicate: #Predicate { plan in plan.weekStartDate == currentWeekStart } ) guard let currentPlan = try? context.fetch(descriptor).first else { return false } return currentPlan.slots.contains { $0.dishId == dishId } } }