/*
 * ********************************************************************************************************************
 *
 *               iFHS7.
 *              ;BBMBMBMc                  rZMBMBR              BMB
 *              MBEr:;PBM,               7MBMMEOBB:             BBB                       RBW
 *     XK:      BO     SB.     :SZ       MBM.       c;;     ir  BBM :FFr       :SSF:    ;xBMB:r   iuGXv.    i:. iF2;
 *     DBBM0r.  :D     S7   ;XMBMB       GMBMu.     MBM:   BMB  MBMBBBMBMS   WMBMBMBBK  MBMBMBM  BMBRBMBW  .MBMBMBMBB
 *      :JMRMMD  ..    ,  1MMRM1;         ;MBMBBR:   MBM  ;MB:  BMB:   MBM. RMBr   sBMH   BM0         UMB,  BMB.  KMBv
 *     ;.   XOW  B1; :uM: 1RE,   i           .2BMBs  rMB. MBO   MBO    JMB; MBB     MBM   BBS    7MBMBOBM:  MBW   :BMc
 *     OBRJ.SEE  MRDOWOR, 3DE:7OBM       .     ;BMB   RMR7BM    BMB    MBB. BMB    ,BMR  .BBZ   MMB   rMB,  BMM   rMB7
 *     :FBRO0D0  RKXSXPR. JOKOOMPi       BMBSSWBMB;    BMBB:    MBMB0ZMBMS  .BMBOXRBMB    MBMDE RBM2;SMBM;  MBB   xBM2
 *         iZGE  O0SHSPO. uGZ7.          sBMBMBDL      :BMO     OZu:BMBK,     rRBMB0;     ,EBMB  xBMBr:ER.  RDU   :OO;
 *     ,BZ, 1D0  RPSFHXR. xWZ .SMr                  . .BBB
 *      :0BMRDG  RESSSKR. 2WOMBW;                   BMBMR
 *         i0BM: SWKHKGO  MBDv
 *           .UB  OOGDM. MK,                                          Copyright (c) 2015-2019.  斯伯坦机器人
 *              ,  XMW  ..
 *                  r                                                                     All rights reserved.
 *
 * ********************************************************************************************************************
 */

package com.sybotan.android.demo.activities

import android.annotation.SuppressLint
import android.graphics.PointF
import android.os.Bundle
import android.text.TextUtils
import android.view.Gravity
import android.widget.*
import cn.hutool.core.util.IdUtil
import cn.sagacloud.android.cadengine.FloorScene
import cn.sagacloud.android.cadengine.items.*
import cn.sagacloud.android.cadengine.types.*
import com.framework.mvvm.model.db.entity.task.InfosforEq
import com.framework.mvvm.model.db.entity.task.ObjectEntity
import com.framework.mvvm.model.db.entity.task.RelationEntity
import com.google.gson.Gson
import com.sybotan.android.demo.R
import com.sybotan.android.demo.bean.RelConfigEntityPackClass
import com.sybotan.android.demo.bean.RelationPackClass
import com.sybotan.android.demo.bean.SpaceInfo
import com.sybotan.android.demo.bean.SpaceNameModel
import com.sybotan.android.demo.bean.result.*
import com.sybotan.android.demo.entitiies.Floor
import com.sybotan.android.demo.graphy.GraphyHelper
import com.sybotan.android.demo.retrofit.Constant
import com.sybotan.android.demo.tools.CommonUtils
import com.sybotan.android.demo.tools.Lasso
import com.sybotan.android.demo.tools.ObjectNameUtils
import com.sybotan.android.demo.tools.ToastUtils
import com.sybotan.android.demo.view.ObjectRelationDialog
import com.sybotan.android.demo.view.SelectListSinglePopupWindow
import com.sybotan.android.demo.viewmodel.ChooseSpaceVM
import com.sybotan.android.graphy.SGraphyView
import com.sybotan.base.utils.SJsonUtil
import org.jetbrains.anko.doAsync
import org.jetbrains.anko.uiThread
import org.kodein.di.DI
import org.kodein.di.DIAware
import org.kodein.di.android.closestDI
import java.lang.StringBuilder
import kotlin.collections.ArrayList

/**
 * 平面图选择空间
 */
class ChooseEquipActivity : BaseActivity(), DIAware {

    override val di: DI by closestDI()

    /** viewModel */
    lateinit var chooseSpaceVM: ChooseSpaceVM

    /** 建筑Id */
    private lateinit var buildingId: String

    /** 楼层Id */
    private lateinit var floorId: String
    private lateinit var projectId: String
    private lateinit var deviceId: String
    private var scale: Float = 0f
    private lateinit var area: ServeAreaItem
    private lateinit var centerPoint: PointF
    private lateinit var position: Position
    var chooseSpaceList = ArrayList<TunableSpaceItem>()
    var chooseRelList = ArrayList<RelationEntity>()
    var chooseEquips = ArrayList<ObjectEntity>()
    var spaceIdList = ArrayList<String>()

    /** 楼层地图 */
    private lateinit var floorMap: String

    var scene = FloorScene()
    private val gson = Gson()
    private lateinit var floors: ArrayList<Floor>
    private lateinit var groupRelConfigEntity: RelConfigEntityPackClass

    private lateinit var graphyView: SGraphyView
    private lateinit var close: TextView
    private lateinit var save: TextView
    private lateinit var floorTv: TextView
    private lateinit var spaceName: TextView
    private lateinit var direction: TextView
    private lateinit var root: LinearLayout
    private lateinit var spaces: ArrayList<ObjectEntity>
    private lateinit var equips: ArrayList<ObjectEntity>

    /** 实际距离 */
    val distance = 3000f

    /** 缩放后的同比例距离 */
    var realDistance = 0f

    /**
     * 创建Activity时的回调函数
     *
     * @param   savedInstanceState
     */
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_choose_equip)
        initView()

        /** 初始化数据 */
        initData()
        graphyView.scene = scene

        /** 点击监听 */
        initListener()
        /** 图形点击-poc业务 */
        initSingleTopUp()
        /** 网络请求回调处理 */
        initViewModel()

        return
    } // Function onCreate()


    private fun initView() {
        graphyView = findViewById(R.id.graphyView)
        close = findViewById(R.id.close)
        save = findViewById(R.id.save)
        floorTv = findViewById(R.id.floorTv)
        root = findViewById(R.id.root)
        spaceName = findViewById(R.id.spaceName)
        direction = findViewById(R.id.direction)
    }

    /**
     * 初始化数据
     */
    private fun initData() {
        val params = intent.getBundleExtra("params")!!
        buildingId = params.getString("buildingId", "")!!
        floorId = params.getString("floorId", "")!!
        floorMap = params.getString("floorMap", "")!!
        projectId = params.getString("projectId", "")!!
        deviceId = params.getString("deviceId", "")!!
        scale = params.getFloat("scale")!!
        centerPoint = params.getParcelable("centerPoint")!!
        groupRelConfigEntity = (params.getSerializable("groupRelConfigEntity") as RelConfigEntityPackClass?)!!
        position = (params.getSerializable("position") as Position?)!!
        val p = Point()
        p.mX = position.x.toFloat()
        p.mY = position.y.toFloat()
        val equipItem = EquipItem(this, p)
        equipItem.zOrder = 100000f
        scene.addItem(equipItem)
        if (groupRelConfigEntity.targetTypes[0].canFrom) {
            direction.text = "<-"
        } else {
            direction.text = "->"
        }
        if (groupRelConfigEntity.targetTypes[0].canFrom && groupRelConfigEntity.targetTypes[0].canTo) {
            direction.setOnClickListener {
                if (direction.text.equals("->")) {
                    direction.text = "<-"
                } else {
                    direction.text = "->"
                }
            }
        }
    }


    /**
     * 图形点击事件
     * */
    private fun initSingleTopUp() {
        scene.setOnSingleTopUp(object : FloorScene.OnSingleTopUp {
            @SuppressLint("SetJavaScriptEnabled")
            override fun onSingUp(x: Float, y: Float) {
                realDistance = distance * scene.defaultPointScale / graphyView.scale

                var hasChooseEquip = false
                var equipList = ArrayList<EquipItem>()

                for (point in scene.equipList) {
                    val sqrt = Math.sqrt(
                        Math.pow(
                            Math.abs(x - point.data.mX).toDouble(),
                            2.0
                        ) + Math.pow(Math.abs(y - point.data.mY).toDouble(), 2.0)
                    ).toInt()
                    if (sqrt < realDistance && !hasChooseEquip) {
                        for (equip in equips) {
                            if (equip.id == point.data.deviceId) {
                                hasChooseEquip = true
                                if (point.data.equipState == 4) {
                                    point.data.equipState = 1
                                    for (rel in chooseRelList) {
                                        if (rel.objFrom.equals(point.data.deviceId) || rel.objTo.equals(point.data.deviceId)) {
                                            chooseRelList.remove(rel)
                                            initRelName()
                                            break
                                        }
                                    }
                                    break
                                }
                                equipList.add(point)
                                val dialog = ObjectRelationDialog(
                                    this@ChooseEquipActivity,
                                    "该设备",
                                    equip,
                                    groupRelConfigEntity
                                )
                                dialog.show()
                                dialog.setOnSubmit {
                                    point.data.equipState = 4
                                    val relEntity = RelationEntity(
                                        id = IdUtil.simpleUUID(),
                                        projectId = projectId,
                                        buildingId = buildingId,
                                        floorId = floorId,
                                        graphCode = groupRelConfigEntity.entity.graphCode,
                                        relCode = groupRelConfigEntity.entity.relCode,
                                        objFrom = null,
                                        objTo = null,
                                        valid = 1,
                                        state = 0
                                    )
                                    if (it) {
                                        relEntity.objFrom = deviceId
                                        relEntity.objTo = equip.id
                                        relEntity.objFromLocalId = "该设备"
                                        relEntity.objToLocalId = ObjectNameUtils.getEquipName(equip)
                                    } else {
                                        relEntity.objTo = deviceId
                                        relEntity.objFrom = equip.id
                                        relEntity.objFromLocalId = ObjectNameUtils.getEquipName(equip)
                                        relEntity.objToLocalId = "该设备"
                                    }
                                    chooseRelList.add(relEntity)
                                    initRelName()
                                }
                                break
                            }
                        }
                    }
                }

                if (!hasChooseEquip) {

                }
            }

        })
    }


    /**
     * 页面全部监听事件
     */
    private fun initListener() {
        floorTv.setOnClickListener {
            val pop = SelectListSinglePopupWindow(this)
            pop.setGenList(floors, Constant.TYPE5)
            pop.setTitle(true, "选择对象")
            pop.showAtLocation(root, Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL, 0, 0)
            pop.setOnItemClickListener {
                val floor = floors[it]
                floorTv.text = floor.localName
                floorId = floor.id
                chooseSpaceVM.getFloorMap(floorId)
            }
        }
        close.setOnClickListener { finish() }
        save.setOnClickListener {
            if (CommonUtils.IsNull(chooseRelList)) {
                ToastUtils.showMyToast("请创建关系")
                return@setOnClickListener
            }
            chooseSpaceVM.insRel(chooseRelList, groupRelConfigEntity, deviceId)
        }
    }

    /**
     * 初始化viewModel
     */
    private fun initViewModel() {
        chooseSpaceVM = ChooseSpaceVM(this.application, { name, params ->
            when (name) {
                /** 加载地图 */
                ChooseSpaceVM.MAP_LOAD -> {
                    val floorOfflineData = gson.fromJson(params.toString(), FloorData::class.java)
                    doAsync {
                        scene.loadData(floorOfflineData)
                        uiThread {
                            graphyView.setCenterPoint(centerPoint, scale)
                            chooseSpaceVM.getFloorList()
                            chooseSpaceVM.getRel(deviceId, groupRelConfigEntity)
                            initRelName()
                        }
                    }
                }

                /** 设备关系 */
                ChooseSpaceVM.EQUIP_RELATION -> {
                    val param = params as ArrayList<RelationPackClass>
                    for (pa in param) {
                        chooseRelList.add(pa.entity)
                    }
                    initRelName()
                }
                ChooseSpaceVM.FLOORS_LIST -> {
                    floors = params as ArrayList<Floor>
                    for (floor in floors) {
                        if (floorId == floor.id) {
                            floorTv.setText(floor.localName)
                            chooseSpaceVM.getEquips(floorId, groupRelConfigEntity)
                        }
                    }
                }
                ChooseSpaceVM.FLOOR_MAP -> {
                    val floorOfflineData = SJsonUtil.fromJson(params.toString(), FloorData::class.java)
                    doAsync {
                        scene = FloorScene()
                        graphyView.scene = scene
                        scene.loadData(floorOfflineData!!)
                        uiThread {
                            initSingleTopUp()
                            for (space in chooseSpaceList) {
                                if (space.data.floorId == floorId) {
                                    scene.addItem(space)
                                }
                            }
                            initRelName()
                            chooseSpaceVM.getEquips(floorId, groupRelConfigEntity)
                            graphyView.fitSceneToView()
                        }
                    }
                }
                ChooseSpaceVM.EQUIPS -> {
                    if (params != null) {
                        equips = params as ArrayList<ObjectEntity>
                        for (equip in equips) {
                            val info = gson.fromJson(equip.infos, InfosforEq::class.java)
                            val point = Point()
                            point.mX = info.location.x()
                            point.mY = -info.location.y()
                            point.equipState = 1
                            point.equipType = 1
                            point.deviceId = equip.id
                            point.name = equip.localName
                            val item = EquipItem(this, point)
                            item.isVisible = true
                            item.zOrder = 1000001f
                            scene.equipList.add(item)
                            scene.addItem(item)

                        }
                    }
                    for (rel in chooseRelList) {
                        for (point in scene.equipList) {
                            if (point.data.deviceId.equals(rel.objFrom) || point.data.deviceId.equals(rel.objTo)) {
                                point.data.equipState = 4
                                break
                            }
                        }
                    }
                }

            }
        }, this, buildingId, floorId, projectId)
        chooseSpaceVM.getMap()

    }

//    private fun initSpaceName() {
//        val sb = StringBuilder()
//        val others = ArrayList<SpaceNameModel>()
//        sb.append(floorTv.text.toString()).append("：")
//        for (space in chooseSpaceList) {
//            if (space.data.floorName == floorTv.text.toString()) {
//                sb.append(space.data.name).append("、")
//            } else {
//                var has = false
//                for (other in others) {
//                    if (other.name == space.data.floorName) {
//                        other.size++
//                        has = true
//                    }
//                }
//                if (!has) {
//                    others.add(SpaceNameModel(space.data.floorName, 1))
//                }
//            }
//        }
//        sb.append("\n\n其他层：\n")
//        for (other in others) {
//            sb.append("${other.name}(${other.size})、")
//        }
//        spaceName.text = sb.toString()
//    }

    private fun initRelName() {

        val sb = StringBuilder()
        for (rel in chooseRelList) {
            sb.append(rel.objFromLocalId).append("->").append(rel.objToLocalId).append("、")
        }
        spaceName.text = sb.toString()
    }


} // Class GraphyActivity
