package com.nexus.cross.sdk.unity

import android.app.Activity
import android.util.Log
import com.unity3d.player.UnityPlayer
import io.crosstoken.crossxwebkit.ActivityProvider
import io.crosstoken.crossxwebkit.CustomTabsWebAuthAdapter
import io.crosstoken.crossxwebkit.WebAuthError
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch

/**
 * Unity - Android Native OAuth Bridge
 * Opens OAuth URLs in an in-app browser using crossx-sdk-webkit's CustomTabsWebAuthAdapter.
 * Counterpart to iOS's CROSSxOAuthWrapper.swift + CROSSxOAuthBridge.mm.
 */
object CROSSxOAuthBridge {

    private const val TAG = "CROSSxOAuthBridge"
    private var webAuth: CustomTabsWebAuthAdapter? = null
    private var authJob: Job? = null

    /**
     * Starts the OAuth flow.
     * Opens a Chrome Custom Tab via CustomTabsWebAuthAdapter.start() and
     * suspends until handleCallbackUrl() is invoked.
     */
    @JvmStatic
    fun startOAuthFlow(authUrl: String, callbackScheme: String) {
        Log.i(TAG, "startOAuthFlow: $authUrl (scheme: $callbackScheme)")

        val activity = UnityPlayer.currentActivity
        if (activity == null) {
            Log.e(TAG, "No current activity available")
            return
        }

        authJob?.cancel()
        webAuth?.cancel()

        webAuth = CustomTabsWebAuthAdapter(
            activityProvider = object : ActivityProvider {
                override fun currentActivity(): Activity? = UnityPlayer.currentActivity
            },
            fallbackContext = activity.applicationContext
        )

        authJob = CoroutineScope(Dispatchers.Main).launch {
            try {
                val result = webAuth!!.start(
                    url = authUrl,
                    callbackScheme = callbackScheme,
                    prefersEphemeralSession = false
                )
                Log.i(TAG, "OAuth completed via adapter: ${result.callbackUrl}")
            } catch (e: WebAuthError.Cancelled) {
                Log.i(TAG, "OAuth cancelled by user")
            } catch (e: WebAuthError.Timeout) {
                Log.w(TAG, "OAuth timed out")
            } catch (e: Exception) {
                Log.e(TAG, "OAuth error: ${e.message}")
            } finally {
                webAuth = null
                authJob = null
            }
        }
    }

    /**
     * Forwards the deep link callback URL to the adapter.
     * Called from C# when a deep link is received to resume the suspended start().
     */
    @JvmStatic
    fun handleCallbackUrl(url: String): Boolean {
        Log.i(TAG, "handleCallbackUrl: $url")
        return webAuth?.handleCallbackUrl(url) ?: false
    }

    /**
     * Cancels the OAuth flow.
     */
    @JvmStatic
    fun cancelFlow() {
        Log.i(TAG, "cancelFlow")
        authJob?.cancel()
        webAuth?.cancel()
        webAuth = null
        authJob = null
    }
}
