import Foundation
import Observation
import GRDB

@Observable
final class LibraryViewModel {
    var tracks: [Track] = []
    var searchText = ""
    var sortColumn = "title"
    var sortAscending = true
    var trackCount = 0

    private let db: DatabaseService
    private var cancellable: AnyDatabaseCancellable?
    private var searchTask: Task<Void, Never>?

    init(db: DatabaseService) {
        self.db = db
        updateQuery()
    }

    func search(_ text: String) {
        searchText = text
        searchTask?.cancel()
        searchTask = Task { @MainActor [weak self] in
            try? await Task.sleep(for: .milliseconds(150))
            guard !Task.isCancelled else { return }
            self?.updateQuery()
        }
    }

    func sort(by column: String) {
        if sortColumn == column {
            sortAscending.toggle()
        } else {
            sortColumn = column
            sortAscending = true
        }
        updateQuery()
    }

    private func updateQuery() {
        cancellable?.cancel()
        let search = searchText
        let col = sortColumn
        let asc = sortAscending

        let observation = ValueObservation.tracking { [db] dbAccess in
            try db.fetchTracks(db: dbAccess, search: search, sortColumn: col, ascending: asc)
        }

        cancellable = observation.start(
            in: db.dbPool,
            onError: { error in
                print("Library observation error: \(error)")
            },
            onChange: { [weak self] tracks in
                self?.tracks = tracks
                self?.trackCount = tracks.count
            }
        )
    }
}
