package com.keyboard.journey.util

import com.keyboard.journey.bean.Author
import com.keyboard.journey.bean.CategoryDataBean
import com.keyboard.journey.bean.Content
import com.keyboard.journey.bean.DetailsBean
import com.keyboard.journey.bean.ItemDataBean
import com.keyboard.journey.bean.LockBean
import com.keyboard.journey.bean.MainDataBean
import com.keyboard.journey.bean.MainItemDataBean
import com.keyboard.journey.bean.ThemeContentBean
import com.keyboard.journey.bean.ThemeDetailsContent
import okhttp3.Call
import okhttp3.Callback
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import org.json.JSONArray
import org.json.JSONObject
import java.io.IOException

interface NetworkCallback<T> {
    fun onSuccess(data: T)
    fun onFailure(errorMessage: String)
}

class NetworkUtil {
    companion object {
        private const val HEADER_AGENT = "User-Agent"
        private const val HEADER_KEY = "User-Key"
        private const val HEADER_KEY_VALUE =
            "f_M2HePkT1-XKO1y9MsJzt:APA91bG_JRru9-AuBlcAE7TwyhQf4POchj2nHGH6dqsL4nZd-2HhyMzZe1eIVy9TBCMG3avCVUYxj4dcN5FgbTv4_LGV-mAtb4x-FEMLztx79vySuH5gpBV7SdPCeBsB-4NmS5OElFwe"
        private const val GET_MAIN_URL = "https://backend-wallpaper.kika-backend.com/v1/api/theme/"
        private const val GET_CATEGORY_URL =
            GET_MAIN_URL + "page/kbtheme_main?offset=0&fetch_size=100&sign=a28aadc61c76c754944f6ddb48962c9c"
        private const val GET_CATEGORY_DETAILS_URL =
            GET_MAIN_URL + "category/"
        private const val GET_DETAILS_URL =
            GET_MAIN_URL + "resource/"

        private val HEADER_AGENT_VALUE =
            "com.ikeyboard.theme.neon.love/200 (2102cf82e4624c3bb94f30359139b1d4/d7b10839af1ba26bc4b64881501e6df0) Country/US Language/en System/android Version/${33} Screen/${560}"
    }

    private val client = OkHttpClient()

    fun fetchData(callback: NetworkCallback<List<MainDataBean>>) {
        val request = Request.Builder()
            .url(GET_CATEGORY_URL)
            .get()
            .addHeader(HEADER_KEY, HEADER_KEY_VALUE)
            .addHeader(HEADER_AGENT, HEADER_AGENT_VALUE)
            .build()

        client.newCall(request).enqueue(object : Callback {
            override fun onResponse(call: Call, response: Response) {
                if (response.isSuccessful) {
                    val jsonData = response.body?.string()
                    jsonData?.let {
                        val resultObj = JSONObject(it)
                        if (resultObj.optBoolean("success")) {
                            val dataObj = resultObj.optJSONObject("data")
                            dataObj?.let {
                                val sectionsArray = dataObj.optJSONArray("sections")
                                sectionsArray?.let {
                                    callback.onSuccess(parseMainDataList(sectionsArray))
                                } ?: callback.onFailure("sections array null")
                            } ?: callback.onFailure("Empty Data ")
                        } else {
                            callback.onFailure("success != true")
                        }
                    } ?: callback.onFailure("Empty response body")
                } else {
                    callback.onFailure("Error: ${response.code}")
                }
            }

            override fun onFailure(call: Call, e: IOException) {
                callback.onFailure("Exception: ${e.message}")
            }
        })
    }

    private fun parseMainDataList(jsonArray: JSONArray): List<MainDataBean> {
        val list = mutableListOf<MainDataBean>()

        for (i in 0 until jsonArray.length()) {
            val jsonObject = jsonArray.getJSONObject(i)
            val mainDataBean = MainDataBean(
                jsonObject.getInt("layout"),
                jsonObject.getInt("grid"),
                jsonObject.getInt("type"),
                jsonObject.getString("title"),
                jsonObject.getString("key"),
                parseMainItemDataBean(jsonObject.optJSONArray("items"))
            )
            list.add(mainDataBean)
        }
        return list
    }

    private fun parseMainItemDataBean(jsonArray: JSONArray): MainItemDataBean {
        val list = mutableListOf<MainItemDataBean>()
        for (i in 0 until jsonArray.length()) {
            val jsonObject = jsonArray.getJSONObject(i)
            list.add(
                MainItemDataBean(
                    jsonObject.optString("key"),
                    jsonObject.optString("title"),
                    jsonObject.optInt("type"),
                    jsonObject.optString("thumbUrl")
                )
            )
        }
        return list[0]
    }


    fun fetchCategory(
        key: String,
        offset: Int,
        pageSize: Int,
        callback: NetworkCallback<List<CategoryDataBean>>
    ) {
        val request = Request.Builder()
            .url(GET_CATEGORY_DETAILS_URL + "${key}/resources?offset=${offset}&pageSize=${pageSize}&sign=a28aadc61c76c754944f6ddb48962c9c")
            .get()
            .addHeader(HEADER_KEY, HEADER_KEY_VALUE)
            .addHeader(HEADER_AGENT, HEADER_AGENT_VALUE)
            .build()

        client.newCall(request).enqueue(object : Callback {
            override fun onResponse(call: Call, response: Response) {
                if (response.isSuccessful) {
                    val jsonData = response.body?.string()
                    jsonData?.let {
                        val resultObj = JSONObject(it)
                        if (resultObj.optBoolean("success")) {
                            val dataObj = resultObj.optJSONObject("data")
                            dataObj?.let {
                                val sectionsArray = dataObj.optJSONArray("sections")
                                sectionsArray?.let {
                                    callback.onSuccess(parseCategoryDataBeanList(sectionsArray))
                                } ?: callback.onFailure("sections array null")
                            } ?: callback.onFailure("Empty Data ")
                        } else {
                            callback.onFailure("success != true")
                        }
                    } ?: callback.onFailure("Empty response body")
                } else {
                    callback.onFailure("Error: ${response.code}")
                }
            }

            override fun onFailure(call: Call, e: IOException) {
                callback.onFailure("Exception: ${e.message}")
            }
        })
    }

    private fun parseCategoryDataBeanList(jsonArray: JSONArray): List<CategoryDataBean> {
        val sectionsList = mutableListOf<CategoryDataBean>()

        for (i in 0 until jsonArray.length()) {
            val sectionObj = jsonArray.getJSONObject(i)
            val layout = sectionObj.getInt("layout")
            val grid = sectionObj.getInt("grid")
            val type = sectionObj.getInt("type")
            val sectionTitle = sectionObj.getString("title")
            val sectionKey = sectionObj.getString("key")

            val itemsArray = sectionObj.getJSONArray("items")
            val itemsList = mutableListOf<ItemDataBean>()

            for (j in 0 until itemsArray.length()) {
                val itemObj = itemsArray.getJSONObject(j)
                val itemKey = itemObj.getString("key")
                val itemTitle = itemObj.getString("title")
                val itemType = itemObj.getInt("type")
                val thumbUrl = itemObj.getString("thumbUrl")
                val thumbUrlGif = itemObj.getString("thumbUrlGif")

                val themeContentObj = itemObj.getJSONObject("themeContent")
                val pushIcon = themeContentObj.getString("pushIcon")
                val themeContent = ThemeContentBean(pushIcon)

                val lockObj = itemObj.getJSONObject("lock")
                val lockType = lockObj.getInt("type")
                val lock = LockBean(lockType)

                val item = ItemDataBean(
                    itemKey,
                    itemTitle,
                    itemType,
                    thumbUrl,
                    thumbUrlGif,
                    themeContent,
                    lock
                )
                itemsList.add(item)
            }

            val section = CategoryDataBean(layout, grid, type, sectionTitle, sectionKey, itemsList)
            sectionsList.add(section)
        }
        return sectionsList
    }

    fun getResourceRequest(
        key: String,
        callback: NetworkCallback<DetailsBean>
    ) {

        val request = Request.Builder()
            .url("$GET_DETAILS_URL$key?sign=a28aadc61c76c754944f6ddb48962c9c")
            .get()
            .addHeader(HEADER_KEY, HEADER_KEY_VALUE)
            .addHeader(HEADER_AGENT, HEADER_AGENT_VALUE)
            .build()

        client.newCall(request).enqueue(object : Callback {
            override fun onResponse(call: Call, response: Response) {
                if (response.isSuccessful) {
                    val jsonData = response.body?.string()
                    jsonData?.let {
                        val resultObj = JSONObject(it)
                        if (resultObj.optBoolean("success")) {
                            val dataObject = resultObj.getJSONObject("data")
                            val itemObject = dataObject.getJSONObject("item")
                            callback.onSuccess(parseDetailsBean(itemObject))
                        } else {
                            callback.onFailure("success != true")
                        }
                    } ?: callback.onFailure("Empty response body")
                } else {
                    callback.onFailure("Error: ${response.code}")
                }
            }

            override fun onFailure(call: Call, e: IOException) {
                callback.onFailure("Exception: ${e.message}")
            }
        })
    }

    private fun parseDetailsBean(itemObject: JSONObject): DetailsBean {
        val key = itemObject.getString("key")
        val title = itemObject.getString("title")
        val type = itemObject.getInt("type")
        val thumbUrl = itemObject.getString("thumbUrl")
        val pkgName = itemObject.getString("pkgName")
        val thumbUrlGif = itemObject.optString("thumbUrlGif")

        val contentObject = itemObject.getJSONObject("content")
        val imageUrl = contentObject.getString("imageUrl")

        val themeContentObject = itemObject.getJSONObject("themeContent")
        val img = themeContentObject.getString("img")
        val imgBanner = themeContentObject.getString("imgBanner")
        val pushIcon = themeContentObject.getString("pushIcon")
        val pushBanner = themeContentObject.getString("pushBanner")
        val androidRawZipUrl = themeContentObject.getString("androidRawZipUrl")

        val authorObject = itemObject.getJSONObject("author")
        val authorName = authorObject.getString("name")
        val authorKey = authorObject.getString("key")
        val photoUrl = authorObject.getString("photoUrl")
        val homeUrl = authorObject.getString("homeUrl")

        val lockObject = itemObject.getJSONObject("lock")
        val lockType = lockObject.getInt("type")

        return DetailsBean(
            key,
            title,
            type,
            thumbUrl,
            pkgName,
            thumbUrlGif,
            Content(imageUrl),
            ThemeDetailsContent(img, imgBanner, "", pushIcon, pushBanner, androidRawZipUrl, ""),
            Author(authorName, authorKey, photoUrl, homeUrl),
            LockBean(lockType)
        )
    }
}