@file:Suppress("UNCHECKED_CAST")

package cn.sagacloud.server.algorithm.services.json

import cn.sagacloud.server.algorithm.models.entities.*
import cn.sagacloud.server.algorithm.models.jsonAnalyzer.AllComponents
import cn.sagacloud.server.algorithm.models.jsonAnalyzer.BaseObj
import cn.sagacloud.server.algorithm.services.CommonService
import com.sybotan.database.SFilter
import com.sybotan.service.SObjectService
import com.sybotan.service.models.enums.SResponseType
import com.sybotan.service.models.requests.SCreateRequest
import java.util.ArrayList

/**
 *
 *
 * @author jxing
 */
object BoundarySegmentAnalyzer {
    /**
     * 分析处理boundarySegment节点
     */
    fun analyze(boundarySegmentService: SObjectService<BoundarySegment>, baseObj: BaseObj<AllComponents>, boundarySegments: ArrayList<BoundarySegment>?) : Boolean{
        if(boundarySegments == null || boundarySegments.isEmpty())
            return true
        val componentsMap = composeComponentMap(baseObj.elements!!.walls, baseObj.elements!!.virtualWalls, baseObj.elements!!.columns, baseObj.elements!!.windows, baseObj.elements!!.doors)
        val bsMap = HashMap<String, BoundarySegment>() // <bs.revitId, bs>
        boundarySegments.forEach { bs ->
            if (componentsMap.containsKey(bs.reference)) {
                bs.belong = componentsMap[bs.reference]!!.id
                bs.belongType = componentsMap[bs.reference]!!.elementType
            }
            bs.id = CommonService.generateUUID(null, true)
            bs.modelId = baseObj.modelId
            bsMap[bs.revitId ?: "none"] = bs
        }
        val spaces = baseObj.elements!!.spaces
        if(spaces != null && spaces.isNotEmpty()){
            spaces.forEach { space ->
                var index1 = 0
                space.boundarySegment?.forEach { pointArr ->
                    var index2 = 0
                    pointArr.forEach { bsRevitId ->
                        if(bsMap.containsKey(bsRevitId)){
                            val bs = bsMap[bsRevitId]
                            bs!!.spaceId = space.id
                            bs.groupIndex = index1
                            bs.sequence = index2
                        }
                        ++index2
                    }
                    ++index1
                }
            }
        }
        boundarySegmentService.delete(SFilter.eq("modelId", baseObj.modelId!!))
        val create = SCreateRequest<BoundarySegment>()
        create.content = boundarySegments
        val result = boundarySegmentService.createList(create)
        return SResponseType.success == result.result
    }

    /**
     * 提取墙, 虚拟墙, 柱子, 窗户, 门的revitId, 表id和类型
     */
    private fun composeComponentMap(walls: ArrayList<Wall>?, virtualWalls: ArrayList<VirtualWall>?, columns: ArrayList<Column>?, windows: ArrayList<Window>?, doors: ArrayList<Door>?): Map<String, BaseComponent> {
        val map = HashMap<String, BaseComponent>()
        putToMap(walls as ArrayList<BaseComponent>?, map)
        putToMap(virtualWalls as ArrayList<BaseComponent>?, map)
        putToMap(columns as ArrayList<BaseComponent>?, map)
        putToMap(windows as ArrayList<BaseComponent>?, map)
        putToMap(doors as ArrayList<BaseComponent>?, map)
        return map
    }

    /**
     * 提取对象到map<revitId, baseComponent>
     */
    private fun putToMap(baseArr: ArrayList<BaseComponent>?, map: HashMap<String, BaseComponent>) {
        baseArr?.forEach { base ->
            if (base.revitId != null)
                map[base.revitId!!] = base
        }
    }
}