package com.nexlab.openclaw.node.service

import android.content.Context
import android.media.AudioAttributes
import android.media.MediaPlayer
import android.net.Uri
import android.util.Base64
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.io.File
import java.io.FileOutputStream
import javax.inject.Inject
import javax.inject.Singleton

/**
 * Service for audio playback
 */
@Singleton
class AudioPlaybackService @Inject constructor(
    @ApplicationContext private val context: Context
) {
    private var mediaPlayer: MediaPlayer? = null
    private var currentFile: File? = null
    private var isPrepared = false

    /**
     * Load and prepare an audio file
     */
    fun loadFile(filePath: String): Boolean {
        release()

        return try {
            mediaPlayer = MediaPlayer().apply {
                setAudioAttributes(
                    AudioAttributes.Builder()
                        .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
                        .setUsage(AudioAttributes.USAGE_MEDIA)
                        .build()
                )
                setDataSource(filePath)
                prepare()
            }
            isPrepared = true
            true
        } catch (e: Exception) {
            release()
            false
        }
    }

    /**
     * Load from URI (content://, file://, etc.)
     */
    fun loadUri(uri: Uri): Boolean {
        release()

        return try {
            mediaPlayer = MediaPlayer().apply {
                setAudioAttributes(
                    AudioAttributes.Builder()
                        .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
                        .setUsage(AudioAttributes.USAGE_MEDIA)
                        .build()
                )
                setDataSource(context, uri)
                prepare()
            }
            isPrepared = true
            true
        } catch (e: Exception) {
            release()
            false
        }
    }

    /**
     * Load from base64 data
     */
    suspend fun loadBase64(base64: String, fileName: String = "playback_${System.currentTimeMillis()}.mp3"): Boolean = withContext(Dispatchers.IO) {
        release()

        try {
            val bytes = Base64.decode(base64, Base64.DEFAULT)
            val outputFile = File(context.cacheDir, fileName)
            FileOutputStream(outputFile).use { it.write(bytes) }
            
            val success = loadFile(outputFile.absolutePath)
            if (success) {
                currentFile = outputFile
            }
            success
        } catch (e: Exception) {
            withContext(Dispatchers.Main) { release() }
            false
        }
    }

    /**
     * Play the loaded audio
     */
    fun play(): Boolean {
        if (!isPrepared || mediaPlayer == null) return false

        return try {
            mediaPlayer?.start()
            true
        } catch (e: Exception) {
            false
        }
    }

    /**
     * Pause playback
     */
    fun pause(): Boolean {
        if (mediaPlayer == null || !isPrepared) return false

        return try {
            mediaPlayer?.pause()
            true
        } catch (e: Exception) {
            false
        }
    }

    /**
     * Stop playback
     */
    fun stop(): Boolean {
        if (mediaPlayer == null) return false

        return try {
            mediaPlayer?.stop()
            isPrepared = false
            true
        } catch (e: Exception) {
            false
        }
    }

    /**
     * Seek to position in milliseconds
     */
    fun seekTo(positionMs: Int): Boolean {
        if (mediaPlayer == null || !isPrepared) return false

        return try {
            mediaPlayer?.seekTo(positionMs)
            true
        } catch (e: Exception) {
            false
        }
    }

    /**
     * Set playback completion listener
     */
    fun setOnCompletionListener(listener: () -> Unit) {
        mediaPlayer?.setOnCompletionListener { listener() }
    }

    /**
     * Set playback error listener
     */
    fun setOnErrorListener(listener: (String) -> Unit) {
        mediaPlayer?.setOnErrorListener { _, what, extra ->
            listener("Error: $what, $extra")
            true
        }
    }

    /**
     * Get current position in milliseconds
     */
    fun getCurrentPosition(): Int {
        return try {
            mediaPlayer?.currentPosition ?: 0
        } catch (e: Exception) {
            0
        }
    }

    /**
     * Get total duration in milliseconds
     */
    fun getDuration(): Int {
        return try {
            mediaPlayer?.duration ?: 0
        } catch (e: Exception) {
            0
        }
    }

    /**
     * Check if currently playing
     */
    fun isPlaying(): Boolean {
        return try {
            mediaPlayer?.isPlaying ?: false
        } catch (e: Exception) {
            false
        }
    }

    /**
     * Set volume (0.0 to 1.0)
     */
    fun setVolume(volume: Float) {
        try {
            mediaPlayer?.setVolume(volume, volume)
        } catch (e: Exception) {
            // Ignore
        }
    }

    /**
     * Release all resources
     */
    fun release() {
        try {
            mediaPlayer?.release()
        } catch (e: Exception) {
            // Ignore
        }
        mediaPlayer = null
        isPrepared = false
    }

    /**
     * Delete cached playback file
     */
    fun cleanupCache() {
        currentFile?.delete()
        currentFile = null
    }
}
