//
//  SearchTabView.swift
//  Nextcloud Cookbook iOS Client
//
//  Created by Vincent Meilinger on 23.01.24.
//

import Foundation
import SwiftUI

struct SearchTabView: View {
    @EnvironmentObject var viewModel: SearchTabView.ViewModel
    @EnvironmentObject var appState: AppState

    var body: some View {
        NavigationStack {
            List {
                let results = viewModel.recipesFiltered()

                if viewModel.searchText.isEmpty {
                    // Icon + explainer
                    Section {
                        VStack(spacing: 12) {
                            Image(systemName: "magnifyingglass")
                                .font(.system(size: 48))
                                .foregroundStyle(.secondary)
                            Text("Search for recipes")
                                .font(.headline)
                                .foregroundStyle(.secondary)
                            Text("Enter a recipe name or keyword to get started.")
                                .font(.subheadline)
                                .foregroundStyle(.tertiary)
                                .multilineTextAlignment(.center)
                        }
                        .frame(maxWidth: .infinity)
                        .padding(.vertical, 24)
                        .listRowSeparator(.hidden)
                    }

                    // Search history
                    if !viewModel.searchHistory.isEmpty {
                        Section {
                            ForEach(viewModel.searchHistory, id: \.self) { term in
                                Button {
                                    viewModel.searchText = term
                                } label: {
                                    HStack(spacing: 10) {
                                        Image(systemName: "clock.arrow.circlepath")
                                            .foregroundStyle(.secondary)
                                            .font(.subheadline)
                                        Text(term)
                                            .font(.subheadline)
                                            .foregroundStyle(.primary)
                                        Spacer()
                                    }
                                }
                            }
                            .onDelete { offsets in
                                viewModel.removeHistory(at: offsets)
                            }
                        } header: {
                            HStack {
                                Text("Recent searches")
                                Spacer()
                                Button {
                                    viewModel.clearHistory()
                                } label: {
                                    Text("Clear")
                                        .font(.caption)
                                        .foregroundStyle(.secondary)
                                }
                            }
                        }
                    }
                } else if results.isEmpty {
                    // No results
                    Section {
                        VStack(spacing: 12) {
                            Image(systemName: "magnifyingglass.circle")
                                .font(.system(size: 48))
                                .foregroundStyle(.secondary)
                            Text("No results found")
                                .font(.headline)
                                .foregroundStyle(.secondary)
                            Text("Try a different search term.")
                                .font(.subheadline)
                                .foregroundStyle(.tertiary)
                                .multilineTextAlignment(.center)
                        }
                        .frame(maxWidth: .infinity)
                        .padding(.vertical, 24)
                        .listRowSeparator(.hidden)
                    }
                } else {
                    // Results
                    Section {
                        ForEach(results, id: \.recipe_id) { recipe in
                            SearchRecipeRow(recipe: recipe)
                                .background(
                                    NavigationLink(value: recipe) {
                                        EmptyView()
                                    }
                                    .buttonStyle(.plain)
                                    .opacity(0)
                                )
                                .listRowInsets(EdgeInsets(top: 6, leading: 15, bottom: 6, trailing: 15))
                                .listRowSeparatorTint(.clear)
                        }
                    }
                }
            }
            .listStyle(.plain)
            .navigationTitle(viewModel.searchText.isEmpty ? "Search recipe" : "Search Results")
            .navigationDestination(for: Recipe.self) { recipe in
                RecipeView(viewModel: RecipeView.ViewModel(recipe: recipe))
            }
            .searchable(text: $viewModel.searchText, prompt: "Search recipes/keywords")
            .onSubmit(of: .search) {
                viewModel.saveToHistory(viewModel.searchText)
            }
        }
        .task {
            if viewModel.allRecipes.isEmpty {
                viewModel.allRecipes = await appState.getRecipes()
            }
        }
        .refreshable {
            viewModel.allRecipes = await appState.getRecipes()
        }
    }

    class ViewModel: ObservableObject {
        @Published var allRecipes: [Recipe] = []
        @Published var searchText: String = ""
        @Published var searchMode: SearchMode = .name
        @Published var searchHistory: [String] = []

        private static let historyKey = "searchHistory"
        private static let maxHistory = 15

        init() {
            self.searchHistory = UserDefaults.standard.stringArray(forKey: Self.historyKey) ?? []
        }

        enum SearchMode: String, CaseIterable {
            case name = "Name & Keywords", ingredient = "Ingredients"
        }

        func recipesFiltered() -> [Recipe] {
            guard searchText != "" else { return [] }
            if searchMode == .name {
                return allRecipes.filter { recipe in
                    recipe.name.lowercased().contains(searchText.lowercased()) ||
                    (recipe.keywords != nil && recipe.keywords!.lowercased().contains(searchText.lowercased()))
                }
            } else if searchMode == .ingredient {
                // TODO: Fuzzy ingredient search
            }
            return []
        }

        func saveToHistory(_ term: String) {
            let trimmed = term.trimmingCharacters(in: .whitespaces)
            guard !trimmed.isEmpty else { return }
            searchHistory.removeAll { $0.lowercased() == trimmed.lowercased() }
            searchHistory.insert(trimmed, at: 0)
            if searchHistory.count > Self.maxHistory {
                searchHistory = Array(searchHistory.prefix(Self.maxHistory))
            }
            UserDefaults.standard.set(searchHistory, forKey: Self.historyKey)
        }

        func removeHistory(at offsets: IndexSet) {
            searchHistory.remove(atOffsets: offsets)
            UserDefaults.standard.set(searchHistory, forKey: Self.historyKey)
        }

        func clearHistory() {
            searchHistory = []
            UserDefaults.standard.removeObject(forKey: Self.historyKey)
        }
    }
}


// MARK: - Horizontal row card for search results

private struct SearchRecipeRow: View {
    @EnvironmentObject var appState: AppState
    @State var recipe: Recipe
    @State private var recipeThumb: UIImage?

    private var keywordsText: String? {
        guard let keywords = recipe.keywords, !keywords.isEmpty else { return nil }
        let items = keywords.components(separatedBy: ",").map { $0.trimmingCharacters(in: .whitespaces) }.filter { !$0.isEmpty }
        guard !items.isEmpty else { return nil }
        return items.prefix(3).joined(separator: " \u{00B7} ")
    }

    var body: some View {
        HStack(spacing: 10) {
            if let recipeThumb {
                Image(uiImage: recipeThumb)
                    .resizable()
                    .aspectRatio(contentMode: .fill)
                    .frame(width: 70, height: 70)
                    .clipShape(RoundedRectangle(cornerRadius: 12))
            } else {
                LinearGradient(
                    gradient: Gradient(colors: [.ncGradientDark, .ncGradientLight]),
                    startPoint: .topLeading,
                    endPoint: .bottomTrailing
                )
                .frame(width: 70, height: 70)
                .overlay {
                    Image(systemName: "fork.knife")
                        .foregroundStyle(.white.opacity(0.7))
                }
                .clipShape(RoundedRectangle(cornerRadius: 12))
            }

            VStack(alignment: .leading, spacing: 3) {
                Text(recipe.name)
                    .font(.subheadline)
                    .fontWeight(.medium)
                    .lineLimit(2)

                if let keywordsText {
                    Text(keywordsText)
                        .font(.caption)
                        .foregroundStyle(.secondary)
                        .lineLimit(1)
                }
            }

            Spacer()
        }
        .task {
            recipeThumb = await appState.getImage(
                id: recipe.recipe_id,
                size: .THUMB,
                fetchMode: UserSettings.shared.storeThumb ? .preferLocal : .onlyServer
            )
        }
    }
}
