package com.radiola.service

import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.util.Log
import androidx.core.app.NotificationCompat
import androidx.media3.common.util.UnstableApi
import androidx.media3.session.MediaSession
import androidx.media3.session.MediaSessionService
import com.radiola.MainActivity
import com.radiola.data.local.dao.AlarmDao
import com.radiola.data.local.dao.StationDao
import com.radiola.data.remote.LoveStreamResolver
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.cancel
import kotlinx.coroutines.launch
import javax.inject.Inject

@AndroidEntryPoint
@UnstableApi
class PlayerService : MediaSessionService() {

    companion object {
        const val ACTION_ALARM = "com.radiola.ALARM"
        private const val CHANNEL_ALARM = "radiola_alarm"
        private const val NOTIF_ID_ALARM = 9001
    }

    @Inject
    lateinit var playerController: PlayerController

    @Inject
    lateinit var alarmDao: AlarmDao

    @Inject
    lateinit var stationDao: StationDao

    @Inject
    lateinit var loveStreamResolver: LoveStreamResolver

    @Inject
    lateinit var alarmScheduler: AlarmScheduler

    private val serviceScope = CoroutineScope(Dispatchers.Main + SupervisorJob())

    private var mediaSession: MediaSession? = null

    override fun onCreate() {
        super.onCreate()
        mediaSession = MediaSession.Builder(this, playerController.player)
            .setSessionActivity(
                PendingIntent.getActivity(
                    this,
                    0,
                    Intent(this, MainActivity::class.java),
                    PendingIntent.FLAG_IMMUTABLE
                )
            )
            .build()
        ensureAlarmChannel()
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        if (intent?.action == ACTION_ALARM) {
            val alarmId = intent.getIntExtra("alarm_id", -1)
            if (alarmId >= 0) handleAlarm(alarmId)
        }
        return START_NOT_STICKY
    }

    private fun handleAlarm(alarmId: Int) {
        // Немедленно поднимаем foreground-уведомление (Android требует ≤5 с после startForegroundService)
        startForeground(NOTIF_ID_ALARM, buildAlarmNotification())

        serviceScope.launch {
            try {
                val alarm = alarmDao.getById(alarmId)
                if (alarm == null) {
                    Log.w("PlayerService", "Будильник #$alarmId не найден в БД")
                    stopForeground(STOP_FOREGROUND_REMOVE)
                    return@launch
                }
                val station = stationDao.getByIdOnce(alarm.stationId)
                if (station == null) {
                    Log.w("PlayerService", "Станция #${alarm.stationId} не найдена, будильник #$alarmId")
                    stopForeground(STOP_FOREGROUND_REMOVE)
                    return@launch
                }
                val url = loveStreamResolver.resolve(station.streamUrl)
                playerController.startAlarmPlayback(
                    url = url,
                    prefix = station.prefix,
                    name = station.name,
                    id = station.id,
                    fadeInMs = alarm.fadeInSec * 1000L
                )
                // Перепланируем или деактивируем будильник
                if (alarm.daysMask != 0) {
                    // Повторяющийся — планируем следующее срабатывание
                    alarmScheduler.schedule(alarm)
                } else {
                    // Разовый — отключаем
                    alarmDao.setEnabled(alarmId, false)
                }
                // MediaSession-уведомление возьмёт на себя отображение воспроизведения
                stopForeground(STOP_FOREGROUND_DETACH)
            } catch (e: Exception) {
                Log.e("PlayerService", "Ошибка воспроизведения будильника #$alarmId", e)
                stopForeground(STOP_FOREGROUND_REMOVE)
            }
        }
    }

    private fun ensureAlarmChannel() {
        val nm = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        if (nm.getNotificationChannel(CHANNEL_ALARM) == null) {
            val channel = NotificationChannel(
                CHANNEL_ALARM,
                "Будильник",
                NotificationManager.IMPORTANCE_HIGH
            ).apply {
                description = "Уведомления о срабатывании будильника"
            }
            nm.createNotificationChannel(channel)
        }
    }

    private fun buildAlarmNotification(): Notification {
        val mainIntent = PendingIntent.getActivity(
            this,
            0,
            Intent(this, MainActivity::class.java),
            PendingIntent.FLAG_IMMUTABLE
        )
        return NotificationCompat.Builder(this, CHANNEL_ALARM)
            .setSmallIcon(android.R.drawable.ic_lock_idle_alarm)
            .setContentTitle("Будильник")
            .setContentText("Запуск радио…")
            .setContentIntent(mainIntent)
            .setOngoing(true)
            .build()
    }

    override fun onGetSession(controllerInfo: MediaSession.ControllerInfo): MediaSession? = mediaSession

    override fun onTaskRemoved(rootIntent: Intent?) {
        if (!playerController.isPlaying.value) {
            stopSelf()
        }
    }

    override fun onDestroy() {
        mediaSession?.release()
        mediaSession = null
        // serviceScope — поле этого сервиса (пере-создаётся при рестарте), отменяем.
        // playerController — @Singleton (переживает рестарт сервиса), его НЕ релизим:
        // иначе новый PlayerService построит MediaSession на освобождённом плеере.
        serviceScope.cancel()
        super.onDestroy()
    }
}
