package cn.sagacloud.server.algorithm.backstage.sync

import cn.sagacloud.server.algorithm.backstage.model.datacenter.DCFloor
import cn.sagacloud.server.algorithm.models.entities.Door
import cn.sagacloud.server.algorithm.models.entities.VirtualWall
import cn.sagacloud.server.algorithm.models.entities.Window
import cn.sagacloud.server.algorithm.models.modelFile.FloorModel
import cn.sagacloud.server.algorithm.services.BaseDataService
import cn.sagacloud.server.algorithm.services.datacenter.DataCenterService
import cn.sagacloud.server.datacenter.models.entities.graphtype.MDoor
import cn.sagacloud.server.datacenter.models.entities.graphtype.MVirtualWall
import cn.sagacloud.server.datacenter.models.entities.graphtype.MWindow
import com.sybotan.database.SFilter
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.context.annotation.Scope
import org.springframework.stereotype.Component

/**
 * 同步部件
 *
 * @author jxing
 */
@Suppress("UNCHECKED_CAST")
@Component
@Scope("prototype")
class SyncModelComponent : SyncObject{

    var modelId: String? = null
    var floor: FloorModel? = null
    var dcFloors : ArrayList<DCFloor>? = null

    // 模型内构件
    var doorArr = ArrayList<Door>()
    var mDoorArr = ArrayList<MDoor>()
    var windowArr = ArrayList<Window>()
    var mWindowArr = ArrayList<MWindow>()
    var virtualWallArr = ArrayList<VirtualWall>()
    var mVirtualWallArr = ArrayList<MVirtualWall>()

    @Autowired
    lateinit var dataCenterService: DataCenterService

    val dataService = BaseDataService

    override fun init(modelId: String, floor: FloorModel, dcFloors: ArrayList<DCFloor>, bimIdPrefix: String): SyncObject {
        this.modelId = modelId
        this.floor = floor
        this.dcFloors = dcFloors
        return this
    }

    override fun prepareModelData(): SyncObject {
        doorArr = dataService.doorService.select(SFilter.eq("modelId", modelId!!)).exec()
        windowArr = dataService.windowService.select(SFilter.eq("modelId", modelId!!)).exec()
        virtualWallArr = dataService.virtualWallService.select(SFilter.eq("modelId", modelId!!)).exec()
        return this
    }

    override fun prepareDataCenterData(): SyncObject {
        return this
    }

    override fun matchClassify(): SyncObject {
        doorArr.forEach {
            val mDoor = MDoor()
            mDoor.elementType = it.elementType
            mDoor.faceDirection = it.faceDirection
            mDoor.familyName = it.familyName
            mDoor.familySymbol = it.familySymbol
            mDoor.handDirection = it.handDirection
            mDoor.id = it.id
            mDoor.location = it.location
            mDoor.modelFloorId = floor!!.id
            mDoor.modelId = it.modelId
            mDoor.name = it.name
            mDoor.outline = it.outline
            mDoor.owner = it.owner
            mDoor.revitId = it.revitId
            mDoor.sourceId = it.sourceId
            mDoor.thick = it.thick
            mDoor.wallId = it.wallId
            mDoorArr.add(mDoor)
        }
        windowArr.forEach {
            val mWindow = MWindow()
            mWindow.elementType = it.elementType
            mWindow.width = it.width
            mWindow.familyName = it.familyName
            mWindow.familySymbol = it.familySymbol
            mWindow.id = it.id
            mWindow.location = it.location
            mWindow.modelFloorId = floor!!.id
            mWindow.modelId = it.modelId
            mWindow.name = it.name
            mWindow.outline = it.outline
            mWindow.owner = it.owner
            mWindow.revitId = it.revitId
            mWindow.sourceId = it.sourceId
            mWindow.thick = it.thick
            mWindow.wallId = it.wallId
            mWindowArr.add(mWindow)
        }
        virtualWallArr.forEach {
            val mVWall = MVirtualWall()
            mVWall.elementType = it.elementType
            mVWall.id = it.id
            mVWall.location = it.location
            mVWall.modelFloorId = floor!!.id
            mVWall.modelId = it.modelId
            mVWall.name = it.name
            mVWall.outline = it.outline
            mVWall.revitId = it.revitId
            mVWall.sourceId = it.sourceId
            mVirtualWallArr.add(mVWall)
        }
        return this
    }

    override fun syncCreate(): SyncObject {
        if(mVirtualWallArr.isNotEmpty()) {
            dataCenterService.sync(mVirtualWallArr as ArrayList<Any>, null, floor!!.projectId!!, DataCenterService.DataCenterOperator.virtualWallCreate)
        }
        if(mWindowArr.isNotEmpty()) {
            dataCenterService.sync(mWindowArr as ArrayList<Any>, null, floor!!.projectId!!, DataCenterService.DataCenterOperator.windowCreate)
        }
        if(mDoorArr.isNotEmpty()) {
            dataCenterService.sync(mDoorArr as ArrayList<Any>, null, floor!!.projectId!!, DataCenterService.DataCenterOperator.doorCreate)
        }
        return this
    }

    override fun syncDelete(): SyncObject {
        return this
    }

    override fun syncUpdate(): SyncObject {
        return this
    }

    override fun buildBIMIDMap(): SyncObject {
        return this
    }
}