package com.casic.common.detector.gd.view

import android.app.Activity
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.graphics.BitmapFactory
import android.graphics.Color
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.media.AudioAttributes
import android.media.SoundPool
import android.os.Bundle
import android.os.Handler
import android.os.IBinder
import android.os.Message
import android.util.Log
import android.view.KeyEvent
import android.view.View
import androidx.activity.result.contract.ActivityResultContracts
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import com.amap.api.location.AMapLocation
import com.amap.api.maps.AMap
import com.amap.api.maps.AMapOptions
import com.amap.api.maps.CameraUpdateFactory
import com.amap.api.maps.CoordinateConverter
import com.amap.api.maps.model.BitmapDescriptorFactory
import com.amap.api.maps.model.LatLng
import com.amap.api.maps.model.LatLngBounds
import com.amap.api.maps.model.Marker
import com.amap.api.maps.model.MarkerOptions
import com.amap.api.maps.model.MyLocationStyle
import com.casic.common.detector.gd.R
import com.casic.common.detector.gd.base.BaseApplication
import com.casic.common.detector.gd.bean.MarkerLocalBean
import com.casic.common.detector.gd.bean.TaskLocalBean
import com.casic.common.detector.gd.callback.OnGetAddressListener
import com.casic.common.detector.gd.callback.OnGetLocationListener
import com.casic.common.detector.gd.callback.OnSerialPortListener
import com.casic.common.detector.gd.cluster.ClusterItem
import com.casic.common.detector.gd.cluster.ClusterOverlay
import com.casic.common.detector.gd.cluster.ClusterRender
import com.casic.common.detector.gd.cluster.OnClickClusterListener
import com.casic.common.detector.gd.cluster.RegionItem
import com.casic.common.detector.gd.databinding.ActivityMainBinding
import com.casic.common.detector.gd.extensions.appendDownloadUrl
import com.casic.common.detector.gd.extensions.createTaskCode
import com.casic.common.detector.gd.extensions.drawCircle
import com.casic.common.detector.gd.extensions.handleSignalStrength
import com.casic.common.detector.gd.extensions.hexToString
import com.casic.common.detector.gd.extensions.initImmersionBar
import com.casic.common.detector.gd.extensions.isNumber
import com.casic.common.detector.gd.extensions.toDegree
import com.casic.common.detector.gd.extensions.toHex
import com.casic.common.detector.gd.model.TaskDetailLocalModel
import com.casic.common.detector.gd.model.TaskModel
import com.casic.common.detector.gd.service.NtripConnectService
import com.casic.common.detector.gd.service.SerialPortService
import com.casic.common.detector.gd.utils.DataBaseManager
import com.casic.common.detector.gd.utils.ExcelTool
import com.casic.common.detector.gd.utils.FileType
import com.casic.common.detector.gd.utils.LocaleConstant
import com.casic.common.detector.gd.utils.LocationTool
import com.casic.common.detector.gd.utils.RouteOnMap
import com.casic.common.detector.gd.vm.TaskViewModel
import com.casic.common.detector.gd.widgets.MarkerDetailDialog
import com.casic.common.detector.gd.widgets.QueryMarkerDialog
import com.casic.common.detector.gd.widgets.SamplePopupWindow
import com.pengxh.kt.lite.base.KotlinBaseActivity
import com.pengxh.kt.lite.extensions.convertDrawable
import com.pengxh.kt.lite.extensions.createDownloadFileDir
import com.pengxh.kt.lite.extensions.dp2px
import com.pengxh.kt.lite.extensions.isNetworkConnected
import com.pengxh.kt.lite.extensions.navigatePageTo
import com.pengxh.kt.lite.extensions.show
import com.pengxh.kt.lite.extensions.timestampToCompleteDate
import com.pengxh.kt.lite.extensions.toJson
import com.pengxh.kt.lite.utils.FileDownloadManager
import com.pengxh.kt.lite.utils.LoadState
import com.pengxh.kt.lite.utils.LoadingDialog
import com.pengxh.kt.lite.utils.SaveKeyValues
import com.pengxh.kt.lite.utils.WeakReferenceHandler
import com.pengxh.kt.lite.widget.TitleBarView
import com.pengxh.kt.lite.widget.dialog.AlertControlDialog
import com.pengxh.kt.lite.widget.dialog.AlertInputDialog
import com.pengxh.kt.lite.widget.dialog.AlertMessageDialog
import com.pengxh.kt.lite.widget.dialog.BottomActionSheet
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.File
import java.util.concurrent.CopyOnWriteArrayList


class MainActivity : KotlinBaseActivity<ActivityMainBinding>(), ClusterRender,
    OnClickClusterListener, OnSerialPortListener, Handler.Callback {

    //TODO 此代码正式版删除
    companion object {
        var weakReferenceHandler: WeakReferenceHandler? = null
    }

    private val kTag = "MainActivity"
    private val context = this
    private val samplePopupWindow by lazy { SamplePopupWindow(this) }
    private val backDrawables by lazy { HashMap<Int, Drawable>() }
    private val detailDialog by lazy { MarkerDetailDialog(this) }
    private val locationTool by lazy { LocationTool(this) }
    private val taskViewModel by lazy { ViewModelProvider(this)[TaskViewModel::class.java] }
    private val attr = AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_ALARM)
        .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC).build()
    private val soundPool = SoundPool.Builder().setMaxStreams(16).setAudioAttributes(attr).build()
    private var clickTime: Long = 0
    private var markers = ArrayList<MarkerLocalBean>()
    private var isFreeTask = false
    private var freeTaskTitle = ""
    private var ids = HashSet<String>()
    private var freeTaskId: String? = null
    private var serialPortService: SerialPortService? = null
    private var soundResourceId = 0
    private var isExecuteTask = false
    private lateinit var aMap: AMap

    override fun initViewBinding(): ActivityMainBinding {
        return ActivityMainBinding.inflate(layoutInflater)
    }

    override fun setupTopBarLayout() {
        binding.rootView.initImmersionBar(this, false, R.color.themeColor)
    }

    private val serviceConnection = object : ServiceConnection {
        override fun onServiceConnected(name: ComponentName?, iBinder: IBinder?) {
            if (iBinder is SerialPortService.ServiceBinder) {
                serialPortService = iBinder.getSerialPortService()
                Log.d(kTag, "onServiceConnected: 服务已绑定")
            }
        }

        override fun onServiceDisconnected(name: ComponentName?) {

        }
    }

    override fun initOnCreate(savedInstanceState: Bundle?) {
        weakReferenceHandler = WeakReferenceHandler(this)
        //绑定串口通信服务
        Intent(this, SerialPortService::class.java).also {
            bindService(it, serviceConnection, Context.BIND_AUTO_CREATE)
        }
        Intent(this, NtripConnectService::class.java).also {
            startService(it)
        }
        soundResourceId = soundPool.load(this, R.raw.ring3, 1)
        //地图初始化
        initMapConfig(savedInstanceState)
        //右上角菜单
        samplePopupWindow.setPopupMenuItem(LocaleConstant.POPUP_TITLES)
        samplePopupWindow.setBackgroundDrawable(null)

        //task网络请求监听
        taskViewModel.markerFileResult.observe(this) {
            if (it.isSuccess) {
                //清空之前的数据
                DataBaseManager.get.clearMarkers()
                //下载最新的数据
                val companyId = SaveKeyValues.getValue(LocaleConstant.USER_COMPANY_ID, "")
                val downloadUrl = companyId.toString().appendDownloadUrl(FileType.EXCEL)
                Log.d(kTag, "downloadUrl => $downloadUrl")
                FileDownloadManager.Builder().setDownloadFileSource(downloadUrl)
                    .setFileSuffix("xls").setFileSaveDirectory(createDownloadFileDir())
                    .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener {
                        override fun onDownloadEnd(file: File) {
                            lifecycleScope.launch(Dispatchers.Main) {
                                withContext(Dispatchers.IO) {
                                    markers = ExcelTool.read(file.absolutePath)
                                    markers.forEach { marker ->
                                        DataBaseManager.get.saveMarkerInLocale(marker)
                                    }
                                }
                                LoadingDialog.dismiss()
                                showLabelsOnMap()
                            }
                        }

                        override fun onFailure(throwable: Throwable) {

                        }

                        override fun onProgressChanged(progress: Int) {

                        }
                    }).build().start()
            }
        }
        taskViewModel.taskResult.observe(this) {
            if (it.success == "true") {
                AlertMessageDialog.Builder().setContext(this).setTitle("温馨提示")
                    .setMessage("您有${it.message.size}个新任务！").setPositiveButton("知道了")
                    .setOnDialogButtonClickListener(object :
                        AlertMessageDialog.OnDialogButtonClickListener {
                        override fun onConfirmClick() {
                            saveUserTasks(it)
                        }
                    }).build().show()
            }
        }
        taskViewModel.freeTaskResult.observe(this) {
            freeTaskId = it
            // 自由巡检保存在本地
            val bean = TaskLocalBean()
            bean.id = freeTaskId.toString().toLong()
            val currentTimeMillis = System.currentTimeMillis()
            bean.taskCode = currentTimeMillis.createTaskCode()
            bean.description = freeTaskTitle
            val time = currentTimeMillis.timestampToCompleteDate()
            bean.createTime = time
            bean.status = "0"
            val userName = SaveKeyValues.getValue(LocaleConstant.USER_NAME, "") as String
            bean.createUserName = userName
            bean.startTime = time
            bean.endTime = ""
            bean.isFreeTask = "1"
            DataBaseManager.get.saveTaskInLocale(bean)
        }
        taskViewModel.uploadTaskMarkerResult.observe(this) {
            "自由巡检任务已完成".show(this)
            ids.clear()
            //清空自由巡检添加的Marker
            aMap.clear()
            showLabelsOnMap()
        }
        taskViewModel.executeTaskResult.observe(this) {
            "工单任务已完成".show(this)
            aMap.clear()
            showLabelsOnMap()
        }
    }

    override fun initEvent() {
        binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener {
            override fun onLeftClick() {

            }

            override fun onRightClick() {
                if (isFreeTask) {
                    AlertMessageDialog.Builder()
                        .setContext(context)
                        .setTitle("温馨提示")
                        .setMessage("正在自由巡检任务中，请完成此次任务之后再使用此功能")
                        .setPositiveButton("好的").setOnDialogButtonClickListener(object :
                            AlertMessageDialog.OnDialogButtonClickListener {
                            override fun onConfirmClick() {

                            }
                        }).build().show()
                } else {
                    lifecycleScope.launch(Dispatchers.Main) {
                        val markers = withContext(Dispatchers.IO) {
                            DataBaseManager.get.queryMarkerByState("0")
                        }
                        //如果有需要补全的标识器，Popup右侧会有小圆点提示
                        if (markers.isNotEmpty()) {
                            samplePopupWindow.setShowPosition(4)
                        }
                        samplePopupWindow.showAsDropDown(
                            binding.titleView, binding.titleView.width, (-17).dp2px(context)
                        )
                    }
                }
            }
        })

        samplePopupWindow.setOnPopupWindowClickListener(object :
            SamplePopupWindow.OnPopupWindowClickListener {
            override fun onPopupItemClicked(position: Int) {
                when (position) {
                    0 -> updateMarkers()
                    1 -> downloadTask()
                    2 -> navigatePageTo<VersionControlActivity>()
                    3 -> uploadEvent()
                    4 -> completionMarker()
                    5 -> {
                        Intent(this@MainActivity, RtkConfigActivity::class.java).also {
                            rtkConfigLauncher.launch(it)
                        }
                    }
                }
            }
        })

        //安装。上传，然后存入本地库
        binding.installButton.setOnClickListener {
            if (isFreeTask) {
                AlertMessageDialog.Builder().setContext(this).setTitle("温馨提示")
                    .setMessage("正在自由巡检任务中，请完成此次任务之后再使用此功能")
                    .setPositiveButton("好的").setOnDialogButtonClickListener(object :
                        AlertMessageDialog.OnDialogButtonClickListener {
                        override fun onConfirmClick() {

                        }
                    }).build().show()
            } else {
                navigatePageTo<InstallMarkerActivity>()
            }
        }

        //查看
        binding.viewButton.setOnClickListener {
            QueryMarkerDialog.Builder().setContext(this).setTitle("查看标识器")
                .setSpinnerArray(LocaleConstant.SPINNER_ARRAY).setNegativeButton("取消")
                .setPositiveButton("确定").setOnDialogButtonClickListener(object :
                    QueryMarkerDialog.OnDialogButtonClickListener {
                    override fun onConfirmClick(selectedItem: String, value: String) {
                        //查询数据库
                        lifecycleScope.launch(Dispatchers.Main) {
                            markers = withContext(Dispatchers.IO) {
                                DataBaseManager.get.loadMarkersByCondition(
                                    selectedItem, value
                                ) as ArrayList<MarkerLocalBean>
                            }

                            if (markers.isEmpty()) {
                                "无法查到相关数据信息，请检查您的查询条件".show(context)
                            } else {
                                val latitudeList = ArrayList<Double>()
                                val longitudeList = ArrayList<Double>()

                                val latitude = markers.first().lat
                                val longitude = markers.first().lng
                                if (latitude.isNotBlank() && longitude.isNotBlank()) {
                                    if (CoordinateConverter.isAMapDataAvailable(
                                            latitude.toDouble(), longitude.toDouble()
                                        )
                                    ) {
                                        //分别缓存经、纬度
                                        latitudeList.add(latitude.toDouble())
                                        longitudeList.add(longitude.toDouble())
                                    }
                                }

                                if (latitudeList.isNotEmpty() && longitudeList.isNotEmpty()) {
                                    //移动地图到所有labelBeans的第一个点
                                    val center = LatLng(latitudeList.first(), longitudeList.first())
                                    //移动到指定经纬度
                                    aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(center, 16f))
                                }

                                showLabelsOnMap()
                            }
                        }
                    }

                    override fun onCancelClick() {

                    }
                }).build().show()
        }

        //巡检
        binding.inspectionButton.setOnClickListener {
            val tasks = DataBaseManager.get.loadLocalTask()
            if (tasks.isNotEmpty()) {
                val arrayList = ArrayList<String>()
                tasks.forEachIndexed { index, task ->
                    arrayList.add("任务${index + 1}：${task.taskId}，${task.description}")
                }

                BottomActionSheet.Builder().setContext(this).setItemTextColor(Color.BLUE)
                    .setActionItemTitle(arrayList)
                    .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener {
                        override fun onActionItemClick(position: Int) {
                            val task = tasks[position]
                            Log.d(kTag, task.toJson())
                            SaveKeyValues.putValue(LocaleConstant.TASK_ID, task.taskId)
                            SaveKeyValues.putValue(LocaleConstant.TASK_CODE, task.taskCode)
                            AlertControlDialog.Builder().setContext(context).setTitle("提示")
                                .setMessage("请选择操作方式").setPositiveButton("执行工单")
                                .setNegativeButton("提交工单")
                                .setOnDialogButtonClickListener(object :
                                    AlertControlDialog.OnDialogButtonClickListener {
                                    override fun onConfirmClick() {
                                        if (task.markerModels.isNotEmpty()) {
                                            //移到Task下属第一个标识器位置
                                            val firstMarker = task.markerModels.first()
                                            val latLng = LatLng(firstMarker.lat, firstMarker.lng)
                                            aMap.moveCamera(
                                                CameraUpdateFactory.newLatLngZoom(latLng, 16f)
                                            )
                                            //执行工单
                                            uploadTask(task.taskId, task.taskCode, "1")
                                            detectRedrawGraphic(task)
                                            isExecuteTask = true
                                        } else {
                                            "此工单下无标识器，将执行自由巡检任务".show(context)
                                            freeTaskId = task.taskId
                                            openSerialPort()
                                        }
                                    }

                                    override fun onCancelClick() {
                                        //提交工单
                                        uploadTask(task.taskId, task.taskCode, "2")
                                        isExecuteTask = false
                                    }
                                }).build().show()
                        }
                    }).build().show()
            } else {
                AlertMessageDialog.Builder().setContext(this).setTitle("温馨提示")
                    .setMessage("所有任务已完成，请点击右上角菜单下载新工单或者开始自由巡检")
                    .setPositiveButton("开始自由巡检").setOnDialogButtonClickListener(object :
                        AlertMessageDialog.OnDialogButtonClickListener {
                        override fun onConfirmClick() {
                            startFreeTask()
                        }
                    }).build().show()
            }
        }

        //探测
        binding.detectionButton.setOnClickListener {
            /**
             * 如果开启自由巡检就不让探测
             * */
            if (isFreeTask) {
                AlertMessageDialog.Builder().setContext(this).setTitle("温馨提示")
                    .setMessage("正在自由巡检任务中，请完成此次任务之后再使用此功能")
                    .setPositiveButton("好的").setOnDialogButtonClickListener(object :
                        AlertMessageDialog.OnDialogButtonClickListener {
                        override fun onConfirmClick() {

                        }
                    }).build().show()
            } else {
                val flag = if (isExecuteTask) {
                    "1"
                } else {
                    "0"
                }
                navigatePageTo<SearchMarkerActivity>(flag)
                //TODO 章丘审计版本
//                navigatePageTo<SearchMarkerAuditActivity>()
            }
        }

        //自由巡检
        binding.stopFreeTaskButton.setOnLongClickListener {
            AlertMessageDialog.Builder().setContext(this).setTitle("温馨提示")
                .setMessage("是否确定结束此次自由巡检任务？").setPositiveButton("是")
                .setOnDialogButtonClickListener(object :
                    AlertMessageDialog.OnDialogButtonClickListener {
                    override fun onConfirmClick() {
                        isFreeTask = false
                        soundPool.autoPause()
                        serialPortService?.closeSerialPort()

                        binding.stopFreeTaskButton.visibility = View.GONE
                        if (freeTaskId.isNullOrBlank()) {
                            "任务ID异常，无法提交任务，请联系服务器管理员".show(context)
                            return
                        }

                        freeTaskId?.apply {
                            taskViewModel.uploadTaskMarker(context, this, ArrayList(ids))
                        }
                    }
                }).build().show()
            true
        }
    }

    //TODO 此代码正式版删除
    override fun handleMessage(msg: Message): Boolean {
        if (msg.what == 2024090301) {
            val gps = msg.obj as String
            //转为度分秒
            val lngLat = gps.split(",")
            val lng = lngLat[0].toDouble().toDegree()
            val lat = lngLat[1].toDouble().toDegree()
            binding.nativeGpsView.text = "$lng, $lat"
        }
        return true
    }

    private val rtkConfigLauncher =
        registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
            if (it.resultCode == Activity.RESULT_OK) {
                val referenceHandler = NtripConnectService.weakReferenceHandler
                    ?: return@registerForActivityResult
                referenceHandler.sendEmptyMessage(2024082201)
            }
        }

    private fun uploadTask(taskId: String, taskCode: String, state: String) {
        if (isNetworkConnected()) {
            val userId = SaveKeyValues.getValue(LocaleConstant.USER_ID, "") as String
            taskViewModel.uploadTask(this, userId, taskId, taskCode, state)
        } else {
            "网络连接已断开，请检查".show(this)
        }
    }

    private fun startFreeTask() {
        AlertInputDialog.Builder().setContext(this).setTitle("新建自由巡检任务")
            .setHintMessage("请输入自由巡检任务简要描述").setNegativeButton("取消")
            .setPositiveButton("确定")
            .setOnDialogButtonClickListener(object : AlertInputDialog.OnDialogButtonClickListener {
                override fun onConfirmClick(value: String) {
                    freeTaskTitle = value
                    val userId = SaveKeyValues.getValue(LocaleConstant.USER_ID, "") as String
                    taskViewModel.createFreeTask(context, userId, value)

                    openSerialPort()
                }

                override fun onCancelClick() {}
            }).build().show()
    }

    private fun openSerialPort() {
        binding.stopFreeTaskButton.visibility = View.VISIBLE
        isFreeTask = true
        serialPortService?.openSerialPort(arrayListOf('2', '6'), this)
    }

    override fun onDataReceived(buffer: ByteArray) {
        //只响一次，因为探测频率高，所以依旧是连续的报警声
        soundPool.play(soundResourceId, 1f, 1f, 0, 0, 1f)
        if (buffer.first() == 78.toByte()) {
            val energy = buffer.handleSignalStrength().take(10).hexToString()
            val signalStrength = energy.substring(1).toInt()
            if (signalStrength <= 1500 && detailDialog.isShowing) {
                detailDialog.dismiss()
            }
        }

        val hex = buffer.toHex()
        val markerId = hex.take(20).hexToString()
        if (markerId.isNumber()) {
            //添加地图Marker
            if (!ids.contains(markerId)) {
                //根据markerId查询标识器经纬度
                val labels = DataBaseManager.get.queryMarkerById(markerId)
                if (labels.isNotEmpty()) {
                    val bean = labels.first()
                    aMap.addMarker(
                        MarkerOptions().position(
                            LatLng(bean.lat.toDouble(), bean.lng.toDouble())
                        ).icon(
                            BitmapDescriptorFactory.fromResource(R.mipmap.label_blue1)
                        )
                    )
                }
            }
            ids.add(markerId)

            //显示标识器详细信息
            if (!detailDialog.isShowing) {
                val markerBean = DataBaseManager.get.queryMarkerById(markerId).firstOrNull()
                if (markerBean == null) {
                    "无法查询到此ID【${markerId}】的信息".show(context)
                } else {
                    detailDialog.setMarker(markerBean)
                    detailDialog.show()
                }
            }
        }
    }

    override fun observeRequestState() {
        taskViewModel.loadState.observe(this) {
            when (it) {
                LoadState.Loading -> LoadingDialog.show(this, "提交工单中，请稍后")

                else -> LoadingDialog.dismiss()
            }
        }
    }

    private fun initMapConfig(savedInstanceState: Bundle?) {
        binding.mapView.onCreate(savedInstanceState)
        aMap = binding.mapView.map

        val uiSettings = aMap.uiSettings
        uiSettings.isCompassEnabled = true
        uiSettings.isMyLocationButtonEnabled = false//不显示默认定位按钮
        uiSettings.isScaleControlsEnabled = true
        uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER
        uiSettings.isRotateGesturesEnabled = false//不许地图随手势旋转角度
        uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜
        //显示定位小蓝点
        val locationStyle = MyLocationStyle()
        locationStyle.radiusFillColor(Color.argb(0, 0, 0, 0))
        locationStyle.strokeColor(Color.argb(0, 0, 0, 0))
        locationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER)//定位、但不会移动到地图中心点，定位点依照设备方向旋转，并且会跟随设备移动。
        aMap.myLocationStyle = locationStyle//设置定位蓝点的Style
        aMap.isMyLocationEnabled = true//设置是否显示定位小蓝点
        aMap.setOnMyLocationChangeListener {
            //TODO 此代码正式版删除
            binding.gdGpsView.text = "${it.longitude}, ${it.latitude}"
            //经纬度逆编码
            locationTool.antiCodingLocation(it, object : OnGetAddressListener {
                override fun onGetAddress(address: String) {
                    binding.currentLocationView.text = address
                }
            })
        }

        //首次移动到定位点
        moveToCurrentLocation()

        aMap.setOnMapLongClickListener {
            //协程异步显示默认数据
            lifecycleScope.launch(Dispatchers.Main) {
                markers = withContext(Dispatchers.IO) {
                    DataBaseManager.get.loadMarkers() as ArrayList<MarkerLocalBean>
                }
                showLabelsOnMap()
            }
        }

        //自定义定位按钮
        binding.aimButton.setOnClickListener { moveToCurrentLocation() }
    }

    private fun moveToCurrentLocation() {
        locationTool.getCurrentLocation(true, object : OnGetLocationListener {
            override fun onSuccess(location: AMapLocation) {
                aMap.moveCamera(
                    CameraUpdateFactory.newLatLngZoom(
                        LatLng(location.latitude, location.longitude), 16f
                    )
                )
            }

            override fun onError() {
                "当前位置信号差，无法移动地图到定位点".show(context)
            }
        })
    }

    private fun saveUserTasks(task: TaskModel) {
        task.message.forEach { model ->
            //保存任务详情
            DataBaseManager.get.saveTaskInLocale(model)
            model.taskDetailInfos.forEach { marker ->
                //只保存有标识器ID得数据
                if (!marker.markerIdReal.isNullOrBlank()) {
                    DataBaseManager.get.saveTaskMarkerInLocale(model.id, model.taskCode, marker)
                }
            }
        }
        "工单下载成功！".show(this)
    }

    private var clusterOverlay: ClusterOverlay? = null

    private fun showLabelsOnMap() {
        val clusterItems = CopyOnWriteArrayList<ClusterItem>()
        if (clusterOverlay == null) {
            clusterOverlay = ClusterOverlay(
                this, aMap, clusterItems, LocaleConstant.RADIUS_SIZE.dp2px(this)
            )
        }
        clusterOverlay?.apply {
            setClusterRender(this@MainActivity)
            setOnClickClusterListener(this@MainActivity)
        }
        markers.forEach {
            if (it.lat.isNotEmpty() && it.lng.isNotEmpty()) {
                val latitude = it.lat.toDouble()
                val longitude = it.lng.toDouble()

                val latLng = LatLng(latitude, longitude, false)
                //用标识器的ID当作地图Marker的Title
                val regionItem = RegionItem(latLng, it.markerId.toString())
                clusterItems.add(regionItem)
            }
        }
    }

    override fun getDrawableByCount(clusterNum: Int): Drawable {
        //聚合点圆形半径
        val radius = 80.dp2px(this)
        if (clusterNum == 1) {
            var bitmapDrawable = backDrawables[1]
            if (bitmapDrawable == null) {
                bitmapDrawable = R.mipmap.label.convertDrawable(this)!!
                backDrawables[1] = bitmapDrawable
            }
            return bitmapDrawable
        } else if (clusterNum < 5) {
            var bitmapDrawable = backDrawables[2]
            if (bitmapDrawable == null) {
                bitmapDrawable = BitmapDrawable(
                    null, radius.drawCircle(Color.argb(159, 100, 149, 237))
                )
                backDrawables[2] = bitmapDrawable
            }
            return bitmapDrawable
        } else if (clusterNum < 10) {
            var bitmapDrawable = backDrawables[3]
            if (bitmapDrawable == null) {
                bitmapDrawable = BitmapDrawable(
                    null, radius.drawCircle(Color.argb(199, 30, 144, 255))
                )
                backDrawables[3] = bitmapDrawable
            }
            return bitmapDrawable
        } else {
            var bitmapDrawable = backDrawables[4]
            if (bitmapDrawable == null) {
                bitmapDrawable = BitmapDrawable(
                    null, radius.drawCircle(Color.argb(235, 65, 105, 225))
                )
                backDrawables[4] = bitmapDrawable
            }
            return bitmapDrawable
        }
    }

    override fun onClick(marker: Marker, clusterItems: MutableList<ClusterItem>) {
        if (clusterItems.size == 1) {
            val clusterItem = clusterItems[0]
            showNavigationOption(clusterItem.title, clusterItem.position)
        } else {
            //聚合点，显示聚合点列表
            val idArray = ArrayList<String>()
            for (clusterItem in clusterItems) {
                idArray.add(clusterItem.title)
            }
            BottomActionSheet.Builder()
                .setContext(this)
                .setItemTextColor(Color.BLUE)
                .setActionItemTitle(idArray)
                .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener {
                    override fun onActionItemClick(position: Int) {
                        val markerId = idArray[position]
                        //根据markerId找到标识器
                        val bean = markers.find { x -> x.markerId == markerId }!!
                        showNavigationOption(
                            bean.markerId, LatLng(bean.lat.toDouble(), bean.lng.toDouble())
                        )
                    }
                }).build().show()
        }
    }

    private fun showNavigationOption(title: String, latLng: LatLng) {
        //移动视图
        val builder = LatLngBounds.Builder()
        builder.include(latLng)
        val latLngBounds = builder.build()
        aMap.animateCamera(CameraUpdateFactory.newLatLngBounds(latLngBounds, 0))

        //显示导航选项
        AlertControlDialog.Builder()
            .setContext(this)
            .setTitle("提示")
            .setMessage("请选择操作方式")
            .setNegativeButton("标识器信息")
            .setPositiveButton("到这里去")
            .setOnDialogButtonClickListener(object :
                AlertControlDialog.OnDialogButtonClickListener {
                override fun onConfirmClick() {
                    RouteOnMap.startNavigation(context, title, latLng)
                }

                override fun onCancelClick() {
                    navigatePageTo<ObjectDetailActivity>(title)
                }
            }).build().show()
    }

    private fun detectRedrawGraphic(task: TaskDetailLocalModel) {
        task.markerModels.forEach {
            val latLng = LatLng(it.lat, it.lng)
            val markerOptions = MarkerOptions()
            markerOptions.position(latLng)
            markerOptions.visible(true) // 设置可见
            if (it.isDetected == "0") {
                markerOptions.icon(
                    BitmapDescriptorFactory.fromBitmap(
                        BitmapFactory.decodeResource(resources, R.mipmap.label_red1)
                    )
                ).title(it.markerId)
            } else {
                markerOptions.icon(
                    BitmapDescriptorFactory.fromBitmap(
                        BitmapFactory.decodeResource(resources, R.mipmap.label_blue1)
                    )
                ).title(it.markerId)
            }
            aMap.addMarker(markerOptions)
        }
        showLabelsOnMap()
    }

    //更新标识器数据
    private fun updateMarkers() {
        AlertControlDialog.Builder().setContext(this).setTitle("提示").setMessage("是否更新数据？")
            .setNegativeButton("取消").setPositiveButton("确定")
            .setOnDialogButtonClickListener(object :
                AlertControlDialog.OnDialogButtonClickListener {
                override fun onConfirmClick() {
                    if (isNetworkConnected()) {
                        val companyId = SaveKeyValues.getValue(LocaleConstant.USER_COMPANY_ID, "")

                        LoadingDialog.show(this@MainActivity, "获取标识器信息中，请稍后")
                        /**
                         * 后台设计如此，都传companyId
                         * */
                        taskViewModel.getMarkerFile(
                            context, companyId.toString(), companyId.toString()
                        )
                    } else {
                        "网络连接已断开，请检查".show(context)
                    }
                }

                override fun onCancelClick() {

                }
            }).build().show()
    }

    //下载工单
    private fun downloadTask() {
        if (isNetworkConnected()) {
            val userName = SaveKeyValues.getValue(LocaleConstant.USER_NAME, "")
            taskViewModel.getTasksByUser(this, userName.toString())
        } else {
            "网络连接已断开，请检查".show(this)
        }
    }

    private fun uploadEvent() {
        val taskId = SaveKeyValues.getValue(LocaleConstant.TASK_ID, "") as String
        if (taskId == "") {
            "已完成全部巡检".show(this)
            return
        }

        navigatePageTo<UploadEventActivity>()
    }

    //标识器补全
    private fun completionMarker() {
        val companyId = SaveKeyValues.getValue(LocaleConstant.USER_COMPANY_ID, "") as String
        val markers = DataBaseManager.get.queryMarkerByState("0")
        if (markers.isNotEmpty()) {
            //TODO 逻辑没梳理明白
//            LoadingDialog.show(this, "标识器补全中，请稍后...")
//            markers.forEach { marker ->
//                taskViewModel.installLabel(
//                    this,
//                    companyId,
//                    labelBean.objectType,
//                    labelBean.pipelineType,
//                    labelBean.pipelineMaterial,
//                    labelBean.pipelineDiameter,
//                    labelBean.buryDeep,
//                    labelBean.lowerType,
//                    labelBean.lowerMaterial,
//                    labelBean.lowerDiameter,
//                    labelBean.lowerDeep,
//                    labelBean.buryMethod,
//                    labelBean.area,
//                    labelBean.line,
//                    labelBean.road,
//                    labelBean.constructTime,
//                    labelBean.owner,
//                    labelBean.objectId,
//                    labelBean.identifierId,
//                    labelBean.identifierType,
//                    labelBean.identifierDeep,
//                    labelBean.person,
//                    labelBean.installTime,
//                    labelBean.lng,
//                    labelBean.lat,
//                    labelBean.color,
//                    labelBean.remark,
//                    arrayListOf()
//                )
//            }
//            LoadingDialog.dismiss()
        } else {
            "没有需要补传的标识器！".show(this)
        }
    }

    override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
        return if (keyCode == KeyEvent.KEYCODE_BACK) {
            if (System.currentTimeMillis() - clickTime > 2000) {
                "再按一次退出程序".show(this)
                clickTime = System.currentTimeMillis()
                true
            } else {
                super.onKeyDown(keyCode, event)
            }
        } else super.onKeyDown(keyCode, event)
    }

    /***以下是地图生命周期管理************************************************************************/

    override fun onResume() {
        super.onResume()
        binding.mapView.onResume()
        //协程异步显示默认数据
        lifecycleScope.launch(Dispatchers.Main) {
            markers = withContext(Dispatchers.IO) {
                DataBaseManager.get.loadMarkers() as ArrayList<MarkerLocalBean>
            }
            showLabelsOnMap()
        }
    }

    override fun onPause() {
        super.onPause()
        binding.mapView.onPause()
    }

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        binding.mapView.onSaveInstanceState(outState)
    }

    override fun onDestroy() {
        super.onDestroy()
        clusterOverlay?.onDestroy()
        binding.mapView.onDestroy()
        soundPool.autoPause()
        serialPortService?.closeSerialPort()
        unbindService(serviceConnection)
        locationTool.stopLocation()
        BaseApplication.get().closeSerialPort()
    }
}