/*
 * *********************************************************************************************************************
 *
 *          !!
 *        .F88X
 *        X8888Y
 *      .}888888N;
 *        i888888N;        .:!              .I$WI:
 *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
 *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
 *            +888888N;  .8888888Y                                  "&&8Y.}8,
 *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
 *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
 *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
 *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
 *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
 *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
 *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
 *      .:R888888I
 *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
 *        ~8888'
 *        .!88~                                                                     All rights reserved.
 *
 * *********************************************************************************************************************
 */

package com.persagy.server.service

import com.persagy.server.dao.mappers.CustomSql
import com.persagy.server.datacenter.models.entities.dictnew.DefClass
import com.persagy.server.models.EquipDictStatistics
import com.persagy.server.models.GatherInfoPoint
import com.persagy.server.models.InfoPoint
import com.persagy.server.models.objects.FloorCompon
import com.persagy.service.SPageContext
import com.persagy.service.models.enums.SResponseType
import com.persagy.service.models.responses.SQueryResponse
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service

/**
 * 自定义sql  服务
 */
@Service
class CustomSqlService {

    /** 自定义查询 */
    @Autowired
    lateinit var mapper: CustomSql

    companion object {
        // 日志
        private val logger = LoggerFactory.getLogger(CustomSqlService::class.java)
    } // Companion object

    /**
     * 查询数据中心未转换到物理世界的数据
     */
    fun dataCenter(projectId: String): ArrayList<EquipDictStatistics>{

        var datacenter= ArrayList<EquipDictStatistics>()
        try {
            datacenter = mapper.datacenter(projectId!!)
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return datacenter
    } //

    /**
     * 查询物理世界未转换到数据中心的数据
     */
    fun dataPlatfrom(projectId: String): ArrayList<EquipDictStatistics>{

        var datacenter= ArrayList<EquipDictStatistics>()
        try {
            datacenter = mapper.dataplatfrom(projectId!!)
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return datacenter
    } //

    /**
     * 租户的建筑楼层
     */
    fun tenantBuildingFloor(projectId: String,objectType: String,tenantId: String): ArrayList<FloorCompon>{
        var floorCounts = ArrayList<FloorCompon>()
        try {
            floorCounts = mapper.floorCounts(projectId, objectType, tenantId)
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return  floorCounts
    } //


    /**
     * 统计设备信息点与总数据占比
     */
    fun infoPoints(): SQueryResponse<InfoPoint> {
        return try {
            val projectId =  SPageContext.getHeader("projectId").toString()
            //项目中所有自定义信息点编码
            var projectCustomInforPoints=mapper.projectCustomInforPoints(projectId!!)
            //项目下所有动态信息点编码
            var dynamicInfoPointCodes=mapper.dynamicInfoPointCodes(projectId!!)
            //项目下所有静态信息点编码
            var staticInfoPointCodes=mapper.staticInfoPointCodes(projectId!!)
            //项目下所有的设备
            val projectEquipment =mapper.projectEquipment(projectId!!)

            var hashMap=calculate(dynamicInfoPointCodes,staticInfoPointCodes,projectCustomInforPoints,projectEquipment,0)

            var infoPoint = InfoPoint()
          infoPoint.customInfoPointCounts=mapper.customInfoPointCounts(projectId!!)
          infoPoint.customInfoPoint=hashMap["customInfoPoint"]
          infoPoint.dynamicInfoPointCounts=mapper.dynamicInfoPointCounts()
          infoPoint.dynamicInfoPoint=hashMap["dynamicInfoPoint"]
          infoPoint.staticInfoPointCounts=mapper.staticInfoPointCounts()
          infoPoint.staticInfoPoint=hashMap["staticInfoPoint"]
            val list = ArrayList<InfoPoint>()
            val sQueryResponse = SQueryResponse<InfoPoint>(SResponseType.success)
            list.add(infoPoint)
            sQueryResponse.content = list
                sQueryResponse
        } catch ( e: Exception){
            e.printStackTrace()
            SQueryResponse(SResponseType.failure)
        }
    }


    /**
     * 统计设备信息点与需采集数据占比
     */
    fun gatherInfoPoints(): SQueryResponse<GatherInfoPoint> {
        return try {
            val projectId =  SPageContext.getHeader("projectId").toString()
            //自定义信息点
            var customInfoPointCounts=mapper.customInfoPointCounts(projectId)
            //数字字典信息点总数
            var controlInfoCounts=mapper.controlInfoCounts()

            //项目下所有已采集自定义信息点编码
            var gatherCustomInforPointCode=mapper.gatherCustomInforPointCode(projectId)
            //项目下所有已采集的动态信息点编码
            var gatherDynamicInfoCode=mapper.gatherDynamicInfoCode(projectId)
            //项目下所有已采集静态信息点编码
            var gatherStaticInfoCode=mapper.gatherStaticInfoCode(projectId)

            //项目下所有的设备
            var projectEquipment=mapper.projectEquipment(projectId)

            var hashMap=calculate(gatherDynamicInfoCode,gatherStaticInfoCode,gatherCustomInforPointCode,projectEquipment,0)

            var gatherInfoPoint=GatherInfoPoint()
            gatherInfoPoint.gatherInfoPointCounts=customInfoPointCounts+controlInfoCounts
            gatherInfoPoint.gatherCustomInfoPointCounts=hashMap["customInfoPoint"]
            gatherInfoPoint.gatherDynamicInfoPointCounts=hashMap["dynamicInfoPoint"]
            gatherInfoPoint.gatherStaticInfoPointCounts=hashMap["staticInfoPoint"]

            var list=ArrayList<GatherInfoPoint>()
            val sQueryResponse = SQueryResponse<GatherInfoPoint>(SResponseType.success)
            list.add(gatherInfoPoint)
            sQueryResponse.content = list
            sQueryResponse
        } catch ( e: Exception){
            e.printStackTrace()
            SQueryResponse(SResponseType.failure)
        }
    }


    /**
     * 统计系统信息点与需采集数据占比
     */
    fun systemInfoPoins():SQueryResponse<GatherInfoPoint>{
        return try {
            val projectId =  SPageContext.getHeader("projectId").toString()
            //系统  数字字典信息点总数
            var systemControlInfoCounts=mapper.systemControlInfoCounts()
            //系统 项目下自定义信息点总数
            var systemCustomInfoCounts=mapper.systemCustomInfoCounts(projectId)

            //系统  已采集动态信息点编码
            var systemDynamicInfoCode=mapper.systemDynamicInfoCode()
            //系统 已采集静态信息点编码
            var systemStaticInfoCode=mapper.systemStaticInfoCode()
            //系统 已采集自定义信息点编码
            var systemCustomInfoCode=mapper.systemCustomInfoCode(projectId)
            //项目下所有的系统
            var projectSystem=mapper.projectSystem(projectId)

            var hashMap=calculate(systemDynamicInfoCode,systemStaticInfoCode,systemCustomInfoCode,projectSystem,1)

            var gatherInfoPoint=GatherInfoPoint()
            gatherInfoPoint.gatherInfoPointCounts=systemControlInfoCounts+systemCustomInfoCounts
            gatherInfoPoint.gatherCustomInfoPointCounts=hashMap["customInfoPoint"]
            gatherInfoPoint.gatherDynamicInfoPointCounts=hashMap["dynamicInfoPoint"]
            gatherInfoPoint.gatherStaticInfoPointCounts=hashMap["staticInfoPoint"]

            var list=ArrayList<GatherInfoPoint>()
            val sQueryResponse = SQueryResponse<GatherInfoPoint>(SResponseType.success)
            list.add(gatherInfoPoint)
            sQueryResponse.content = list
            sQueryResponse
        } catch ( e: Exception){
            e.printStackTrace()
            SQueryResponse(SResponseType.failure)
        }
    }


    /**
     * 计算信息点
     *
     */
    fun calculateInfoPoints(str: String,type:String, infoPointCodes:ArrayList<HashMap<String,String>>):HashMap<String,Any> {
        var counts=0
        var hashMap=HashMap<String,Any>()
        val iterator = infoPointCodes.iterator()
        while (iterator.hasNext()){
            val next = iterator.next()
            if(str.contains(next["info_point_code"].toString()) && type==next["type"]){
                counts++
                hashMap["next"]=next
                iterator.remove()
            }
        }
        hashMap["counts"]=counts
        return hashMap
    }

    /**
     * 计算动态、静态信息点
     */
    fun calculate(dynamicInfoPointCodes:ArrayList<HashMap<String,String>>,staticInfoPointCodes:ArrayList<HashMap<String,String>>,customInfoPointCodes:ArrayList<HashMap<String,String>>,projectEquipment:ArrayList<HashMap<String,Any>>,num:Int):HashMap<String,Int> {
        var hashMap = HashMap<String, Int>()
        var dynamicInfoPoint = 0
        var staticInfoPoint = 0
        var customInfoPoint=0
        val iterator1 = staticInfoPointCodes.iterator()
        for (equipmentInforPoint in projectEquipment) {
            while (iterator1.hasNext()) {
                val next = iterator1.next()
                if (equipmentInforPoint["id"] != null && "EquipID" == next["info_point_code"] && equipmentInforPoint["category"] == next["type"]) {
                    staticInfoPoint++
                    iterator1.remove()
                }
                if (equipmentInforPoint["id"] != null && "SysID" == next["info_point_code"] && "GeneralSystem" == next["type"]) {
                    staticInfoPoint++
                    iterator1.remove()
                }
                if (equipmentInforPoint["name"] != null && "EquipName" == next["info_point_code"] && equipmentInforPoint["category"] == next["type"]) {
                    staticInfoPoint++
                    iterator1.remove()
                }
                if (equipmentInforPoint["name"] != null && "SysName" == next["info_point_code"]) {
                    staticInfoPoint++
                    iterator1.remove()
                }
                if (equipmentInforPoint["local_id"] != null && "EquipLocalID" == next["info_point_code"] && equipmentInforPoint["category"] == next["type"]) {
                    staticInfoPoint++
                    iterator1.remove()
                }
                if (equipmentInforPoint["local_id"] != null && "SysLocalID" == next["info_point_code"]) {
                    staticInfoPoint++
                    iterator1.remove()
                }
                if (equipmentInforPoint["local_name"] != null && "EquipLocalName" == next["info_point_code"] && equipmentInforPoint["category"] == next["type"]) {
                    staticInfoPoint++
                    iterator1.remove()
                }
                if (equipmentInforPoint["local_name"] != null && "SysLocalName" == next["info_point_code"]) {
                    staticInfoPoint++
                    iterator1.remove()
                }
                if (equipmentInforPoint["qr_code"] != null && "EquipQRCode" == next["info_point_code"] && equipmentInforPoint["category"] == next["type"]) {
                    staticInfoPoint++
                    iterator1.remove()
                }
                if (equipmentInforPoint["cad_id"] != null && "CADID" == next["info_point_code"] && equipmentInforPoint["category"] == next["type"] && num==0) {
                    staticInfoPoint++
                    iterator1.remove()
                }
                if (equipmentInforPoint["cad_id"] != null && "CADID" == next["info_point_code"] && num==1) {
                    staticInfoPoint++
                    iterator1.remove()
                }
                if (equipmentInforPoint["bim_id"] != null && "BIMID" == next["info_point_code"] && equipmentInforPoint["category"] == next["type"] && num==0) {
                    staticInfoPoint++
                    iterator1.remove()
                }
                if (equipmentInforPoint["bim_id"] != null && "BIMID" == next["info_point_code"] && num==1) {
                    staticInfoPoint++
                    iterator1.remove()
                }
                if (equipmentInforPoint["bim_location"] != null && "BIMLocation" == next["info_point_code"] && equipmentInforPoint["category"] == next["type"]) {
                    staticInfoPoint++
                    iterator1.remove()
                }
                if (equipmentInforPoint["equip_serial"] != null && "EquipSerial" == next["info_point_code"] && equipmentInforPoint["category"] == next["type"]) {
                    staticInfoPoint++
                    iterator1.remove()
                }
                if (equipmentInforPoint["family_name"] != null && "BIMFamilyName" == next["info_point_code"] && equipmentInforPoint["category"] == next["type"]) {
                    staticInfoPoint++
                    iterator1.remove()
                }
                if (equipmentInforPoint["family_symbol"] != null && "BIMFamilySymbol" == next["info_point_code"] && equipmentInforPoint["category"] == next["type"]) {
                    staticInfoPoint++
                    iterator1.remove()
                }
            }
        }

        for (equipmentInforPoint in projectEquipment) {
            if (equipmentInforPoint["ledger_param"] != null) {
                var dynamic=calculateInfoPoints(equipmentInforPoint["ledger_param"].toString(), equipmentInforPoint["category"].toString(), dynamicInfoPointCodes)
                var static=calculateInfoPoints(equipmentInforPoint["ledger_param"].toString(), equipmentInforPoint["category"].toString(), staticInfoPointCodes)
                dynamicInfoPoint += dynamic["counts"] as Int
                staticInfoPoint +=dynamic["counts"] as Int
                dynamicInfoPointCodes.remove(dynamic["next"])
                staticInfoPointCodes.remove(static["next"])
            }
            if (equipmentInforPoint["comm_param"] != null) {
                var dynamic=calculateInfoPoints(equipmentInforPoint["comm_param"].toString(), equipmentInforPoint["category"].toString(), dynamicInfoPointCodes)
                var static=calculateInfoPoints(equipmentInforPoint["comm_param"].toString(), equipmentInforPoint["category"].toString(), staticInfoPointCodes)
                dynamicInfoPoint += dynamic["counts"] as Int
                staticInfoPoint +=dynamic["counts"] as Int
                dynamicInfoPointCodes.remove(dynamic["next"])
                staticInfoPointCodes.remove(static["next"])
            }
            if (equipmentInforPoint["tech_param"] != null) {
                var dynamic=calculateInfoPoints(equipmentInforPoint["tech_param"].toString(), equipmentInforPoint["category"].toString(), dynamicInfoPointCodes)
                var static=calculateInfoPoints(equipmentInforPoint["tech_param"].toString(), equipmentInforPoint["category"].toString(), staticInfoPointCodes)
                dynamicInfoPoint += dynamic["counts"] as Int
                staticInfoPoint +=dynamic["counts"] as Int
                dynamicInfoPointCodes.remove(dynamic["next"])
                staticInfoPointCodes.remove(static["next"])
            }
            if (equipmentInforPoint["run_param"] != null) {
                var dynamic=calculateInfoPoints(equipmentInforPoint["run_param"].toString(), equipmentInforPoint["category"].toString(), dynamicInfoPointCodes)
                var static=calculateInfoPoints(equipmentInforPoint["run_param"].toString(), equipmentInforPoint["category"].toString(), staticInfoPointCodes)
                dynamicInfoPoint += dynamic["counts"] as Int
                staticInfoPoint +=dynamic["counts"] as Int
                dynamicInfoPointCodes.remove(dynamic["next"])
                staticInfoPointCodes.remove(static["next"])
            }
            if (equipmentInforPoint["setting_param"] != null) {
                var dynamic=calculateInfoPoints(equipmentInforPoint["setting_param"].toString(), equipmentInforPoint["category"].toString(), dynamicInfoPointCodes)
                var static=calculateInfoPoints(equipmentInforPoint["setting_param"].toString(), equipmentInforPoint["category"].toString(), staticInfoPointCodes)
                dynamicInfoPoint += dynamic["counts"] as Int
                staticInfoPoint +=dynamic["counts"] as Int
                dynamicInfoPointCodes.remove(dynamic["next"])
                staticInfoPointCodes.remove(static["next"])
            }
            if (equipmentInforPoint["alram"] != null) {
                var dynamic=calculateInfoPoints(equipmentInforPoint["alram"].toString(), equipmentInforPoint["category"].toString(), dynamicInfoPointCodes)
                var static=calculateInfoPoints(equipmentInforPoint["alram"].toString(), equipmentInforPoint["category"].toString(), staticInfoPointCodes)
                dynamicInfoPoint += dynamic["counts"] as Int
                staticInfoPoint +=dynamic["counts"] as Int
                dynamicInfoPointCodes.remove(dynamic["next"])
                staticInfoPointCodes.remove(static["next"])
            }
            if (equipmentInforPoint["tech_param_general"] != null) {
                var dynamic=calculateInfoPoints(equipmentInforPoint["tech_param_general"].toString(), equipmentInforPoint["category"].toString(), dynamicInfoPointCodes)
                var static=calculateInfoPoints(equipmentInforPoint["tech_param_general"].toString(), equipmentInforPoint["category"].toString(), staticInfoPointCodes)
                dynamicInfoPoint += dynamic["counts"] as Int
                staticInfoPoint +=dynamic["counts"] as Int
                dynamicInfoPointCodes.remove(dynamic["next"])
                staticInfoPointCodes.remove(static["next"])
            }
            if (equipmentInforPoint["run_param_general"] != null) {
                var dynamic=calculateInfoPoints(equipmentInforPoint["run_param_general"].toString(), equipmentInforPoint["category"].toString(), dynamicInfoPointCodes)
                var static=calculateInfoPoints(equipmentInforPoint["run_param_general"].toString(), equipmentInforPoint["category"].toString(), staticInfoPointCodes)
                dynamicInfoPoint += dynamic["counts"] as Int
                staticInfoPoint +=dynamic["counts"] as Int
                dynamicInfoPointCodes.remove(dynamic["next"])
                staticInfoPointCodes.remove(static["next"])
            }
            if (equipmentInforPoint["custom_param"]!=null){
                var custom=calculateInfoPoints(equipmentInforPoint["custom_param"].toString(),equipmentInforPoint["category"].toString(),customInfoPointCodes)
                customInfoPoint+=custom["counts"] as Int
                customInfoPointCodes.remove(custom["next"])
            }
        }

        hashMap["dynamicInfoPoint"]=dynamicInfoPoint
        hashMap["staticInfoPoint"]=staticInfoPoint
        hashMap["customInfoPoint"]=customInfoPoint

        return hashMap

    }


    /**
     * 统计空间所在的多建筑多楼层的数量
     */
    fun spaceBdFls(projectId: String):Int{
        val setId = HashSet<String>()
        try {
            val spaceFlList = mapper.spaceFl(projectId)
            val spaceBdList = mapper.spaceBd(projectId)

            if (!spaceFlList.isNullOrEmpty()){
                for (space in spaceFlList){
                    if (space.count!=null&&space.count!!>1){
                        setId.add(space.space_id!!)
                    }
                }
            }
            if (!spaceBdList.isNullOrEmpty()){
                for (space in spaceBdList){
                    if (space.count!=null&&space.count!!>1){
                        setId.add(space.space_id!!)
                    }
                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return setId.size
    } //

    /**
     * 统计空间所在的多建筑多楼层的数量
     */
    fun spaceBdFlObj(projectId: String):HashSet<String>{
        val setId = HashSet<String>()
        try {
            val spaceFlList = mapper.spaceFl(projectId)
            val spaceBdList = mapper.spaceBd(projectId)

            if (!spaceFlList.isNullOrEmpty()){
                for (space in spaceFlList){
                    if (space.count!=null&&space.count!!>1){
                        setId.add(space.space_id!!)
                    }
                }
            }
            if (!spaceBdList.isNullOrEmpty()){
                for (space in spaceBdList){
                    if (space.count!=null&&space.count!!>1){
                        setId.add(space.space_id!!)
                    }
                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return setId
    } //

    /**
     * 项目下所有设备类型以及名称
     */
    fun equipType(projectId: String): ArrayList<DefClass> {
        return mapper.equipTypeName(projectId)
    }



} // class CustomSqlService