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() {
        configureAudioSession()
    }

    private func configureAudioSession() {
        do {
            let audioSession = AVAudioSession.sharedInstance()
            try audioSession.setCategory(.playback, mode: .default, options: [])
            try audioSession.setActive(true)
            print("✅ Audio session configured successfully")
        } catch {
            print("❌ Failed to configure audio session: \(error)")
        }
    }
    
    func playAudio(songId: String, audioURL: String?, skipDataAssets: Bool = false) {
        // 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, skipDataAssets: skipDataAssets) else {
            print("❌ Failed to get audio URL for: \(audioURL ?? "nil")")
            return
        }
        
        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)")
        }
    }
    
    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?, skipDataAssets: Bool = false) {
        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, skipDataAssets: skipDataAssets)
        }
    }
    
    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 {
            print("❌ startScrubbing: No audio player")
            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 {
            print("❌ endScrubbing: No audio player")
            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?, skipDataAssets: Bool = false) -> URL? {
        // If audioURL is nil, alternate between song1 and song2 for variety
        let audioFileName: String
        if let audioURL = audioURL {
            audioFileName = audioURL
        } else {
            // Alternate between song1 and song2 for existing songs without audioURL
            audioFileName = Bool.random() ? "song1" : "song2"
        }

        // Try to get audio as data asset first (song1, song2, etc.) unless skipDataAssets is true
        if !skipDataAssets, let asset = NSDataAsset(name: audioFileName) {
            let tempURL = FileManager.default.temporaryDirectory.appendingPathComponent("\(audioFileName).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: \(audioFileName)")
                return tempURL
            } catch {
                print("❌ Failed to write audio data asset: \(error)")
            }
        }

        // Load from bundle resources (or fallback if data asset failed)
        if let url = Bundle.main.url(forResource: audioFileName, withExtension: "mp3") {
            print("🎵 Audio file loaded from bundle: \(audioFileName)")
            return url
        }

        print("❌ Could not find audio file: \(audioFileName)")
        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
    }
}