package com.offline.music.task.player

import android.app.Application
import android.content.Context
import com.offline.music.task.player.db.bean.Audio
import com.offline.music.task.player.db.bean.CurrentPlayingAudio
import com.offline.music.task.player.db.bean.ResourcesList
import com.offline.music.task.player.db.tools.CurrentAudioManager
import com.offline.music.task.player.db.tools.DatabaseManager
import com.offline.music.task.player.tools.media.MediaControllerManager
import com.offline.music.task.player.tools.util.parseResources
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.BufferedReader
import java.io.InputStreamReader

class ProApp : Application() {
    companion object {
        lateinit var appContext: Context
        lateinit var proApp: ProApp
            private set
        lateinit var currentAudioManager: CurrentAudioManager
            private set
        lateinit var databaseManager: DatabaseManager
            private set
        var currentPlayingAudio: CurrentPlayingAudio? = null
            private set
        lateinit var importList: List<Audio>
            private set
        lateinit var resourcesList: ResourcesList
            private set

        lateinit var realHumanVoiceList: List<Audio>
            private set

        lateinit var soundsOfAppliancesList: List<Audio>
            private set

        lateinit var soundsOfNatureList: List<Audio>
            private set

        private var isInitialized = false

        fun initialize(context: Context) {
            if (!isInitialized) {
                val jsonString = readAssetsFile(context)
                resourcesList = parseResources(context, jsonString)
                splitResourcesList()
                isInitialized = true
            }
        }

        fun initCurrentPlayingAudio() {
            CoroutineScope(Dispatchers.IO).launch {
                currentPlayingAudio = currentAudioManager.getCurrentPlayingAudio()
            }
        }

        fun initImportAudio(callback: (List<Audio>) -> Unit = {}) {
            CoroutineScope(Dispatchers.IO).launch {
                importList = databaseManager.getAllAudioFiles()
                withContext(Dispatchers.Main) {
                    callback(importList)
                }
            }
        }

        private fun readAssetsFile(context: Context): String {
            val assetManager = context.assets
            val inputStream = assetManager.open("resources.json")
            val bufferedReader = BufferedReader(InputStreamReader(inputStream))
            val stringBuilder = StringBuilder()
            var line: String?
            while (bufferedReader.readLine().also { line = it } != null) {
                stringBuilder.append(line)
            }
            return stringBuilder.toString()
        }

        private fun splitResourcesList() {
            realHumanVoiceList = mutableListOf()
            soundsOfAppliancesList = mutableListOf()
            soundsOfNatureList = mutableListOf()

            for (category in resourcesList.categories) {
                when (category.name) {
                    "Sound of instrument" -> realHumanVoiceList = category.audios
                    "White noise" -> soundsOfAppliancesList = category.audios
                    "Voice of Nature" -> soundsOfNatureList = category.audios
                }
            }
        }
    }

    override fun onCreate() {
        super.onCreate()
        proApp = this
        appContext = this
        initialize(this)
        MediaControllerManager.init(this)
        currentAudioManager = CurrentAudioManager.getInstance(this)
        databaseManager = DatabaseManager.getInstance(this)
        initCurrentPlayingAudio()
        initImportAudio()
    }

}