package com.nexlab.openclaw.node.service

import android.Manifest
import android.content.Context
import android.content.pm.PackageManager
import android.media.MediaRecorder
import android.os.Build
import android.util.Base64
import androidx.core.content.ContextCompat
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.io.File
import java.io.FileInputStream
import javax.inject.Inject
import javax.inject.Singleton

/**
 * Service for microphone recording
 */
@Singleton
class MicrophoneService @Inject constructor(
    @ApplicationContext private val context: Context
) {
    private var mediaRecorder: MediaRecorder? = null
    private var isRecording = false
    private var currentFile: File? = null

    /**
     * Check if audio recording permission is granted
     */
    fun hasAudioPermission(): Boolean {
        return ContextCompat.checkSelfPermission(
            context, Manifest.permission.RECORD_AUDIO
        ) == PackageManager.PERMISSION_GRANTED
    }

    /**
     * Start recording audio
     */
    @Suppress("MissingPermission")
    fun startRecording(outputFile: File): Boolean {
        if (isRecording) return false
        if (!hasAudioPermission()) return false

        return try {
            mediaRecorder = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
                MediaRecorder(context)
            } else {
                @Suppress("DEPRECATION")
                MediaRecorder()
            }.apply {
                setAudioSource(MediaRecorder.AudioSource.MIC)
                setOutputFormat(MediaRecorder.OutputFormat.MPEG_4)
                setAudioEncoder(MediaRecorder.AudioEncoder.AAC)
                setAudioEncodingBitRate(128000)
                setAudioSamplingRate(44100)
                setOutputFile(outputFile.absolutePath)
                prepare()
                start()
            }
            currentFile = outputFile
            isRecording = true
            true
        } catch (e: Exception) {
            mediaRecorder?.release()
            mediaRecorder = null
            false
        }
    }

    /**
     * Stop recording and return the file
     */
    fun stopRecording(): File? {
        if (!isRecording) return null

        return try {
            mediaRecorder?.apply {
                stop()
                reset()
                release()
            }
            mediaRecorder = null
            isRecording = false
            currentFile
        } catch (e: Exception) {
            mediaRecorder?.release()
            mediaRecorder = null
            isRecording = false
            null
        }
    }

    /**
     * Get recording duration in milliseconds
     */
    fun getRecordingDuration(): Long {
        return 0L // Duration tracking not implemented in this simplified version
    }

    /**
     * Convert audio file to base64
     */
    suspend fun fileToBase64(file: File): String? = withContext(Dispatchers.IO) {
        try {
            val bytes = file.readBytes()
            Base64.encodeToString(bytes, Base64.NO_WRAP)
        } catch (e: Exception) {
            null
        }
    }

    /**
     * Record a short audio clip (for voice messages)
     */
    suspend fun recordVoiceMessage(
        maxDurationMs: Int = 60000,
        outputDir: File = File(context.cacheDir, "voice")
    ): Result<String> = withContext(Dispatchers.IO) {
        if (!hasAudioPermission()) {
            return@withContext Result.failure(SecurityException("Audio permission not granted"))
        }

        outputDir.mkdirs()
        val outputFile = File(outputDir, "voice_${System.currentTimeMillis()}.m4a")

        val started = startRecording(outputFile)
        if (!started) {
            return@withContext Result.failure(Exception("Failed to start recording"))
        }

        // Wait for max duration or stop manually
        kotlinx.coroutines.delay(maxDurationMs.toLong())
        
        val file = stopRecording()
        if (file == null || !file.exists()) {
            return@withContext Result.failure(Exception("Recording failed"))
        }

        val base64 = fileToBase64(file)
        if (base64 != null) {
            Result.success(base64)
        } else {
            Result.failure(Exception("Failed to encode audio"))
        }
    }

    /**
     * Get amplitude (for voice level visualization)
     */
    fun getAmplitude(): Int {
        return try {
            mediaRecorder?.maxAmplitude ?: 0
        } catch (e: Exception) {
            0
        }
    }

    fun isCurrentlyRecording(): Boolean = isRecording

    fun release() {
        mediaRecorder?.release()
        mediaRecorder = null
        isRecording = false
    }
}
