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

import android.hardware.Sensor
import android.hardware.SensorEvent
import android.hardware.SensorEventListener
import android.hardware.SensorManager
import android.media.AudioAttributes
import android.media.SoundPool
import android.os.Bundle
import androidx.lifecycle.lifecycleScope
import com.amap.api.location.AMapLocation
import com.amap.api.maps.AMapUtils
import com.amap.api.maps.model.LatLng
import com.casic.common.detector.gd.R
import com.casic.common.detector.gd.callback.OnGetLocationListener
import com.casic.common.detector.gd.databinding.ActivitySearchMarkerAuditBinding
import com.casic.common.detector.gd.utils.DataBaseManager
import com.casic.common.detector.gd.utils.LocaleConstant
import com.casic.common.detector.gd.utils.LocationTool
import com.casic.common.detector.gd.widgets.RadarScanView
import com.pengxh.kt.lite.base.KotlinBaseActivity
import com.pengxh.kt.lite.extensions.getSystemService
import com.pengxh.kt.lite.extensions.navigatePageTo
import com.pengxh.kt.lite.extensions.show
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.util.Timer
import java.util.TimerTask
import kotlin.math.atan2

class SearchMarkerAuditActivity : KotlinBaseActivity<ActivitySearchMarkerAuditBinding>(),
    SensorEventListener {

    private val kTag = "SearchMarkerActivity"
    private val context = this
    private val locationTool by lazy { LocationTool(this) }
    private val sensorManager by lazy { getSystemService<SensorManager>() }
    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 val rotationMatrix = FloatArray(9)//旋转矩阵缓存
    private val valueArray = FloatArray(3)//方位角数值
    private var nearestMarkerId = ""//探测不到标识器的时候计算出来的最近的标识器ID
    private var gravity: FloatArray? = null
    private var geomagnetic: FloatArray? = null
    private lateinit var searchSignalEnergyTimer: Timer

    override fun initOnCreate(savedInstanceState: Bundle?) {
        val fastSoundResourceId = soundPool.load(this, R.raw.ring2, 1)

        //点位渲染，每次定位都计算当前位置与符合条件的点距离
        locationTool.getCurrentLocation(false, object : OnGetLocationListener {
            override fun onSuccess(location: AMapLocation) {
                renderDataPoint(location)
            }

            override fun onError() {
                "当前位置信号差，无法获取定位".show(context)
            }
        })

        searchSignalEnergyTimer = Timer()
        searchSignalEnergyTimer.schedule(object : TimerTask() {
            override fun run() {
                soundPool.play(fastSoundResourceId, 1f, 1f, 0, 0, 1f)
            }
        }, 0, 100)
    }

    override fun initEvent() {
        binding.markerInfoButton.setOnClickListener {
            //查库
            val result = DataBaseManager.get.queryMarkerById(nearestMarkerId)
            if (result.isNotEmpty()) {
                navigatePageTo<ObjectDetailActivity>(nearestMarkerId)
            } else {
                navigatePageTo<NewObjectDetailActivity>(nearestMarkerId)
            }
        }
    }

    /**
     * 计算并渲染数据点。点太多采用协程计算，不然会有点卡顿。默认2s计算一次
     * @param location 定位点（RTK获取）
     * */
    private fun renderDataPoint(location: AMapLocation) {
        val longitude = location.longitude
        val latitude = location.latitude
        lifecycleScope.launch(Dispatchers.IO) {
            val dataPoints = ArrayList<RadarScanView.DataPoint>()
            DataBaseManager.get.loadMarkers().forEach {
                val distance = AMapUtils.calculateLineDistance(
                    LatLng(it.lat.toDouble(), it.lng.toDouble()), LatLng(latitude, longitude)
                )
                val formatDistance = "%.2f".format(distance).toFloat()
                val angle = atan2(
                    (it.lat.toDouble() - latitude), (it.lng.toDouble() - longitude)
                ) + Math.PI
                val formatAngle = "%.2f".format(angle).toDouble()

                dataPoints.add(
                    RadarScanView.DataPoint(it.markerId, formatAngle, formatDistance)
                )
            }
            withContext(Dispatchers.Main) {
                binding.radarScanView.renderPointData(dataPoints,
                    object : RadarScanView.OnGetNearestPointCallback {
                        override fun getNearestPoint(point: RadarScanView.DataPoint?) {
                            if (point == null) {
                                binding.distanceValueView.text = "大于5.5m"
                                binding.distancePgBar.progress = 100
                            } else {
                                nearestMarkerId = point.markerId
                                binding.distanceValueView.text = "${point.distance}m"
                                val progress = if (point.distance > LocaleConstant.MAX_DISTANCE) {
                                    100
                                } else {
                                    (point.distance / LocaleConstant.MAX_DISTANCE) * 100
                                }
                                binding.distancePgBar.progress = progress.toInt()
                            }
                        }
                    }
                )
            }
        }
    }

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

    override fun observeRequestState() {

    }

    override fun setupTopBarLayout() {

    }

    override fun onResume() {
        super.onResume()
        //注册加速度传感器监听
        val accelerometer = sensorManager?.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
        sensorManager?.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_NORMAL)

        //注册磁场传感器监听
        val magnetic = sensorManager?.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD)
        sensorManager?.registerListener(this, magnetic, SensorManager.SENSOR_DELAY_NORMAL)
    }

    override fun onPause() {
        super.onPause()
        sensorManager?.unregisterListener(this)
    }

    override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {
        //精度发生变化时触发
    }

    override fun onSensorChanged(event: SensorEvent?) {
        //值发生变化时触发
        val type = event?.sensor?.type

        if (type == Sensor.TYPE_ACCELEROMETER) {
            gravity = event.values
        } else if (type == Sensor.TYPE_MAGNETIC_FIELD) {
            geomagnetic = event.values
        }

        if (gravity == null || geomagnetic == null) {
            return
        }

        if (SensorManager.getRotationMatrix(rotationMatrix, null, gravity, geomagnetic)) {
            SensorManager.getOrientation(rotationMatrix, valueArray)

            val degree = ((360f + valueArray[0] * 180f / Math.PI) % 360).toInt()
            //更新罗盘角度
            binding.radarScanView.setDegreeValue(degree)
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        searchSignalEnergyTimer.cancel()
        soundPool.release()
        locationTool.stopLocation()
    }
}