/*
 * ********************************************************************************************************************
 *
 *                      :*$@@%$*:                         ;:                ;;    ;;
 *                    :@@%!  :!@@%:                       %!             ;%%@@%$ =@@@@@@@%;     @%@@@%%%%@@@@@
 *                   :@%;       :$=                       %%$$$%$$         ;$$  ;$@=   !@$
 *                   =@!                                  %!              @ $=;%   !@@@%:      !$$$$$$$$$$$$$$=
 *                   =@*                                  %!              @ $= % %@=   =%@!      %=
 *              *$%%! @@=        ;=$%%%$*:                %!              @ $= % =%%%%%%@$      *%:         =%
 *            %@@!:    !@@@%=$@@@@%!  :*@@$:              %!              @ $= % $*     ;@      @*          :%*
 *          ;@@!          ;!!!;:         ;@%:      =======@%========*     @ $$ % $%*****$@     :@$=*********=@$
 *          $@*   ;@@@%=!:                *@*
 *          =@$    ;;;!=%@@@@=!           =@!
 *           %@$:      =@%: :*@@@*       %@=                    Copyright (c) 2016-2019.  北京上格云技术有限公司
 *            ;%@@$=$@@%*       *@@@$=%@@%;
 *               ::;::             ::;::                                              All rights reserved.
 *
 * ********************************************************************************************************************
 */
package cn.sagacloud.server.algorithm.controllers.modelFile

import cn.sagacloud.server.algorithm.backstage.sync.SyncUtil
import cn.sagacloud.server.algorithm.dao.mapper.FloorMapper
import cn.sagacloud.server.algorithm.models.config.MyProperties
import cn.sagacloud.server.algorithm.models.modelFile.FloorModel
import cn.sagacloud.server.algorithm.models.modelFile.FloorModelView
import cn.sagacloud.server.algorithm.models.request.BindFloorRequest
import cn.sagacloud.server.algorithm.services.BaseDataService
import cn.sagacloud.server.algorithm.services.CommonService
import cn.sagacloud.server.algorithm.services.comparator.FloorComparator
import cn.sagacloud.server.algorithm.services.datacenter.DataCenterService
import cn.sagacloud.server.algorithm.services.endpoint.FloorModelService
import cn.sagacloud.server.algorithm.services.endpoint.FloorService
import com.alibaba.fastjson.JSONObject
import com.sybotan.database.SFilter
import com.sybotan.service.SPageContext
import com.sybotan.service.models.enums.SResponseType
import com.sybotan.service.models.requests.SCountRequest
import com.sybotan.service.models.requests.SCreateRequest
import com.sybotan.service.models.requests.SQueryRequest
import com.sybotan.service.models.requests.SUpdateRequest
import com.sybotan.service.models.responses.SBaseResponse
import com.sybotan.service.models.responses.SCountResponse
import com.sybotan.service.models.responses.SCreateResponse
import com.sybotan.service.models.responses.SQueryResponse
import io.swagger.annotations.Api
import io.swagger.annotations.ApiOperation
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestBody
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
import java.lang.StringBuilder

/**
 *
 *
 * @author jxing
 */
@Api(tags = ["楼层模型接口"])
@RestController
@RequestMapping("/model-floor")
class FloorModelController {
    companion object {
        // 日志
        private val logger = LoggerFactory.getLogger(FloorModelController::class.java)
    } // Companion object

    val dataService = BaseDataService

    @Autowired
    lateinit var dataCenterService : DataCenterService

    @Autowired
    lateinit var floorComparator : FloorComparator

    @Autowired
    lateinit var floorService : FloorService

    @Autowired
    lateinit var floorMapper : FloorMapper

    @Autowired
    lateinit var myProperties : MyProperties

    // 同步数据中心数据
    @Autowired
    lateinit var syncUtil : SyncUtil

    /**
     * 查询文件夹下的所有有模型文件的楼层
     *
     * @param   request     查询请求
     * @return  查询结果应答信息
     */
    @ApiOperation(value = "查询文件夹下的所有楼层", notes = "")
    @PostMapping(value = ["/query-list"])
    fun queryList(@RequestBody request: SQueryRequest): SQueryResponse<FloorModelView> {
        val response = FloorModelService.pageQuery(request)
        val list = response.content
        if(list != null && list.isNotEmpty())
            response.content = list.sortedWith(floorComparator)
        return response
    } // Function queryList()


    /**
     * 查询文件夹下的所有有模型文件的楼层(缺失楼层用null表示)
     *
     * @param   request     查询请求
     * @return  查询结果应答信息
     */
    @ApiOperation(value = "查询文件夹下的所有楼层", notes = "")
    @PostMapping(value = ["/query-list-missing"])
    fun queryListWithMissing(@RequestBody request: SQueryRequest): SQueryResponse<FloorModelView> {
        val response = FloorModelService.pageQuery(request)
        val list = response.content
        if(list != null && list.isNotEmpty())
            response.content = list.sortedWith(floorComparator)
        else
            return response
        var content = response.content!!.toMutableList()
        response.content = floorService.addMissingFloor(content)
        return response
    } // Function queryList()

    /**
     * 查询楼层
     *
     * @param   request     查询请求
     * @return  查询结果应答信息
     */
    @ApiOperation(value = "查询楼层", notes = "")
    @PostMapping(value = ["/query"])
    fun query(@RequestBody request: SQueryRequest): SQueryResponse<FloorModel> {
        val sb = StringBuilder()
        if(request.filters == null){
            sb.append("ProjectId = '${SPageContext.getHeader("ProjectId")}'")
        }else{
            sb.append(request.filters)
            if(!sb.trim().endsWith(";"))
                sb.append(" and ")
            sb.append("ProjectId = '${SPageContext.getHeader("ProjectId")}'")
        }
        request.filters = sb.toString()
        return dataService.floorModelService.pageQuery(request)
    } // Function query()

    /**
     * 创建模型楼层
     *
     * @param   entity     实体
     * @return  创建结果应答信息
     */
    @ApiOperation(value = "创建模型楼层", notes = "")
    @PostMapping(value = ["/create"])
    fun create(@RequestBody entity: SCreateRequest<FloorModel>): SCreateResponse<FloorModel> {
        entity.content.stream().forEach { x ->
            x.id = CommonService.generateUUID("", true)
            x.projectId = SPageContext.getHeader("ProjectId")
        }
        return dataService.floorModelService.createList(entity)
    } // Function create()

    /**
     * 删除模型文件夹
     *
     * @param   idList      删除模型文件夹ID列表
     * @return  删除结果应答信息
     */
    @ApiOperation(value = "删除模型文件夹", notes = "")
    @PostMapping(value = ["/delete"])
    fun delete(@RequestBody idList: ArrayList<FloorModel>): SBaseResponse {
        return dataService.floorModelService.deleteByKeysList(idList)
    } // Function delete()

    /**
     * 更新模型文件名字
     *
     * @param   request     更新请求
     * @return  更新结果应答信息
     */
    @ApiOperation(value = "更新模型文件名字", notes = "")
    @PostMapping(value = ["/update"])
    fun update(@RequestBody request: SUpdateRequest<FloorModel>): SBaseResponse {
        return dataService.floorModelService.updateList(request)
    } // Function update()

    /**
     * 根据条件查询统计数量
     */
    @ApiOperation(value = "根据条件查询统计数量", notes = "")
    @PostMapping(value = ["/count"])
    fun count(@RequestBody request: SCountRequest): SCountResponse {
        val sb = StringBuilder()
        if(request.filters == null){
            sb.append("ProjectId = '${SPageContext.getHeader("ProjectId")}'")
        }else{
            sb.append(request.filters)
            if(!sb.trim().endsWith(";"))
                sb.append(" and ")
            sb.append("ProjectId = '${SPageContext.getHeader("ProjectId")}'")
        }
        request.filters = sb.toString()
        return dataService.floorModelService.count(request)
    } // Function count()

    /**
     * 绑定数据中心楼层id, 并生成底图文件上传文件服务器
     */
    @ApiOperation(value = "绑定数据中心楼层id (FloorId), 并生成底图文件上传文件服务器", notes = "输入需要Id(模型文件管理id), FloorId(数据中心楼层id)")
    @PostMapping(value = ["/bind"])
    fun bind(@RequestBody request: FloorModel): SBaseResponse {
        try {
            if(request.id.isNullOrBlank()){
                return SBaseResponse(SResponseType.failure, "id不能为空")
            }
            if(request.floorId.isNullOrBlank() || !request.floorId!!.startsWith("Fl")){
                return SBaseResponse(SResponseType.failure, "绑定的楼层不能为空或格式不正确")
            }
            val floorArr = dataService.floorModelService.select(SFilter.eq("id", request.id!!)).exec()
            if(floorArr.isEmpty()){
                return SBaseResponse(SResponseType.failure, "指定的id不存在")
            }
            val floor = floorArr[0]
            val model = dataService.modelFileService.select(SFilter.eq("id", floor.currentModelId!!)).entity()
                    ?: return SBaseResponse(SResponseType.failure, "楼层上没有绑定的模型")
            //            if(floor.floorIdList == null)
//                floor.floorIdList = ArrayList()
//            // 如果覆盖以前绑定的楼层
//            if(request.isCover == true){
//                floor.floorIdList!!.clear()
//            }
//            if(!floor.floorIdList!!.contains(request.floorId!!)){
//                floor.floorIdList!!.add(request.floorId!!)

                // 调用数据中心绑定楼层的接口
//                val prevFloors = floorMapper.getFloorByDcFloorId(request.floorId!!)
                var prevBimId : String? = null
//                var prevFloor : FloorModel? = null
//                if(!prevFloors.isNullOrEmpty()){
//                    prevFloor = prevFloors[0]
//                    prevFloor.floorIdList = ArrayList()
//                    val list = JSONObject.parseArray(prevFloor.bind_floor_ids, String::class.java) as List<String>
//                    prevFloor.floorIdList!!.addAll(list)
//
//                    prevFloor.floorIdList!!.remove(request.floorId!!)
//                    prevBimId = CommonService.generateBIMIDPrefix(prevFloor.projectId!!, prevFloor.folderId!!, prevFloor.floorName!!, false)
//                }
            /** 处理楼层id 获取之前的模型信息 */
            if (!request.currentModelId.isNullOrEmpty()) {
                try {
                    val floorModel = dataService.floorModelService.select(SFilter.eq("id", request.currentModelId!!)).entity()
                    prevBimId = CommonService.generateBIMIDPrefix(SPageContext.getHeader("ProjectId")!!, floorModel!!.folderId!!, floorModel!!.floorName!!, false)
                } catch (e: Exception) {
                    e.printStackTrace()
                }
            }
                val bimId = CommonService.generateBIMIDPrefix(floor.projectId!!, floor.folderId!!, floor.floorName!!, false)
                val bindFloorRequest = BindFloorRequest()
                bindFloorRequest.attributeMap["floorElevation"] = model.baseLevel
                bindFloorRequest.bimId = bimId
                bindFloorRequest.oldBimId = prevBimId
                bindFloorRequest.floorId = request.floorId
                bindFloorRequest.floorMap = "${myProperties.fileService.baseGraph}/${floor.currentModelId}.jsonz"
                bindFloorRequest.modelId = floor.id
                // 访问数据中心绑定楼层接口
                if(!dataCenterService.bindFloor(bindFloorRequest, floor.projectId!!)){
                    return SBaseResponse(SResponseType.failure, "绑定失败, 数据中心访问失败")
                }
//                // 解绑原来的楼层
//                if(prevFloor != null){
//                    dataService.floorModelService.update(prevFloor)
//                }
                // 绑定楼层
//                val result = dataService.floorModelService.update(floor)
//                if(!result)
//                    return SBaseResponse(SResponseType.failure, "绑定失败")
//            }
            return SBaseResponse(SResponseType.success)
        }catch (e : Exception){
            return SBaseResponse(SResponseType.failure, e.message ?: "")
        }
    } // Function count()
}