package com.aaron.kakao.hospitalmapfortube.ui.main

import android.Manifest
import android.annotation.SuppressLint
import android.content.Context
import android.content.pm.PackageManager
import android.location.Criteria
import android.location.Location
import android.location.LocationListener
import android.location.LocationManager
import android.os.Build
import android.os.Bundle
import android.support.v4.app.ActivityCompat
import android.util.Log
import android.widget.Toast
import com.aaron.kakao.hospitalmapfortube.R
import com.aaron.kakao.hospitalmapfortube.databinding.ActivityMainBinding
import com.aaron.kakao.hospitalmapfortube.ui.BindingActivity
import com.tedpark.tedpermission.rx2.TedRx2Permission
import io.reactivex.rxkotlin.Observables
import net.daum.mf.map.api.MapPOIItem
import net.daum.mf.map.api.MapPoint
import net.daum.mf.map.api.MapReverseGeoCoder
import net.daum.mf.map.api.MapView
import org.koin.android.viewmodel.ext.android.getViewModel

class MainActivity : BindingActivity<ActivityMainBinding, MainViewModel>() {

    private val mapView by lazy { MapView(this) }
    private val locationManager by lazy { getSystemService(Context.LOCATION_SERVICE) as LocationManager}

    override fun getLayoutResId() = R.layout.activity_main

    override fun getMyViewModel(): MainViewModel = getViewModel()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        viewModel.doMapReverseGeoCoder = {
            MapReverseGeoCoder(
                "07bc209d76a94c562690876602676468",
                mapView.mapCenterPoint,
                object : MapReverseGeoCoder.ReverseGeoCodingResultListener {
                    override fun onReverseGeoCoderFailedToFindAddress(p0: MapReverseGeoCoder?) {
                        Log.d("aaron", "onReverseGeoCoderFailedToFindAddress")
                    }

                    override fun onReverseGeoCoderFoundAddress(
                        p0: MapReverseGeoCoder?,
                        p1: String?
                    ) {
                        Log.d("aaron", "onReverseGeoCoderFoundAddress")
                        Log.d("aaron", p1)
                    }

                }, this
            ).startFindingAddress()
            it.documents.forEach {
                mapView.addPOIItem(MapPOIItem().apply {
                    itemName = it.place_name
                    tag = it.id.toInt()
                    mapPoint = MapPoint.mapPointWithGeoCoord(it.x.toDouble(), it.y.toDouble())
                    markerType = MapPOIItem.MarkerType.BluePin
                    selectedMarkerType = MapPOIItem.MarkerType.RedPin
                })
            }
        }
        initMap()
    }

    override fun onDestroy() {
        super.onDestroy()
        locationManager.removeUpdates(locationListener)
    }

    private fun initMap() {
        if (needPermission()) {
            TedRx2Permission.with(this)
                .setRationaleTitle("권한 요청")
                .setRationaleMessage("앱을 사용하기 위해 사용자 위치정보 수집 권한이 필요합니다.")
                .setPermissions(Manifest.permission.ACCESS_FINE_LOCATION)
                .request()
                .subscribe({permissionResult ->
                    if (permissionResult.isGranted) {
                        Toast.makeText(this, "Permission Granted", Toast.LENGTH_SHORT).show()
                        initMap()
                    } else {
                        Toast.makeText(this,
                            "Permission Denied\n" + permissionResult.deniedPermissions.toString(), Toast.LENGTH_SHORT)
                            .show()
                        finish()
                    }
                }, {})
        } else {
            binding.mapLayout.addView(mapView.apply {
                setMapViewEventListener(this@MainActivity.mapViewEventListener)
            })
        }
    }

    private val mapViewEventListener = object : MapView.MapViewEventListener {
        override fun onMapViewDoubleTapped(p0: MapView?, p1: MapPoint?) {
        }

        override fun onMapViewInitialized(mapView: MapView?) {
            Log.d("aaron", "onMapViewInitialized!!!")
            mapView?.run {
                Log.d("aaron", "setMapView!!!")
                viewModel.getCategory(getCurrentLocation())
                startLocationCheck()
            }
            Log.d("aaron", "showCurrentMarker = ${mapView?.isShowingCurrentLocationMarker}")
//            if (getCurrentLocation() != null) {
//                mapView?.run {
//                    setMapCenterPoint(
//                        MapPoint.mapPointWithGeoCoord(
//                            getCurrentLocation()!!.latitude,
//                            getCurrentLocation()!!.longitude
//                        ), false
//                    )
//                    addPOIItem(
//                        MapPOIItem().apply {
//                            Log.d("aaron", "addMarker!!!")
//                            itemName = "Current Marker"
//                            tag = 1
//                            mapPoint = MapPoint.mapPointWithGeoCoord(getCurrentLocation()!!.latitude, getCurrentLocation()!!.latitude)
//                            markerType = MapPOIItem.MarkerType.CustomImage
//                            customImageResourceId = R.drawable.current_marker_red
//                            isCustomImageAutoscale = true
//                            setCustomImageAnchor(0.5f, 0.5f)
//                        })
//                    setShowCurrentLocationMarker(true)
//                    Log.d("aaron", "showCurrentMarker = $isShowingCurrentLocationMarker")
//                }
//            }
        }

        override fun onMapViewDragStarted(p0: MapView?, p1: MapPoint?) {
        }

        override fun onMapViewMoveFinished(p0: MapView?, p1: MapPoint?) {
        }

        override fun onMapViewCenterPointMoved(mapView: MapView?, movedPoint: MapPoint?) {
        }

        override fun onMapViewDragEnded(p0: MapView?, p1: MapPoint?) {
        }

        override fun onMapViewSingleTapped(p0: MapView?, p1: MapPoint?) {
        }

        override fun onMapViewZoomLevelChanged(p0: MapView?, p1: Int) {
        }

        override fun onMapViewLongPressed(p0: MapView?, p1: MapPoint?) {
        }

    }

    @SuppressLint("MissingPermission")
    private fun getCurrentLocation(): Location? {
        val locationProvider = locationManager.getBestProvider(Criteria().apply {
            accuracy = Criteria.NO_REQUIREMENT
            powerRequirement = Criteria.NO_REQUIREMENT
            isAltitudeRequired = false
            isBearingRequired = false
            isSpeedRequired = false
            isCostAllowed = true
        }, true)
        Log.d("aaron", "currentLocation = ${locationManager.getLastKnownLocation(locationProvider)}")
        return locationManager.getLastKnownLocation(locationProvider)
    }

    private fun needPermission() = ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
            && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M

    @SuppressLint("MissingPermission")
    private fun startLocationCheck() {
        locationManager.run {
            requestLocationUpdates(LocationManager.GPS_PROVIDER, 100L, 1f, locationListener)
            requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 100L, 1f, locationListener)
        }
    }

    private val locationListener = object : LocationListener {
        override fun onLocationChanged(location: Location?) {
            location?.let {
                mapView.addPOIItem(MapPOIItem().apply {
                    itemName = "Current Marker"
                    tag = 1
                    mapPoint = MapPoint.mapPointWithGeoCoord(it.latitude, it.longitude)
                    markerType = MapPOIItem.MarkerType.CustomImage
                    customImageResourceId = R.drawable.current_marker_red
                    setCustomImageAnchor(0.5f, 0.5f)
                })
                mapView.setMapCenterPoint(MapPoint.mapPointWithGeoCoord(it.latitude, it.longitude), false)
                viewModel.getCategory(location)
            }
        }

        override fun onStatusChanged(p0: String?, p1: Int, p2: Bundle?) {
        }

        override fun onProviderEnabled(p0: String?) {
        }

        override fun onProviderDisabled(p0: String?) {
        }

    }
}