//
//  MenuView.swift
//  TigerDine
//
//  Created by Campbell on 11/3/25.
//

import SwiftUI

struct MenuView: View {
    @State var accountId: Int
    @State var locationId: Int
    @State private var menuItems: [FDMenuItem] = []
    @State private var searchText: String = ""
    @State private var isLoading: Bool = true
    @State private var loadFailed: Bool = false
    @State private var selectedMealPeriod: Int = 0
    @State private var openPeriods: [Int] = []
    @StateObject private var dietaryRestrictionsModel = MenuDietaryRestrictionsModel()
    @State private var showingDietaryRestrictionsSheet: Bool = false
    
    func getOpenPeriods() async {
        // Only run this if we haven't already gotten the open periods. This is somewhat of a bandaid solution to the issue of
        // fetching this information more than once, but hey it works!
        if openPeriods.isEmpty {
            switch await getFDMealPlannerOpenings(locationId: locationId) {
            case .success(let openingResults):
                openPeriods = openingResults.data.map { Int($0.id) }
                selectedMealPeriod = openPeriods[0]
                // Since this only runs once when the view first loads, we can safely use this to call the method to get the data
                // the first time. This also ensures that it doesn't happen until we have the opening periods collected.
                await getMenuForPeriod(mealPeriodId: selectedMealPeriod)
            case .failure(let error):
                print(error)
                loadFailed = true
            }
        }
    }
    
    func getMenuForPeriod(mealPeriodId: Int) async {
        switch await getFDMealPlannerMenu(locationId: locationId, accountId: accountId, mealPeriodId: mealPeriodId) {
        case .success(let menus):
            menuItems = parseFDMealPlannerMenu(menu: menus)
            isLoading = false
        case .failure(let error):
            print(error)
            loadFailed = true
        }
    }
    
    func getPriceString(price: Double) -> String {
        if price == 0.0 {
            return "Price Unavailable"
        } else {
            return "$\(String(format: "%.2f", price))"
        }
    }
    
    private var filteredMenuItems: [FDMenuItem] {
        var newItems = menuItems
        // Filter out allergens.
        newItems = newItems.filter { item in
            if !item.allergens.isEmpty {
                for allergen in item.allergens {
                    if let checkingAllergen = Allergen(rawValue: allergen.lowercased()) {
                        if dietaryRestrictionsModel.dietaryRestrictions.contains(checkingAllergen) {
                            return false
                        }
                    }
                }
            }
            return true
        }
        // Filter down to vegetarian/vegan only if enabled.
        if dietaryRestrictionsModel.isVegetarian || dietaryRestrictionsModel.isVegan {
            newItems = newItems.filter { item in
                if dietaryRestrictionsModel.isVegetarian && (item.dietaryMarkers.contains("Vegetarian") || item.dietaryMarkers.contains("Vegan")) {
                    return true
                } else if dietaryRestrictionsModel.isVegan && (item.dietaryMarkers.contains("Vegan")) {
                    return true
                }
                return false
            }
        }
        // Filter out pork/beef.
        if dietaryRestrictionsModel.noBeef {
            newItems = newItems.filter { item in
                item.dietaryMarkers.contains("Beef") == false
            }
        }
        if dietaryRestrictionsModel.noPork {
            newItems = newItems.filter { item in
                item.dietaryMarkers.contains("Pork") == false
            }
        }
        // Filter down to search contents.
        newItems = newItems.filter { item in
            let searchedLocations = searchText.isEmpty || item.name.localizedCaseInsensitiveContains(searchText)
            return searchedLocations
        }
        newItems.sort { firstItem, secondItem in
            return firstItem.name.localizedCaseInsensitiveCompare(secondItem.name) == .orderedAscending
        }
        return newItems
    }
    
    var body: some View {
        if isLoading {
            VStack {
                LoadingView(loadFailed: $loadFailed)
            }
            .task {
                await getOpenPeriods()
            }
        } else {
            VStack {
                if !menuItems.isEmpty {
                    List {
                        Section {
                            ForEach(filteredMenuItems) { item in
                                NavigationLink(destination: MenuItemView(menuItem: item)) {
                                    VStack(alignment: .leading) {
                                        HStack {
                                            Text(item.name)
                                            ForEach(item.dietaryMarkers, id: \.self) { dietaryMarker in
                                                Text(dietaryMarker)
                                                    .foregroundStyle(Color.white)
                                                    .font(.caption)
                                                    .padding(5)
                                                    .background(
                                                        RoundedRectangle(cornerRadius: 16)
                                                            .fill({
                                                                switch dietaryMarker {
                                                                case "Vegan", "Vegetarian":
                                                                    return Color.green
                                                                default:
                                                                    return Color.orange
                                                                }
                                                            }())
                                                    )
                                            }
                                        }
                                        Text("\(item.calories) Cal • \(getPriceString(price: item.price))")
                                            .foregroundStyle(.secondary)
                                    }
                                }
                            }
                        }
                    }
                    .navigationTitle("Menu")
                    .navigationBarTitleDisplayMode(.large)
                    .searchable(text: $searchText, prompt: "Search")
                } else {
                    Image(systemName: "clock.badge.exclamationmark")
                        .resizable()
                        .scaledToFit()
                        .frame(width: 75, height: 75)
                        .foregroundStyle(.accent)
                    Text("No menu is available for the selected meal period today. Try selecting a different meal period.")
                        .foregroundStyle(.secondary)
                        .multilineTextAlignment(.center)
                }
            }
            .toolbar {
                ToolbarItem(placement: .primaryAction) {
                    Menu {
                        Picker("Meal Period", selection: $selectedMealPeriod) {
                            ForEach(openPeriods, id: \.self) { period in
                                Text(fdmpMealPeriodsMap[period]!).tag(period)
                            }
                        }
                    } label: {
                        Image(systemName: "clock")
                        Text("Meal Periods")
                    }
                }
                ToolbarItemGroup(placement: .bottomBar) {
                    Button(action: {
                        showingDietaryRestrictionsSheet = true
                    }) {
                        Image(systemName: "line.3.horizontal.decrease")
                    }
                    if #unavailable(iOS 26.0) {
                        Spacer()
                    }
                }
                if #available(iOS 26.0, *) {
                    ToolbarSpacer(.flexible, placement: .bottomBar)
                    DefaultToolbarItem(kind: .search, placement: .bottomBar)
                }
            }
            .onChange(of: selectedMealPeriod) {
                isLoading = true
                Task {
                    await getMenuForPeriod(mealPeriodId: selectedMealPeriod)
                }
            }
            .sheet(isPresented: $showingDietaryRestrictionsSheet) {
                MenuDietaryRestrictionsSheet(dietaryRestrictionsModel: dietaryRestrictionsModel)
            }
        }
    }
}

#Preview {
    MenuView(accountId: 1, locationId: 1)
}
