import Foundation

@MainActor
final class AddBooksViewModel: ObservableObject {
    enum Mode: String, CaseIterable {
        case title
        case scan
        case filter

        var title: String {
            switch self {
            case .title: return String(localized: "add.searchByTitle")
            case .scan: return String(localized: "add.scanBarcode")
            case .filter: return String(localized: "add.filter")
            }
        }
    }

    @Published var mode: Mode = .title
    @Published var titleQuery = ""
    @Published var filterTitle = ""
    @Published var filterYear = ""
    @Published var results: [BookRemote] = []
    @Published var isLoading = false
    @Published var errorMessage: String?

    private var debounceTask: Task<Void, Never>?
    private let booksService: BooksServiceProtocol

    init(booksService: BooksServiceProtocol) {
        self.booksService = booksService
    }

    func titleChanged() {
        debounceTask?.cancel()

        let query = titleQuery.trimmingCharacters(in: .whitespacesAndNewlines)
        guard query.count >= 2 else {
            results = []
            return
        }

        debounceTask = Task {
            try? await Task.sleep(for: .milliseconds(400))
            await searchByTitle(query)
        }
    }

    func searchByTitle(_ query: String? = nil) async {
        let value = query ?? titleQuery
        guard !value.isEmpty else { return }
        isLoading = true
        defer { isLoading = false }

        do {
            results = try await booksService.searchByTitle(value, locales: "tr,en")
            errorMessage = nil
        } catch {
            errorMessage = error.localizedDescription
        }
    }

    func searchByISBN(_ isbn: String) async {
        guard !isbn.isEmpty else { return }
        isLoading = true
        defer { isLoading = false }

        do {
            results = try await booksService.searchByISBN(isbn, locales: "tr,en")
            errorMessage = nil
        } catch {
            errorMessage = error.localizedDescription
        }
    }

    func applyFilter() async {
        guard !filterTitle.isEmpty, !filterYear.isEmpty else { return }
        isLoading = true
        defer { isLoading = false }

        do {
            results = try await booksService.filter(title: filterTitle, year: filterYear, locales: "tr,en")
            errorMessage = nil
        } catch {
            errorMessage = error.localizedDescription
        }
    }
}
