package kz.istt.locust;

import androidx.core.app.ActivityCompat;
import androidx.core.content.res.ResourcesCompat;
import androidx.fragment.app.FragmentActivity;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Parcelable;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.Polygon;
import com.google.android.gms.maps.model.PolygonOptions;
import com.google.maps.android.PolyUtil;
import com.google.maps.android.SphericalUtil;
import com.google.maps.android.clustering.ClusterManager;
import com.google.maps.android.ui.IconGenerator;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import dbfields.selectDB;
import tctable.Point;
import tools.ClusterMarker;

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, LocationListener, GoogleMap.OnMapLongClickListener {

    private GoogleMap mMap=null;

    private boolean first=true;
    private List<LatLng> places = new ArrayList<>();
    private String mapsApiKey;
    private int width;

    private double _lat    = 0; // от устройства
    private double _lon    = 0; // от устройства
    ArrayList<LatLon> points=new ArrayList<LatLon>();
    ArrayList<Polygon> polygons=new ArrayList<Polygon>();
    Polygon polygon=null;

    String g_uid="";
    private Marker marker=null;
    private LocationManager lm;


    //To use vector image as marker icon need convert him in bitmap
    public Bitmap getMarker(int resID) {
        IconGenerator iconGen = new IconGenerator(this);

        // Define the size you want from dimensions file
        int shapeSize = 32;//this.getResources().getDimensionPixelSize(R.dimen.custom_marker_size);

        Drawable shapeDrawable = ResourcesCompat.getDrawable(this.getResources(), resID, null);
        iconGen.setBackground(shapeDrawable);

        // Create a view container to set the size
        View view = new View(this);
        view.setLayoutParams(new ViewGroup.LayoutParams(shapeSize, shapeSize));
        iconGen.setContentView(view);

        // Create the bitmap
        Bitmap bitmap = iconGen.makeIcon();
        return bitmap;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_maps);
        // Obtain the SupportMapFragment and get notified when the map is ready to be used.
        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);

        Intent intent = getIntent();
        points = intent.getParcelableArrayListExtra("LatLon");
        g_uid = intent.getStringExtra("uid");
        if(g_uid==null) g_uid="";

        // Чтоб слушать GPS


        lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && checkSelfPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{
                    android.Manifest.permission.ACCESS_FINE_LOCATION,
                    android.Manifest.permission.ACCESS_COARSE_LOCATION
            }, 1001);
        }else{
            lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 500, 1, this);
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        if (requestCode == 1) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 500, 1, this);
            } else {
                Toast.makeText(this, getResources().getString(R.string.Please_activate_GPS), Toast.LENGTH_LONG).show();
            }
        }
    }

    /**
     * Manipulates the map once available.
     * This callback is triggered when the map is ready to be used.
     * This is where we can add markers or lines, add listeners or move the camera. In this case,
     * we just add a marker near Sydney, Australia.
     * If Google Play services is not installed on the device, the user will be prompted to install
     * it inside the SupportMapFragment. This method will only be triggered once the user has
     * installed Google Play services and returned to the app.
     */
    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;
        mMap.setOnMapLongClickListener(this);
        polygons.clear();

        // Add a marker in Sydney and move the camera
        LatLng center = new LatLng(46.24, 50.30);
        marker=mMap.addMarker(new MarkerOptions()
                .position(center)
                .title("Inspector")
                .icon(BitmapDescriptorFactory.fromBitmap(getMarker(R.drawable.ic_inspector)))
        );
        marker.setVisible(false);

        //Отобразить все геозоны кроме текущей, обследования саранчи  (текущие ниже)
        DbOpenHelper dboh = new DbOpenHelper(this);
        SQLiteDatabase rdb = null;
        try {

            rdb = dboh.getReadableDatabase();
            Cursor cursor=null;
            try {
                String sql = """
                        select
                            frmlocust_uid,
                            lat,
                            lon
                        from
                            frmlocust_locations
                        where
                            frmlocust_uid!=?
                        order by
                            frmlocust_uid,
                            pos
                        """;
                cursor = rdb.rawQuery(sql, new String[]{g_uid});
                if (cursor.moveToFirst()) {
                    String uid = "";
                    PolygonOptions pOptions2 = new PolygonOptions();
                    do {
                        if (pOptions2.getPoints().size() > 1) {
                            Polygon polygon = mMap.addPolygon(pOptions2);
                            polygons.add(polygon);
                            polygon.setFillColor(0x7F0000FF);
                        }
                        if (!uid.equals(cursor.getString(0))) {
                            pOptions2 = new PolygonOptions();
                            uid = cursor.getString(0);
                        }
                        pOptions2.add(new LatLng(cursor.getDouble(1), cursor.getDouble(2)));
                    } while (cursor.moveToNext());

                    if (pOptions2.getPoints().size() > 1) {
                        Polygon polygon = mMap.addPolygon(pOptions2);
                        polygons.add(polygon);
                        polygon.setFillColor(0x7F0000FF);
                    }
                }
            }catch(Exception e){
                e.printStackTrace();
            }finally{
                if(cursor!=null){ cursor.close(); }
            }

            //Отобразить все геозоны кроме текущей, противосаначовой обработки (текущие ниже)
            cursor=null;
            try {
                String sql = """
                        select
                            frmlocustdel_uid,
                            lat,
                            lon
                        from
                            frmlocustdel_locations
                        where
                            frmlocustdel_uid!=?
                        order by
                            frmlocustdel_uid,
                            pos
                        """;
                cursor = rdb.rawQuery(sql, new String[]{g_uid});
                if (cursor.moveToFirst()) {
                    String uid = "";
                    PolygonOptions pOptions2 = new PolygonOptions();
                    do {
                        if (!uid.equals(cursor.getString(0)) && pOptions2.getPoints().size() > 1) {
                            Polygon polygon = mMap.addPolygon(pOptions2);
                            polygons.add(polygon);
                            polygon.setFillColor(0x7FFF0000);
                        }
                        if (!uid.equals(cursor.getString(0))) {
                            pOptions2 = new PolygonOptions();
                            uid = cursor.getString(0);
                        }
                        pOptions2.add(new LatLng(cursor.getDouble(1), cursor.getDouble(2)));
                    } while (cursor.moveToNext());
                    if (pOptions2.getPoints().size() > 1) {
                        Polygon polygon = mMap.addPolygon(pOptions2);
                        polygons.add(polygon);
                        polygon.setFillColor(0x7FFF0000);
                    }
                }
            }catch(Exception e){
                e.printStackTrace();
            }finally{
                if(cursor!=null){ cursor.close(); }
            }

            //Отображаю все центральные точки с анкет противосаранчовой обработки
            cursor=null;
            try {
                String sql = """
                        select
                            uid,
				            lat_center,
				            lon_center
                        from
                            frmlocustdel
                        where
                            del = 0
                            and uid!=?
                """;
                cursor = rdb.rawQuery(sql, new String[]{g_uid});
                if (cursor.moveToFirst()) {
                    do {
                        center = new LatLng(cursor.getDouble(1), cursor.getDouble(2));
                        mMap.addMarker(new MarkerOptions()
                                .position(center)
                                .title("Spray")
                                .icon(BitmapDescriptorFactory.fromBitmap(getMarker(R.drawable.ic_flag)))
                        );
                    } while (cursor.moveToNext());
                }
            }catch(Exception e){
                e.printStackTrace();
            }finally{
                if(cursor!=null){ cursor.close(); }
            }




        }catch(Exception e){
            e.printStackTrace();
        }finally{
            if(rdb!=null){ rdb.close(); }
        }
        dboh.close();
/**/
        //Create a geopolygon for the current survey. (The main polygon at the end since they overlap each)
        PolygonOptions pOptions = new PolygonOptions();

        for(int i=0;i<points.size();i++){
            if(points.get(i)!=null && points.get(i).lon!=0 && points.get(i).lat!=0)
                pOptions.add(new LatLng(points.get(i).lat, points.get(i).lon));
        }

        if(!pOptions.getPoints().isEmpty()) {
            Polygon polygon = mMap.addPolygon(pOptions);
            polygon.setFillColor(0x7F00FF00);
            center = getPolygonCenterPoint(pOptions.getPoints());

            //I derive the square of the region
            double area=SphericalUtil.computeArea(pOptions.getPoints())/10000.0;
            DecimalFormat df = new DecimalFormat("#.###");
            IconGenerator iconFactory = new IconGenerator(this);
            iconFactory.setColor(Color.CYAN);
            addIcon(mMap, iconFactory, df.format(area) + "ha", center);
        }

        mMap.moveCamera(CameraUpdateFactory.zoomTo( 5.0f ) );
        mMap.moveCamera(CameraUpdateFactory.newLatLng(center));
        mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
    }

    @Override
    public void onLocationChanged(Location location) {
        _lat = location.getLatitude(); // от устройства
        _lon = location.getLongitude(); // от устройства

        if(marker!=null)
        {
            marker.setPosition(new LatLng(_lat,_lon));
            marker.setVisible(true);
            if(first) {
                mMap.moveCamera(CameraUpdateFactory.newLatLng(marker.getPosition()));
                mMap.animateCamera(CameraUpdateFactory.zoomTo(12.0f));
                first=false;
            }
        }
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {

    }

    @Override
    public void onProviderEnabled(String provider) {

    }

    @Override
    public void onProviderDisabled(String provider) {

    }
    //GoogleMap gm;
//gm.setOnMapLongClickListener(this);

    @Override
    public void onMapLongClick(LatLng point) {
        boolean find=false;
        if(mMap!=null){
            for(int i=0;i<polygons.size();i++){
                Polygon polygon=polygons.get(i);
                if(PolyUtil.containsLocation(point, polygon.getPoints(), true)){
                    this.polygon=polygon;

                    AlertDialog.Builder adb = new AlertDialog.Builder(this,R.style.AlertDialogTheme);
                    adb.setTitle(getString(R.string.Warning));
                    adb.setMessage(MapsActivity.this.getResources().getString(R.string.Copy_polygon));
                    adb.setPositiveButton(MapsActivity.this.getResources().getString(R.string.Yes), new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int id) {
                            Intent intent = new Intent();
                            ArrayList<LatLon> list=new ArrayList<LatLon>();
                            for(int j=0;j<MapsActivity.this.polygon.getPoints().size()-1;j++){
                                list.add(new LatLon(UUID.randomUUID().toString(),MapsActivity.this.polygon.getPoints().get(j).latitude,MapsActivity.this.polygon.getPoints().get(j).longitude));
                            }
                            intent.putParcelableArrayListExtra("LatLon", list);
                            MapsActivity.this.setResult(Activity.RESULT_OK,intent);
                            MapsActivity.this.finish();
                        }
                    });
                    adb.setNegativeButton(MapsActivity.this.getResources().getString(R.string.No), new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int id) {

                        }
                    });
                    AlertDialog ad = adb.show();
                    ad.getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(Color.BLACK);
                    ad.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(Color.BLACK);

                    find=true;
                    break;
                }
            }
        }
        if(!find)
            Toast.makeText(MapsActivity.this, MapsActivity.this.getResources().getString(R.string.Not_found), Toast.LENGTH_LONG).show();
    }

    private LatLng getPolygonCenterPoint(List<LatLng> polygonPointsList){
        LatLng centerLatLng = null;
        LatLngBounds.Builder builder = new LatLngBounds.Builder();
        for(int i = 0 ; i < polygonPointsList.size() ; i++)
        {
            builder.include(polygonPointsList.get(i));
        }
        LatLngBounds bounds = builder.build();
        centerLatLng =  bounds.getCenter();

        return centerLatLng;
    }

    private void addIcon(GoogleMap googleMap, IconGenerator iconFactory, CharSequence text, LatLng position) {
        MarkerOptions markerOptions = new MarkerOptions().
                icon(BitmapDescriptorFactory.fromBitmap(iconFactory.makeIcon(text))).
                position(position).
                anchor(iconFactory.getAnchorU(), iconFactory.getAnchorV());

        googleMap.addMarker(markerOptions);
    }

}

