package com.waytous.anticollision.ui

import android.content.Context
import android.graphics.Color
import android.text.Spannable
import android.text.SpannableString
import android.text.style.ForegroundColorSpan
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.widget.FrameLayout
import androidx.appcompat.widget.AppCompatImageView
import androidx.appcompat.widget.AppCompatTextView
import com.blankj.utilcode.util.LogUtils
import com.mapbox.geojson.Point
import com.mapbox.maps.CameraOptions
import com.mapbox.maps.MapView
import com.mapbox.maps.MapboxMap
import com.mapbox.maps.Style
import com.mapbox.maps.extension.style.expressions.dsl.generated.get
import com.mapbox.maps.extension.style.layers.generated.circleLayer
import com.mapbox.maps.extension.style.layers.generated.fillLayer
import com.mapbox.maps.extension.style.layers.generated.lineLayer
import com.mapbox.maps.extension.style.layers.generated.symbolLayer
import com.mapbox.maps.extension.style.layers.properties.generated.*
import com.mapbox.maps.extension.style.projection.generated.projection
import com.mapbox.maps.extension.style.sources.addSource
import com.mapbox.maps.extension.style.sources.generated.geoJsonSource
import com.mapbox.maps.extension.style.style
import com.mapbox.maps.plugin.animation.flyTo
import com.mapbox.maps.plugin.attribution.attribution
import com.mapbox.maps.plugin.compass.compass
import com.mapbox.maps.plugin.logo.logo
import com.waytous.anticollision.BuildConfig
import com.waytous.anticollision.R


/**
 * mapbox及控制组件封装
 * @author male
 * @param context
 * @param attributeSet
 * */
class MapBoxLayout(context: Context, private val attributeSet: AttributeSet):FrameLayout(context,attributeSet) {

    /**
     * mapbox地图
     * */
    private var mapView:MapView
    /**
     * mapbox
     * */
    private var mapBox:MapboxMap
    /**
     * sos按钮
     * */
    private var sosButton: AppCompatImageView
    /**
     * 急停按钮
     * */
    private var emergency: AppCompatImageView
    /**
     * 放大按钮
     * */
    private var zoomOut: AppCompatImageView
    /**
     * 缩小按钮
     * */
    private var zoomIn: AppCompatImageView
    /**
     * 定位车辆位置
     * */
    private var locationTruck: AppCompatImageView
    /**
     * 关闭&显示安全距离
     * */
    private var toggleSafetyRange: AppCompatImageView
    /**
     * 地图采集信息文本
     * */
    private var collectDataText:AppCompatTextView

    private var cameraOptions:CameraOptions

    private var zoomLevel:Double = 14.0

    private lateinit var style: Style

    companion object{
        private val scaleLengths = listOf(5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 50000, 100000, 200000, 500000, 1000000, 2000000)
        private const val MINIMUM_ZOOM_LEVEL = 11.0
        private const val MAXIMUM_ZOOM_LEVEL = 26.0
    }

    init {
        val root:View = LayoutInflater.from(context).inflate(R.layout.layout_map_box,this,true)
        mapView = root.findViewById<MapView>(R.id.mapView).also {
            it.logo.enabled = false
            it.compass.enabled = false
            it.attribution.enabled = false
        }
        mapBox = mapView.getMapboxMap().also {mapbox ->
            mapbox.loadStyle(style(MainViewModel.MY_MAP_BOX_STYLE){
                +projection(ProjectionName.GLOBE)
            }){
                style = it
                addTruckPathSource()
            }
        }
        cameraOptions = CameraOptions.Builder().center(Point.fromLngLat(BuildConfig.DEFAULT_LONGITUDE,BuildConfig.DEFAULT_LATITUDE)).zoom(zoomLevel).build()
        sosButton = root.findViewById<AppCompatImageView?>(R.id.sos).also {
            it.setOnClickListener {

            }
        }
        emergency = root.findViewById(R.id.emergency)
        zoomOut = root.findViewById<AppCompatImageView?>(R.id.zoomOut).also {
            it.setOnClickListener {

            }
        }
        zoomIn = root.findViewById<AppCompatImageView?>(R.id.zoomIn).also {

        }
        locationTruck = root.findViewById<AppCompatImageView?>(R.id.locationTruck).also {

        }
        toggleSafetyRange = root.findViewById<AppCompatImageView?>(R.id.toggleSafetyRange).also {

        }
        collectDataText = root.findViewById(R.id.collectDataText)
    }


    fun updateCenter(center:Point){
        mapBox.flyTo(cameraOptions.toBuilder().center(center).build())
    }


    private fun calculateScale(){

    }

    fun addRunnableAreaSource(source: String){
        style.addSource{
            geoJsonSource(MainViewModel.RUNNABLE_AREA_SOURCE) {
                data(source)
            }
            fillLayer(
                MainViewModel.RUNNABLE_AREA_LAYER,
                MainViewModel.RUNNABLE_AREA_SOURCE
            ){
                fillColor("#98a0a0")
                fillOpacity(0.85)
                fillOutlineColor("#FFFF00")
                visibility(Visibility.VISIBLE)
            }
        }
    }

    fun addLaneSource(source: String){
        style.addSource{
            geoJsonSource(MainViewModel.LANE_SOURCE) {
                data(source)
            }
            lineLayer(
                MainViewModel.LANE_LAYER,
                MainViewModel.LANE_SOURCE
            ){
                lineColor("white")
                lineWidth(3.0)
                lineJoin(LineJoin.ROUND)
                lineCap(LineCap.ROUND)
                visibility(Visibility.VISIBLE)
            }
        }
    }

    fun addStaticObjectsSource(source: String){
        style.addSource{
            geoJsonSource(MainViewModel.STATIC_OBJECTS_SOURCE) {
                data(source)
            }
            fillLayer(
                MainViewModel.STATIC_OBJECTS_LAYER,
                MainViewModel.STATIC_OBJECTS_SOURCE
            ){
                fillColor("#98a0a0")
                fillOpacity(0.85)
                fillAntialias(false)
                visibility(Visibility.VISIBLE)
            }
            symbolLayer(MainViewModel.STATIC_OBJECTS_TEXT_LAYER, MainViewModel.STATIC_OBJECTS_SOURCE){
                textColor(Color.BLACK)
                textField(get("name"))
                textFont(listOf("DIN Offc Pro Italic", "Arial Unicode MS Regular"))
                textLineHeight(1.0)
                textPadding(1.0)
                textOffset(listOf(0.5,-0.5))
                textRotationAlignment(TextRotationAlignment.MAP)
                textAnchor(TextAnchor.TOP)
                textSize(16.0)
                textMaxAngle(10.0)
                visibility(Visibility.VISIBLE)
            }
        }
    }

    fun addDiggingWorkAreaSource(source: String){
        style.addSource{
            geoJsonSource(MainViewModel.DIGGING_WORK_AREA_SOURCE) {
                data(source)
            }
            fillLayer(
                MainViewModel.DIGGING_WORK_AREA_LAYER,
                MainViewModel.DIGGING_WORK_AREA_SOURCE
            ){
                fillColor("#886e26")
                fillOpacity(0.85)
                fillAntialias(false)
                visibility(Visibility.VISIBLE)
            }
            symbolLayer(MainViewModel.DIGGING_WORK_AREA_TEXT_LAYER, MainViewModel.DIGGING_WORK_AREA_SOURCE){
                textColor(Color.BLACK)
                textField(get("name"))
                textFont(listOf("DIN Offc Pro Italic", "Arial Unicode MS Regular"))
                textLineHeight(1.0)
                textPadding(1.0)
                textOffset(listOf(0.5,-0.5))
                textRotationAlignment(TextRotationAlignment.MAP)
                textAnchor(TextAnchor.TOP)
                textSize(16.0)
                textMaxAngle(10.0)
                visibility(Visibility.VISIBLE)
            }
        }
    }

    fun addBarricadeSource(source: String){
        style.addSource{
            geoJsonSource(MainViewModel.BARRICADE_SOURCE) {
                data(source)
            }
            lineLayer(
                MainViewModel.BARRICADE_LAYER,
                MainViewModel.BARRICADE_SOURCE
            ){
                lineColor("blue")
                lineWidth(4.0)
                lineJoin(LineJoin.ROUND)
                lineCap(LineCap.ROUND)
                visibility(Visibility.VISIBLE)
            }
        }
    }

    fun addObstaclesSource(source: String){
        style.addSource{
            geoJsonSource(MainViewModel.OBSTACLES_SOURCE) {
                data(source)
            }
            fillLayer(
                MainViewModel.OBSTACLES_LAYER,
                MainViewModel.OBSTACLES_SOURCE
            ){
                fillColor("#6f9bdd")
                fillOpacity(0.8)
                visibility(Visibility.VISIBLE)
            }
            symbolLayer(MainViewModel.OBSTACLES_TEXT_LAYER, MainViewModel.OBSTACLES_SOURCE){
                textColor(Color.BLACK)
                textField(get("name"))
                textFont(listOf("DIN Offc Pro Italic", "Arial Unicode MS Regular"))
                textLineHeight(1.0)
                textPadding(1.0)
                textOffset(listOf(0.5,-0.5))
                textRotationAlignment(TextRotationAlignment.MAP)
                textAnchor(TextAnchor.TOP)
                textSize(16.0)
                textMaxAngle(10.0)
                visibility(Visibility.VISIBLE)
            }
        }
    }

    fun addStationAreaSource(source: String){
        style.addSource{
            geoJsonSource(MainViewModel.STATION_AREA_SOURCE) {
                data(source)
            }
            fillLayer(
                MainViewModel.STATION_AREA_LAYER,
                MainViewModel.STATION_AREA_SOURCE
            ){
                fillColor("lightgreen")
                fillOpacity(0.8)
                visibility(Visibility.VISIBLE)
            }
            symbolLayer(MainViewModel.STATION_AREA_TEXT_LAYER, MainViewModel.STATION_AREA_SOURCE){
                textColor(Color.BLACK)
                textField(get("name"))
                textFont(listOf("DIN Offc Pro Italic", "Arial Unicode MS Regular"))
                textLineHeight(1.0)
                textPadding(1.0)
                textOffset(listOf(0.5,-0.5))
                textRotationAlignment(TextRotationAlignment.MAP)
                textAnchor(TextAnchor.TOP)
                textSize(16.0)
                textMaxWidth(10.0)
            }
        }
    }

    fun addLaneNodeSource(source: String){
        style.addSource{
            geoJsonSource(MainViewModel.LANE_NODE_SOURCE) {
                data(source)
            }
            circleLayer(
                MainViewModel.LANE_NODE_LAYER,
                MainViewModel.LANE_NODE_SOURCE
            ){
                circleColor("red")
                circleRadius(6.0)
                visibility(Visibility.VISIBLE)
            }
            symbolLayer(MainViewModel.LANE_TEXT_LAYER, MainViewModel.LANE_NODE_SOURCE){
                textColor(Color.BLACK)
                textField(get("name"))
                textFont(listOf("DIN Offc Pro Italic", "Arial Unicode MS Regular"))
                textLineHeight(1.0)
                textPadding(1.0)
                textOffset(listOf(0.5,-0.5))
                textRotationAlignment(TextRotationAlignment.MAP)
                textAnchor(TextAnchor.TOP)
                textSize(9.0)
                textMaxAngle(10.0)
                visibility(Visibility.VISIBLE)
            }
        }
    }

    fun addParkSpotSource(source: String){
        style.addSource{
            geoJsonSource(MainViewModel.PARK_SPOT_SOURCE) {
                data(source)
            }
            fillLayer(
                MainViewModel.PARK_SPOT_LAYER,
                MainViewModel.PARK_SPOT_SOURCE
            ){
                fillColor(get("#7e8185"))
                fillOpacity(0.8)
                fillAntialias(false)
                visibility(Visibility.VISIBLE)
            }
            symbolLayer(MainViewModel.PARK_SPOT_TEXT_LAYER, MainViewModel.PARK_SPOT_SOURCE){
                textColor(Color.BLACK)
                textField(get("name"))
                textFont(listOf("DIN Offc Pro Italic", "Arial Unicode MS Regular"))
                textLineHeight(1.0)
                textPadding(1.0)
                textOffset(listOf(0.5,-0.5))
                textRotationAlignment(TextRotationAlignment.MAP)
                textAnchor(TextAnchor.TOP)
                textSize(9.0)
                textMaxAngle(10.0)
                visibility(Visibility.VISIBLE)
            }
        }
    }

    fun addElectronicFenceSource(source: String){
        style.addSource{
            geoJsonSource(MainViewModel.ELECTRONIC_FENCE_SOURCE) {
                data(source)
            }
            fillLayer(
                MainViewModel.ELECTRONIC_FENCE_LAYER,
                MainViewModel.ELECTRONIC_FENCE_SOURCE
            ){
                fillColor(get("color"))
                fillOpacity(0.85)
                fillAntialias(false)
                visibility(Visibility.VISIBLE)
            }
            symbolLayer(MainViewModel.ELECTRONIC_FENCE_TEXT_LAYER, MainViewModel.ELECTRONIC_FENCE_SOURCE){
                textColor(Color.BLACK)
                textField(get("name"))
                textFont(listOf("DIN Offc Pro Italic", "Arial Unicode MS Regular"))
                textLineHeight(1.0)
                textPadding(1.0)
                textOffset(listOf(0.5,-0.5))
                textRotationAlignment(TextRotationAlignment.MAP)
                textAnchor(TextAnchor.TOP)
                textSize(16.0)
                textMaxAngle(10.0)
                visibility(Visibility.VISIBLE)
            }
        }
    }

    fun addWetAreaSource(source: String){
        style.addSource{
            geoJsonSource(MainViewModel.WET_AREA_SOURCE) {
                data(source)
            }
            fillLayer(
                MainViewModel.WET_AREA_LAYER,
                MainViewModel.WET_AREA_SOURCE
            ){
                fillColor(get("color"))
                fillOpacity(0.8)
                fillAntialias(false)
                visibility(Visibility.VISIBLE)
            }
            symbolLayer(MainViewModel.WET_AREA_TEXT_LAYER, MainViewModel.WET_AREA_SOURCE){
                textColor(Color.BLACK)
                textField(get("name"))
                textFont(listOf("DIN Offc Pro Italic", "Arial Unicode MS Regular"))
                textLineHeight(1.0)
                textPadding(1.0)
                textOffset(listOf(0.5,-0.5))
                textRotationAlignment(TextRotationAlignment.MAP)
                textAnchor(TextAnchor.TOP)
                textSize(16.0)
                textMaxAngle(10.0)
                visibility(Visibility.VISIBLE)
            }
        }
    }

    fun addDumpAreaSource(source: String){
        style.addSource{
            geoJsonSource(MainViewModel.DUMP_AREA_SOURCE) {
                data(source)
            }
            fillLayer(
                MainViewModel.DUMP_AREA_LAYER,
                MainViewModel.DUMP_AREA_SOURCE
            ){
                fillColor("#886e26")
                fillOpacity(0.85)
                fillAntialias(false)
                visibility(Visibility.VISIBLE)
            }
            symbolLayer(MainViewModel.DUMP_AREA_TEXT_LAYER, MainViewModel.DUMP_AREA_SOURCE){
                textColor(Color.BLACK)
                textField(get("name"))
                textFont(listOf("DIN Offc Pro Italic", "Arial Unicode MS Regular"))
                textLineHeight(1.0)
                textPadding(1.0)
                textOffset(listOf(0.5,-0.5))
                textRotationAlignment(TextRotationAlignment.MAP)
                textAnchor(TextAnchor.TOP)
                textSize(16.0)
                textMaxAngle(10.0)
                visibility(Visibility.VISIBLE)
            }
        }
    }

    private fun addTruckPathSource(){
        style.addSource{
            geoJsonSource("truckPathSource") {
                data("{ \"type\": \"FeatureCollection\", \"features\":[]}")
            }
            lineLayer(
                "truckPathLayer",
                "truckPathSource"
            ){
                lineColor("green")
                lineWidth(8.0)
                lineOpacity(0.8)
                lineJoin(LineJoin.ROUND)
                lineCap(LineCap.ROUND)
                visibility(Visibility.VISIBLE)
            }
        }
    }

    fun formatCollectionData(text:String){
        val tagSpan = ForegroundColorSpan(Color.parseColor("#666666"))
        val contentSpan = ForegroundColorSpan(Color.parseColor("#000000"))
        val spannableString = SpannableString(text)
        spannableString.setSpan(tagSpan, 0, 4, Spannable.SPAN_INCLUSIVE_INCLUSIVE)
        val textPointIndex = text.indexOf("采集点数")
        spannableString.setSpan(contentSpan, 5, textPointIndex, Spannable.SPAN_INCLUSIVE_EXCLUSIVE)
        spannableString.setSpan(tagSpan, textPointIndex, textPointIndex+4, Spannable.SPAN_INCLUSIVE_INCLUSIVE)
        val textPositionIndex = text.indexOf("当前位置")
        spannableString.setSpan(contentSpan, textPointIndex+1, textPositionIndex, Spannable.SPAN_INCLUSIVE_EXCLUSIVE)
        spannableString.setSpan(tagSpan, textPositionIndex, textPositionIndex+4, Spannable.SPAN_INCLUSIVE_INCLUSIVE)
        val textAltitudeIndex = text.indexOf("高程")
        spannableString.setSpan(contentSpan, textPositionIndex+1, textAltitudeIndex, Spannable.SPAN_INCLUSIVE_EXCLUSIVE)
        spannableString.setSpan(tagSpan, textAltitudeIndex, textAltitudeIndex+2, Spannable.SPAN_INCLUSIVE_INCLUSIVE)
        collectDataText.text = spannableString
    }

    override fun onAttachedToWindow() {
        super.onAttachedToWindow()
    }

}