package com.persagy.server.services.objects

import cn.sagacloud.server.datacenter.utils.IdUtils
import cn.sagacloud.server.datacenter.utils.ShaftNameUtil
import com.alibaba.fastjson.JSONObject
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.persagy.base.utils.SJsonUtil
import com.persagy.database.SFilter
import com.persagy.database.SPageQueryInfo
import com.persagy.mybatis.SMybatisDao
import com.persagy.server.datacenter.models.entities.assistant.ShaftFuncType
import com.persagy.server.datacenter.models.entities.assistant.ShaftWithCount
import com.persagy.server.datacenter.models.entities.dict.DataDictionaryDescription
import com.persagy.server.datacenter.models.entities.logs.DataCenterLogs
import com.persagy.server.datacenter.models.entities.objects.*
import com.persagy.server.datacenter.models.entities.rel.*
import com.persagy.server.datacenter.models.entities.task.BuildingDic
import com.persagy.server.datacenter.models.entities.task.FloorDic
import com.persagy.server.services.base.Service
import com.persagy.server.synchronize.MessageHandler
import com.persagy.service.SBaseService
import com.persagy.service.SObjectService
import com.persagy.service.SPageContext
import com.persagy.service.models.enums.SResponseType
import com.persagy.service.models.requests.SQueryRequest
import com.persagy.service.models.responses.SBaseResponse
import com.persagy.service.models.responses.SQueryResponse
import org.slf4j.LoggerFactory
import org.springframework.web.bind.annotation.RequestBody
import java.util.*
import kotlin.collections.ArrayList
import kotlin.collections.HashMap
import kotlin.collections.HashSet

/**
 * 竖井信息服务
 *
 * @author 张维新
 */
object ShaftService : Service<Shaft>(SMybatisDao(Shaft::class.java)) {
    private val logger = LoggerFactory.getLogger(ShaftService::class.java)

    /** 竖井和业务空间关系 */
    var rSh2SpService = SObjectService(SMybatisDao(RSh2Sp::class.java))


    /**
     * 创建之前操作
     *
     * @param   shaft   竖井对象
     */
    override fun onCreateBefore(shaft: Shaft): Boolean  {
        val projectId = SPageContext.getHeader("ProjectId")
        /** 竖井id */
        if (!shaft.id.isNullOrEmpty()) {
            val isWith = shaft.id!!.startsWith("Sh")
            if (!isWith) {
                shaft.id = IdUtils.shaftIdCreate(projectId!!)
            }
        } else {
            shaft.id = IdUtils.shaftIdCreate(projectId!!)
        }
        shaft.projectId = projectId
        if (shaft.name.isNullOrEmpty()) {
            shaft.name = ShaftNameUtil.shaftName("竖井-")
        }
        return true
    } // Function onCreateBefore()

    /**
     * 查询竖井信息-包含统计信息
     *
     * @param       request
     * @return      竖井统计信息
     */
    fun queryWithCount(@RequestBody request: SQueryRequest): SQueryResponse<ShaftWithCount> {
        val service = SBaseService(SMybatisDao(ShaftWithCount::class.java))
        return try {
//            val queryBuilder = service.select(request.filters).filter(SFilter.notNull("id")).filter(SFilter.eq("ProjectId", SPageContext.getHeader("ProjectId")!!))
            val queryBuilder = service.select(request.filters).filter(SFilter.eq("ProjectId", SPageContext.getHeader("ProjectId")!!))
            if (null != request.projection) {
                queryBuilder.projection(request.projection!!)
            }
            if (null != request.orders) {
                queryBuilder.order(request.orders!!)
            }
            val pageInfo = queryBuilder.pageQuery(request.pageNumber, request.pageSize)
            SQueryResponse(pageInfo)
        } catch (e: Exception) {
            e.printStackTrace()
            SQueryResponse(SResponseType.failure, e.message!!)
        }

    } // Function queryWithCount()

    /** 解析 ArrayList<HashMap<String, Any?>> 类型的辅助类*/
    class T {
        val a = ArrayList<HashMap<String, Any?>>()
    }

    /**
     * 查询竖井功能
     *
     * @return      竖井功能列表
     */
    fun queryShaftFuncType(): SQueryResponse<ShaftFuncType> {
//        val service = SBaseService(SMybatisDao(ExplainShaft::class.java))
        val service = SBaseService(SMybatisDao(DataDictionaryDescription::class.java))
        val result = SQueryResponse<ShaftFuncType>()
        result.content = ArrayList()
        return try {
            val projectId = SPageContext.getHeader("ProjectId")
            val entity = service.select(SFilter.eq("type", "Shaft"), SFilter.eq("InfoPointCode", "ShaftFuncType")).entity()
            val listType = ArrayList<ShaftFuncType>()
            // val dataDictionaryMap = SJsonUtil.fromJson<ArrayList<HashMap<String, Any?>>>(entity!!.dataSource!!)
           /** 获取到field类型 获取到泛型类 */
            val t = T()
            val field = t::class.java.getDeclaredField("a")
            val dataDictionaryMap = SJsonUtil.fromJson(entity!!.dataSource!!, field.genericType) as ArrayList<HashMap<String, Any?>>
//            val list = baseDao.select(SFilter.eq("projectId", projectId!!), SFilter.notNull("StructureInfo.ShaftFuncType")).exec()
            val list = baseDao.select("projectId = '$projectId' ").exec()
            if (list.isNotEmpty()) {
                val set = HashSet<String>()
                for (shaft in list) {
                    if (shaft.structureInfo!!["ShaftFuncType"] != null) {
                        val any = shaft.structureInfo!!["ShaftFuncType"].toString()
                        set.add(any)
                    }
                }
                for (str in set) {

                    for (map  in dataDictionaryMap) {
                        val id = map["Code"].toString()
                        val name = map["Name"].toString()
                        if (id == str) {
                            val shaftFuncType = ShaftFuncType()
                            shaftFuncType.id = id
                            shaftFuncType.name = name
                            listType.add(shaftFuncType)
                        }
                    }
                }
            }
//            val shaftFuncTypeList = JSONUtils.parse((service.select(SFilter.eq("type", "Shaft"),SFilter.eq("InfoPointCode", "ShaftFuncType")).entity() )!!.dataSource)
//            val shaftFuncTypeMap = jsonToMap(shaftFuncTypeList as ArrayList<Map<String, String>>)
//            val map = HashMap<String, ShaftFuncType>()
//            for (shaft in list) {
//                if (shaft.structureInfo!!["ShaftFuncType"]!=null&&shaftFuncTypeMap.containsKey(shaft.structureInfo!!["ShaftFuncType"]!!) && !map.containsKey(shaft.structureInfo!!["ShaftFuncType"]!!)) {
//                    val shaftFuncType = ShaftFuncType()
//                    shaftFuncType.id = shaft.structureInfo!!["ShaftFuncType"]!!.toString()
//                    shaftFuncType.name = shaftFuncTypeMap[shaft.structureInfo!!["ShaftFuncType"]!!]!!.toString()
//                    map[shaftFuncType.id!!] = shaftFuncType
//                }
//            }
//            (result.content as ArrayList<ShaftFuncType>).addAll(map.values)
            result.content = listType
            result
        } catch (e: Exception) {
            e.printStackTrace()
            SQueryResponse(SResponseType.failure, e.message!!)
        }
    } // Function queryShaftFuncType()

    private fun jsonToMap(shaftFuncTypeList: ArrayList<Map<String, String>>): Map<String, String> {
        val result = HashMap<String, String>()
        for (map in shaftFuncTypeList) {
            result[map["id"].toString()] = map["name"].toString()
        }
        return result
    }// Function jsonToMap()

    /**
     * 关联元空间
     *
     * @param       request
     * @return      关联反馈
     */
    fun relateSpace(request: RelationSpaceShaft, messageHandler: MessageHandler?): SBaseResponse {
        val failureList = ArrayList<Any>()
        val service = SBaseService(SMybatisDao(RelationSpaceShaft::class.java))
        // 先取消后重新建立
        service.delete("shaftId" to request.shaftId!!)
        return try {
            val projectId = SPageContext.getHeader("ProjectId")
            for (space in request.spaceId!!.split(Regex(","))) {
                val relationSpaceShaft = RelationSpaceShaft()
                relationSpaceShaft.id = UUID.randomUUID().toString()
                relationSpaceShaft.spaceId = space
                relationSpaceShaft.shaftId = request.shaftId
                relationSpaceShaft.projectId = projectId
                if (space.isNotEmpty() && spaceExists(space, failureList)) {
                    service.insert(relationSpaceShaft)
                }
            }
            if (failureList.size == 0) {
                val jsonObject = JSONObject()
                jsonObject["type"] = "8"
                jsonObject["id"] = request.shaftId
                jsonObject["projectId"] = projectId
                jsonObject["description"] = request.spaceId
                /** 发送消息 */
                messageHandler!!.sendMessage(jsonObject.toString())
                SBaseResponse(SResponseType.success)
            } else {
                SBaseResponse(SResponseType.failure, "元空间$failureList" + "不存在")
            }
        } catch (e: Exception) {
            e.printStackTrace()
            SBaseResponse(SResponseType.failure)
        }
    } // Function relateSpace()

    /**
     * 元空间是否存在
     *
     * @param       space       failureList
     * @return      是否存在
     */
    private fun spaceExists(space: String, failureList: ArrayList<Any>): Boolean {
        val service = SBaseService(SMybatisDao(ZoneIspace::class.java))
        val list = service.select(SFilter.eq("RoomID", space)).exec()
        if (list.size > 0) {
            return true
        }
        failureList.add(space)
        return false
    } // Function spaceExists()


    override fun onDeleteBefore(entity: Shaft): Boolean {
        try {
            val  shaft = this.select(SFilter.eq("id", entity.id!!)).entity()

            val projectId = SPageContext.getHeader("ProjectId")
            val coming = SPageContext.getHeader("Coming")
            val account = SPageContext.getHeader("Account")
            /** 日志 */
            val dataCenterLogs = DataCenterLogs()
            dataCenterLogs.id = IdUtils.uuidCreate()
            dataCenterLogs.author = "dataCenter"
            dataCenterLogs.projectId = projectId
            dataCenterLogs.objectType = entity.objectType
            dataCenterLogs.type = "delete"
            dataCenterLogs.account = account
            dataCenterLogs.coming = coming
            dataCenterLogs.objectId = shaft!!.id
            val hashMap = HashMap<String, Any?>()
            hashMap[entity.objectType!!] = shaft
            dataCenterLogs.dataSource = hashMap
            logService.insert(dataCenterLogs)
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return super.onDeleteBefore(entity)
    } // Function onDeleteBefore()


//    /**
//     * 是否已关联元空间
//     *
//     * @param       request
//     * @return      关联反馈
//     */
//    private fun isSpaceRelated(request: RelationSpaceShaft): Boolean {
//        val service = SBaseService(SMybatisDao(RelationSpaceShaft::class.java))
//        val list = service.select(SFilter.eq("spaceId", request.spaceId!!), SFilter.eq("shaftId", request.shaftId!!)).exec()
//        if (list.size > 0) {
//            return true
//        }
//        return false
//    } // Function isSpaceRelated()

    /**
     * 查询没有和当前竖井贯通的竖井
     *
     * @param   shaftId     竖井id
     * @param   request     条件
     */
//    fun unShaftThroughShaft(shaftId: String,@RequestBody request: SQueryRequest): SQueryResponse<Shaft> {
//        return try {
//            val listf = ArrayList<SFilter>()
//            val list = ArrayList<String>()
//            val projectId = SPageContext.getHeader("ProjectId")
//            try {
//                val execList = RShaftThroughShaftService.select(SFilter.eq("shaftId", shaftId), SFilter.eq("projectId", projectId!!)).exec()
//                val execOtherList = RShaftThroughShaftService.select(SFilter.eq("shaftOtherId", shaftId), SFilter.eq("projectId", projectId!!)).exec()
//
//                for (exec in execList){
//                    list.add(exec.shaftOtherId!!)
//                }
//                for (exec in execOtherList){
//                    list.add(exec.shaftId!!)
//                }
//            } catch (e: Exception) {
//                e.printStackTrace()
//            }
//
//            if (list.size>0){
//                listf.add(SFilter.eq("projectId",projectId!!))
//                listf.add(SFilter.not(SFilter.inList("ShaftID",list)))
//            }else{
//
//                listf.add(SFilter.eq("projectId",projectId!!))
//            }
//
//            val pageQuery = ShaftService.pageQuery(request, listf)
//            pageQuery
//        } catch (e: Exception) {
//            e.printStackTrace()
//            SQueryResponse(SResponseType.failure, e.message!!)
//        }
//
//    } // Function unShaftThroughShaft()

    /**
     * 查询和当前竖井有关联的空间
     */
    fun shaftZoneSpaceBaseTable(shaftId: String, request: SQueryRequest): SQueryResponse<ZoneSpace>{
        return try {
            val list = ArrayList<String>()
            val listf = ArrayList<SFilter>()
            val projectId = SPageContext.getHeader("ProjectId")
            val zoneSpaceBaseTableService = SObjectService(SMybatisDao(ZoneSpace::class.java))
            val rShContainSpBaseervice = SObjectService(SMybatisDao(RShContainSpBase::class.java))
            val rShContainSpBaseList = rSh2SpService.select(SFilter.eq("Id1", shaftId), SFilter.eq("projectId", projectId!!)).exec()
            logger.error("空间数量= ${rShContainSpBaseList.size}")
            for (rShContainSpBase in rShContainSpBaseList) {
                list.add(rShContainSpBase.id2!!)
            }
            listf.add(SFilter.eq("projectId", projectId!!))
            if (list.size > 0) {
                listf.add(SFilter.inList("id", list))
            }else{
                listf.add(SFilter.eq("id", ""))
            }
            logger.error("空间数量总= ${list.size}")
            zoneSpaceBaseTableService.pageQuery(request, listf)
        }catch (e: Exception) {
            e.printStackTrace()
            SQueryResponse(SResponseType.failure, e.message.toString())
        }
    } // Fun shaftZoneSpaceBaseTable

    /**
     * 查询和当前竖井没有关联的空间
     */
    fun unShaftZoneSpaceBaseTable(shaftId: String, request: SQueryRequest): SQueryResponse<ZoneSpace>{
        return try {
            val list = ArrayList<String>()
            val listf = ArrayList<SFilter>()
            val projectId = SPageContext.getHeader("ProjectId")
            val zoneSpaceBaseTableService = SObjectService(SMybatisDao(ZoneSpace::class.java))

            val rShContainSpBaseList = rSh2SpService.select(SFilter.eq("Id1", shaftId), SFilter.eq("projectId", projectId!!)).exec()

            for (rShContainSpBase in rShContainSpBaseList) {
                list.add(rShContainSpBase.id2!!)
            }
            listf.add(SFilter.eq("projectId", projectId!!))
            if (list.size > 0) {
                listf.add(SFilter.not(SFilter.inList("id", list)))
            }

            zoneSpaceBaseTableService.pageQuery(request, listf)
        }catch (e: Exception) {
            e.printStackTrace()
            SQueryResponse(SResponseType.failure, "")
        }
    } // Fun unShaftZoneSpaceBaseTable

    /**
     * 查询和当前竖井有关联的业务空间所在建筑及楼层信息
     */
    fun shaftZoneSpaceBaseTableBuilding(shaftId: String,objectType:String?): SQueryResponse<BuildingDic>{
        val pageQuery: SPageQueryInfo<BuildingDic>
        val gson = Gson()
        return try {
            val projectId = SPageContext.getHeader("ProjectId")
            var request = SQueryRequest()
            val service = SBaseService(SMybatisDao(BuildingDic::class.java))
            val queryBuilder = service.select(request.filters)
            queryBuilder.tableName = "public.f_get_building_dic_for_sh2sp('$projectId','$shaftId','$objectType')"
            pageQuery = queryBuilder.pageQuery(1, 1000)
            logger.debug("數據打印*******************************************************************")
            for(floor in pageQuery.content!!){

                if(floor.floorListStr != null){
                    val listStr = floor.floorListStr!!.replace("/\\","")
                    val newStr = "["+listStr.substring(1,listStr.length-1)+"]"
                    val type = object : TypeToken<ArrayList<FloorDic>>() {
                    }.type
                    val siInSpList = gson.fromJson<ArrayList<FloorDic>>(newStr, type)
                    /** 排序处理 */
                    val setId = HashSet<String>()
                    for (floor in siInSpList){
                        setId.add(floor.floorId!!)
                    }
                    val floorLists = ArrayList<FloorDic>()
                    val floorList = FloorService.select(SFilter.inList("id", setId.toList())).order("sequenceId desc").exec()
                    for (floors in floorList){
                        val floorDic = FloorDic()
                        floorDic.floorId = floors.id
                        floorDic.floorLocalName = floors.localName
                        floorDic.floorName = floors.name
                        floorLists.add(floorDic)
                    }
                    floor.floorList = floorLists
                    floor.floorListStr = null
                }
            }
            SQueryResponse(pageQuery)
        }catch (e: Exception) {
            e.printStackTrace()
            SQueryResponse(SResponseType.failure, "")
        }
    } // Fun shaftZoneSpaceBaseTable


    /**
     * 查询没有和当前竖井关联的设备
     *
     * @param  shaftId        竖井id
     */
    fun unShaftEquip(shaftId: String, request: SQueryRequest): SQueryResponse<Equipment>{
        return  try {
            val projectId = SPageContext.getHeader("ProjectId")
            val equipmentService = SObjectService(SMybatisDao(Equipment::class.java))
            val rEqInShService = SObjectService(SMybatisDao(REqInSh::class.java))
            val rSyEqList = rEqInShService.select(SFilter.eq("shaftId", shaftId), SFilter.eq("projectId", projectId!!)).exec()

            val list = ArrayList<String>()
            val listf = ArrayList<SFilter>()
            for (rSyEq in rSyEqList){
                list.add(rSyEq.equipId!!)
            }

            if (list.size>0){
                listf.add(SFilter.eq("projectId", projectId!!))
                listf.add(SFilter.not(SFilter.inList("id", list)))
            }else{
                listf.add(SFilter.eq("projectId", projectId!!))
            }

            equipmentService.pageQuery(request,listf)
        } catch (e: Exception) {
            e.printStackTrace()
            SQueryResponse(SResponseType.failure, "")
        }
    } // Fun unShaftEquip

    /**
     * 查询没有和当前竖井关联的设备
     *
     * @param  shaftId        竖井id
     */
    fun unShaftOtherShaft(shaftId: String, request: SQueryRequest): SQueryResponse<Shaft>{
        return  try {
            val projectId = SPageContext.getHeader("ProjectId")
            val rShaftThroughShaftService = SObjectService(SMybatisDao(RShaftThroughShaft::class.java))
            val rShaftThroughShaftList = rShaftThroughShaftService.select(SFilter.eq("shaftId", shaftId), SFilter.eq("projectId", projectId!!)).exec()

            val list = ArrayList<String>()
            val listf = ArrayList<SFilter>()
            for (rShaftThroughShaft in rShaftThroughShaftList){
                list.add(rShaftThroughShaft.shaftOtherId!!)
            }

            if (list.size>0){
                listf.add(SFilter.eq("projectId", projectId!!))
                listf.add(SFilter.not(SFilter.inList("id", list)))
            }else{
                listf.add(SFilter.eq("projectId", projectId!!))
            }

            ShaftService.pageQuery(request,listf)
        } catch (e: Exception) {
            e.printStackTrace()
            SQueryResponse(SResponseType.failure, "")
        }
    } // Fun unShaftOtherShaft

    /**
     * 查询没有和当前竖井关联的系统
     *
     * @param  shaftId        竖井id
     */
    fun unShaftSys(shaftId: String, request: SQueryRequest): SQueryResponse<GeneralSystem>{
        return  try {
            val projectId = SPageContext.getHeader("ProjectId")
            val generalSystemService = SObjectService(SMybatisDao(GeneralSystem::class.java))
            val rSyInShService = SObjectService(SMybatisDao(RSyInSh::class.java))
            val rSyInShList = rSyInShService.select(SFilter.eq("shaftId", shaftId), SFilter.eq("projectId", projectId!!)).exec()

            val list = ArrayList<String>()
            val listf = ArrayList<SFilter>()
            for (rSyInSh in rSyInShList){
                list.add(rSyInSh.sysId!!)
            }

            if (list.size>0){
                listf.add(SFilter.eq("projectId", projectId!!))
                listf.add(SFilter.not(SFilter.inList("id", list)))
            }else{
                listf.add(SFilter.eq("projectId", projectId!!))
            }

            generalSystemService.pageQuery(request,listf)
        } catch (e: Exception) {
            e.printStackTrace()
            SQueryResponse(SResponseType.failure, "")
        }
    } // Fun unShaftSys

} // Object ShaftService