package com.github.libretube.helpers

import android.content.Context
import android.content.Intent
import androidx.annotation.WorkerThread
import com.github.libretube.ui.activities.AccessCodeActivity
import com.github.libretube.ui.activities.AbstractPlayerHostActivity
import kotlinx.coroutines.*
import retrofit2.HttpException
import com.github.libretube.api.PanelAuthHelper

object TokenWatchdog {
    private val scope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
    private var job: Job? = null

    /**
     * Start the watchdog. Pass an Activity or Application context.
     */
    fun start(context: Context) {
        if (job?.isActive == true) return

        job = scope.launch {
            while (isActive) {
                val token = PreferenceHelper.getToken().trim()
                if (token.isNotEmpty()) {
                    val shouldExpire = checkTokenExpired(token)
                    if (shouldExpire) {
                        withContext(Dispatchers.Main) {
                            // Attempt to stop playback if possible: remove player fragment and stop media service
                            try {
                                val activity = ContextHelper.tryUnwrapActivity<AbstractPlayerHostActivity>(context)
                                activity?.supportFragmentManager?.fragments?.firstOrNull { it.javaClass.simpleName == "PlayerFragment" }?.let {
                                    activity.supportFragmentManager.beginTransaction().remove(it).commitAllowingStateLoss()
                                }
                            } catch (_: Exception) {}

                            try {
                                BackgroundHelper.stopBackgroundPlay(context)
                            } catch (_: Exception) {}

                            // Clear token and force navigate to login
                            PreferenceHelper.clearToken()
                            val intent = Intent(context.applicationContext, AccessCodeActivity::class.java)
                            intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
                            intent.putExtra("expired", true)
                            context.applicationContext.startActivity(intent)
                        }
                        stop()
                        return@launch
                    }
                }

                delay(60_000)
            }
        }
    }

    fun stop() {
        job?.cancel()
        job = null
    }

    @WorkerThread
    private suspend fun checkTokenExpired(token: String): Boolean {
        return try {
            val result = PanelAuthHelper.validarToken(token)
            if (result.isFailure) {
                val ex = result.exceptionOrNull()
                if (ex is HttpException && ex.code() == 403) return true
                return false
            }
            val resp = result.getOrNull()
            resp == null || !resp.status.equals("active", ignoreCase = true)
        } catch (e: Exception) {
            // treat network or unexpected errors as non-expiry; avoid kicking users due to transient network issues
            false
        }
    }
}
