package com.aves.google_cast.cast

import android.os.Handler
import android.os.Looper
import android.util.Log
import com.google.android.gms.cast.framework.CastSession
import com.google.android.gms.cast.framework.SessionManagerListener
import io.flutter.plugin.common.MethodChannel

class CastSessionHandler(
    private val channel: MethodChannel
) : SessionManagerListener<CastSession> {

    private val mainHandler = Handler(Looper.getMainLooper())
    private var readySent = false
    private var currentSession: CastSession? = null

    // ⭐ mediaClient viene assegnato DOPO la creazione
    private var mediaClient: CastMediaClient? = null

    fun setMediaClient(client: CastMediaClient) {
        mediaClient = client
    }

    override fun onSessionStarting(session: CastSession) {
        Log.d("GCAST_NATIVE", "onSessionStarting")
        currentSession = session

        mediaClient?.attachCurrentClientIfNeeded()   // ⭐ PATCH
        trySendReadyWhenClientExists()
    }

    override fun onSessionStarted(session: CastSession, sessionId: String) {
        Log.d("GCAST_NATIVE", "onSessionStarted sessionId=$sessionId")
        currentSession = session

        mediaClient?.attachCurrentClientIfNeeded()   // ⭐ PATCH
        trySendReadyWhenClientExists()
    }

    override fun onSessionResuming(session: CastSession, sessionId: String) {
        Log.d("GCAST_NATIVE", "onSessionResuming sessionId=$sessionId")
        currentSession = session

        mediaClient?.attachCurrentClientIfNeeded()   // ⭐ PATCH
        trySendReadyWhenClientExists()
    }

    override fun onSessionResumed(session: CastSession, wasSuspended: Boolean) {
        Log.d("GCAST_NATIVE", "onSessionResumed wasSuspended=$wasSuspended")
        currentSession = session

        mediaClient?.attachCurrentClientIfNeeded()   // ⭐ PATCH
        trySendReadyWhenClientExists()
    }

    override fun onSessionSuspended(session: CastSession, reason: Int) {
        Log.d("GCAST_NATIVE", "onSessionSuspended reason=$reason")
        currentSession = session

        mediaClient?.attachCurrentClientIfNeeded()   // ⭐ PATCH
        trySendReadyWhenClientExists()
    }

    override fun onSessionEnded(session: CastSession, error: Int) {
        Log.d("GCAST_NATIVE", "onSessionEnded error=$error")

        currentSession = null
        readySent = false

        mainHandler.post {
            Log.d("GCAST_NATIVE", "invokeMethod onCastStopped")
            channel.invokeMethod("onCastStopped", null)
        }
    }

    override fun onSessionStartFailed(session: CastSession, error: Int) {
        Log.d("GCAST_NATIVE", "onSessionStartFailed error=$error")
    }

    override fun onSessionResumeFailed(session: CastSession, error: Int) {
        Log.d("GCAST_NATIVE", "onSessionResumeFailed error=$error")
    }

    override fun onSessionEnding(session: CastSession) {
        Log.d("GCAST_NATIVE", "onSessionEnding")
    }

    private fun trySendReadyWhenClientExists() {
        val session = currentSession ?: return
        val client = session.remoteMediaClient ?: return

        if (readySent) return
        readySent = true

        mainHandler.post {
            Log.d("GCAST_NATIVE", "invokeMethod onCastReady")
            channel.invokeMethod("onCastReady", null)
        }
    }
}
