import SwiftUI

struct DebouncedSearchModifier: ViewModifier {
    @Binding var searchText: String
    @Binding var searchTask: Task<Void, Never>?
    let action: () async -> Void

    func body(content: Content) -> some View {
        content
            .onChange(of: searchText) {
                searchTask?.cancel()
                searchTask = Task {
                    do {
                        try await Task.sleep(for: .milliseconds(300))
                    } catch {
                        return
                    }
                    await action()
                }
            }
    }
}

extension View {
    func debouncedSearch(
        text: Binding<String>,
        task: Binding<Task<Void, Never>?>,
        action: @escaping () async -> Void,
    ) -> some View {
        modifier(DebouncedSearchModifier(searchText: text, searchTask: task, action: action))
    }
}
