import Foundation
import AVFoundation
import UIKit

class AudioManager: ObservableObject {
    static let shared = AudioManager()
    
    @Published var currentlyPlayingSongId: String?
    @Published var isCurrentlyPlaying: Bool = false
    @Published var currentProgress: Double = 0.0
    @Published var totalDuration: Double = 0.0
    
    private var audioPlayer: AVAudioPlayer?
    private var timer: Timer?
    private var wasPlayingBeforeScrubbing: Bool = false
    private var originalVolume: Float = 1.0
    
    private init() {}
    
    func playAudio(songId: String, audioURL: String?) {
        // Stop any currently playing audio
        stopAudio()
        
        // Set the currently playing song
        currentlyPlayingSongId = songId
        
        // Get the audio file URL based on the audioURL parameter
        guard let url = getAudioFileURL(for: audioURL) else {
            print("❌ Failed to get audio URL for: \(audioURL ?? "nil")")
            return
        }
        
        // If it's a remote URL, download it first
        if url.scheme == "http" || url.scheme == "https" {
            downloadAndPlayAudio(url: url, songId: songId)
            return
        }
        
        // Local file - play directly
        do {
            audioPlayer = try AVAudioPlayer(contentsOf: url)
            audioPlayer?.prepareToPlay()
            totalDuration = audioPlayer?.duration ?? 0.0
            audioPlayer?.play()
            
            isCurrentlyPlaying = true
            startProgressTimer()
            print("🎵 Started playing audio for songId: \(songId)")
        } catch {
            print("❌ Failed to play audio: \(error)")
        }
    }
    
    private func downloadAndPlayAudio(url: URL, songId: String) {
        print("📥 Downloading audio from: \(url.absoluteString)")
        
        URLSession.shared.dataTask(with: url) { [weak self] data, response, error in
            guard let self = self else { return }
            
            if let error = error {
                print("❌ Failed to download audio: \(error)")
                return
            }
            
            guard let data = data else {
                print("❌ No data received from audio URL")
                return
            }
            
            // Save to temporary file
            let tempURL = FileManager.default.temporaryDirectory.appendingPathComponent("\(songId).mp3")
            
            do {
                // Remove existing temp file if it exists
                if FileManager.default.fileExists(atPath: tempURL.path) {
                    try FileManager.default.removeItem(at: tempURL)
                }
                try data.write(to: tempURL)
                
                DispatchQueue.main.async {
                    do {
                        self.audioPlayer = try AVAudioPlayer(contentsOf: tempURL)
                        self.audioPlayer?.prepareToPlay()
                        self.totalDuration = self.audioPlayer?.duration ?? 0.0
                        self.audioPlayer?.play()
                        
                        self.isCurrentlyPlaying = true
                        self.startProgressTimer()
                        print("🎵 Started playing downloaded audio for songId: \(songId)")
                    } catch {
                        print("❌ Failed to play downloaded audio: \(error)")
                    }
                }
            } catch {
                print("❌ Failed to save downloaded audio: \(error)")
            }
        }.resume()
    }
    
    func pauseAudio() {
        audioPlayer?.pause()
        stopProgressTimer()
        isCurrentlyPlaying = false
        // Keep currentlyPlayingSongId - don't set to nil when pausing
        print("⏸️ Paused audio")
    }
    
    func stopAudio() {
        audioPlayer?.stop()
        audioPlayer?.currentTime = 0
        stopProgressTimer()
        currentlyPlayingSongId = nil
        isCurrentlyPlaying = false
        currentProgress = 0.0
        print("⏹️ Stopped audio")
    }
    
    func togglePlayback(songId: String, audioURL: String?) {
        if currentlyPlayingSongId == songId {
            // Same song is playing, pause it (don't stop completely)
            guard let player = audioPlayer else { return }
            if player.isPlaying {
                player.pause()
                stopProgressTimer()
                isCurrentlyPlaying = false
                print("⏸️ Paused audio (keeping position)")
            } else {
                player.play()
                startProgressTimer()
                isCurrentlyPlaying = true
                print("▶️ Resumed audio from current position")
            }
        } else {
            // Different song or no song playing, start playing
            playAudio(songId: songId, audioURL: audioURL)
        }
    }
    
    func seekToProgress(_ progress: Double) {
        guard let player = audioPlayer else { return }
        let seekTime = progress * totalDuration
        player.currentTime = seekTime
        currentProgress = progress
    }
    
    func startScrubbing() {
        guard let player = audioPlayer else {
            // Silently return if no player - this can happen if waveform is shown but audio hasn't loaded yet
            return
        }
        
        // Remember if audio was playing and current volume
        wasPlayingBeforeScrubbing = player.isPlaying
        originalVolume = player.volume
        
        // Mute the audio during scrubbing
        player.volume = 0.0
        
        print("🎚️ Started scrubbing - muted audio (was playing: \(wasPlayingBeforeScrubbing), original volume: \(originalVolume))")
    }
    
    func endScrubbing() {
        guard let player = audioPlayer else {
            // Silently return if no player - this can happen if waveform is shown but audio hasn't loaded yet
            return
        }
        
        // Restore original volume
        player.volume = originalVolume
        
        print("🎚️ Ending scrubbing - wasPlayingBeforeScrubbing: \(wasPlayingBeforeScrubbing), player.isPlaying: \(player.isPlaying), restored volume: \(originalVolume)")
        
        // Resume playback if it was playing before scrubbing
        if wasPlayingBeforeScrubbing && !player.isPlaying {
            player.play()
            startProgressTimer()
            isCurrentlyPlaying = true
            print("🎚️ Ended scrubbing - resumed audio playback")
        } else if wasPlayingBeforeScrubbing && player.isPlaying {
            // Already playing, just make sure timer is running
            if timer == nil {
                startProgressTimer()
            }
            print("🎚️ Ended scrubbing - audio was already playing, ensured timer is running")
        } else {
            print("🎚️ Ended scrubbing - restored audio volume (was not playing before)")
        }
    }
    
    private func getAudioFileURL(for audioURL: String?) -> URL? {
        // If audioURL is nil or empty, return nil (no fallback to test files)
        guard let audioURL = audioURL, !audioURL.isEmpty else {
            return nil
        }
        
        // If audioURL is a remote URL (http/https), return it directly
        if let url = URL(string: audioURL), 
           (url.scheme == "http" || url.scheme == "https") {
            print("🎵 Using remote audio URL: \(audioURL)")
            return url
        }
        
        // If it's not a remote URL, treat it as a local file name
        // Try to get audio as data asset first
        if let asset = NSDataAsset(name: audioURL) {
            let tempURL = FileManager.default.temporaryDirectory.appendingPathComponent("\(audioURL).mp3")
            do {
                // Remove existing temp file if it exists
                if FileManager.default.fileExists(atPath: tempURL.path) {
                    try FileManager.default.removeItem(at: tempURL)
                }
                try asset.data.write(to: tempURL)
                print("🎵 Audio file loaded from data asset: \(audioURL)")
                return tempURL
            } catch {
                print("❌ Failed to write audio data asset: \(error)")
            }
        }
        
        // Fallback to bundle resources
        if let url = Bundle.main.url(forResource: audioURL, withExtension: "mp3") {
            print("🎵 Audio file loaded from bundle: \(audioURL)")
            return url
        }
        
        print("❌ Could not find audio file: \(audioURL)")
        return nil
    }
    
    private func startProgressTimer() {
        timer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { _ in
            guard let player = self.audioPlayer else { return }
            
            self.currentProgress = player.currentTime / self.totalDuration
            
            // Stop when track ends
            if !player.isPlaying && player.currentTime > 0 {
                self.isCurrentlyPlaying = false
                self.stopProgressTimer()
                print("🔚 Track finished naturally")
            }
        }
    }
    
    private func stopProgressTimer() {
        timer?.invalidate()
        timer = nil
    }
}