/*
 * *********************************************************************************************************************
 *
 *          !!
 *        .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.services.relation_calc

import com.persagy.server.services.base.RService
import com.persagy.server.utils.IdUtils
import com.persagy.server.datacenter.models.entities.graphtype.RelationTypeProject
import com.persagy.server.datacenter.models.entities.graphtype.block.ConnectedBlock
import com.persagy.server.datacenter.models.entities.rel.REq2Eq
import com.persagy.server.mappers.ICalcSpecialMapper
import com.persagy.server.services.assistant.RUpDateEquipAndSapceService
import com.persagy.database.SFilter
import com.persagy.mybatis.SMybatisDao
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.SCreateRequest
import com.persagy.service.models.responses.SBaseResponse
import org.json.JSONObject
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service

/**
 * 关系计算-管网
 *
 * @author 邓婷婷
 */
@Service
open class CalcSpecialService {


    /** 实例化 mapper 对象 */
    @Autowired
    lateinit var mapper: ICalcSpecialMapper

    @Autowired
    lateinit var mepSystemCalcService: MepSystemCalcService

    val connectedBlockService = SObjectService(SMybatisDao(ConnectedBlock::class.java))
    /** 关系总览服务 */
    val relationTypeProjectservice = SBaseService(SMybatisDao(RelationTypeProject::class.java))
    val rEq2EqService = SObjectService(SMybatisDao(REq2Eq::class.java))

    /**
     * 管网系统设备分块
     *@param calcName   计算关系名称
     *@param systemName 需要计算的系统名称
     *@param domain 需要计算的管道系统类型，枚举（水管或风管）：DomainPiping，DomainHvac
     */
    fun sysBolck(relationType: String): SBaseResponse {
        try {
            val buildingId: String? = null
            val projectId = SPageContext.getHeader("projectId").toString()
            upDateBiaoji(projectId,relationType ,3)
            val entity = relationTypeProjectservice.select(SFilter.eq("projectId", projectId), SFilter.eq("relationType", relationType)).entity()
            if (entity != null) {
                if (!entity.mepSystemType.isNullOrEmpty()){
                    val systemName = entity.mepSystemType!!
                    val calcName = entity.relationTypeName!!
                    // 分块
                    for (name in systemName) {
                        val domain = toolsMap(name)
                        val result = mapper.sysBolck(projectId, buildingId, name, domain)
                        if (!result) {
                            upDateBiaoji(projectId,relationType ,5)
                            return SBaseResponse(SResponseType.success)
                        }
                    }
                    // 设置源
                    val sourceType = mepSystemCalcService.setSourceType(projectId, calcName, null, systemName)
                    if (!sourceType) {
                        upDateBiaoji(projectId,relationType ,5)
                        return SBaseResponse(SResponseType.success)
                    }
                    // 计算流向
                    val exec = connectedBlockService.select(SFilter.eq("projectId", projectId), SFilter.inList("mepSystemType", systemName)).group("mepSystemType", "blockId").projection(arrayListOf("mepSystemType", "blockId")).exec()
                    exec.forEach {
                        val domain = toolsMap(it.mepSystemType!!)
                        val result = mapper.sysDirection(projectId, buildingId, it.blockId!!, it.mepSystemType!!, domain, true)
                        if (!result) {
                            upDateBiaoji(projectId,relationType ,5)
                            return SBaseResponse(SResponseType.success)
                        }
                    }
                    try {
                        // 生成数据中心使用的关系
                        val generateRelation = mepSystemCalcService.generateRelation(projectId, relationType, null, systemName)
                        generateRelation.addAll(mepSystemCalcService.generateNonDirectionalRelation(projectId, relationType, null, systemName))
                        if (generateRelation.size>0){
                            val delete = rEq2EqService.delete(SFilter.eq("projectId", projectId), SFilter.eq("type", relationType), SFilter.eq("sign", 2))

                            val rEqForSps = rEq2EqService.select(SFilter.eq("projectId", projectId), SFilter.eq("type", relationType), SFilter.eq("sign", 2)).exec()
                            val jsonObject = JSONObject()
                            val mapList = ArrayList<HashMap<String,String>>()
                            if(rEqForSps != null){
                                for (rEqForSp in rEqForSps) {
                                    val map = HashMap<String,String>()
                                    map["id1"] = rEqForSp.id1!!
                                    map["id2"] = rEqForSp.id2!!
                                    mapList.add(map)
                                }
                            }
                            jsonObject.put("type", "12")
                            jsonObject.put("projectId", projectId)
                            jsonObject.put("relation",mapList)
                            jsonObject.put("obj_type", relationType)

                            /** 发送消息 */
                            RService.messageHandler.sendMessage(jsonObject.toString())

                            val sCreateRequest = SCreateRequest<REq2Eq>()
                            sCreateRequest.content = generateRelation
                            rEq2EqService.createList(sCreateRequest)

                            val createJsonObject = JSONObject()
                            val createMapList = ArrayList<HashMap<String,String>>()
                            for (rEq2Eq in generateRelation) {
                                val map = HashMap<String,String>()
                                map["id1"] = rEq2Eq.id1!!
                                map["id2"] = rEq2Eq.id2!!
                                createMapList.add(map)
                            }
                            createJsonObject.put("type", "11")
                            createJsonObject.put("projectId", projectId)
                            createJsonObject.put("obj_type", relationType)
                            createJsonObject.put("relation",createMapList)
                            /** 发送消息 */
                            RService.messageHandler.sendMessage(createJsonObject.toString())
                        }
                    } catch (e: Exception) {
                        upDateBiaoji(projectId,relationType ,5)
                        return SBaseResponse(SResponseType.success)
                    }
                }
            }
            upDate(projectId,relationType)
            return SBaseResponse(SResponseType.success)
        } catch (e: Exception) {
            e.printStackTrace()
            return SBaseResponse(SResponseType.failure, e.message!!)
        }
    } // Fun sysBolck

    /**
     * 管网系统确定流向
     *@param buildingId 需要计算的building_id，如果没有提供时请传入null，不能传""
     *@param blockId 需要计算的块id
     *@param systemName 需要计算的系统名称
     *@param domain 需要计算的管道系统类型，枚举（水管或风管）：DomainPiping，DomainHvac
     */
    fun sysDirection(buildingId: String?, blockId: String, systemName: String, domain: String, isSource: Boolean): SBaseResponse {
        try {
            val projectId = SPageContext.getHeader("projectId").toString()
            val result = mapper.sysDirection(projectId, buildingId, blockId, systemName, domain, isSource)
            if (result) {
                return SBaseResponse(SResponseType.success)
            }
            return SBaseResponse(SResponseType.failure)
        } catch (e: Exception) {
            e.printStackTrace()
            return SBaseResponse(SResponseType.failure, e.message!!)
        }
    } // Fun sysDirection

    /**
     *
     */
    fun toolsMap(name: String): String {

        if (name == "补风管"||name == "空调送风风管"|| name == "空调排风风管"||name == "通风送风风管"
                ||name == "正压送风风管"|| name == "新风风管"||name == "排烟风管"||name == "通风排风风管"
                ||name == "送风兼消防补风风管"|| name == "排风兼排烟管"||name == "排油烟管"||name == "回风风管"
                ){
            return "DomainHvac"
        }
        return "DomainPiping"
    } //

    /**
     * 修改标记
     */
    fun upDate(projectId: String,type: String){
        try {
            val entity = relationTypeProjectservice.select(SFilter.eq("projectId", projectId), SFilter.eq("relationType", type)).entity()
            if (entity!=null){
                entity.computationalState = 1
                entity.computingTime = IdUtils.time()
                RUpDateEquipAndSapceService.relationTypeProjectservice.update(entity)
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
    } // Fun

    /**
     * 计算中标记
     */
    fun upDateBiaoji(projectId: String,type: String,sing: Int){
        try {
            if (sing == 3){
                val entity = relationTypeProjectservice.select(SFilter.eq("projectId", projectId), SFilter.eq("relationType", type)).entity()
                if (entity!=null){
                    entity.computationalState = 3
                    entity.computingTime = IdUtils.time()
                    RUpDateEquipAndSapceService.relationTypeProjectservice.update(entity)
                }
            }else{
                val entity = relationTypeProjectservice.select(SFilter.eq("projectId", projectId), SFilter.eq("relationType", type)).entity()
                if (entity!=null){
                    entity.computationalState = 5
                    entity.computingTime = IdUtils.time()
                    RUpDateEquipAndSapceService.relationTypeProjectservice.update(entity)
                }
            }

        } catch (e: Exception) {
            e.printStackTrace()
        }
    } // Fun

} // Class CalcSpecialService