package com.base.browserwhite.help

import com.base.browserwhite.BuildConfig
import com.base.browserwhite.bean.NewsBean
import com.base.browserwhite.utils.AppPreferences
import com.base.browserwhite.utils.LogEx
import com.google.gson.Gson
import com.google.gson.JsonParser
import com.google.gson.reflect.TypeToken
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import okhttp3.Call
import okhttp3.Callback
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.Response
import okhttp3.logging.HttpLoggingInterceptor
import org.json.JSONObject
import java.io.IOException
import java.lang.reflect.Type
import java.util.concurrent.TimeUnit


object NewsUtils {
    private val TAG = "NewsUtils"

    private val url by lazy {
        val pkg = ConfigHelper.packageName
        val pkgSubString = pkg.filter { it.isLowerCase() }.substring(4, 9)
        val url = StringBuilder("${ConfigHelper.apiUrl}/${pkgSubString}ne")
        url.append("?pkg=$pkg")
        url.toString()
    }

    fun requestNews(
        categoryId: Int = 0,
        pageNumber: Long? = null,
        errorCallBack: (() -> Unit)? = null,
        beanCallBack: (beanList: List<NewsBean>) -> Unit
    ) {
        val pkg = ConfigHelper.packageName
        val s = JSONObject()

        s.put("categoryId", categoryId)
        pageNumber?.let {
            s.put("pageNumber", pageNumber)
        }

        val s2 = JSONObject()
            .put("${pkg}_3", AppPreferences.getInstance().getString("Equipment", ""))
            .put("${pkg}_4", AppPreferences.getInstance().getString("Manufacturer", ""))
            .put("${pkg}_5", AppPreferences.getInstance().getString("svn", ""))
            .put("${pkg}_8", BuildConfig.VERSION_NAME)
            .put("${pkg}_9", AppPreferences.getInstance().getString("uuid", ""))
            .put("${pkg}_10", AppPreferences.getInstance().getString("gid", ""))
            .put("${pkg}_13", "android")
            .put("${pkg}_14", BuildConfig.VERSION_CODE)
            .put("${pkg}_15", "google")
            .put("${pkg}_24", BuildConfig.BUILD_TYPE)

        val data = JSONObject()
            .put("data", s)
            .put("bp", s2)
            .toString()

        val body = AESHelper.encrypt(data)
            .toRequestBody("application/json;charset=utf-8".toMediaTypeOrNull())

        val client = OkHttpClient.Builder().apply {
            if (BuildConfig.DEBUG) {
                addInterceptor(HttpLoggingInterceptor().apply {
                    level = HttpLoggingInterceptor.Level.BODY
                })
            }
        }.build()

        val request = Request.Builder()
            .url(url)
            .post(body)
            .build()

        CoroutineScope(Dispatchers.IO).launch {
            client.newCall(request).enqueue(object : Callback {
                override fun onFailure(call: Call, e: IOException) {
                    LogEx.logDebug(TAG, "onFailure $e")
                    errorCallBack?.invoke()
                }

                override fun onResponse(call: Call, response: Response) {
                    response.body?.string()?.let {
                        LogEx.logDebug(TAG, "NewsUtils it=$it")
                        val dataJson = getDataJson(it)
                        LogEx.logDebug(TAG, "dataJson dataJson=$dataJson")
                        val list = parseNewsBean(dataJson)
                        LogEx.logDebug(TAG, "${list.size}")
                        beanCallBack.invoke(list)
                    }
                }
            })
        }

    }

    fun getNews(): List<NewsBean>? {
        val pkg = ConfigHelper.packageName
        val s = JSONObject()

        s.put("categoryId", 0)
        val s2 = JSONObject()
            .put("${pkg}_3", AppPreferences.getInstance().getString("Equipment", ""))
            .put("${pkg}_4", AppPreferences.getInstance().getString("Manufacturer", ""))
            .put("${pkg}_5", AppPreferences.getInstance().getString("svn", ""))
            .put("${pkg}_8", BuildConfig.VERSION_NAME)
            .put("${pkg}_9", AppPreferences.getInstance().getString("uuid", ""))
            .put("${pkg}_10", AppPreferences.getInstance().getString("gid", ""))
            .put("${pkg}_13", "android")
            .put("${pkg}_14", BuildConfig.VERSION_CODE)
            .put("${pkg}_15", "google")
            .put("${pkg}_24", BuildConfig.BUILD_TYPE)

        val data = JSONObject()
            .put("data", s)
            .put("bp", s2)
            .toString()

        val body = AESHelper.encrypt(data)
            .toRequestBody("application/json;charset=utf-8".toMediaTypeOrNull())

        val client = OkHttpClient.Builder()
            .apply {
                if (BuildConfig.DEBUG) {
                    addInterceptor(HttpLoggingInterceptor().apply {
                        level = HttpLoggingInterceptor.Level.BODY
                    })
                }
                connectTimeout(10, TimeUnit.SECONDS)
                readTimeout(20, TimeUnit.SECONDS)
                writeTimeout(15, TimeUnit.SECONDS)
            }.build()

        val request = Request.Builder()
            .url(url)
            .post(body)
            .build()

        val response = client.newCall(request).execute()
        response.body?.string()?.let {
            LogEx.logDebug(TAG, "NewsUtils it=$it")
            val dataJson = getDataJson(it)
            LogEx.logDebug(TAG, "dataJson dataJson=$dataJson")
            val list = parseNewsBean(dataJson)
            LogEx.logDebug(TAG, "${list.size}")
            return list
        }
        return null
    }

    private fun getDataJson(jsonString: String): String {
        val jsonRootObject = JsonParser.parseString(jsonString).getAsJsonObject()
        return jsonRootObject["result"].getAsJsonObject()["data"].toString()
    }

    private fun parseNewsBean(jsonString: String): List<NewsBean> {
        val newsBeanListType: Type = object : TypeToken<List<NewsBean>>() {}.type
        return Gson().fromJson(jsonString, newsBeanListType)
    }


}