package com.useasy.callsdk.demo

import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.app.Service
import android.content.Context
import android.content.Intent
import android.media.AudioAttributes
import android.media.AudioFocusRequest
import android.media.AudioManager
import android.os.Build
import android.os.IBinder
import android.os.PowerManager
import androidx.core.app.NotificationCompat
import com.useasy.callsdk.utils.Loger

class CallService : Service() {

    companion object {
        private const val TAG = "CallService"
        private const val NOTIFICATION_ID = 1001
        private const val CHANNEL_ID = "CALL_CHANNEL"
        private const val WAKE_LOCK_TIMEOUT = 10 * 60 * 1000L // 10分钟

        const val EXTRA_PHONE_NUMBER = "extra_phone_number"
        const val ACTION_START_CALL = "com.useasy.callsdk.demo.action.START_CALL"
        const val ACTION_STOP_CALL = "com.useasy.callsdk.demo.action.STOP_CALL"
    }

    private var wakeLock: PowerManager.WakeLock? = null
    private var audioFocusRequest: AudioFocusRequest? = null
    private var phoneNumber: String = ""
    private val audioManager by lazy { getSystemService(AUDIO_SERVICE) as AudioManager }

    override fun onCreate() {
        super.onCreate()
        Loger.dTag(TAG, "CallService onCreate")
        createNotificationChannel()
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        Loger.dTag(TAG, "CallService onStartCommand: ${intent?.action}")

        when (intent?.action) {
            ACTION_START_CALL -> {
                phoneNumber = intent.getStringExtra(EXTRA_PHONE_NUMBER) ?: ""
                startForegroundService()
                initAudio()
            }
            ACTION_STOP_CALL -> {
                stopForegroundService()
            }
        }

        return START_STICKY
    }

    override fun onDestroy() {
        super.onDestroy()
        Loger.dTag(TAG, "CallService onDestroy")
        releaseAudio()
        stopForeground(STOP_FOREGROUND_REMOVE)
    }

    override fun onBind(intent: Intent?): IBinder? = null

    private fun createNotificationChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel(
                CHANNEL_ID,
                getString(R.string.callsdk_notification_channel_name),
                NotificationManager.IMPORTANCE_DEFAULT
            ).apply {
                description = getString(R.string.callsdk_notification_channel_description)
                setShowBadge(false)
                enableLights(false)
                enableVibration(false)
            }
            val nm = getSystemService(NotificationManager::class.java)
            nm.createNotificationChannel(channel)
            Loger.dTag(TAG, "Notification channel created: $CHANNEL_ID")
        }
    }

    private fun startForegroundService() {
        try {
            val notification = buildNotification()
            
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                startForeground(NOTIFICATION_ID, notification)
                Loger.dTag(TAG, "Foreground service started with notification (API >= 26)")
            } else {
                val nm = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
                nm.notify(NOTIFICATION_ID, notification)
                Loger.dTag(TAG, "Foreground service started with notification (API < 26)")
            }
            
            // 验证通知是否已显示
            val nm = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            val activeNotifications = nm.activeNotifications
            Loger.dTag(TAG, "Active notifications count: ${activeNotifications.size}")
            activeNotifications.forEach {
                if (it.id == NOTIFICATION_ID) {
                    Loger.dTag(TAG, "Our notification is active: ${it.notification}")
                }
            }
        } catch (e: Exception) {
            Loger.eTag(TAG, "Failed to start foreground service: ${e.message}")
            e.printStackTrace()
        }
    }

    private fun buildNotification(): Notification {
        val intent = Intent(this, CallActivity::class.java).apply {
            flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
        }
        val pendingIntent = PendingIntent.getActivity(
            this,
            0,
            intent,
            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
        )

        val contentText = if (phoneNumber.isNotEmpty()) {
            getString(R.string.callsdk_notification_content_text, phoneNumber)
        } else {
            getString(R.string.callsdk_notification_content_text_default)
        }

        val notification = NotificationCompat.Builder(this, CHANNEL_ID)
            .setContentTitle(getString(R.string.callsdk_notification_title))
            .setContentText(contentText)
            .setSmallIcon(android.R.drawable.ic_menu_call)
            .setContentIntent(pendingIntent)
            .setOngoing(true)
            .setPriority(NotificationCompat.PRIORITY_DEFAULT) // 改为 DEFAULT
            .setCategory(NotificationCompat.CATEGORY_CALL)
            .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
            .setAutoCancel(false) // 不自动取消
            .build()
        
        Loger.dTag(TAG, "Notification built: title=${getString(R.string.callsdk_notification_title)}, text=$contentText")
        return notification
    }

    private fun initAudio() {
        try {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                val audioAttributes = AudioAttributes.Builder()
                    .setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION)
                    .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
                    .build()

                audioFocusRequest = AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN)
                    .setAudioAttributes(audioAttributes)
                    .setAcceptsDelayedFocusGain(false)
                    .setOnAudioFocusChangeListener { focusChange ->
                        handleAudioFocusChange(focusChange)
                    }
                    .build()

                val result = audioManager.requestAudioFocus(audioFocusRequest!!)
                if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
                    Loger.dTag(TAG, "Audio focus granted")
                } else {
                    Loger.wTag(TAG, "Audio focus request failed: $result")
                }
            } else {
                @Suppress("DEPRECATION")
                val result = audioManager.requestAudioFocus(
                    null,
                    AudioManager.STREAM_VOICE_CALL,
                    AudioManager.AUDIOFOCUS_GAIN
                )
                if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
                    Loger.dTag(TAG, "Audio focus granted (legacy)")
                } else {
                    Loger.wTag(TAG, "Audio focus request failed (legacy): $result")
                }
            }

            val powerManager = getSystemService(POWER_SERVICE) as PowerManager
            wakeLock = powerManager.newWakeLock(
                PowerManager.PARTIAL_WAKE_LOCK,
                "CallSDK:CallWakeLock"
            ).apply {
                acquire(WAKE_LOCK_TIMEOUT)
            }
            Loger.dTag(TAG, "WakeLock acquired")

            audioManager.mode = AudioManager.MODE_IN_COMMUNICATION
            Loger.dTag(TAG, "Audio initialized")
        } catch (e: Exception) {
            Loger.eTag(TAG, "Failed to initialize audio: ${e.message}")
            e.printStackTrace()
        }
    }

    private fun handleAudioFocusChange(focusChange: Int) {
        when (focusChange) {
            AudioManager.AUDIOFOCUS_LOSS -> {
                Loger.wTag(TAG, "Audio focus lost permanently")
            }
            AudioManager.AUDIOFOCUS_LOSS_TRANSIENT -> {
                Loger.wTag(TAG, "Audio focus lost temporarily")
            }
            AudioManager.AUDIOFOCUS_GAIN -> {
                Loger.dTag(TAG, "Audio focus gained")
            }
        }
    }

    private fun releaseAudio() {
        try {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                audioFocusRequest?.let {
                    audioManager.abandonAudioFocusRequest(it)
                    audioFocusRequest = null
                }
            } else {
                @Suppress("DEPRECATION")
                audioManager.abandonAudioFocus(null)
            }
            Loger.dTag(TAG, "Audio focus abandoned")

            wakeLock?.let {
                if (it.isHeld) {
                    it.release()
                    Loger.dTag(TAG, "WakeLock released")
                }
                wakeLock = null
            }
        } catch (e: Exception) {
            Loger.eTag(TAG, "Failed to release audio: ${e.message}")
            e.printStackTrace()
        }
    }

    private fun stopForegroundService() {
        releaseAudio()
        stopForeground(STOP_FOREGROUND_REMOVE)
        stopSelf()
    }
}

