import IndieSync
import SwiftData
import SwiftUI

/// The Search tab: full-library search over note text, tags, and capture
/// location. Lives behind the tab bar's dedicated search tab (`role: .search`),
/// which iOS 26 renders as the separated magnifier at the trailing edge.
struct SearchView: View {
    @Environment(SyncEngine.self) private var syncEngine
    @Query(sort: \NoteEntity.createdAt, order: .reverse) private var notes: [NoteEntity]

    @State private var searchText = ""
    @State private var editingNote: NoteEntity?

    var body: some View {
        NavigationStack {
            List {
                ForEach(results) { note in
                    row(note)
                }
            }
            .navigationTitle("Search")
            .searchable(text: $searchText, prompt: "Search notes and tags")
            .overlay {
                if searchText.isEmpty {
                    ContentUnavailableView(
                        "Search your notes",
                        systemImage: "magnifyingglass",
                        description: Text("Find notes by text, tag, or the place you captured them.")
                    )
                } else if results.isEmpty {
                    ContentUnavailableView.search(text: searchText)
                }
            }
            .sheet(item: $editingNote) { note in
                NoteEditorView(mode: .edit(note))
            }
        }
    }

    private func row(_ note: NoteEntity) -> some View {
        Button {
            editingNote = note
        } label: {
            NoteRowView(note: note)
        }
        .buttonStyle(.plain)
        .swipeActions(edge: .trailing) {
            Button(role: .destructive) {
                delete(note)
            } label: {
                Label("Delete", systemImage: "trash")
            }
        }
    }

    private var results: [NoteEntity] {
        guard !searchText.isEmpty else { return [] }
        return notes.filter { $0.matches(search: searchText) }
    }

    private func delete(_ note: NoteEntity) {
        guard let id = ULID(string: note.id) else { return }
        Task {
            try? await syncEngine.deleteNote(id: id)
        }
    }
}

extension NoteEntity {
    /// Case-insensitive match against text, tags, and capture location.
    func matches(search: String) -> Bool {
        let needle = search.lowercased()
        return text.lowercased().contains(needle)
            || tags.contains { $0.lowercased().contains(needle) }
            || (placeName?.lowercased().contains(needle) ?? false)
            || (locality?.lowercased().contains(needle) ?? false)
    }
}
