package com.casic.detector.view

import android.app.ProgressDialog
import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.PowerManager
import android.provider.Settings
import android.util.Log
import android.view.KeyEvent
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.FileProvider
import androidx.lifecycle.ViewModelProvider
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.model.LatLng
import com.amap.api.maps.model.LatLngBounds
import com.amap.api.maps.model.MyLocationStyle
import com.casic.detector.BuildConfig
import com.casic.detector.R
import com.casic.detector.bean.LabelBean
import com.casic.detector.bean.TaskBean
import com.casic.detector.callback.ILocationListener
import com.casic.detector.cluster.ClusterItem
import com.casic.detector.cluster.ClusterOverlay
import com.casic.detector.cluster.RegionItem
import com.casic.detector.extensions.appendDownloadUrl
import com.casic.detector.extensions.drawCircle
import com.casic.detector.extensions.initLayoutImmersionBar
import com.casic.detector.model.TaskModel
import com.casic.detector.utils.*
import com.casic.detector.vm.TaskViewModel
import com.casic.detector.vm.VersionViewModel
import com.casic.detector.widgets.QueryMarkerDialog
import com.casic.detector.widgets.SamplePopupWindow
import com.gyf.immersionbar.ImmersionBar
import com.pengxh.kt.lite.callback.OnDownloadListener
import com.pengxh.kt.lite.extensions.*
import com.pengxh.kt.lite.utils.SaveKeyValues
import com.pengxh.kt.lite.vm.LoadState
import com.pengxh.kt.lite.widget.dialog.AlertControlDialog
import com.pengxh.kt.lite.widget.dialog.AlertMessageDialog
import com.pengxh.kt.lite.widget.dialog.BottomActionSheet
import com.pengxh.kt.lite.widget.dialog.NoNetworkDialog
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.File


class MainActivity : AppCompatActivity() {

    private val kTag = "MainActivity"
    private val context: Context = this@MainActivity
    private var clickTime: Long = 0
    private lateinit var aMap: AMap
    private lateinit var locationStyle: MyLocationStyle
    private lateinit var versionViewModel: VersionViewModel
    private lateinit var taskViewModel: TaskViewModel
    private val samplePopupWindow by lazy { SamplePopupWindow(this) }
    private val progressDialog by lazy { ProgressDialog(this) }
    private var labelBeans = ArrayList<LabelBean>()
    private var clusterOverlay: ClusterOverlay? = null
    private val backDrawables = HashMap<Int, Drawable>()
    private val regionRadius by lazy { LocaleConstant.RADIUS_SIZE.dp2px(this) }
    private var latitude: Double = 0.0
    private var longitude: Double = 0.0
    private val powerManager by lazy { getSystemService<PowerManager>() }
    private var wakeLock: PowerManager.WakeLock? = null
    private var taskBean: TaskBean? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        wakeLock = powerManager?.run {
            newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, this@MainActivity.localClassName).apply {
                //1h不休眠
                acquire(60 * 60 * 1000L)
            }
        }

        setupTopBarLayout()
        initMapConfig(savedInstanceState)
        initData()
        observeRequestState()
        initEvent()
    }

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

        val uiSettings = aMap.uiSettings
        uiSettings.isCompassEnabled = true
        uiSettings.isMyLocationButtonEnabled = true
        uiSettings.isScaleControlsEnabled = true
        uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER
        uiSettings.isRotateGesturesEnabled = false//不许地图随手势旋转角度
        //显示定位小蓝点
        locationStyle = MyLocationStyle()
        locationStyle.interval(2000)
        locationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER)//定位、但不会移动到地图中心点，定位点依照设备方向旋转，并且会跟随设备移动。
        aMap.myLocationStyle = locationStyle//设置定位蓝点的Style
        aMap.isMyLocationEnabled = true//设置是否显示定位小蓝点
        aMap.setOnMyLocationChangeListener {
            longitude = it.longitude
            latitude = it.latitude
            //经纬度逆编码
            LocationHub.antiCodingLocation(context, it) { address ->
                currentLocationView.text = address
            }
        }

        //首次移动到定位点
        LocationHub.getCurrentLocation(this, object : ILocationListener {
            override fun onAMapLocationGet(location: AMapLocation?) {
                if (location != null) {
                    aMap.moveCamera(
                        CameraUpdateFactory.newLatLngZoom(
                            LatLng(location.latitude, location.longitude), 15f
                        )
                    )
                } else {
                    "当前位置信号差，无法移动地图到定位点".show(context)
                }
            }
        })

        aMap.setOnMapLongClickListener {
            //协程异步显示默认数据
            CoroutineScope(Dispatchers.Main).launch {
                labelBeans = withContext(Dispatchers.IO) {
                    DataBaseManager.get.loadTaskLabels() as ArrayList<LabelBean>
                }
                showLabelsOnMap()
            }
        }
    }

    private fun initData() {
        samplePopupWindow.setPopupMenuItem(LocaleConstant.POPUP_TITLES)
        samplePopupWindow.setBackgroundDrawable(null)

        //初始化下载对话框
        progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL)
        progressDialog.setProgressDrawable(resources.getDrawable(R.drawable.download_progress))
        progressDialog.setCanceledOnTouchOutside(false)
        progressDialog.setCancelable(false)

        //协程异步显示默认数据
        CoroutineScope(Dispatchers.Main).launch {
            labelBeans = withContext(Dispatchers.IO) {
                DataBaseManager.get.loadTaskLabels() as ArrayList<LabelBean>
            }
            showLabelsOnMap()
        }

        versionViewModel = ViewModelProvider(this)[VersionViewModel::class.java]
        versionViewModel.versionResult.observe(this) {
            if (it.version.toInt() > BuildConfig.VERSION_CODE) {
                AlertControlDialog.Builder()
                    .setContext(this)
                    .setTitle("提示")
                    .setMessage("有新版本，是否更新？")
                    .setNegativeButton("稍后再说")
                    .setPositiveButton("立即下载")
                    .setOnDialogButtonClickListener(object :
                        AlertControlDialog.OnDialogButtonClickListener {
                        override fun onConfirmClick() {
                            downloadApk(it.path)
                        }

                        override fun onCancelClick() {

                        }
                    }).build().show()
            } else {
                "已是最新版本，无需更新".show(this)
            }
        }

        taskViewModel = ViewModelProvider(this)[TaskViewModel::class.java]
        taskViewModel.markerFileResult.observe(this) {
            if (it.isSuccess) {
                //清空之前的数据
                DataBaseManager.get.clearTaskLabels()
                //下载最新的数据
                val companyId = SaveKeyValues.getValue(LocaleConstant.USER_COMPANY_ID, "")
                val downloadUrl = companyId.toString().appendDownloadUrl(FileType.EXCEL)
                downloadUrl.downloadFile(createDownloadFileDir().toString(),
                    object : OnDownloadListener {
                        override fun onDownloadEnd(file: File?) {
                            labelBeans = ExcelHub.read(file?.absolutePath)
                            labelBeans.forEach { label ->
                                DataBaseManager.get.insertTaskLabel(label)
                            }
                            LoadingDialogHub.dismiss()
                            showLabelsOnMap()
                        }

                        override fun onDownloadStart(totalBytes: Long) {

                        }

                        override fun onProgressChanged(currentBytes: Long) {

                        }
                    })
            }
        }
        taskViewModel.taskResult.observe(this) {
            if (it.success == "true") {
                //清空之前的数据
                DataBaseManager.get.clearTasks()
                AlertMessageDialog.Builder()
                    .setContext(this)
                    .setTitle("温馨提示")
                    .setMessage("您有${it.message.size}个新任务！")
                    .setPositiveButton("知道了")
                    .setOnDialogButtonClickListener(object :
                        AlertMessageDialog.OnDialogButtonClickListener {
                        override fun onConfirmClick() {
                            saveTaskInformation(it)
                        }
                    }).build().show()
            }
        }
    }

    private fun saveTaskInformation(it: TaskModel) {
        val userName = SaveKeyValues.getValue(LocaleConstant.USER_NAME, "") as String
        if (it.message.size > 0) {
            it.message.forEach { messageModel ->
                val count = DataBaseManager.get.countTaskById(messageModel.id.toString())
                if (count == 0) {
                    messageModel.taskDetailInfos.forEach { info ->
                        DataBaseManager.get.insertTaskInformation(
                            userName,
                            messageModel.description,
                            info.taskId.toString(),
                            info.taskCode.toString(),
                            info.markerId.toString(),
                            info.markerIdReal.toString(),
                            info.longitude.toString(),
                            info.latitude.toString(),
                            messageModel.status
                        )
                    }
                }
            }
            "工单下载成功！".show(context)
        }
    }

    private fun showLabelsOnMap() {
        clusterOverlay?.onDestroy()
        val clusterItems = ArrayList<ClusterItem>()
        labelBeans.forEach {
            val latLng = LatLng(it.lat.toDouble(), it.lng.toDouble(), false)
            val regionItem = RegionItem(latLng, it.id.toString())
            clusterItems.add(regionItem)
        }

        clusterOverlay = ClusterOverlay(context, aMap, clusterItems, regionRadius)
        clusterOverlay?.setClusterRender { clusterNum ->
            val radius = 80f.dp2px(context)
            if (clusterNum == 1) {
                var bitmapDrawable: Drawable? = backDrawables[1]
                if (bitmapDrawable == null) {
                    bitmapDrawable = resources.getDrawable(R.mipmap.label_location)
                    backDrawables[1] = bitmapDrawable
                }
                bitmapDrawable!!
            } else if (clusterNum < 5) {
                var bitmapDrawable: Drawable? = backDrawables[2]
                if (bitmapDrawable == null) {
                    bitmapDrawable = BitmapDrawable(
                        null, radius.drawCircle(Color.argb(159, 210, 154, 6))
                    )
                    backDrawables[2] = bitmapDrawable
                }
                bitmapDrawable
            } else if (clusterNum < 10) {
                var bitmapDrawable: Drawable? = backDrawables[3]
                if (bitmapDrawable == null) {
                    bitmapDrawable = BitmapDrawable(
                        null, radius.drawCircle(Color.argb(199, 217, 114, 0))
                    )
                    backDrawables[3] = bitmapDrawable
                }
                bitmapDrawable
            } else {
                var bitmapDrawable: Drawable? = backDrawables[4]
                if (bitmapDrawable == null) {
                    bitmapDrawable = BitmapDrawable(
                        null, radius.drawCircle(Color.argb(235, 215, 66, 2))
                    )
                    backDrawables[4] = bitmapDrawable
                }
                bitmapDrawable
            }
        }
        clusterOverlay?.setOnClusterClickListener { _, items ->
            var item: RegionItem? = null
            val builder = LatLngBounds.Builder()
            for (clusterItem in items) {
                builder.include(clusterItem.position)
                item = clusterItem as RegionItem
            }
            //点击Marker移到Marker视图
            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() {
                        if (item == null) {
                            "标识器经纬度异常".show(context)
                            return
                        }

                        RouteOnMap.startNavigation(
                            context, item.title,
                            LatLng(item.position.latitude, item.position.longitude)
                        )
                    }

                    override fun onCancelClick() {
                        labelBeans.forEach {
                            if (it.id.toString() == item?.title) {
                                navigatePageTo<ObjectDetailActivity>(it.toJson())
                            }
                        }
                    }
                }).build().show()
        }
    }

    private fun initEvent() {
        rightImageView.setOnClickListener {
            val x = rightImageView.width - samplePopupWindow.width - 1f.dp2px(this)
            samplePopupWindow.showAsDropDown(rightImageView, x, 1f.dp2px(this))
        }

        samplePopupWindow.setOnPopupWindowClickListener(object :
            SamplePopupWindow.OnPopupWindowClickListener {
            override fun onPopupItemClicked(position: Int) {
                when (position) {
                    0 -> updateTaskData()
                    1 -> downloadTask()
                    2 -> versionViewModel.getApplicationVersion()
                    3 -> uploadEvent()
                    4 -> uploadLabel()
                }
            }
        })

        //安装
        installButton.setOnClickListener {

        }

        //查看
        viewButton.setOnClickListener {
            QueryMarkerDialog.Builder()
                .setContext(context)
                .setTitle("查看标识器")
                .setSpinnerArray(LocaleConstant.SPINNER_ARRAY)
                .setHintMessage("请输入查询条件")
                .setNegativeButton("取消")
                .setPositiveButton("确定")
                .setOnDialogButtonClickListener(object :
                    QueryMarkerDialog.OnDialogButtonClickListener {
                    override fun onConfirmClick(selectedItem: String, value: String) {
                        //查询数据库
                        CoroutineScope(Dispatchers.Main).launch {
                            labelBeans = withContext(Dispatchers.IO) {
                                DataBaseManager.get.loadLabelByCondition(
                                    selectedItem, value
                                ) as ArrayList<LabelBean>
                            }
                            showLabelsOnMap()
                        }
                    }

                    override fun onCancelClick() {

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

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

                BottomActionSheet.Builder()
                    .setContext(this)
                    .setItemTextColor(Color.BLUE)
                    .setActionItemTitle(arrayList)
                    .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener {
                        override fun onActionItemClick(position: Int) {
                            taskBean = task[position]

                            AlertControlDialog.Builder()
                                .setContext(context)
                                .setTitle("提示")
                                .setMessage("请选择操作方式")
                                .setPositiveButton("执行工单")
                                .setNegativeButton("提交工单")
                                .setOnDialogButtonClickListener(object :
                                    AlertControlDialog.OnDialogButtonClickListener {
                                    override fun onConfirmClick() {
                                        uploadTask(taskBean?.taskId, "1")
                                    }

                                    override fun onCancelClick() {
                                        uploadTask(taskBean?.taskId, "2")
                                    }
                                }).build().show()
                        }
                    }).build().show()
            } else {
                AlertMessageDialog.Builder()
                    .setContext(this)
                    .setTitle("温馨提示")
                    .setMessage("现有任务已完成，请点击右上角菜单按钮下载新工单！")
                    .setPositiveButton("知道了")
                    .setOnDialogButtonClickListener(object :
                        AlertMessageDialog.OnDialogButtonClickListener {
                        override fun onConfirmClick() {

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

        //探测
        detectionButton.setOnClickListener {

        }
    }

    private fun uploadTask(taskId: String?, state: String) {
        if (isNetworkConnected()) {
            val userId = SaveKeyValues.getValue(LocaleConstant.USER_ID, "") as String
            taskViewModel.uploadTask(userId, taskId, state)
        } else {
            NoNetworkDialog.Builder()
                .setContext(context)
                .setOnDialogButtonClickListener(object :
                    NoNetworkDialog.OnDialogButtonClickListener {
                    override fun onButtonClick() {
                        val intent = Intent(Settings.ACTION_SETTINGS)
                        startActivity(intent)
                    }
                }).build().show()
        }
    }

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

                        LoadingDialogHub.show(this@MainActivity, "获取标识器信息中，请稍后")
                        taskViewModel.getMarkerFile(userId.toString(), companyId.toString())
                    } else {
                        NoNetworkDialog.Builder()
                            .setContext(context)
                            .setOnDialogButtonClickListener(object :
                                NoNetworkDialog.OnDialogButtonClickListener {
                                override fun onButtonClick() {
                                    val intent = Intent(Settings.ACTION_SETTINGS)
                                    startActivity(intent)
                                }
                            }).build().show()
                    }
                }

                override fun onCancelClick() {

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

    //下载工单
    private fun downloadTask() {
        if (isNetworkConnected()) {
            val userName = SaveKeyValues.getValue(LocaleConstant.USER_NAME, "")
            taskViewModel.getTask(userName.toString())
        } else {
            NoNetworkDialog.Builder()
                .setContext(context)
                .setOnDialogButtonClickListener(object :
                    NoNetworkDialog.OnDialogButtonClickListener {
                    override fun onButtonClick() {
                        val intent = Intent(Settings.ACTION_SETTINGS)
                        startActivity(intent)
                    }
                }).build().show()
        }
    }

    //TODO
    //事件上报
    private fun uploadEvent() {
        if (latitude != 0.0 && longitude != 0.0) {
//            if () {
//
//            } else {
//
//            }
        } else {
            "定位中，请稍后再试...".show(this)
        }
    }

    //标识器补全
    private fun uploadLabel() {
        val companyId = SaveKeyValues.getValue(LocaleConstant.USER_COMPANY_ID, "") as String
        val labelBeans = DataBaseManager.get.queryLabelById("0")
        if (labelBeans.isNotEmpty()) {
            LoadingDialogHub.show(this, "标识器补全中，请稍后...")
            labelBeans.forEach { labelBean ->
                taskViewModel.installLabel(
                    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
                )
            }
            LoadingDialogHub.dismiss()
        } else {
            "没有需要补传的标识器！".show(this)
        }
    }

    private fun observeRequestState() {
        versionViewModel.loadState.observe(this) {
            when (it) {
                LoadState.Loading -> LoadingDialogHub.show(this, "检查版本中，请稍后")
                else -> LoadingDialogHub.dismiss()
            }
        }

        taskViewModel.loadState.observe(this) {
            when (it) {
                LoadState.Loading -> LoadingDialogHub.show(this, "提交工单中，请稍后")
                else -> LoadingDialogHub.dismiss()
            }
        }
    }

    private fun downloadApk(url: String?) {
        progressDialog.setMessage("下载新版本中...")
        progressDialog.show()
        if (url.toString().isBlank()) {
            "抱歉，版本下载失败".show(this)
            return
        }
        /**
         * http://139.198.18.188:8090/ems/apk/EMSCJTX202011052026(V3.14.0).apk
         * */
        val downloadPath = url!!.appendDownloadUrl(FileType.APK)
        Log.d(kTag, "downloadApk => $downloadPath")
        //开始下载
        downloadPath.downloadFile(createDownloadFileDir().toString(), object : OnDownloadListener {
            override fun onDownloadStart(totalBytes: Long) {
                progressDialog.max = totalBytes.toInt()
            }

            override fun onProgressChanged(currentBytes: Long) {
                progressDialog.progress = currentBytes.toInt()
            }

            override fun onDownloadEnd(file: File?) {
                progressDialog.dismiss()
                progressDialog.progress = 0
                //安装APK
                installApk(file)
            }
        })
    }

    private fun installApk(apkPackage: File?) {
        if (apkPackage == null) {
            "安装文件异常，无法安装".show(this)
            return
        }
        val intent = Intent(Intent.ACTION_VIEW)
        val data: Uri
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //判断版本大于等于7.0
            data = FileProvider.getUriForFile(this, LocaleConstant.APP_AUTHORITY, apkPackage)
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) // 给目标应用一个临时授权
        } else {
            data = Uri.fromFile(apkPackage)
        }
        /**
         * android 10
         * content://com.casic.app.smartwell.fileprovider/smartWell/Download/1.0.1.apk
         * */
        intent.setDataAndType(data, "application/vnd.android.package-archive")
        startActivity(intent)
    }

    private fun setupTopBarLayout() {
        ImmersionBar.with(this).statusBarDarkFont(false).statusBarColor(R.color.themeColor).init()
        initLayoutImmersionBar(rootView)
    }

    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()
        mapView.onResume()
    }

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

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

    override fun onDestroy() {
        wakeLock?.release()
        super.onDestroy()
        mapView.onDestroy()
    }
}