package com.framework.mvvm.mv

import android.content.SharedPreferences
import androidx.core.content.edit
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import cn.sagacloud.cadengine.OkhttpUtil
import com.framework.app.IP
import com.framework.app.DEVICE_ID
import com.framework.app.pathDownloadMap
import com.framework.app.timestamp
import com.framework.mvvm.model.db.entity.ObjectEntity
import com.framework.mvvm.model.repository.AdmRepository
import com.framework.mvvm.model.vo.AdmRequest
import com.framework.mvvm.model.vo.FloorInfo
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.SharingStarted.Companion.WhileSubscribed
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json


class AdmViewModel(private val repository: AdmRepository) : ViewModel() {

    /**
     * 请求架构数据
     */
    fun requestFrame(request: AdmRequest) {
        viewModelScope.launch {
            repository.requestFrame(request)
        }
    }

    /**
     * 请求字典数据
     */
    fun requestDict(request: AdmRequest) {
        viewModelScope.launch {
            repository.requestDict(request)
        }
    }

    fun requestFrameAndDict(request: AdmRequest, block: (() -> Unit)? = null) {
        viewModelScope.launch {
            repository.requestFrame(request)
            repository.requestDict(request)
            block?.invoke()
        }
    }
    /* 请求建筑数据

     fun requestBuilding(request: AdmRequest, block: ((Building) -> Unit)? = null) {
         viewModelScope.launch(Dispatchers.IO) {
             repository.requestBuilding(request, block)
             val floors = repository.getFloors()
             floors.forEach {
                 val strInfo = it.strInfos
                 if (!strInfo.isNullOrEmpty() && strInfo.contains("floorMap")) {
                     try {
                         val info = Json.decodeFromString<FloorInfo>(strInfo)
                         val map = info.floorMap
                         val floorMap =
                             OkhttpUtil.getGzipMap("$IP$pathDownloadMap${map!!}")
                         it.floorMap = floorMap
                         repository.updateObject(it)
                     } catch (e: Exception) {
                         println("floor map Exception: $e")
                     }
                 }
             }

             println("floor map over !!!, floors: ${floors.size}")
         }
     }*/

    /**
     * 上传建筑数据
     */
    fun uploadBuilding(block: (() -> Unit)? = null) {
        viewModelScope.launch(Dispatchers.IO) {
            val buildings = repository.getBuildings()
            for (building in buildings) {
                repository.uploadBuilding(building.projectId, building.id)
            }
            withContext(Dispatchers.Main) {
                block?.invoke()
            }
        }
    }

    /**
     *  下载建筑数据
     */
    fun downloadBuilding(sp: SharedPreferences, block: (() -> Unit)? = null) {
        viewModelScope.launch(Dispatchers.IO) {
            val buildings = repository.getBuildings()
            println("downloadBuilding will download : ${buildings.size} $buildings")
            for (building in buildings) {
                repository.requestBuilding(
                    AdmRequest(
                        userId = "bdtp",
                        projectId = building.projectId,
                        groupCode = "BR",
                        buildingId = building.id,
                        uploadFlag = sp.getString(DEVICE_ID, "") ?: "",
                        lastDownloadTime = sp.getString(timestamp, "") ?: ""
                    )
                ) {
                    println("downloadBuilding save buildingId and Timestamp  -> ${it.buildingId}, ${it.timestamp}")
                    sp.edit { putString(it.buildingId, it.timestamp) }
                }
            }

            // 下载地图
            val floors = repository.getFloors()
            floors.forEach {
                val strInfo = it.strInfos
                if (!strInfo.isNullOrEmpty()) {
                    try {
                        val info = Json.decodeFromString<FloorInfo>(strInfo)
                        val map = info.floorMap
                        val floorMap =
                            OkhttpUtil.getGzipMap("$IP$pathDownloadMap${map!!}")
                        it.floorMap = floorMap
                        repository.updateObject(it)
                    } catch (e: Exception) {
                        println("floor map Exception: $e")
                    }
                }
            }

            withContext(Dispatchers.Main) {
                block?.invoke()
            }
        }
    }

    /**
     * 获取建筑数量
     */
    val buildings: StateFlow<List<ObjectEntity>> = flow {
        emit(repository.getBuildings())
    }.stateIn(
        scope = viewModelScope,
        started = WhileSubscribed(5000),
        initialValue = arrayListOf()
    )

    /**
     * 获取本地数据中的建筑信息
     */
    suspend fun getBuildings(): List<ObjectEntity> {
        return repository.getBuildings()
    }
}