/*
 * *********************************************************************************************************************
 *
 *          !!
 *        .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.service.dict

import com.persagy.database.SFilter
import com.persagy.database.SPageQueryInfo
import com.persagy.database.SQueryBuilder
import com.persagy.mybatis.SMybatisDao
import com.persagy.server.Opt
import com.persagy.server.dao.mappers.CustomSql
import com.persagy.server.datacenter.models.entities.dict.DictSQueryRequest
import com.persagy.server.datacenter.models.entities.dict.EquipFamily
import com.persagy.server.datacenter.models.entities.dict.Family
import com.persagy.server.datacenter.models.entities.dictnew.*
import com.persagy.server.datacenter.models.requests.CategoryRequest
import com.persagy.server.service.CustomSqlService
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.SCreateResponse
import com.persagy.service.models.responses.SQueryResponse
import com.persagy.service.utils.SSpringContextUtil

/**
 * 字典服务
 *
 * @author wx  <zhangweixin@sagacloud.com>
 * @date  2020/11/17 17:28
 */
object DictDefClassService: SObjectService<DefFuncId>(SMybatisDao(DefFuncId::class.java)) {

    /** 自定义sql */
    val customSqlService by lazy {
        SSpringContextUtil.getBean(CustomSql::class.java) as CustomSql
    }

    /** 平台集团对象类型 */
    private val defClassService = SObjectService(SMybatisDao(DefClass::class.java))
    /**
     * 查询 M 和 L 类型的信息点
     */
    fun queryMOrL(dictTypeList: ArrayList<String>): SQueryResponse<DefFuncId> {
        /** 返回对象 */
        val sQueryResponse = SQueryResponse<DefFuncId>(SResponseType.success)
        /** 对象列表 */
        var list = ArrayList<DefFuncId>()
        /** 入参不为空 */
        if (!dictTypeList.isNullOrEmpty()){
            /** 遍历入参列表 */
            for (dictType in dictTypeList){
                /** 类型筛选 */
                when(dictType){
                    "project" -> {
                        /** 项目 */
                        list.add(typeStatisticsOne("project","项目"))
                    }
                    "building" -> {
                        /** 建筑 */
                        list.add(typeStatisticsOne("building","建筑"))
                    }
                    "floor" -> {
                        /** 楼层 */
                        list.add(typeStatisticsOne("floor","楼层"))
                    }
                    "equipment" -> {
                        /** 设备 */
                        list.add(typeStatisticsTwo("equipment","设备"))
                    }
                    "component" -> {
                        /** 部件 */
                        list.add(typeStatisticsTwo("component","部件"))
                    }
                    "system" -> {
                        /** 系统 */
                        list.add(typeStatisticsTwo("system","系统"))
                    }
                    "space" -> {
                        /** 空间 */
                        list.add(typeStatisticsTwo("space","空间"))
                    }
                }
            }

            /** 列表赋值 */
            sQueryResponse.content = list
        }else {
            /** 返回状态 */
            sQueryResponse.result = SResponseType.failure
        }

        /** 返回对象 */
        return sQueryResponse
    }

    /** 自定义SQL 对象 */
    private val schemeService by lazy {
        SSpringContextUtil.getBean(CustomSqlService::class.java) as CustomSqlService
    }

    /** 设备族 */
    private val familyService = SObjectService(SMybatisDao(Family::class.java))
    /** 专业 */
    private val dictMajorService = SObjectService(SMybatisDao(DictMajor::class.java))
    /** 详细信息点 需采集信息点配置 */
    private val defFuncIdGatherService = SObjectService(SMybatisDao(DefFuncIdGather::class.java))
    /** 设备族和设备类型对应表服务 */
    private val equipFamilyService = SObjectService(SMybatisDao(EquipFamily::class.java))

    /**
     * 项目、建筑、楼层 M 或 L 信息点统计
     *
     * @param code  编码
     * @param name  名称
     * @return 信息点对象
     */
    private fun typeStatisticsOne(code: String,name:String): DefFuncId {
        /** 实例化对象 */
        val defFuncId = DefFuncId()
        /** 查询 M 或 L 信息点 */
        val infosList = select(
            SFilter.eq("projectId", Opt.projectId!!), SFilter.eq("classCode", code),
           SFilter.not(SFilter.eq("category","STATIC"))
        ).exec()
        /** 编码赋值 */
        defFuncId.code = code
        /** 名称赋值 */
        defFuncId.name = name
        /** 列表赋值 */
        defFuncId.content = infosList
        /** 返回对象 */
        return defFuncId
    }

    /**
     * 设备、部件、系统、空间 M 或 L 信息点统计
     *
     * @param code  编码
     * @param name  名称
     * @return 信息点对象
     */
    private fun typeStatisticsTwo(code: String,name:String): DefFuncId {
        /** 返回对象 */
        val defFuncId = DefFuncId()
        /** 名称 */
        defFuncId.name = name
        /** 编码 */
        defFuncId.code = code
        /** 对象列表 */
        var equipList = ArrayList<DefFuncId>()
        /** 查询  */
        val typeList = defClassService.select(
            SFilter.eq("parentCode", code),
            SFilter.eq("projectId", Opt.projectId!!)
        ).exec()
        /** 遍历列表 */
        for (type in typeList){
            /** 实例化对象 */
            val defFuncId = DefFuncId()
            /** 名称 */
            defFuncId.name = type.name
            /** 编码 */
            defFuncId.code = type.code
            /** 查询 */
            val equipInfosList = select(
                SFilter.eq("projectId", Opt.projectId!!), SFilter.eq("classCode", type.code!!),
                SFilter.not(SFilter.eq("category","STATIC"))
            ).exec()
            /** 列表赋值 */
            defFuncId.content = equipInfosList
            /** 添加到列表 */
            equipList.add(defFuncId)
        }

        /** 列表赋值 */
        defFuncId.content = equipList
        /** 返回对象 */
        return defFuncId
    }


    /**
     * 查询设备、部件、系统、专业类型
     *
     * @param categoryRequest   类型查询对象
     * @return 返回结果
     */
    fun equipQuery(categoryRequest: CategoryRequest): SQueryResponse<DefClass> {
        val sQueryResponse = SQueryResponse<DefClass>()
        if (!categoryRequest.type.isNullOrEmpty()){
            var dictSchemeCategoryList = ArrayList<DefClass>()
                var queryBuilder : SQueryBuilder<DefClass>? = null
                var pageInfo : SPageQueryInfo<DefClass>? = null
                when (categoryRequest.type) {
                    "equipment" -> {
//                    queryBuilder = select(SFilter.eq(SLength("id"), 4), SFilter.not(SFilter.isNull("parentId")))
//                    pageInfo = queryBuilder.pageQuery(1, 1000)

                        dictSchemeCategoryList = defClassService.select(
                                SFilter.eq("parentCode","equipment"),
                                SFilter.eq("type","common")
                        ).order("code").exec()

                    }
                    "component" -> {
//                    queryBuilder = select(SFilter.eq(SLength("id"), 6), SFilter.not(SFilter.isNull("parentId")),
//                        SFilter.not(SFilter.eq("parentId","Space")),SFilter.not(SFilter.eq("name","租户"))
//                    )
//                    pageInfo = queryBuilder.pageQuery(1, 1000)
                        dictSchemeCategoryList = defClassService.select(
                                SFilter.eq("parentCode","component"),
                                SFilter.eq("type","common")
                        ).order("code").exec()
                    }
                    "system" -> {
//                    queryBuilder = select(SFilter.eq(SLength("id"), 2), SFilter.not(SFilter.eq("parentId","AllProfessionalSystemEquipment")))
//                    pageInfo = queryBuilder.pageQuery(1, 1000)
                        dictSchemeCategoryList = defClassService.select(
                                SFilter.eq("parentCode","system"),
                                SFilter.eq("type","common")
                        ).exec()
                    }
                    "major" -> {
//                    queryBuilder = select(SFilter.eq(SLength("id"), 2), SFilter.eq("parentId","AllProfessionalSystemEquipment"))
////                    pageInfo = queryBuilder.pageQuery(1, 1000)
                        val dictMajorList = dictMajorService.selectAll().exec()
                        if (dictMajorList.size>0){
                            for (dictMajor in dictMajorList){
                                val defClass = DefClass()
                                defClass.code = dictMajor.code
                                defClass.name = dictMajor.name
                                defClass.aliasName = dictMajor.aliasName
                                defClass.aliasCode = dictMajor.aliasCode
                                dictSchemeCategoryList.add(defClass)
                            }
                        }
                    }
                    "majorSystem" -> {
//                    val listClassDef = DClassDefService.select(SFilter.eq("parentId", "AllProfessionalSystemEquipment")).exec()
//                    for (classDef in listClassDef){
//                        val exec = DClassDefService.select(SFilter.eq("parentId", classDef.id!!)).exec()
//                        classDef.listClassDef = exec
//                    }
//                    pageInfo = SPageQueryInfo(1, 1000)
//                    pageInfo.content  = listClassDef
                        val dictMajorList = dictMajorService.selectAll().exec()
                        if (dictMajorList.size>0){
                            for (dictMajor in dictMajorList){
                                val defClass = DefClass()
                                defClass.code = dictMajor.code
                                defClass.name = dictMajor.name
                                defClass.aliasName = dictMajor.aliasName
                                defClass.aliasCode = dictMajor.aliasCode
                                val defClassList = defClassService.select(
                                        SFilter.eq("parentCode", "system"),
                                        SFilter.eq("type","common"),
                                        SFilter.eq("majorCode", defClass.code!!)
                                ).exec()
                                defClass.children = defClassList
                                dictSchemeCategoryList.add(defClass)
                            }
                        }
                    }
                    "space" -> {
                        /** 业务空间类型 */
                        dictSchemeCategoryList = defClassService.select(
                                SFilter.eq("parentCode","space"),
                                SFilter.eq("type","common")
                        ).exec()
                    }
                    "majorEquipment" -> {
                        /** 专业下的设备 */
                        val dictMajorList = dictMajorService.selectAll().exec()
                        if (dictMajorList.size>0){
                            for (dictMajor in dictMajorList){
                                val defClass = DefClass()
                                defClass.code = dictMajor.code
                                defClass.name = dictMajor.name
                                defClass.aliasName = dictMajor.aliasName
                                defClass.aliasCode = dictMajor.aliasCode
                                val defClassList = defClassService.select(
                                        SFilter.eq("parentCode", "equipment"),
                                        SFilter.eq("type","common"),
                                        SFilter.eq("majorCode", defClass.code!!)
                                ).exec()
                                defClass.children = defClassList
                                dictSchemeCategoryList.add(defClass)
                            }
                        }
                    }
                    "equipmentAndComponent" -> {
                        /** 设备和部件 */
                        dictSchemeCategoryList = defClassService.select(
                                SFilter.or(SFilter.eq("parentCode","component"),
                                        SFilter.eq("parentCode","equipment")),
                                SFilter.eq("type","common")

                        ).exec()
                    }
                    "equipmentComponent" ->{
                        /** 设备下的部件 */
                        dictSchemeCategoryList = defClassService.select(
                                SFilter.eq("parentCode","equipment"),
                                SFilter.eq("type","common")
                        ).exec()
                        val defClassList = defClassService.select(
                                SFilter.eq("parentCode", "component"),
                                SFilter.eq("type","common")
                        ).exec()
                        if (dictSchemeCategoryList.size > 0){
                            for (dictSchemeCategory in dictSchemeCategoryList){
                                var list = ArrayList<DefClass>()
                                for (defClass in defClassList){
                                    if (defClass.equipmentCode == dictSchemeCategory.code){
                                        list.add(defClass)
                                    }
                                }
                                if (list.size>0){
                                    dictSchemeCategory.children = list
                                }
                            }
                        }
                    }
                    "majorSystemEquip" -> {
                        /** 专业下的系统，系统下的设备 */
                        val dictMajorList = dictMajorService.selectAll().exec()
                        if (dictMajorList.size>0){
                            for (dictMajor in dictMajorList){
                                val defClass = DefClass()
                                defClass.code = dictMajor.code
                                defClass.name = dictMajor.name
                                defClass.aliasName = dictMajor.aliasName
                                defClass.aliasCode = dictMajor.aliasCode
                                dictSchemeCategoryList.add(defClass)
                            }
                        }
                        /** 系统 */
                        val systemList = defClassService.select(
                                SFilter.eq("parentCode", "system"),
                                SFilter.eq("type","common")
                        ).exec()
                        /** 设备 */
                        val equipmentList = defClassService.select(
                                SFilter.eq("parentCode","equipment"),
                                SFilter.eq("type","common")
                        ).exec()
                        /** 系统下的设备 */
                        for (system in systemList){
                            for (equipment in equipmentList){
                                if (system.code == equipment.systemCode){
                                    if (system.children.isNullOrEmpty()){
                                        system.children = ArrayList<DefClass>()
                                    }
                                    system.children!!.add(equipment)
                                }
                            }
                        }
                        /** 专业下的系统 */
                        for (system in systemList){
                            for (dictMajor in dictSchemeCategoryList){
                                if (dictMajor.code == system.majorCode ){
                                    if (dictMajor.children.isNullOrEmpty()){
                                        dictMajor.children = ArrayList<DefClass>()
                                    }
                                    dictMajor.children!!.add(system)
                                }
                            }
                        }
                    }
                    "property" -> {
                        /** 资产 */
                        val familyList = familyService.selectAll().exec()
                        for (family in familyList){
                            val defClass = DefClass()
                            defClass.code = family.code
                            defClass.name = family.name
                            defClass.aliasName = family.code
                            defClass.aliasCode = family.name
                            dictSchemeCategoryList.add(defClass)
                        }
                    }
                }
                sQueryResponse.result = SResponseType.success
                sQueryResponse.content = dictSchemeCategoryList
                sQueryResponse.total = dictSchemeCategoryList.size.toLong()
        }else{
            sQueryResponse.result = SResponseType.failure
            sQueryResponse.message = "请输入查询类型"
        }
        return sQueryResponse
    }

    /**
     * 查询项目下对象类型对应的信息点
     *
     * @param request   查询条件
     * @return 返回结果
     */
    fun categoryInfoQuery(request: DictSQueryRequest): SQueryResponse<DefFuncIdGather> {
        /** 项目id */
        val projectId = SPageContext.getHeader("projectId")
        /** 返回对象 */
        val sQueryResponse = SQueryResponse<DefFuncIdGather>()
        sQueryResponse.result = SResponseType.failure
        /** 类型不能为空 */
        if (!request.type.isNullOrEmpty()) {

                /** 项目定制已存在直接返回 */
                if(request.type!!.length == 3){
                    val defFuncIdGatherList = defFuncIdGatherService.select(SFilter.eq("classCode", request.type!!)).exec()
                    if (defFuncIdGatherList.size>0) {
                        val dictDefFuncBuilder = defFuncIdGatherService.select(
                                SFilter.eq("classCode", request.type!!)
                        )
                        val dictDefFuncList = dictDefFuncBuilder.table("dict.def_funcid_project").order("sort").exec()
                        sQueryResponse.content = dictDefFuncList
                        sQueryResponse.total = dictDefFuncList.size.toLong()
                    }else {
                        val familyList = equipFamilyService.select(SFilter.eq("family", request.type!!)).exec()
                        if (familyList.size>0){
                            val equipFamily = familyList[0]
//                            schemeService.dictInfoProperty(projectId!!, dictProject.groupCode!!, equipFamily.equipCode!!,request.type!!)
                        }
                    }

                }else {
                    val dictDefFuncBuilder = defFuncIdGatherService.select(request.filters).filter(
                            SFilter.eq("type","common"),
                            SFilter.eq("classCode", request.type!!))
                    /** 过滤 */
                    if (null != request.projection) {
                        dictDefFuncBuilder.projection(request.projection!!)
                    }
                    /** 排序 */
                    if (null != request.orders) {
                        dictDefFuncBuilder.order(request.orders!!)
                    }

                    /** 去重 */
                    if (null != request.distinct && request.distinct!!) {
                        dictDefFuncBuilder.distinct()
                    }
                    val dictDefFuncList = dictDefFuncBuilder.table("dict.def_funcid_gather").order("sort").exec()
                    sQueryResponse.content = dictDefFuncList
                    sQueryResponse.total = dictDefFuncList.size.toLong()
                    sQueryResponse.result = SResponseType.success
                }

        }else {
            return  defFuncIdGatherService.pageQuery(request, arrayListOf(SFilter.eq("projectId", projectId!!)))
        }
        return sQueryResponse
    }

    /**
     * 项目定制化设置
     *
     * @param request   字典信息列表
     * @return 返回结果
     */
    fun settingDict(request: SCreateRequest<DefFuncIdGather>): SCreateResponse<DefFuncIdGather> {
        /** 返回对象实例 */
        val sCreateResponse = SCreateResponse<DefFuncIdGather>()
        sCreateResponse.result = SResponseType.failure
        return try {
            /** 数组不为空 */
            if (!request.content.isNullOrEmpty()) {
                /** 遍历字典信息列表 */
                for (dictProject in request.content) {
                    try {
                        /** 插入字典信息数据 */
                        defFuncIdGatherService.update(dictProject)
                    } catch (e: Exception) {
                        e.printStackTrace()
                    }
                }
                sCreateResponse.result = SResponseType.success
                sCreateResponse.entityList = request.content
                sCreateResponse
            } else {
                sCreateResponse
            }
        } catch (e: Exception) {
            e.printStackTrace()
            sCreateResponse.message = e.message!!
            sCreateResponse
        }
    }

    /**
     * 同步到项目
     */
    fun synDictProject(): SCreateResponse<DefFuncIdGather>{

        try {
            customSqlService.updateVisible()
            customSqlService.updateVisibleMain()
        } catch (e: Exception) {
            e.localizedMessage
        }

        return SCreateResponse(SResponseType.success)
    }


}