import SwiftUI struct AlternativesScreen: View { @EnvironmentObject var appState: AppState let product: Product @State private var alternatives: [Alternative] = [] @State private var isLoading = true @State private var selectedSort: SortOption = .rating @State private var activeFilters: Set = [] enum SortOption: String, CaseIterable { case rating = "Rating" case price = "Price" case distance = "Distance" case processing = "Processing Level" } enum FilterOption: String, CaseIterable { case vegan = "Vegan" case vegetarian = "Vegetarian" case glutenFree = "Gluten-Free" case dairyFree = "Dairy-Free" case nutFree = "Nut-Free" case organic = "Organic" case delivery = "Delivery" case pickup = "Pickup" case buyOnline = "Buy Online" } var body: some View { VStack(spacing: 0) { // Sort and Filter Controls VStack(spacing: 12) { // Sort Picker HStack { Text("Sort by:") .font(.subheadline) .foregroundColor(.secondary) Picker("Sort", selection: $selectedSort) { ForEach(SortOption.allCases, id: \.self) { option in Text(option.rawValue).tag(option) } } .pickerStyle(.menu) Spacer() } .padding(.horizontal) // Filter Chips FilterChips(activeFilters: $activeFilters) } .padding(.vertical, 12) .background(Color(.secondarySystemBackground)) // Alternatives List if isLoading { Spacer() ProgressView("Finding alternatives...") Spacer() } else if filteredAlternatives.isEmpty { Spacer() VStack(spacing: 16) { Image(systemName: "magnifyingglass") .font(.system(size: 50)) .foregroundColor(.secondary) Text("No alternatives found") .font(.headline) Text("Try adjusting your filters") .font(.subheadline) .foregroundColor(.secondary) } Spacer() } else { ScrollView { LazyVStack(spacing: 12) { ForEach(filteredAlternatives) { alternative in if alternative.isSponsored && !appState.isPremium { SponsoredCard(alternative: alternative) } else if !alternative.isSponsored { AlternativeCard(alternative: alternative) } } } .padding() } } } .navigationTitle("Alternatives") .navigationBarTitleDisplayMode(.inline) .task { await loadAlternatives() } .onChange(of: selectedSort) { _ in Task { await loadAlternatives() } } } private var filteredAlternatives: [Alternative] { alternatives.filter { alternative in if activeFilters.isEmpty { return true } for filter in activeFilters { switch filter { case .vegan: if !alternative.product.dietaryTags.contains(where: { $0.lowercased() == "vegan" }) { return false } case .vegetarian: if !alternative.product.dietaryTags.contains(where: { $0.lowercased() == "vegetarian" }) { return false } case .glutenFree: if !alternative.product.dietaryTags.contains(where: { $0.lowercased().contains("gluten") }) { return false } case .dairyFree: if !alternative.product.dietaryTags.contains(where: { $0.lowercased().contains("dairy") }) { return false } case .nutFree: if !alternative.product.dietaryTags.contains(where: { $0.lowercased().contains("nut") }) { return false } case .organic: if !alternative.product.dietaryTags.contains(where: { $0.lowercased() == "organic" }) { return false } case .delivery: if !alternative.hasDelivery { return false } case .pickup: if !alternative.hasPickup { return false } case .buyOnline: if !alternative.hasBuyLink { return false } } } return true } } private func loadAlternatives() async { isLoading = true do { let sortParam = selectedSort.rawValue.lowercased().replacingOccurrences(of: " ", with: "_") let result = try await APIService.shared.getAlternatives(productId: product.id, sort: sortParam) await MainActor.run { alternatives = result isLoading = false } } catch { await MainActor.run { isLoading = false appState.showError(error.localizedDescription) } } } }