package com.abbidot.tracker.ui.fragment.map.baidumap

import android.content.Context
import android.graphics.Point
import android.view.MotionEvent
import android.view.View
import androidx.core.view.isVisible
import com.abbidot.baselibrary.util.LogUtil
import com.abbidot.baselibrary.util.Utils
import com.abbidot.tracker.bean.FencesBean
import com.abbidot.tracker.constant.ConstantInt
import com.abbidot.tracker.ui.common.map.FencesAddEditMapCommon
import com.abbidot.tracker.util.LonAndLatUtil
import com.abbidot.tracker.util.Util
import com.abbidot.tracker.widget.FencesCircleView
import com.abbidot.tracker.widget.FencesPolygonView
import com.abbidot.tracker.widget.FencesRectView
import com.baidu.location.BDLocation
import com.baidu.mapapi.map.BaiduMap
import com.baidu.mapapi.map.MapStatus
import com.baidu.mapapi.model.LatLng
import kotlin.math.pow

/**
 *Created  by .yzq on 2024/5/15/015.
 * @link
 * @description:
 */
class FencesAddEditBaiduMapFragment : BaseBaiduMapFragment() {

    private lateinit var mFencesBean: FencesBean
    private var isEditFences = false
    private lateinit var mFencesCircleView: FencesCircleView
    private lateinit var mFencesRectView: FencesRectView
    private lateinit var mFencesPolygonView: FencesPolygonView
    private var mOnActivityCallBack: FencesAddEditMapCommon.OnActivityCallBack? = null

    private lateinit var mMapLoadOk: () -> Unit

    companion object {
        @JvmStatic
        fun newInstance(
            context: Context,
            fencesBean: FencesBean,
            fencesCircleView: FencesCircleView,
            fencesRectView: FencesRectView,
            fencesPolygonView: FencesPolygonView,
            isEdit: Boolean,
            onActivityCallBack: FencesAddEditMapCommon.OnActivityCallBack?,
            mapLoadOk: () -> Unit
        ) = FencesAddEditBaiduMapFragment().apply {
            mContext = context
            mFencesBean = fencesBean
            isEditFences = isEdit
            mFencesCircleView = fencesCircleView
            mFencesRectView = fencesRectView
            mFencesPolygonView = fencesPolygonView
            mOnActivityCallBack = onActivityCallBack
            mMapLoadOk = mapLoadOk
        }
    }

    override fun onMapLoadOk(baiduMap: BaiduMap) {

        mBaiduMap?.apply {

            setOnMapLongClickListener {
                resetFencesViewCentre(it)
                mapOkAndDistancePointLatLng(10)
            }

            setOnMapGestureListener(object : BaiduMap.onMapGestureListener {
                override fun onMapScroll(p0: Point?, p1: Point?, p2: MapStatus?): Boolean {
                    //平移
                    mFencesBean.let {
                        resetFencesViewCentre(
                            getBaiduMapLatLng(
                                it.latitudeCenter, it.longitudeCenter
                            )
                        )
                    }
                    return false
                }

                override fun onMapDoubleTouch(p0: Point?, p1: MapStatus?): Boolean {
                    //双击放大
                    LogUtil.e("onMapDoubleTouch")
                    return false
                }

                override fun onMapTwoClick(p0: Point?, p1: Point?, p2: MapStatus?): Boolean {
                    //双指点击缩小
                    LogUtil.e("onMapTwoClick")
                    return false
                }

                override fun onMapKneading(p0: Point?, p1: Point?, p2: MapStatus?): Boolean {
                    LogUtil.e("onMapKneading")
                    //监听地图放大缩小操作
                    if (getBaiduMapZoom() != mapStatus.zoom) {
                        setBaiduMapZoom(mapStatus.zoom)
                        resetFencesViewSize()

                        mFencesBean.let {
                            resetFencesViewCentre(
                                getBaiduMapLatLng(
                                    it.latitudeCenter, it.longitudeCenter
                                )
                            )
                        }
                    }
                    return false
                }

                override fun onMapOverLooking(p0: Point?, p1: Point?, p2: MapStatus?): Boolean {
                    LogUtil.e("onMapOverLooking")
                    return false
                }

                override fun onMapFling(
                    p0: MotionEvent?, p1: Float, p2: Float, p3: MapStatus?
                ): Boolean {
                    //惯性抛出手势
                    LogUtil.e("onMapFling1")
                    return false
                }

                override fun onMapStatusChangeFinish(p0: MapStatus?) {
                    LogUtil.e("onMapStatusChangeFinish")
                }
            })
        }

        startLocation()

        //变量是否初始化
        if (::mMapLoadOk.isInitialized) mMapLoadOk()
    }

    override fun locationSuccess(location: BDLocation?) {
        if (isEditFences) {
            mFencesBean.apply {
                moveCameraLocation(
                    latitudeCenter, longitudeCenter
                )
            }

            //延时执行，防止围栏没画好/地图摄像头移动中
            mFencesCircleView.postDelayed({
                restoreEditFences()
            }, 500)

            return
        }


        location?.apply {
            //定位返回的经纬度已经是转换好的GCJ02坐标,需要转换为gps原生坐标
            val convertLonLat = LonAndLatUtil.convertFromGCJ02ToWGS84(latitude, longitude)
            mFencesBean.latitudeCenter = convertLonLat[0]
            mFencesBean.longitudeCenter = convertLonLat[1]
            moveCameraLocation(latitude, longitude, false)

            mapOkAndDistancePointLatLng()
        }
    }

    /**
     * 地图准备好计算距离
     */
    fun mapOkAndDistancePointLatLng(delayMillis: Long = 500) {
        //延时计算距离，防止围栏没画好/地图摄像头移动中
        mFencesCircleView.postDelayed({
            val arrayOfDistance = getLatLngAndCalDistance()
            mOnActivityCallBack?.calculationDistance(arrayOfDistance)
        }, delayMillis)
    }

    /**
     * 还原围栏
     */
    private fun restoreEditFences() {
        var arrayOfDistance = arrayOf("0")
        mFencesBean.apply {
            when (mFencesBean.fenceShapeType) {
                ConstantInt.CircleShapeType -> {
                    val radiusPx = getCircleRadiusPx(radius.toDouble())
                    mFencesCircleView.let {
                        it.visibility = View.VISIBLE
                        it.setCircleRadiusPx(radiusPx.toFloat())
                        arrayOfDistance = arrayOf("$radius")
                    }
                }

                ConstantInt.RectangleShapeType -> {
                    restoreRectFences()
                    arrayOfDistance = arrayOf("$longDistance", "$shortDistance")
                }

                ConstantInt.PolygonShapeType -> {
                    restorePolygonFences()
                    arrayOfDistance = arrayOf("0")
                }
            }

            mOnActivityCallBack?.calculationDistance(arrayOfDistance)
        }
    }

    /**
     * 重新设置围栏控件的中心点位置
     */
    fun resetFencesViewCentre(centreLatLng: LatLng) {
        mBaiduMap?.projection?.toScreenLocation(centreLatLng)?.apply {
            if (mFencesCircleView.isVisible) {
                mFencesCircleView.setCentreXY(this)
            } else if (mFencesRectView.isVisible) {
                mFencesRectView.setCentreXY(this)
            } else if (mFencesPolygonView.isVisible) {
                mFencesPolygonView.setCentreXY(this)
            }
        }
    }

    /**
     * 重新设置围栏控件的大小
     */
    private fun resetFencesViewSize() {
        if (mFencesCircleView.isVisible) {
            if (mFencesBean.radius <= 0.0) return
            val radiusPx = zoomToCircleRadiusPx(mFencesBean.radius.toDouble())
            mFencesCircleView.setCircleRadiusPx(radiusPx.toFloat())
        } else if (mFencesRectView.isVisible) {
            restoreRectFences()
        } else if (mFencesPolygonView.isVisible) {
            restorePolygonFences()
        }
    }

    private fun getLatLngAndCalDistance(): Array<String> {
        // 经纬度转换为手机坐标点
//            val x = mBaiduMap!!.projection.toScreenLocation(it).x
        return when (mFencesBean.fenceShapeType) {
            ConstantInt.CircleShapeType -> {
                //手机坐标点转换为经纬度
                val centreLatLng = mFencesCircleView.getCircleCentrePoint()
                    .let { mBaiduMap!!.projection.fromScreenLocation(it) }
                val endLatLng = mFencesCircleView.getCircleLineEndPoint()
                    .let { mBaiduMap!!.projection.fromScreenLocation(it) }
                //            mEndLatLng = endLatLng
                LogUtil.e("mBaiduMap,getLatLngAndCalDistance 监听回调")
                LogUtil.e("startLatLng=$centreLatLng,endLatLng=$endLatLng")
                val distance = Util.measureLatLonDistance(
                    centreLatLng.latitude,
                    centreLatLng.longitude,
                    endLatLng.latitude,
                    endLatLng.longitude
                )
                //把输出的GCJ02坐标转换为gps原生坐标WGS84
                val gpsWGS84 = LonAndLatUtil.convertFromGCJ02ToWGS84(
                    centreLatLng.latitude, centreLatLng.longitude
                )
                mFencesBean.apply {
                    latitudeCenter = gpsWGS84[0]
                    longitudeCenter = gpsWGS84[1]
                }
                arrayOf(
                    Utils.formatDecimal(distance, 2)
                )
            }

            ConstantInt.RectangleShapeType -> {
                val centreLatLng = mFencesRectView.getRectCentrePoint()
                    .let { mBaiduMap!!.projection.fromScreenLocation(it) }
                val rectALatLng = mFencesRectView.getRectABCDPoint(FencesPolygonView.POINT_A).let {
                    mBaiduMap!!.projection.fromScreenLocation(it)
                }
                val rectBLatLng = mFencesRectView.getRectABCDPoint(FencesPolygonView.POINT_B).let {
                    mBaiduMap!!.projection.fromScreenLocation(it)
                }
                val rectCLatLng = mFencesRectView.getRectABCDPoint(FencesPolygonView.POINT_C).let {
                    mBaiduMap!!.projection.fromScreenLocation(it)
                }
                val rectDLatLng = mFencesRectView.getRectABCDPoint(FencesPolygonView.POINT_D).let {
                    mBaiduMap!!.projection.fromScreenLocation(it)
                }
                val rectWidthDistance = Util.measureLatLonDistance(
                    rectALatLng.latitude,
                    rectALatLng.longitude,
                    rectBLatLng.latitude,
                    rectBLatLng.longitude
                )
                val rectHeightDistance = Util.measureLatLonDistance(
                    rectBLatLng.latitude,
                    rectBLatLng.longitude,
                    rectCLatLng.latitude,
                    rectCLatLng.longitude
                )

                //把输出的GCJ02坐标转换为gps原生坐标WGS84
                val centreGpsWGS84 = LonAndLatUtil.convertFromGCJ02ToWGS84(
                    centreLatLng.latitude, centreLatLng.longitude
                )
                val rectAGpsWGS84 = LonAndLatUtil.convertFromGCJ02ToWGS84(
                    rectALatLng.latitude, rectALatLng.longitude
                )
                val rectBGpsWGS84 = LonAndLatUtil.convertFromGCJ02ToWGS84(
                    rectBLatLng.latitude, rectBLatLng.longitude
                )
                val rectCGpsWGS84 = LonAndLatUtil.convertFromGCJ02ToWGS84(
                    rectCLatLng.latitude, rectCLatLng.longitude
                )
                val rectDGpsWGS84 = LonAndLatUtil.convertFromGCJ02ToWGS84(
                    rectDLatLng.latitude, rectDLatLng.longitude
                )
                mFencesBean.apply {
                    latitudeCenter = centreGpsWGS84[0]
                    longitudeCenter = centreGpsWGS84[1]
                    latitudeA = rectAGpsWGS84[0]
                    longitudeA = rectAGpsWGS84[1]
                    latitudeB = rectBGpsWGS84[0]
                    longitudeB = rectBGpsWGS84[1]
                    latitudeC = rectCGpsWGS84[0]
                    longitudeC = rectCGpsWGS84[1]
                    latitudeD = rectDGpsWGS84[0]
                    longitudeD = rectDGpsWGS84[1]
                }
                //长度和高度
                arrayOf(
                    Utils.formatDecimal(rectWidthDistance, 2),
                    Utils.formatDecimal(rectHeightDistance, 2)
                )
            }

            else -> {
                val centreLatLng = mFencesPolygonView.getPolygonCentrePoint()
                    .let { mBaiduMap!!.projection.fromScreenLocation(it) }
                val polygonALatLng =
                    mFencesPolygonView.getPolygonABCDEFPoint(FencesPolygonView.POINT_A).let {
                        mBaiduMap!!.projection.fromScreenLocation(it)
                    }
                val polygonBLatLng =
                    mFencesPolygonView.getPolygonABCDEFPoint(FencesPolygonView.POINT_B).let {
                        mBaiduMap!!.projection.fromScreenLocation(it)
                    }
                val polygonCLatLng =
                    mFencesPolygonView.getPolygonABCDEFPoint(FencesPolygonView.POINT_C).let {
                        mBaiduMap!!.projection.fromScreenLocation(it)
                    }
                val polygonDLatLng =
                    mFencesPolygonView.getPolygonABCDEFPoint(FencesPolygonView.POINT_D).let {
                        mBaiduMap!!.projection.fromScreenLocation(it)
                    }
                val polygonELatLng =
                    mFencesPolygonView.getPolygonABCDEFPoint(FencesPolygonView.POINT_E).let {
                        mBaiduMap!!.projection.fromScreenLocation(it)
                    }
                val polygonFLatLng =
                    mFencesPolygonView.getPolygonABCDEFPoint(FencesPolygonView.POINT_F).let {
                        mBaiduMap!!.projection.fromScreenLocation(it)
                    }

                //把输出的GCJ02坐标转换为gps原生坐标WGS84
                val centreGpsWGS84 = LonAndLatUtil.convertFromGCJ02ToWGS84(
                    centreLatLng.latitude, centreLatLng.longitude
                )
                val polygonAGpsWGS84 = LonAndLatUtil.convertFromGCJ02ToWGS84(
                    polygonALatLng.latitude, polygonALatLng.longitude
                )
                val polygonBGpsWGS84 = LonAndLatUtil.convertFromGCJ02ToWGS84(
                    polygonBLatLng.latitude, polygonBLatLng.longitude
                )
                val polygonCGpsWGS84 = LonAndLatUtil.convertFromGCJ02ToWGS84(
                    polygonCLatLng.latitude, polygonCLatLng.longitude
                )
                val polygonDGpsWGS84 = LonAndLatUtil.convertFromGCJ02ToWGS84(
                    polygonDLatLng.latitude, polygonDLatLng.longitude
                )
                val polygonEGpsWGS84 = LonAndLatUtil.convertFromGCJ02ToWGS84(
                    polygonELatLng.latitude, polygonELatLng.longitude
                )
                val polygonFGpsWGS84 = LonAndLatUtil.convertFromGCJ02ToWGS84(
                    polygonFLatLng.latitude, polygonFLatLng.longitude
                )
                mFencesBean.apply {
                    latitudeCenter = centreGpsWGS84[0]
                    longitudeCenter = centreGpsWGS84[1]
                    latitudeA = polygonAGpsWGS84[0]
                    longitudeA = polygonAGpsWGS84[1]
                    latitudeB = polygonBGpsWGS84[0]
                    longitudeB = polygonBGpsWGS84[1]
                    latitudeC = polygonCGpsWGS84[0]
                    longitudeC = polygonCGpsWGS84[1]
                    latitudeD = polygonDGpsWGS84[0]
                    longitudeD = polygonDGpsWGS84[1]
                    latitudeE = polygonEGpsWGS84[0]
                    longitudeE = polygonEGpsWGS84[1]
                    latitudeF = polygonFGpsWGS84[0]
                    longitudeF = polygonFGpsWGS84[1]
                }
                //多边形，不需要计算距离
                arrayOf("0")
            }
        }
    }

    /**
     * 还原矩形围栏大小
     */
    private fun restoreRectFences() {
        mFencesBean.apply {
            mFencesRectView.let {
                it.visibility = View.VISIBLE
                mBaiduMap!!.projection.apply {
                    val pointCentre =
                        toScreenLocation(getBaiduMapLatLng(latitudeCenter, longitudeCenter))
                    val pointA = toScreenLocation(
                        getBaiduMapLatLng(latitudeA, longitudeA)
                    )
                    val pointB = toScreenLocation(
                        getBaiduMapLatLng(latitudeB, longitudeB)
                    )
                    val pointC = toScreenLocation(
                        getBaiduMapLatLng(latitudeC, longitudeC)
                    )
                    val pointD = toScreenLocation(
                        getBaiduMapLatLng(latitudeD, longitudeD)
                    )
                    it.setRectABCDXYPoint(
                        pointCentre, pointA, pointB, pointC, pointD
                    )
                }
            }
        }
    }

    /**
     * 还原多边形围栏大小
     */
    private fun restorePolygonFences() {
        mFencesBean.apply {
            mFencesPolygonView.let {
                it.visibility = View.VISIBLE
                mBaiduMap!!.projection.apply {
                    val pointCentre =
                        toScreenLocation(getBaiduMapLatLng(latitudeCenter, longitudeCenter))
                    val pointA = toScreenLocation(
                        getBaiduMapLatLng(latitudeA, longitudeA)
                    )
                    val pointB = toScreenLocation(
                        getBaiduMapLatLng(latitudeB, longitudeB)
                    )
                    val pointC = toScreenLocation(
                        getBaiduMapLatLng(latitudeC, longitudeC)
                    )
                    val pointD = toScreenLocation(
                        getBaiduMapLatLng(latitudeD, longitudeD)
                    )
                    val pointE = toScreenLocation(
                        getBaiduMapLatLng(latitudeE, longitudeE)
                    )
                    val pointF = toScreenLocation(
                        getBaiduMapLatLng(latitudeF, longitudeF)
                    )
                    it.setPolygonABCDEFPoint(
                        pointCentre, pointA, pointB, pointC, pointD, pointE, pointF
                    )
                }
            }
        }
    }

    /**
     * 根据地图显示级别,计算比例尺的一像素对应几米
     */
    private fun getCircleRadiusPx(distanceRadius: Double): Double {
        val zoom = getDistanceZoom(distanceRadius)
        //一像素对应几米
        val pxDis = 2.0.pow(17.0 - zoom)
        //计算现在半径有多少像素
        return distanceRadius / pxDis
    }

    /**
     * 根据地图显示级别,计算比例尺的一像素对应几米
     */
    private fun zoomToCircleRadiusPx(distanceRadius: Double): Double {
        val zoom = getBaiduMapZoom()
        //一像素对应几米
        val pxDis = 2.0.pow(17.0 - zoom)
        //计算现在半径有多少像素
        return distanceRadius / pxDis
    }
}