//
//  AuditionSoundManager.swift
//  SodaLive
//
//  Created by klaus on 1/7/25.
//

import Foundation
import AVKit
import Combine

class AuditionSoundManager: NSObject, ObservableObject {
    static let shared = AuditionSoundManager()
    
    @Published private (set) var isPlaying = false
    
    @Published var isLoading = false
    @Published var errorMessage = ""
    @Published var isShowPopup = false
    
    @Published var currentTime: Double = 0.0
    @Published private (set) var duration: Double = 0.0
    
    private var player: AVAudioPlayer!
    private var timer: Timer?
    @Published private (set) var applicantId = -1
    
    func resetPlayer() {
        stop()
    }
    
    func playOrPause(applicantId: Int, url: String) {
        if applicantId <= 0 {
            stop()
        }
        
        if self.applicantId != applicantId {
            stop()
            setupPlayer(with: url)
            self.applicantId = applicantId
        } else {
            if !isPlaying {
                player?.play()
                isPlaying = player?.isPlaying ?? false
                startTimer()
            } else {
                player?.pause()
                isPlaying = player?.isPlaying ?? false
                stopTimer()
            }
        }
    }
    
    private func stop() {
        stopTimer()
        isPlaying = false
        isLoading = false
        player?.stop()
        player?.currentTime = 0
        currentTime = 0.0
        duration = 0.0
        applicantId = -1
    }
    
    private func setupPlayer(with url: String) {
        guard let url = URL(string: url) else {
            self.errorMessage = "오류가 발생했습니다. 다시 시도해 주세요."
            self.isShowPopup = true
            return
        }
        
        isLoading = true
        URLSession.shared.dataTask(with: url) { [unowned self] data, response, error in
            guard let audioData = data else {
                self.isLoading = false
                return
            }
            
            do {
                self.player = try AVAudioPlayer(data: audioData)
                
                DispatchQueue.main.async {
                    self.player?.volume = 1
                    self.player?.delegate = self
                    self.player?.prepareToPlay()
                    
                    self.player?.play()
                    self.duration = self.player?.duration ?? 0.0
                    self.isPlaying = self.player.isPlaying
                    self.isLoading = false
                    self.startTimer()
                }
            } catch {
                DispatchQueue.main.async {
                    self.errorMessage = "오류가 발생했습니다. 다시 시도해 주세요."
                    self.isShowPopup = true
                    self.isLoading = false
                }
            }
        }.resume()
    }
    
    private func startTimer() {
        stopTimer() // 기존 타이머 제거
        timer = Timer.scheduledTimer(withTimeInterval: 0.5, repeats: true) { [weak self] _ in
            self?.updateCurrentTime()
        }
    }
    
    // 타이머 정지
    private func stopTimer() {
        timer?.invalidate()
        timer = nil
    }
    
    private func updateCurrentTime() {
        guard let audioPlayer = player else { return }
        currentTime = audioPlayer.currentTime
    }
}

extension AuditionSoundManager: AVAudioPlayerDelegate {
    func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
        stop()
    }
}
