package com.framework.mvvm.model.repository

import android.util.Log
import androidx.lifecycle.LiveData
import com.framework.app.api.Api
import com.framework.app.base.IRepository
import com.framework.mvvm.model.data.Data
import com.framework.mvvm.model.data.dataSource
import com.framework.mvvm.model.data.request
import com.framework.mvvm.model.db.AdmDatabase
import com.framework.mvvm.model.db.entity.*
import com.framework.mvvm.model.vo.AdmRequest

class AdmRepository(
    private val api: Api,
    private val db: AdmDatabase
) : IRepository {

    fun getProjects(request: AdmRequest): LiveData<Data<List<ProjectEntity>>> {
        return dataSource(
            fromDb = { db.projectDao().getProjects() },
            fromNt = { request { api.getFrame(request) } },
            isFromNt = { true },
            onSuccess = { frame ->
                val projects = frame.projects
                val bafs = frame.buildingsAndFloors
                try {
                    db.projectDao().insProject(projects)
                    db.objectDao().insObjects(bafs)
                } catch (e: Exception) {
                    Log.d("IRepository:${AdmRepository::class.simpleName}", e.message!!)
                }
            },
            onFailure = {
                println("onFailure: ${it.msg}")
            }
        )
    }

    fun getProjects(): LiveData<List<ProjectEntity>> {
        return db.projectDao().getProjects()
    }

    suspend fun insProject(projects: List<ProjectEntity>) {
        return db.projectDao().insProject(projects)
    }

    suspend fun insProblem(problem: ProblemArchEntity) {
        return db.problemArchDao().insProblem(problem)
    }

    suspend fun getProblem(): List<ProblemArchEntity> {
        return db.problemArchDao().getProblems()
    }

    suspend fun getProblemById(id: String): ProblemArchEntity {
        return db.problemArchDao().getProblemById(id)
    }

    suspend fun insFile(file: FileEntity) {
        return db.fileDao().insFile(file)
    }

    suspend fun getRefFile(refId: String): List<FileEntity> {
        return db.fileDao().getFileByRefId(refId)
    }

    suspend fun insQrcode(qrcode: QrCodeEntity) {
        return db.qrCodeDao().insQrCode(qrcode)
    }

    suspend fun getQrcode(objId: String): List<QrCodeEntity> {
        return db.qrCodeDao().getQrCodeByObjId(objId)
    }

    suspend fun getInfosConfigByObjType(type: String): List<InfosConfigEntity> {
        return db.infosConfigDao().getConfigByObjType(type)
    }

    suspend fun insObject(`object`: ObjectEntity) {
        return db.objectDao().insObject(`object`)
    }

    suspend fun getObject(objId: String): ObjectEntity {
        return db.objectDao().getObjectById(objId)
    }

    suspend fun getSpaceByArchStateFloorId(id: String, archState: String): List<SpaceEntity> {
        return db.spaceDao().getSpaceByArchStateFloorId(id, archState)
    }

    suspend fun getSpaceByEquipStateFloorId(id: String, equipState: String): List<SpaceEntity> {
        return db.spaceDao().getSpaceByEquipStateFloorId(id, equipState)
    }

    suspend fun getBuildByObjType(objType: String): List<ObjectEntity> {
        return db.objectDao().getObjectByObjType(objType)
    }

    suspend fun getFloorByBuildingId(buildingId: String, type: String): List<ObjectEntity> {
        return db.objectDao().getObjectByBuildingId(buildingId, type)
    }

    suspend fun getSpaceBySpaceId(id: String): SpaceEntity {
        return db.spaceDao().getSpaceBySpaceId(id)
    }

    suspend fun insSpace(space: SpaceEntity) {
        return db.spaceDao().insSpace(space)
    }

    /**
     * 请求框架数据
     */
    suspend fun requestFrame(request: AdmRequest) {
        request(
            from = { api.getFrame(request) },
            to = { frame ->
                println("frame: $frame")
                val projects = frame.projects
                val objects = frame.buildingsAndFloors
                try {
                    db.projectDao().insProject(projects)
                    db.objectDao().insObjects(objects)
                } catch (e: Exception) {
                    Log.d("IRepository:${AdmRepository::class.simpleName}", e.message!!)
                }
            },
            error = {
                Log.d("requestFrame error: ", it)
            }
        )
    }

    /**
     * 请求字典数据
     */
    suspend fun requestDict(request: AdmRequest) {
        request(
            from = { api.getDict(request) },
            to = { dict ->
                val pipeConfig = dict.pipeConfig
                val infosConfig = dict.infosConfig
                val config = dict.config
                val m2dTypes = dict.m2dTypes
                val relConfig = dict.relConfig
                val system = dict.dict.system
                val equipment = dict.dict.equipment
                val relation = dict.dict.relation
                val major = dict.dict.major

                try {
                    db.pipeConfigDao().insConfigs(pipeConfig)
                    db.infosConfigDao().insConfigs(infosConfig)
                    db.configDao().insConfigs(config)
                    db.m2dEquipDao().insM2ds(m2dTypes)
                    db.relConfigDao().insConfigs(relConfig)
                    db.systemDao().insSystems(system)
                    db.equipmentDao().insEquipments(equipment)
                    db.relationDictDao().insRelationDicts(relation)
                    db.majorDao().insMajors(major)
                } catch (e: Exception) {
                    Log.d("requestDict", e.message!!)
                }
            },
            error = { println("error:$it") }
        )
    }

    /**
     * 请求建筑数据
     */
    suspend fun requestBuilding(request: AdmRequest) {
        request(
            from = { api.getBuilding(request) },
            to = { building ->
                val file = building.file
                val space = building.jobSpace
                val objects = building.objects
                val problemArch = building.problemArch
                val problemEquip = building.problemEquip
                val qrCode = building.qrCode
                val relations = building.relations

                try {
                    db.fileDao().insFiles(file)
                    db.spaceDao().insSpaces(space)
                    db.objectDao().insObjects(objects)
                    db.problemArchDao().insProblems(problemArch)
                    db.problemEquipDao().insProblems(problemEquip)
                    db.qrCodeDao().insQrCodes(qrCode)
                    db.relationDao().insRelations(relations)
                } catch (e: Exception) {
                    Log.d(
                        "FrameRepositoryFrameRepository",
                        e.message ?: "requestBuilding has error"
                    )
                }
            }
        )
    }

    /**
     * 返回楼层
     */
    suspend fun getFloors(): List<ObjectEntity> {
        return db.objectDao().getFloors()
    }

    /**
     * 更新 ObjectEntity
     */
    suspend fun upObject(obj: ObjectEntity) {
        db.objectDao().upObject(obj)
    }
}