package com.mytatvarnsdk.network

import android.util.Log
import com.mytatvarnsdk.utils.EncryptionUtil.getDecryptedData
import com.mytatvarnsdk.utils.EncryptionUtil.getEncryptedText
import com.mytatvarnsdk.utils.EncryptionUtil.getEncryptionIv
import com.mytatvarnsdk.utils.EncryptionUtil.getEncryptionKey
import com.mytatvarnsdk.utils.RetrofitInstance
import com.mytatvarnsdk.utils.TATVA_ENVIRONMENT
import com.mytatvarnsdk.utils.TatvaEncryptionConfig.PROD_API_KEY
import com.mytatvarnsdk.utils.TatvaEncryptionConfig.PROD_BASE_URL
import com.mytatvarnsdk.utils.TatvaEncryptionConfig.PROD_ENC_IV
import com.mytatvarnsdk.utils.TatvaEncryptionConfig.PROD_ENC_KEY
import com.mytatvarnsdk.utils.TatvaEncryptionConfig.STAGE_API_KEY
import com.mytatvarnsdk.utils.TatvaEncryptionConfig.STAGE_BASE_URL
import com.mytatvarnsdk.utils.TatvaEncryptionConfig.STAGE_ENC_IV
import com.mytatvarnsdk.utils.TatvaEncryptionConfig.STAGE_ENC_KEY
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.RequestBody.Companion.toRequestBody
import retrofit2.HttpException

class AuthenticateSDKService(val scope: CoroutineScope) {


    fun postCGMData(
        environment: TATVA_ENVIRONMENT,
        data: String,
        token: String,
        responseListener: ResponseListener
    ) {
        scope.launch {
            try {

                val apiServiceInterface = RetrofitInstance.getRetroInstance().create(
                    ApiServiceInterface::class.java
                )

                val encryptionKey = getEncryptionKey(
                    env = TATVA_ENVIRONMENT.PROD,
                    prodEncKey = PROD_ENC_KEY,
                    stagEncKey = STAGE_ENC_KEY
                )

                val encryptionIv = getEncryptionIv(
                    env = TATVA_ENVIRONMENT.PROD, prodEncIv = PROD_ENC_IV, stagEncIv = STAGE_ENC_IV
                )

                Log.d("API Response", "data: $data")

                val encryptedString = getEncryptedText(
                    data = data,
                    encryptionKey = encryptionKey,
                    encryptionIv = encryptionIv
                )

                Log.d("API Response", "encryptedString: $encryptedString")

                val decryptedString = getDecryptedData(
                    cipherText = encryptedString,
                    encryptionKey = encryptionKey,
                    encryptionIv = encryptionIv
                )

                Log.d("API Response", "decryptedString: $decryptedString")

                val headers = mapOf(
                    "api-key" to if (environment == TATVA_ENVIRONMENT.PROD) PROD_API_KEY else STAGE_API_KEY,
                    "token" to token,
                    "Content-Type" to "text/plain"
                )

                val url =
                    "${if (environment == TATVA_ENVIRONMENT.PROD) PROD_BASE_URL else STAGE_BASE_URL}/cgm/logs"

                val requestBody = encryptedString.toRequestBody("text/plain".toMediaType())

                val response = apiServiceInterface.postCgmLogs(url, headers, requestBody).string()

                val decryptedResponse = getDecryptedData(
                    cipherText = response.toString(),
                    encryptionKey = encryptionKey,
                    encryptionIv = encryptionIv
                )

                Log.d("API Response", "API response: $decryptedResponse")

                responseListener.onResponseSuccess(response)
            } catch (e: Exception) {
                responseListener.onResponseFail()
                e.printStackTrace()
                Log.d("API Response", "Exception: ${e.message}")
            }
        }
    }


    fun postDeviceData(
        environment: TATVA_ENVIRONMENT,
        data: String,
        token: String,
        loaderListener: LoaderListener
    ) {
        scope.launch {
            try {
                loaderListener.onShowLoader()

                val apiServiceInterface = RetrofitInstance.getRetroInstance().create(
                    ApiServiceInterface::class.java
                )

                val encryptionKey = getEncryptionKey(
                    env = TATVA_ENVIRONMENT.PROD,
                    prodEncKey = PROD_ENC_KEY,
                    stagEncKey = STAGE_ENC_KEY
                )

                val encryptionIv = getEncryptionIv(
                    env = TATVA_ENVIRONMENT.PROD, prodEncIv = PROD_ENC_IV, stagEncIv = STAGE_ENC_IV
                )

                Log.d("API Response", "data: $data")

                val encryptedString = getEncryptedText(
                    data = data,
                    encryptionKey = encryptionKey,
                    encryptionIv = encryptionIv
                )

                Log.d("API Response", "encryptedString: $encryptedString")

                val decryptedString = getDecryptedData(
                    cipherText = encryptedString,
                    encryptionKey = encryptionKey,
                    encryptionIv = encryptionIv
                )

                Log.d("API Response", "decryptedString: $decryptedString")

                val headers = mapOf(
                    "api-key" to if (environment == TATVA_ENVIRONMENT.PROD) PROD_API_KEY else STAGE_API_KEY,
                    "token" to token,
                    "Content-Type" to "text/plain"
                )

                val url =
                    "${if (environment == TATVA_ENVIRONMENT.PROD) PROD_BASE_URL else STAGE_BASE_URL}/cgm/connection"

                val requestBody = encryptedString.toRequestBody("text/plain".toMediaType())

                val response = apiServiceInterface.postCgmLogs(url, headers, requestBody).string()

                val decryptedResponse = getDecryptedData(
                    cipherText = response.toString(),
                    encryptionKey = encryptionKey,
                    encryptionIv = encryptionIv
                )

                Log.d("API Response", "API response: $decryptedResponse")

            } catch (e: HttpException) {
                if (e.code() == 401) {
                    Log.d("API Error", "401 Unauthorized - Token: $token")
                    // Further handling if necessary
                } else {
                    throw e
                }
            } catch (e: Exception) {
                e.printStackTrace()
                Log.d("API Response", "Exception: ${e.message}")
            } finally {
                loaderListener.onHideLoader()
            }
        }
    }

    fun getCGMData(
        environment: TATVA_ENVIRONMENT,
        token: String,
        responseListener: ResponseListener
    ) {
        scope.launch {
            try {

                val apiServiceInterface = RetrofitInstance.getRetroInstance().create(
                    ApiServiceInterface::class.java
                )

                val encryptionKey = getEncryptionKey(
                    env = TATVA_ENVIRONMENT.PROD,
                    prodEncKey = PROD_ENC_KEY,
                    stagEncKey = STAGE_ENC_KEY
                )

                val encryptionIv = getEncryptionIv(
                    env = TATVA_ENVIRONMENT.PROD, prodEncIv = PROD_ENC_IV, stagEncIv = STAGE_ENC_IV
                )

                val headers = mapOf(
                    "api-key" to if (environment == TATVA_ENVIRONMENT.PROD) PROD_API_KEY else STAGE_API_KEY,
                    "token" to token
                )

                val url =
                    "${if (environment == TATVA_ENVIRONMENT.PROD) PROD_BASE_URL else STAGE_BASE_URL}/cgm/status"

                val response = apiServiceInterface.getCgmStatus(url, headers).string()

                val decryptedResponse = getDecryptedData(
                    cipherText = response.toString(),
                    encryptionKey = encryptionKey,
                    encryptionIv = encryptionIv
                )

                Log.d("API Response", "API Response: $decryptedResponse")

                responseListener.onResponseSuccess(decryptedResponse)
            } catch (e: Exception) {
                responseListener.onResponseFail()
                e.printStackTrace()
                Log.d("API Response", "Exception: ${e.message}")
            }
        }
    }

    fun verifyDevice(
        environment: TATVA_ENVIRONMENT,
        token: String,
        sensorId: String,
        responseListener: ResponseListener
    ) {
        scope.launch {
            try {

                val apiServiceInterface = RetrofitInstance.getRetroInstance().create(
                    ApiServiceInterface::class.java
                )

                val encryptionKey = getEncryptionKey(
                    env = TATVA_ENVIRONMENT.PROD,
                    prodEncKey = PROD_ENC_KEY,
                    stagEncKey = STAGE_ENC_KEY
                )

                val encryptionIv = getEncryptionIv(
                    env = TATVA_ENVIRONMENT.PROD, prodEncIv = PROD_ENC_IV, stagEncIv = STAGE_ENC_IV
                )

                val headers = mapOf(
                    "api-key" to if (environment == TATVA_ENVIRONMENT.PROD) PROD_API_KEY else STAGE_API_KEY,
                    "token" to token
                )

                val baseUrl = if (environment == TATVA_ENVIRONMENT.PROD) PROD_BASE_URL else STAGE_BASE_URL
                val url = "$baseUrl/helper/device_verification?deviceId=$sensorId&deviceType=CGM&vendor=diasens"

                Log.d("API Response", "Device Verification URL: $url")

                val response = apiServiceInterface.getCgmStatus(url, headers).string()

                val decryptedResponse = getDecryptedData(
                    cipherText = response.toString(),
                    encryptionKey = encryptionKey,
                    encryptionIv = encryptionIv
                )

                Log.d("API Response", "Device Verification API Response: $decryptedResponse")

                responseListener.onResponseSuccess(decryptedResponse)
            } catch (e: Exception) {
                responseListener.onResponseFail()
                e.printStackTrace()
                Log.d("API Response", "Device Verification Exception: ${e.message}")
            }
        }
    }

    interface LoaderListener {
        fun onShowLoader()
        fun onHideLoader()
    }

    interface ResponseListener {
        fun onResponseSuccess(response: String)
        fun onResponseFail()
    }

}
