import Foundation
import Testing
@testable import Music

struct SmartPlaylistTests {
    // Creates a SmartPlaylist in memory and verifies its properties.
    @Test func smartPlaylistProperties() throws {
        let sp = SmartPlaylist(
            id: nil,
            name: "Miles Davis",
            searchQuery: "miles davis",
            createdAt: Date()
        )
        #expect(sp.name == "Miles Davis")
        #expect(sp.searchQuery == "miles davis")
        #expect(sp.isSmartPlaylist == true)
    }

    // Creates a smart playlist in the database and fetches it back.
    @Test func createAndFetchSmartPlaylist() throws {
        let db = try DatabaseService(inMemory: true)
        let sp = try db.createSmartPlaylist(name: "Jazz Vibes", searchQuery: "jazz")

        #expect(sp.id != nil)
        #expect(sp.name == "Jazz Vibes")
        #expect(sp.searchQuery == "jazz")

        let all = try db.fetchSmartPlaylists()
        #expect(all.count == 1)
        #expect(all[0].name == "Jazz Vibes")
    }

    // Renames a smart playlist and verifies the new name persists.
    @Test func renameSmartPlaylist() throws {
        let db = try DatabaseService(inMemory: true)
        let sp = try db.createSmartPlaylist(name: "Old Name", searchQuery: "old")
        try db.renameSmartPlaylist(id: sp.id!, name: "New Name")

        let all = try db.fetchSmartPlaylists()
        #expect(all[0].name == "New Name")
    }

    // Updates the search query of a smart playlist.
    @Test func updateSmartPlaylistQuery() throws {
        let db = try DatabaseService(inMemory: true)
        let sp = try db.createSmartPlaylist(name: "Jazz", searchQuery: "jazz")
        try db.updateSmartPlaylistQuery(id: sp.id!, searchQuery: "jazz fusion")

        let all = try db.fetchSmartPlaylists()
        #expect(all[0].searchQuery == "jazz fusion")
    }

    // Deletes a smart playlist and verifies it's gone.
    @Test func deleteSmartPlaylist() throws {
        let db = try DatabaseService(inMemory: true)
        let sp = try db.createSmartPlaylist(name: "To Delete", searchQuery: "delete")
        try db.deleteSmartPlaylist(id: sp.id!)

        let all = try db.fetchSmartPlaylists()
        #expect(all.isEmpty)
    }

    // Verifies smart playlist tracks are computed via FTS5 search (not stored).
    @Test func smartPlaylistReturnsDynamicResults() throws {
        let db = try DatabaseService(inMemory: true)
        var t1 = Track.fixture(fileURL: "/a.mp3", title: "Kind of Blue", artist: "Miles Davis")
        var t2 = Track.fixture(fileURL: "/b.mp3", title: "Hotel California", artist: "Eagles")
        var t3 = Track.fixture(fileURL: "/c.mp3", title: "Bitches Brew", artist: "Miles Davis")
        try db.insert(&t1)
        try db.insert(&t2)
        try db.insert(&t3)

        // Smart playlist uses the existing fetchTracks with its searchQuery
        let results = try db.fetchTracks(search: "miles davis", sortColumn: "title", ascending: true)
        #expect(results.count == 2)
        #expect(results[0].title == "Bitches Brew")
        #expect(results[1].title == "Kind of Blue")
    }
}
