package com.awesomeproject3;


import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.util.Base64;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.res.ResourcesCompat;
import androidx.fragment.app.Fragment;

import com.facebook.react.ReactActivity;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReadableType;
import com.facebook.react.bridge.WritableArray;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.tplmaps3d.CameraPosition;
import com.tplmaps3d.IconFactory;
import com.tplmaps3d.LngLat;
import com.tplmaps3d.MapController;
import com.tplmaps3d.MapView;
import com.tplmaps3d.Marker;
import com.tplmaps3d.MarkerOptions;
import com.tplmaps3d.Polyline;
import com.tplmaps3d.PolylineOptions;
import com.tplmaps3d.sdk.model.IconSize;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;


public class MyFragment extends Fragment implements MapView.OnMapReadyCallback, ModuleCallback {
    CustomView customView;
    private MapView mapView;
    MapController _mapController = null;
    TplMapsController tplMapsController;
    GLSurfaceView glSurfaceView;


    // @Override
    // protected void onCreate(Bundle savedInstanceState) {
    //     super.onCreate(savedInstanceState);
    //     setContentView(R.layout.fragmnet_map);
    //     mapView  = findViewById(R.id.map);
    //     mapView.onCreate(savedInstanceState);
    //     tplMapsController = new TplMapsController(this);
    //     mapView.loadMapAsync(this);

    // }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
        super.onCreateView(inflater, parent, savedInstanceState);

        View rootView = inflater.inflate(R.layout.fragmnet_map, parent, false);
        mapView = rootView.findViewById(R.id.map);
        glSurfaceView = new GLSurfaceView(getActivity());
        return rootView;
    }


    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        if (!Constant.isResume) {
            mapView.onCreate(savedInstanceState);
        }

        tplMapsController = new TplMapsController(this);

        try {
            mapView.loadMapAsync(this);

        } catch (Exception e) {
            Log.d("ERRORCHEKC", e.toString());
        }

    }

    @Override
    public void onPause() {
        super.onPause();
        mapView.onPause();
        // do any logic that should happen in an `onPause` method
        // e.g.: customView.onPause();
    }

    @Override
    public void onResume() {
        super.onResume();

//        if(mapView!= null && _mapController != null){
//
//            mapView.loadMapAsync(this);
//            _mapController.requestRender();
//            mapView.onResume();
//
//        }

    }


    @Override
    public void onDestroy() {
        super.onDestroy();
        // do any logic that should happen in an `onDestroy` method
        // e.g.: customView.onDestroy();
    }

    @Override
    public void onMapReady(MapController mapController) {
        _mapController = mapController;

        if (Constant.map_Controller == null) {
            Constant.map_Controller = mapController;
        }


        mapController.setOnCameraChangeEndListener(new MapController.OnCameraChangeEndListener() {
            @Override
            public void onCameraChangeEnd(CameraPosition cameraPosition) {
                if (Constant.promise != null) {
                    Constant.promise.resolve(cameraPosition.getPosition().latitude + ";" + cameraPosition.getPosition().longitude);
                }

            }
        });

        mapController.setOnMarkerClickListener(new MapController.OnMarkerClickListener() {
            @Override
            public void onMarkerClick(Marker marker) {
                if (Constant.promise != null) {
                    Constant.promise.resolve(marker.getPosition().latitude + ";" + marker.getPosition().longitude);
                }
            }
        });

        mapController.setOnCameraChangeEndListener(new MapController.OnCameraChangeEndListener() {
            @Override
            public void onCameraChangeEnd(CameraPosition cameraPosition) {
                Constant.reactApplicationContext
                        .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
                        .emit("onReady", cameraPosition.getPosition().latitude + ";" + cameraPosition.getPosition().longitude);
            }
        });

        if (Constant.reactApplicationContext != null) {
            Constant.reactApplicationContext
                    .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
                    .emit("onReady", "MapReady");

        }


        if (Constant.map_Controller != null && Constant.isResume) {

            _mapController.animateCamera(new CameraPosition(_mapController, Constant.map_Controller.getMapCameraPosition().getPosition(), (float) Constant.map_Controller.getMapCameraPosition().getZoom(), 0.0f, 0.0f), 0);

            for (int i = 0; i < Constant.map_Controller.getAllMarkers().size(); i++) {

                Marker marker_ = Constant.map_Controller.getAllMarkers().get(i);
                Marker marker = _mapController.addMarker(new MarkerOptions().position(marker_.getPosition()));
                marker.setTitle(marker_.getTitle());
                marker.setDescription(marker_.getDescription());
                marker.setIcon(marker_.getIcon());
            }

            if (Constant.map_Controller.getAllPolyLines().size() > 0) {

                ArrayList<LngLat> lngLats = new ArrayList<>();



                for (int i = 0; i < Constant.map_Controller.getAllPolyLines().size(); i++) {

                    lngLats.add(new LngLat(Constant.map_Controller.getAllPolyLines().get(i).getPoints().get(i).longitude ,
                            Constant.map_Controller.getAllPolyLines().get(i).getPoints().get(i).latitude));
                }

                Polyline polyline1 = _mapController.addPolyline(new PolylineOptions().addAll(lngLats));
                polyline1.setOutlineWidth(Constant.PolyLineWidth);
                polyline1.setOutlineColor(Color.parseColor(Constant.PolyLineColor));
            }

        }

    }

    public void zoomCurrentLoc() {
        if (_mapController != null) {
            _mapController.setMyLocationEnabled(true, MapController.MyLocationArg.ZOOM_LOCATION_ON_FIRST_FIX);
        }

    }

    public void onResumeMap() {

    }


    private void addMarker(LngLat lngLat) {

        //  LngLat coord = new LngLat(longitude, latitude);
        Marker marker = _mapController.addMarker(new MarkerOptions().position(lngLat).title("My Location"));
        Constant.map_Controller = _mapController;

    }


    private void addCustomMarker(LngLat lngLat, String imageName, String width, String height, String bearing, String title, String des) {

        int _width = Integer.parseInt(width);
        int _height = Integer.parseInt(height);

        Marker marker = _mapController.addMarker(new MarkerOptions().position(lngLat));
        marker.setTitle(title);
        marker.setDescription(des);
        marker.setRotation(Float.parseFloat(bearing));


        if (imageName.equals("rider")) {
            marker.setIcon(IconFactory.fromResource(R.drawable.rider, new IconSize(_width, _height)));
        } else if (imageName.equals("other")) {
            marker.setIcon(IconFactory.fromResource(R.drawable.other, new IconSize(_width, _height)));
        } else if (imageName.equals("branch")) {
            marker.setIcon(IconFactory.fromResource(R.drawable.branches, new IconSize(_width, _height)));
        }

        Constant.map_Controller = _mapController;

    }

    private void addCustomMarkerWithImage(LngLat lngLat, Bitmap bitmap, String bearing, String title, String des) {

        Marker marker = _mapController.addMarker(new MarkerOptions().position(lngLat));
        marker.setTitle(title);
        marker.setDescription(des);
        marker.setRotation(Float.parseFloat(bearing));
        marker.setIcon(IconFactory.fromBitmap(bitmap));
//        if (imageName.equals("rider")) {
//            marker.setIcon(IconFactory.fromResource(R.drawable.rider, new IconSize(_width, _height)));
//        } else if (imageName.equals("other")) {
//            marker.setIcon(IconFactory.fromResource(R.drawable.other, new IconSize(_width, _height)));
//        } else if (imageName.equals("branch")) {
//            marker.setIcon(IconFactory.fromResource(R.drawable.branches, new IconSize(_width, _height)));
//        }

        Constant.map_Controller = _mapController;

    }

    private void addPolyLines(WritableArray bundle) {


        _mapController.removeAllPolyLines();
        ArrayList<LngLat> lngLats = new ArrayList<>();

        for (int i = 0; i < bundle.size(); i++) {
            if (bundle.getType(i) == ReadableType.String) {
                String lnglat = bundle.getString(i);
                Log.d("WritableArray", lnglat);
                lngLats.add(new LngLat(Double.parseDouble(lnglat.split(";")[0]), Double.parseDouble(lnglat.split(";")[1])));
            }
        }

        Polyline polyline1 = _mapController.addPolyline(new PolylineOptions().addAll(lngLats));
        polyline1.setOutlineWidth(Constant.PolyLineWidth);
        polyline1.setOutlineColor(Color.parseColor(Constant.PolyLineColor));

        Constant.map_Controller = _mapController;
    }

    private void removeAllMarkers(){
        _mapController.removeAllMarkers();
        Constant.map_Controller = _mapController;
    }

    private void removeAllPolyLine(){
        _mapController.removeAllPolyLines();
        Constant.map_Controller = _mapController;
    }


    private void setCameraAnimate(double lat, double lng, double zoom) {
        LngLat lngLat = new LngLat(lng, lat);
        _mapController.animateCamera(new CameraPosition(_mapController, lngLat, (float) zoom, 0.0f, 0.0f), 1000);
        Constant.map_Controller = _mapController;
    }


    @Override
    public void nativeModuleCalled(int type, String bundle) {

        switch (type) {
            case 1:
                LngLat lngLat = new LngLat(Double.parseDouble(bundle.split(";")[0]), Double.parseDouble(bundle.split(";")[1]));
                addMarker(lngLat);
                break;

            case 2:
                setCameraAnimate(Double.parseDouble(bundle.split(";")[1]),
                        Double.parseDouble(bundle.split(";")[0]), Double.parseDouble(bundle.split(";")[2]));
                break;
            default:
                break;

            case 3:
                try {
                    lngLat = new LngLat(Double.parseDouble(bundle.split(";")[0]), Double.parseDouble(bundle.split(";")[1]));
                    addCustomMarker(lngLat, bundle.split(";")[2], bundle.split(";")[3], bundle.split(";")[4], bundle.split(";")[5], bundle.split(";")[6], bundle.split(";")[7]);
                } catch (Exception e) {
                    Toast.makeText(getActivity(), "Invalid Marker Request", Toast.LENGTH_SHORT).show();
                }
                break;


            case 4:
                removeAllMarkers();
                break;
            case 5:
                removeAllPolyLine();
                break;
        }

    }

    @Override
    public void nativeModuleCalled(int type, WritableArray bundle) {
        switch (type) {
            case 4:
                addPolyLines(bundle);
                break;
        }
    }

    @Override
    public void nativeModuleCalled(int type, String str, String longStr) {
        switch (type) {
            case 5:
                LngLat lngLat = new LngLat(Double.parseDouble(str.split(";")[0]), Double.parseDouble(str.split(";")[1]));
                addCustomMarkerWithImage(lngLat , decodeBase64ToBitmap(longStr) , str.split(";")[2] , str.split(";")[3] , str.split(";")[4]);
                break;
        }
    }

    public static Bitmap decodeBase64ToBitmap(String base64String) {
        // Remove the data:image/*;base64, prefix if present
//        String base64Image = base64String.replaceFirst("data:image/[;]+;base64,", "");
//
//        byte[] decodedBytes = Base64.decode(base64Image, Base64.DEFAULT);
//        return BitmapFactory.decodeByteArray(decodedBytes, 0, decodedBytes.length);

        final String pureBase64Encoded = base64String.substring(base64String.indexOf(",")  + 1);
        byte[] decodedString = Base64.decode(pureBase64Encoded, Base64.DEFAULT);
        Bitmap decodedByte = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);

        return decodedByte;
    }


}
