Kotlin

package com.example.myapplication

// Importing necessary Android libraries
import android.annotation.SuppressLint
import android.os.Bundle
import android.util.Log
import android.webkit.JavascriptInterface
import android.webkit.WebChromeClient
import android.webkit.WebView
import android.widget.Button
import android.widget.EditText
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import com.google.gson.Gson
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.RequestBody.Companion.toRequestBody
import org.json.JSONObject
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response



class MainActivity : AppCompatActivity() {

    // Declaring UI elements
    private lateinit var platformCodeEditText: EditText
    private lateinit var participantCodeEditText: EditText
    private lateinit var webView: WebView

    // Declaring my Javascript Interface to handle communication between the WebView and the Android app
    private lateinit var myJavascriptInterface: MyJavascriptInterface

    // Declaring variables to store the SDK module, URL for the WebView, and JWT
    private var sdkModule: String = ""
    private var url: String = ""
    private var jwt: String? = ""

    val sdkMobileServer = "https://sdk-mobile.cert.zerohash.com/v1/"
    val zeroHashAppsURL = "https://web-sdk.cert.zerohash.com/"

    @SuppressLint("SetJavaScriptEnabled")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContentView(R.layout.activity_main)
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
            val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
            insets
        }


        val button = findViewById<Button>(R.id.button)

        // Configuring the WebView to enable JavaScript and DOM storage
        webView = findViewById(R.id.webview)
        webView.settings.javaScriptEnabled = true
        webView.settings.domStorageEnabled = true
        webView.settings.allowContentAccess = true
        webView.settings.allowFileAccess = true

        webView.webChromeClient = WebChromeClient()

        // Configuring the WebView to use the MyJavascriptInterface for communication
        webView.addJavascriptInterface(MyJavascriptInterface(webView).apply {
            myJavascriptInterface = this
            // IMPORTANT: This is the name that will be used to communicate with the WebView
            // THIS NAME SHOULD NOT BE CHANGED
        }, "NativeAndroid")
        
        // Configuring the WebView to handle camera permissions
        webView.webChromeClient = object : WebChromeClient() {
            override fun onPermissionRequest(request: PermissionRequest) {
                request.grant(request.resources)
            }
        }

        button.setOnClickListener {
            // Setting the SDK module to "crypto-buy"
            sdkModule = "crypto-buy"
            myJavascriptInterface.setSdkModule("crypto-buy")

            // Fetching the JWT
            fetchJwt(sdkModule)
        }
    }

    private fun fetchJwt(sdkModule: String) {
        val permissions = listOf(
            "fiat-deposits",
            "fiat-withdrawals",
            "crypto-withdrawals",
            "crypto-buy",
            "crypto-sell"
        )
        val participant_code = "<PARTICIPANT_CODE>"

        // Creating the payload for the fetchJwt API
        val jwtPayload = Gson().toJson(FetchJwtData(participant_code, permissions))
            .toRequestBody("application/json".toMediaType())

        // Making the API call to fetch the JWT
        // service() is a HTTP client that is used to make API calls
        service().fetchJwt(jwtPayload).enqueue(object : Callback<JwtResponse> {
            override fun onResponse(call: Call<JwtResponse>, response: Response<JwtResponse>) {
                if (response.isSuccessful) {
                    val currentJwt = response.body()?.message?.token
                    jwt = currentJwt
                    val currentUrl = "${sdkMobileServer}?zeroHashAppsURL=$zeroHashAppsURL&${sdkModule}JWT=$jwt"
                    url = currentUrl
                    myJavascriptInterface.setJwt(jwt)
                    loadWebView()
                }
            }

            override fun onFailure(call: Call<JwtResponse>, t: Throwable) {
                println("Error: ${t.message}")
                t.printStackTrace()
            }
        })

    }

    // Open the WebView and load the URL
    private fun loadWebView() {
        webView.loadUrl(url)
        webView.visibility = WebView.VISIBLE
    }
}

class MyJavascriptInterface(private val webView: WebView){

    private var sdkModule: String = ""
    private var jwt: String? = null

    fun setSdkModule(sdkModule: String) {
        this.sdkModule = sdkModule
    }

    fun setJwt(jwt: String?) {
        this.jwt = jwt
    }

    @JavascriptInterface
    fun postMessage(message: String) {
        Log.d("WebViewMessage", "Message received: $message")

        val json = JSONObject(message)
        val messageType = json.optString("type")

        // If the message type is "SDK_MOBILE_READY", send a message to the WebView to open the modal
        if (messageType == "SDK_MOBILE_READY") {
            val script = "window.postMessage({type: 'OPEN_MODAL', payload: { appIdentifier: '$sdkModule', jwt: '$jwt'}});"
            println("Sending message to WebView: OPEN_MODAL")

            println(script)

            webView.post {
                webView.evaluateJavascript(script) {
                    println("Message sent to WebView: OPEN_MODAL")
                }
            }
        }

        // If the message type is "CRYPTO_BUY_CLOSE_BUTTON_CLICKED", hide the WebView
        if (messageType == "CRYPTO_BUY_CLOSE_BUTTON_CLICKED") {
            webView.visibility = WebView.GONE
        }
    }
}