package com.waytous.anticollision.ui

import android.graphics.Bitmap
import android.graphics.Color
import android.os.Bundle
import androidx.core.graphics.scale
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.withStarted
import com.mapbox.geojson.Point
import com.mapbox.maps.CameraOptions
import com.mapbox.maps.MapView
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.sources.generated.geoJsonSource
import com.mapbox.maps.extension.style.style
import com.mapbox.maps.plugin.annotation.annotations
import com.mapbox.maps.plugin.annotation.generated.PointAnnotation
import com.mapbox.maps.plugin.annotation.generated.PointAnnotationManager
import com.mapbox.maps.plugin.annotation.generated.PointAnnotationOptions
import com.mapbox.maps.plugin.annotation.generated.createPointAnnotationManager
import com.mapbox.maps.viewannotation.ViewAnnotationManager
import com.waytous.anticollision.R
import com.waytous.anticollision.api.ApiService
import com.waytous.anticollision.repository.MainRepository
import com.waytous.anticollision.utils.getBitmapFromVectorDrawable
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

open class BaseFragment : Fragment() {

    private val mapModel: MainViewModel by viewModels{
        MainViewModel.MainViewModelFactory(MainRepository(requireContext()))
    }

    private lateinit var viewAnnotationManager: ViewAnnotationManager

    private lateinit var pointAnnotationManager: PointAnnotationManager

    private lateinit var pointAnnotation: PointAnnotation

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    }

    fun updateMapBox(mapView:MapView){
        mapView.getMapboxMap().setCamera(
            CameraOptions.Builder().center(
                Point.fromLngLat(
                    MainViewModel.LONGITUDE,
                    MainViewModel.LATITUDE
                )).zoom(14.0).build()
        )
        lifecycleScope.launch{
            withContext(Dispatchers.IO){
                val apiService = ApiService.create()
                val runnableAreaSource = apiService.runnableAreaVersion("-1")
                val laneSource = apiService.laneVersion("-1")
                val laneNodeSource = apiService.laneNodeVersion("-1")
                val diggingWorkAreaSource = apiService.diggingWorkAreaVersion("-1")
                val obstaclesSource = apiService.obstaclesVersion("-1")
                val electronicFenceSource = apiService.electronicFenceVersion("-1")
                val dumpAreaSource = apiService.dumpAreaVersion("-1")
                val staticObjectsSource = apiService.staticObjectsVersion("-1")
                val stationAreaSource = apiService.stationAreaVersion("-1")
                val barricadeSource = apiService.barricadeVersion("-1")
                val parkSpotSource = apiService.parkSpotVersion("-1")
                val wetAreaSource = apiService.wetAreaVersion("-1")
                withStarted {
                    mapView.getMapboxMap().loadStyle(
                        style(styleUri = MainViewModel.MY_MAP_BOX_STYLE) {
                            +geoJsonSource(MainViewModel.RUNNABLE_AREA_SOURCE) {
                                data(runnableAreaSource!!.geojson)
                                +fillLayer(
                                    MainViewModel.RUNNABLE_AREA_LAYER,
                                    MainViewModel.RUNNABLE_AREA_SOURCE
                                ){
                                    fillColor("#98a0a0")
                                    fillOpacity(0.85)
                                    fillOutlineColor("#FFFF00")
                                    visibility(Visibility.VISIBLE)
                                }
                            }
                            +geoJsonSource(MainViewModel.LANE_SOURCE) {
                                data(laneSource!!.geojson)
                                +lineLayer(
                                    MainViewModel.LANE_LAYER,
                                    MainViewModel.LANE_SOURCE
                                ){
                                    lineColor("white")
                                    lineWidth(3.0)
                                    lineJoin(LineJoin.ROUND)
                                    lineCap(LineCap.ROUND)
                                    visibility(Visibility.VISIBLE)
                                }
                            }
                            +geoJsonSource(MainViewModel.STATIC_OBJECTS_SOURCE) {
                                data(staticObjectsSource!!.geojson)
                                +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)
                                }
                            }
                            +geoJsonSource(MainViewModel.DIGGING_WORK_AREA_SOURCE) {
                                data(diggingWorkAreaSource!!.geojson)
                                +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)
                                }
                            }
                            +geoJsonSource(MainViewModel.BARRICADE_SOURCE) {
                                data(barricadeSource!!.geojson)
                                +lineLayer(
                                    MainViewModel.BARRICADE_LAYER,
                                    MainViewModel.BARRICADE_SOURCE
                                ){
                                    lineColor("blue")
                                    lineWidth(4.0)
                                    lineJoin(LineJoin.ROUND)
                                    lineCap(LineCap.ROUND)
                                    visibility(Visibility.VISIBLE)
                                }
                            }
                            +geoJsonSource(MainViewModel.OBSTACLES_SOURCE) {
                                data(obstaclesSource!!.geojson)
                                +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)
                                }
                            }
                            +geoJsonSource(MainViewModel.STATION_AREA_SOURCE) {
                                data(stationAreaSource!!.geojson)
                                +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)
                                }
                            }
                            +geoJsonSource(MainViewModel.LANE_NODE_SOURCE) {
                                data(laneNodeSource!!.geojson)
                                +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)
                                }
                            }
                            +geoJsonSource(MainViewModel.PARK_SPOT_SOURCE) {
                                data(parkSpotSource!!.geojson)
                                +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)
                                }
                            }
                            +geoJsonSource(MainViewModel.ELECTRONIC_FENCE_SOURCE) {
                                data(electronicFenceSource!!.geojson)
                                +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)
                                }
                            }
                            +geoJsonSource(MainViewModel.WET_AREA_SOURCE) {
                                data(wetAreaSource!!.geojson)
                                +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)
                                }
                            }
                            +geoJsonSource(MainViewModel.DUMP_AREA_SOURCE) {
                                data(dumpAreaSource!!.geojson)
                                +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)
                                }
                            }
                            +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)
                                }
                            }
                        }
                    ){
                        val bitmap: Bitmap? =
                            activity?.getBitmapFromVectorDrawable(R.drawable.my_vehicle_normal, 4)
                        val annotationPlugin = mapView.annotations
                        val pointAnnotationOptions: PointAnnotationOptions = PointAnnotationOptions()
                            .withPoint(mapModel.center.value!!)
                            .withIconImage(bitmap!!.apply {
                                scale(bitmap.width / 4, bitmap.height / 4)
                            })
                            .withIconAnchor(IconAnchor.BOTTOM)
                            .withDraggable(false)
                        pointAnnotationManager = annotationPlugin.createPointAnnotationManager()
                        pointAnnotation = pointAnnotationManager.create(pointAnnotationOptions)
                    }
                }
            }
        }
    }

}