package com.lanyun.wanglaotou.viewModel

import android.util.Log
import android.view.View
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.lanyun.common.base.BaseViewModel
import com.lanyun.wanglaotou.App
import com.lanyun.wanglaotou.AppConfig
import com.lanyun.wanglaotou.dao.AppInfo
import com.lanyun.wanglaotou.model.NodeModel
import com.lanyun.wanglaotou.model.UserSubModel
import com.lanyun.wanglaotou.model.VersionModel
import com.lanyun.wanglaotou.public.PageState
import com.lanyun.wanglaotou.util.AngConfigManager
import com.lanyun.wanglaotou.util.AppManagerUtil
import com.lanyun.wanglaotou.util.MmkvManager
import com.tencent.mmkv.MMKV
import kotlinx.coroutines.launch
import rx.android.schedulers.AndroidSchedulers
import rx.schedulers.Schedulers
import java.text.Collator
import java.util.ArrayList
import java.util.HashSet

class PerAppComposeViewModel : BaseViewModel(){


    var viewStates by mutableStateOf(PerAppViewState())
        private set


    private val settingsStorage by lazy { MMKV.mmkvWithID(MmkvManager.ID_SETTING, MMKV.MULTI_PROCESS_MODE) }

    private var appInfoCache :List<AppInfo> = emptyList()

    private var mblacklist: MutableSet<String> = HashSet()


    init {
       dispatch(PerAppViewAction.AppProxy)
    }

    fun dispatch(action: PerAppViewAction) {
        when(action){
            is PerAppViewAction.AppProxy -> getAppProxy()
        }
    }


    private fun getAppProxy() {
        viewStates = viewStates.copy(pageState = PageState.Loading)
       val blacklist = decodeAppProxySet()
        AppManagerUtil.rxLoadNetworkAppList(App.CONTEXT)
        .subscribeOn(Schedulers.io())
            .map {
                if (blacklist != null) {
                    it.forEach { one ->
                        if ((blacklist.contains(one.packageName))) {
                            one.isSelected = 1
                        } else {
                            one.isSelected = 0
                        }
                    }
                    val comparator = Comparator<AppInfo> { p1, p2 ->
                        when {
                            p1.isSelected > p2.isSelected -> -1
                            p1.isSelected == p2.isSelected -> 0
                            else -> 1
                        }
                    }
                    it.sortedWith(comparator)
                } else {
                    val comparator = object : java.util.Comparator<AppInfo> {
                        val collator = Collator.getInstance()
                        override fun compare(o1: AppInfo, o2: AppInfo) = collator.compare(o1.appName, o2.appName)
                    }
                    it.sortedWith(comparator)
                }
            }
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe {
                appInfoCache = it
                mblacklist = if (blacklist == null) HashSet() else HashSet(blacklist)
                viewStates = viewStates.copy(blacklist=mblacklist ,dataList=it, pageState = PageState.Success(it.isEmpty()))
            }

    }


    fun updateSelectIndex(packageName:String,index :Int){
        val inBlacklist: Boolean = mblacklist.contains(packageName)
        if (!inBlacklist){
            mblacklist.add(packageName)
        } else {
            mblacklist.remove(packageName)
        }
        Log.e("修改之前","inBlacklist${inBlacklist}")
        val list = viewStates.dataList.toMutableList()
        val i  = index
        viewModelScope.launch {
            val inBlacklist_Tmp: Boolean = mblacklist.contains(list[i].packageName)
            list[i] = list[i].apply {
                isSelected = if (inBlacklist_Tmp){
                    1
                } else {
                    0
                }
            }
            Log.e("修改之后","inBlacklist_Tmp${inBlacklist_Tmp}")
            viewStates = viewStates.copy(blacklist = mblacklist, selectedIndex = getPosition(packageName), initialChecked = inBlacklist)
        }

    }
    private fun getPosition(gggg: String) : Int {
        val serversCache = viewStates.dataList
        serversCache.forEachIndexed { index, it ->
            if (it.packageName == gggg)
                return index
        }
        return -1
    }

    fun updateProxySet(){
        encodeAppProxySet(viewStates.blacklist)
    }

    private fun  decodeAppProxySet() : Set<String>?{
        return   settingsStorage?.decodeStringSet(AppConfig.PREF_PER_APP_PROXY_SET)
    }

    private fun encodeAppProxySet(v :Set<String>){
        settingsStorage?.encode(AppConfig.PREF_PER_APP_PROXY_SET,v)
    }


    fun decodeAppProxy() : Boolean{
        return settingsStorage?.decodeBool(AppConfig.PREF_PER_APP_PROXY) ?: false
    }
    fun encodeAppProxy(v:Boolean){
        settingsStorage?.encode(AppConfig.PREF_PER_APP_PROXY,v)
    }

    fun decodeBypassApp() : Boolean{
        return settingsStorage?.decodeBool(AppConfig.PREF_BYPASS_APPS) ?: false
    }
    fun encodeBypassApp(v:Boolean){
        settingsStorage?.encode(AppConfig.PREF_BYPASS_APPS,v)
    }

    fun filterProxyApp(content: String): Boolean {
        //viewStates = viewStates.copy(dataList= emptyList())
        val apps = ArrayList<AppInfo>()
        val key = content.uppercase()
        if (key.isNotEmpty()) {
            appInfoCache.forEach {
                if (it.appName.uppercase().indexOf(key) >= 0
                    || it.packageName.uppercase().indexOf(key) >= 0) {
                    apps.add(it)
                }
            }
        } else {
            appInfoCache.forEach {
                apps.add(it)
            }
        }

        viewStates = viewStates.copy(dataList=apps.toMutableList())

        return true
    }

    fun updateData()
    {
        //viewStates = viewStates.copy(dataList= emptyList())
        viewStates = viewStates.copy(dataList=appInfoCache.toMutableList())
    }
}


data class PerAppViewState(
    val dataList: List<AppInfo> = emptyList(),
    val blacklist: MutableSet<String> = HashSet(),
    var selectedIndex:Int = -1,
    val initialChecked: Boolean = false,
    val pageState: PageState = PageState.Loading,
    val listState: LazyListState = LazyListState(),
) {
    val size = dataList.size
    var checked by mutableStateOf(initialChecked)
}

sealed class  PerAppViewAction {
    object AppProxy : PerAppViewAction()
}
