package io.nexilis.service

import android.util.Log
import io.newuniverse.SDK.nuSDKService
import io.nexilis.service.core.Data
import io.nexilis.service.core.decrypt
import kotlinx.coroutines.*
import java.util.concurrent.ConcurrentHashMap

private val passArray = charArrayOf(
    '6',
    'g',
    'o',
    'y',
    'k',
    't',
    'u',
    'j',
    't',
    'O',
    'Q',
    'J',
    'Y',
    '0',
    't',
    '9',
    'z',
    'l',
    'u',
    'Y',
    'g',
    'o',
    '1',
    '8',
    '4',
    'y',
    'g',
    'k',
    '7',
    'y',
    'y',
    'k',
    'i',
    'i',
    'g'
)

private const val DEFAULT_TIMEOUT: Long = 10 * 1000


internal val pass = String(passArray).decrypt()

internal const val namePreference = "cpaas"

internal const val tag = "SAPI"

internal val apiScope = CoroutineScope(SupervisorJob())

class Service {

    companion object {

        fun sendSync(data: Data): Data? {
            try {
                Log.d(tag, "Service:sGetResponse >>> $data")
                val response = nuSDKService.getInstance(pass)
                    .sGetResponse(pass, data.toString(), DEFAULT_TIMEOUT, false)
                    ?: return null
                Log.d(tag, "Service:sGetResponse <<< $response")
                val r = Data()
                if (r.parse(response)) {
                    return r
                }
            } catch (e: Exception) {
                Log.e(tag, e.message, e)
            }
            return null
        }

        fun sendAsync(data: Data): String? {
            try {
                Log.d(tag, "Service:sSend:$data")
                var d: Any? = data.toString()
                if (data.media.isNotEmpty()) {
                    d = data.toByteArray()
                }
                return nuSDKService.getInstance(pass).sSend(pass, d, 1, DEFAULT_TIMEOUT)
            } catch (e: Exception) {
                Log.e(tag, e.message, e)
            }
            return null
        }

        val map = ConcurrentHashMap<String, suspend CoroutineScope.(Data) -> Unit>()

        fun sendAsync(data: Data, callback: suspend CoroutineScope.(Data) -> Unit) {
            map[data.status] = callback
            sendAsync(data)
        }

        fun response(data: Data): String? {
            try {
                Log.d(tag, "Service:sSendResponse:$data")
                return nuSDKService.getInstance(pass)
                    .sSendResponse(pass, data.packetId, data.toString(), DEFAULT_TIMEOUT)
            } catch (e: Exception) {
                Log.e(tag, e.message, e)
            }
            return null
        }

        fun sendAck(pin: String?, id: String) {
            try {
                Log.d(tag, "Service:sendAck:$id")
                pin?.let {
                    sendAsync(
                        Data(
                            code = "A02",
                            status = id,
                            f_pin = it,
                            bodies = mutableMapOf("A18" to id)
                        )
                    )
                }
            } catch (e: Exception) {
                Log.e(tag, e.message, e)
            }
        }

    }

}