import SwiftUI
import FirebaseFirestore
import FirebaseCore

class UploadedSongManager: ObservableObject {
    static let shared = UploadedSongManager()

    @Published var songs: [UploadedSong] = []
    @Published var isLoading: Bool = false
    @Published var errorMessage: String?

    private let db = Firestore.firestore()
    private var listener: ListenerRegistration?

    init() {}

    func fetchUploadedSongs() {
        isLoading = true
        errorMessage = nil
        
        // Query Firestore for songs where isUpload == true
        listener = db.collection("song")
            .whereField("isUpload", isEqualTo: true)
            .addSnapshotListener { [weak self] querySnapshot, error in
                guard let self = self else { return }
                
                if let error = error {
                    DispatchQueue.main.async {
                        self.isLoading = false
                        self.errorMessage = "Error fetching songs: \(error.localizedDescription)"
                        print("❌ Error fetching uploaded songs: \(error)")
                    }
                    return
                }
                
                guard let documents = querySnapshot?.documents else {
                    DispatchQueue.main.async {
                        self.isLoading = false
                        self.errorMessage = "No songs found"
                        self.songs = []
                    }
                    return
                }
                
                // Fetch all songs with their artist info
                self.fetchSongsWithArtistInfo(documents: documents)
            }
    }
    
    private func fetchSongsWithArtistInfo(documents: [QueryDocumentSnapshot]) {
        let group = DispatchGroup()
        var fetchedSongs: [UploadedSong] = []
        
        for document in documents {
            let data = document.data()
            guard let name = data["name"] as? String,
                  let createdAt = (data["createdAt"] as? Timestamp)?.dateValue(),
                  let createdByRef = data["createdBy"] as? DocumentReference,
                  let lyrics = data["lyrics"] as? String,
                  !lyrics.isEmpty else {
                continue
            }

            group.enter()
            // Fetch the artist info from the user reference
            createdByRef.getDocument { artistDoc, error in
                defer { group.leave() }

                if let error = error {
                    print("❌ Error fetching artist for song \(name): \(error)")
                    return
                }

                guard let artistDoc = artistDoc,
                      artistDoc.exists,
                      let artistData = artistDoc.data(),
                      let artistName = artistData["displayName"] as? String else {
                    print("⚠️ No artist data found for song \(name)")
                    return
                }

                let song = UploadedSong(
                    id: document.documentID,
                    name: name,
                    artistName: artistName,
                    artistId: createdByRef.documentID,
                    createdAt: createdAt,
                    imageURL: data["imageURL"] as? String,
                    audioURL: data["audioURL"] as? String,
                    hasBeenRemixed: data["hasBeenRemixed"] as? Bool ?? false
                )

                fetchedSongs.append(song)
            }
        }
        
        group.notify(queue: .main) { [weak self] in
            self?.isLoading = false
            self?.songs = fetchedSongs
            print("✅ Fetched \(fetchedSongs.count) uploaded songs")
        }
    }

    func songForID(_ id: String) -> UploadedSong? {
        return songs.first(where: { $0.id == id })
    }

    func stopListening() {
        listener?.remove()
        listener = nil
    }
    
    deinit {
        stopListening()
    }
}

