package com.persagy.revit.backstage.state

import com.persagy.database.SFilter
import com.persagy.revit.backstage.sync.SyncFloor
import com.persagy.revit.backstage.sync.SyncUtil
import com.persagy.revit.models.config.MyProperties
import com.persagy.revit.models.message.MessageType
import com.persagy.revit.models.modelFile.ModelFile
import com.persagy.revit.services.BaseDataService
import com.persagy.revit.services.CommonService
import com.persagy.revit.services.endpoint.ModelFileService
import com.persagy.revit.services.excel.ExcelService
import com.persagy.revit.services.json.JSONAnalyzerService
import com.persagy.revit.services.message.MessageService
import com.persagy.revit.services.modelCheck.ModelCheckService
import com.persagy.revit.services.monitor.ModelMonitorService
import com.persagy.service.utils.SSpringContextUtil
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Component
import java.util.*

/**
 *
 *
 * @author jxing
 */
@Component
class ExportPassedState_3 : ModelState {

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

    @Autowired
    lateinit var myProperties: MyProperties

    @Autowired
    lateinit var syncUtil : SyncUtil

    @Autowired
    lateinit var modelFileService: ModelFileService

    @Autowired
    lateinit var messageService: MessageService

    @Autowired
    lateinit var modelCheckService: ModelCheckService

    @Autowired
    lateinit var jsonAnalyzerService: JSONAnalyzerService

    @Autowired
    lateinit var monitorService: ModelMonitorService

    val dataService = BaseDataService

    var modelList: ArrayList<ModelFile>? = null

    /**
     * 准备数据
     */
    override fun prepareModel() {
        modelList = dataService.modelFileService.select(SFilter.eq("status", 3), SFilter.eq("removed", false)).exec()
    }

    /**
     *       1. 没有绑定楼层时
     *              1. 找是否上一个模型数据已上传 (BIMID : ModelId : SourceId) (新BIMID格式 : PjId + FolderId + FloorName)
     *                      1. 找到的话, 同步新数据(BIMID 改为新模型id)
     *                      2. 没找到的话, 尝试用当前ModelId去寻找是否有数据
     *                              1. 找到的话, 同步新数据
     *                              2. 没找到的话, 直接全部添加
     *       2. 绑定一个或多个楼层时, 对每个楼层foreach
     *              1. 如果该楼层有outline, 则同步在outline内的数据
     *              2. 如果该楼层没有outline, 则同步所有数据到该楼层
     *
     *
     *
     * 1. 同步数据, 楼层, 元空间, 设备, 部件
     *       floor --> FloorMap = base/modelId.jsonz,   modelId --> 模型id
     *
     * 2. 上传底图到文件服务器(更新楼层的信息点 FloorMap = base/modelId.jsonz)
     */
    override fun handle() {
        if (modelList.isNullOrEmpty()) {
            return
        }
        modelList!!.forEach {
            try {
                if (it.floorModelId == null || it.id == null)
                    return@forEach
                val floorModelArr = dataService.floorModelService.select(SFilter.eq("id", it.floorModelId!!)).exec()
                if (floorModelArr.size != 1)
                    return@forEach
                val floor = floorModelArr[0]
                val folderFloorName = CommonService.getReportPrefix(floor)
                // 获取模型导出的zip文件
                val objData = monitorService.analyzeJsonz(it.id!!)
                // 导入数据进数据库
                val bimIdPrefix = CommonService.generateBIMIDPrefix(it.projectId!!, floor.folderId!!, floor.floorName!!, true)
                monitorService.persistenceData(it.id!!, objData!!, bimIdPrefix)
                // excel报告
                val excelService = SSpringContextUtil.getBean(ExcelService::class.java) as ExcelService
                excelService.readBlockingExcel2007()
                // 多楼层的模型检查
                val isPassed = monitorService.doMultiFloorCheck(it, excelService, floor.projectId!!, floor.folderId!!, floor.floorName)
                // 如果标高和轴网检查没通过, 则删除所有数据, 并回退到上个版本
                if(!isPassed){
                    modelFileService.removeSingle(it, myProperties, isForce = true, isMarkDelete = false)
                    //发送标高和轴网检查没通过的消息
                    val message = messageService.buildMultiModelCheckErrorMessage(floor.projectId!!, it.userId?: "",
                            "${folderFloorName.first}的${folderFloorName.second}未通过模型检查，请修改后重新上传", excelService.getDownloadUrl(it.id!!), folderFloorName)
                    messageService.sendMessage(message)
                    return@forEach
                }
                val syncFloor = SSpringContextUtil.getBean(SyncFloor::class.java) as SyncFloor
                syncFloor.init(floor).prepareDataCenterData()
                // 开始同步设备, 部件, 元空间
                syncUtil.syncDataWithBindingFloor(syncFloor, it, floor)
                // 转状态到4
                it.status = 4
                dataService.modelFileService.update(it, arrayListOf("status"))
                val message = messageService.buildMessageEntityWithoutLink("${folderFloorName.first}的${folderFloorName.second}模型上传成功", MessageType.Success, it.projectId, arrayListOf(it.userId?:""), "")
                messageService.sendMessage(message)
            } catch (e: Exception) {
                // 转状态到31
                try {
                    it.status = 31
                    it.syncRetryDate = Date()
                    it.syncErrorMsg = e.message + CommonService.getStackTrace(e)
                    dataService.modelFileService.update(it, arrayListOf("status", "syncRetryDate", "syncErrorMsg"))
                }catch (e : Exception){}
                e.printStackTrace()
                logger.error(e.message)
            }
        }
    }


//    override fun handle() {
//        if (modelList == null || modelList!!.isEmpty()) {
//            return
//        }
//        modelList!!.forEach {
//            try {
//                if (it.floorModelId == null || it.id == null)
//                    return@forEach
//                val floorModelArr = dataService.floorModelService.select(SFilter.eq("id", it.floorModelId!!)).exec()
//                if (floorModelArr.size != 1)
//                    return@forEach
//                val floor = floorModelArr[0]
//                // 如果没有绑定楼层
//                if (floor.floorIdList.isNullOrEmpty()) {
//                    return@forEach
//                }
//                val syncFloor = SSpringContextUtil.getBean(SyncFloor::class.java) as SyncFloor
//                syncFloor.init(floor).prepareDataCenterData()
//                // 数据中心没有查到该楼层
//                if (syncFloor.dcFloor.isNullOrEmpty()) {
//                    return@forEach
//                }else {
//                    // 开始同步设备, 部件, 元空间
//                    syncUtil.syncDataWithBindingFloor(syncFloor, it, true)
//                    // 转状态到4
//                    it.status = 4
//                    dataService.modelFileService.update(it, arrayListOf("status"))
//                }
//            } catch (e: Exception) {
//                // 转状态到31
//                try {
//                    it.status = 31
//                    it.syncRetryDate = Date()
//                    it.syncErrorMsg = e.message + CommonService.getStackTrace(e)
//                    dataService.modelFileService.update(it, arrayListOf("status", "syncRetryDate", "syncErrorMsg"))
//                }catch (e : Exception){}
//                e.printStackTrace()
//                logger.error(e.message)
//            }
//        }
//    }


}