package com.casic.dcms.view.map;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;

import androidx.annotation.Nullable;

import com.amap.api.location.AMapLocation;
import com.casic.dcms.R;
import com.casic.dcms.databinding.ActivityGisBinding;
import com.casic.dcms.model.CommunityEnevlopBean;
import com.casic.dcms.model.PointFutureBean;
import com.casic.dcms.model.ShopFeatureBean;
import com.casic.dcms.utils.ArcGisMapCreator;
import com.casic.dcms.utils.AuthenticationHelper;
import com.casic.dcms.utils.HttpRequestManager;
import com.casic.dcms.utils.LocaleConstant;
import com.casic.dcms.utils.LocationHelper;
import com.casic.dcms.utils.ViewGroupKit;
import com.casic.dcms.utils.callback.ICommunityListener;
import com.casic.dcms.utils.callback.ILocationListener;
import com.esri.arcgisruntime.concurrent.ListenableFuture;
import com.esri.arcgisruntime.data.Feature;
import com.esri.arcgisruntime.data.QueryParameters;
import com.esri.arcgisruntime.data.ServiceFeatureTable;
import com.esri.arcgisruntime.geometry.Envelope;
import com.esri.arcgisruntime.geometry.Point;
import com.esri.arcgisruntime.geometry.SpatialReferences;
import com.esri.arcgisruntime.layers.FeatureLayer;
import com.esri.arcgisruntime.mapping.ArcGISMap;
import com.esri.arcgisruntime.mapping.Basemap;
import com.esri.arcgisruntime.mapping.BasemapStyle;
import com.esri.arcgisruntime.mapping.GeoElement;
import com.esri.arcgisruntime.mapping.Viewpoint;
import com.esri.arcgisruntime.mapping.view.DefaultMapViewOnTouchListener;
import com.esri.arcgisruntime.mapping.view.Graphic;
import com.esri.arcgisruntime.mapping.view.GraphicsOverlay;
import com.esri.arcgisruntime.mapping.view.IdentifyLayerResult;
import com.esri.arcgisruntime.symbology.PictureMarkerSymbol;
import com.esri.arcgisruntime.symbology.SimpleMarkerSymbol;
import com.esri.arcgisruntime.util.ListenableList;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.pengxh.androidx.lite.base.AndroidxBaseActivity;
import com.pengxh.androidx.lite.kit.ContextKit;
import com.pengxh.androidx.lite.utils.LoadingDialog;
import com.pengxh.androidx.lite.utils.SaveKeyValues;
import com.pengxh.androidx.lite.widget.dialog.AlertControlDialog;
import com.qmuiteam.qmui.widget.dialog.QMUIDialog;

import org.json.JSONException;
import org.json.JSONObject;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * 地图点位选择
 */
public class ArcGISMapActivity extends AndroidxBaseActivity<ActivityGisBinding> implements View.OnClickListener {

    private static final String TAG = "ArcGISMapActivity";
    private final Context context = ArcGISMapActivity.this;
    private FeatureLayer communityLayer, pointLayer, packageLayer;
    private Point clickPoint;
    private Gson gson;
    private String caseType;
    private ListenableList<Graphic> overlayGraphics;
    private ListenableList<GraphicsOverlay> graphicsOverlays;
    private GraphicsOverlay mGraphicsOverlay;
    private final List<Double> maxLat = new ArrayList<>();
    private final List<Double> minLat = new ArrayList<>();
    private final List<Double> maxLng = new ArrayList<>();
    private final List<Double> minLng = new ArrayList<>();

    @Override
    protected void setupTopBarLayout() {
        ViewGroupKit.initImmersionBar(binding.rootView, this, true, R.color.white);

        binding.titleBarLayout.titleView.setText("选择点位");
        binding.titleBarLayout.leftBackView.setOnClickListener(v -> finish());
    }

    @Override
    protected void observeRequestState() {

    }

    @Override
    protected void initOnCreate(@Nullable Bundle savedInstanceState) {
        caseType = getIntent().getStringExtra("type");
        gson = new Gson();
        binding.mapView.setAttributionTextVisible(false);//去掉左下角属性标识

        ArcGISMap arcGISMap = new ArcGISMap(BasemapStyle.ARCGIS_STREETS);
        //创建底图、并设置底图图层
        Basemap basemap = new Basemap(ArcGisMapCreator.createBaseLayer());
        arcGISMap.setBasemap(basemap);
        binding.mapView.setMap(arcGISMap);

        //获取崇仁范围边界
        String assetsData = ContextKit.readAssetsFile(context, "enevlop.json");
        Type type = new TypeToken<List<CommunityEnevlopBean>>() {
        }.getType();
        List<CommunityEnevlopBean> enevlopBeans = gson.fromJson(assetsData, type);
        for (CommunityEnevlopBean bean : enevlopBeans) {
            maxLat.add(bean.getEnevlop().getX_max());
            minLat.add(bean.getEnevlop().getX_min());
            maxLng.add(bean.getEnevlop().getY_max());
            minLng.add(bean.getEnevlop().getY_min());
        }

        //设置定位点
        LocationHelper.get().getCurrentLocation(this, new ILocationListener() {
            @Override
            public void onAMapLocationGet(AMapLocation aMapLocation) {
                if (aMapLocation != null) {
                    /**
                     * x_min : 116.04140203446151
                     * y_min : 27.753370580776277
                     * x_max : 116.05680864304304
                     * y_max : 27.753712385601723
                     */
                    if (!aMapLocation.getAddress().contains("崇仁")) {
                        //设置地图显示的区域
                        Envelope initialExtent = new Envelope(new Point(Collections.min(minLng), Collections.min(minLat), SpatialReferences.getWgs84()), new Point(Collections.max(maxLng), Collections.max(maxLat), SpatialReferences.getWgs84()));
                        Viewpoint viewpoint = new Viewpoint(initialExtent);
                        binding.mapView.setViewpoint(viewpoint);
                    } else {
                        Point point = new Point(aMapLocation.getLongitude(), aMapLocation.getLatitude(), SpatialReferences.getWgs84());
                        addPictureMarker(point);
                        binding.mapView.setViewpointCenterAsync(point, 2800);
                    }
                }
            }
        }, true);

        //网格和社区 (ID: 13)
        ServiceFeatureTable communityFeatureTable = ArcGisMapCreator.createGridFeatureTable();
        communityFeatureTable.setFeatureRequestMode(ServiceFeatureTable.FeatureRequestMode.ON_INTERACTION_NO_CACHE);
        communityLayer = new FeatureLayer(communityFeatureTable);
        /**
         * 设置地图数据图层，这里可以添加很多别的图层
         *
         * 如果是事件，加载单元网格图层，如果是部件，加载部件图层
         * */
        switch (caseType) {
            case "部件":
                //部件点图层 (ID: 2)
                ServiceFeatureTable pointFeatureTable = ArcGisMapCreator.createOtherFeatureTable("部件点");
                pointFeatureTable.setFeatureRequestMode(ServiceFeatureTable.FeatureRequestMode.ON_INTERACTION_NO_CACHE);
                pointLayer = new FeatureLayer(pointFeatureTable);
                arcGISMap.getOperationalLayers().add(pointLayer);
                break;
            case "三包上报":
            case "商铺变更":
                //门前三包 (ID: 1)
                ServiceFeatureTable packageFeatureTable = ArcGisMapCreator.createOtherFeatureTable("店铺三包");
                packageFeatureTable.setFeatureRequestMode(ServiceFeatureTable.FeatureRequestMode.ON_INTERACTION_NO_CACHE);
                packageLayer = new FeatureLayer(packageFeatureTable);
                arcGISMap.getOperationalLayers().add(packageLayer);
                break;
        }
        binding.mapView.setMap(arcGISMap);

        //Marker相关Layer
        mGraphicsOverlay = new GraphicsOverlay();
        overlayGraphics = mGraphicsOverlay.getGraphics();
        graphicsOverlays = binding.mapView.getGraphicsOverlays();
    }

    @SuppressLint("ClickableViewAccessibility")
    @Override
    protected void initEvent() {
        binding.mapView.setOnTouchListener(new DefaultMapViewOnTouchListener(this, binding.mapView) {
            @Override
            public boolean onSingleTapConfirmed(MotionEvent e) {
                android.graphics.Point screenPoint = new android.graphics.Point(Math.round(e.getX()), Math.round(e.getY()));
                clickPoint = binding.mapView.screenToLocation(screenPoint);
                addMarker(clickPoint);

                //查询参数
                QueryParameters queryParameters = new QueryParameters();
                queryParameters.setGeometry(clickPoint);//查询点击位置所在的社区

                //不管是事件还是部件，都的需要社区信息
                LocationHelper.get().getCurrentCommunity(communityLayer, queryParameters, new ICommunityListener() {
                    @Override
                    public void onCommunityFeatureGet(Feature feature) {
                        if (caseType.equals("事件")) {
                            Map<String, Object> attributes = feature.getAttributes();
                            showDialog((String) attributes.get("GBID"), (String) attributes.get("Note"));
                        }
                    }
                });
                switch (caseType) {
                    case "部件":
                        LocationHelper.get().getCurrentCommunity(communityLayer, queryParameters, new ICommunityListener() {
                            @Override
                            public void onCommunityFeatureGet(Feature feature) {
                                //先取社区信息，再取部件信息
                                List<Map<String, Object>> pointList = new ArrayList<>();
                                ListenableFuture<IdentifyLayerResult> pointFuture = binding.mapView.identifyLayerAsync(pointLayer, screenPoint, 15, false, -1);
                                pointFuture.addDoneListener(new Runnable() {
                                    @Override
                                    public void run() {
                                        try {
                                            IdentifyLayerResult identifyLayerResult = pointFuture.get();
                                            List<GeoElement> elements = identifyLayerResult.getElements();
                                            for (GeoElement element : elements) {
                                                Map<String, Object> attributes = element.getAttributes();
                                                pointList.add(attributes);
                                            }
//                                        Log.d(TAG, "onCommunityFeatureGet: " + gson.toJson(pointList));
                                            runOnUiThread(() -> {
                                                QMUIDialog.MenuDialogBuilder menuDialogBuilder = new QMUIDialog.MenuDialogBuilder(context);
                                                menuDialogBuilder.setTitle("请选择您要上报的部件");
                                                Type gridType = new TypeToken<List<PointFutureBean>>() {
                                                }.getType();
                                                List<PointFutureBean> beans = gson.fromJson(gson.toJson(pointList), gridType);
                                                for (PointFutureBean featureBean : beans) {
                                                    menuDialogBuilder.addItem(featureBean.getObjid() + "（" + featureBean.getObjname() + "）", new DialogInterface.OnClickListener() {
                                                        @Override
                                                        public void onClick(DialogInterface dialog, int which) {
                                                            dialog.dismiss();
                                                            showDialog(featureBean.getBgid(), featureBean.getObjid(), featureBean.getObjname(), (String) feature.getAttributes().get("Note"));
                                                        }
                                                    });
                                                }
                                                menuDialogBuilder.create().show();
                                            });
                                        } catch (Exception e1) {
                                            e1.printStackTrace();
                                        }
                                    }
                                });
                            }
                        });
                        break;
                    case "三包上报":
                    case "商铺变更":
                        LocationHelper.get().getCurrentCommunity(communityLayer, queryParameters, new ICommunityListener() {
                            @Override
                            public void onCommunityFeatureGet(Feature feature) {
                                //先取社区信息，再取部件信息
                                List<Map<String, Object>> shopList = new ArrayList<>();
                                ListenableFuture<IdentifyLayerResult> packageFuture = binding.mapView.identifyLayerAsync(packageLayer, screenPoint, 15, false, -1);
                                packageFuture.addDoneListener(new Runnable() {
                                    @Override
                                    public void run() {
                                        try {
                                            IdentifyLayerResult identifyLayerResult = packageFuture.get();
                                            List<GeoElement> elements = identifyLayerResult.getElements();
                                            for (GeoElement element : elements) {
                                                Map<String, Object> attributes = element.getAttributes();
                                                shopList.add(attributes);
                                            }
//                                            Log.d(TAG, "shopList: " + gson.toJson(shopList));
                                            runOnUiThread(() -> {
                                                QMUIDialog.MenuDialogBuilder menuDialogBuilder = new QMUIDialog.MenuDialogBuilder(context);
                                                menuDialogBuilder.setTitle("请选择您要上报的部件");
                                                Type shopType = new TypeToken<List<ShopFeatureBean>>() {
                                                }.getType();
                                                List<ShopFeatureBean> shopBeans = gson.fromJson(gson.toJson(shopList), shopType);

                                                //设置dialog列表
                                                menuDialogBuilder.setTitle("请选择商户");
                                                for (ShopFeatureBean featureBean : shopBeans) {
                                                    menuDialogBuilder.addItem(featureBean.getDutyname(), new DialogInterface.OnClickListener() {
                                                        @Override
                                                        public void onClick(DialogInterface dialog, int which) {
                                                            dialog.dismiss();
                                                            LoadingDialog.show(ArcGISMapActivity.this, "查询商户信息中，请稍后");

                                                            String ip = (String) SaveKeyValues.getValue(LocaleConstant.IP_KEY, "http://111.198.10.15:11409");
                                                            new HttpRequestManager.Builder().setAuthentication("token", AuthenticationHelper.getToken()).setRequestTarget(ip + LocaleConstant.SHOP_MERCHANT_ID + featureBean.getObjid()).setOnHttpRequestListener(new HttpRequestManager.OnHttpRequestListener() {
                                                                @Override
                                                                public void onSuccess(String result) {
                                                                    LoadingDialog.dismiss();
                                                                    try {
                                                                        JSONObject jsonObject = new JSONObject(result);
                                                                        JSONObject data = jsonObject.getJSONObject("data");
                                                                        String shopId = data.getString("id");
                                                                        showShopDialog(featureBean.getBgid(), (String) feature.getAttributes().get("Note"), featureBean.getDutyname(), shopId);
                                                                    } catch (JSONException e) {
                                                                        e.printStackTrace();
                                                                    }
                                                                }

                                                                @Override
                                                                public void onFailure(Throwable throwable) {

                                                                }
                                                            }).build().start();
                                                        }
                                                    });
                                                }
                                                menuDialogBuilder.create().show();
                                            });
                                        } catch (Exception e) {
                                            e.printStackTrace();
                                        }
                                    }
                                });
                            }
                        });
                        break;
                }
                return true;
            }
        });
    }

    /**
     * 三包
     */
    private void showShopDialog(String gridId, String communityName, String shopName, String shopID) {
        if (!this.isFinishing()) {
            new AlertControlDialog.Builder().setContext(this).setTitle("提示").setMessage("已选择商户：" + shopName + "\r\n确认提交？").setNegativeButton("取消").setPositiveButton("确定").setOnDialogButtonClickListener(new AlertControlDialog.OnDialogButtonClickListener() {
                @Override
                public void onConfirmClick() {
                    Intent intent = new Intent();
                    intent.putExtra("shopName", shopName);
                    intent.putExtra("shopID", shopID);
                    intent.putExtra("latitude", clickPoint.getY());
                    intent.putExtra("longitude", clickPoint.getX());
                    intent.putExtra("community", communityName);
                    intent.putExtra("gridId", gridId);
                    setResult(RESULT_OK, intent);
                    finish();
                }

                @Override
                public void onCancelClick() {

                }
            }).build().show();
        }
    }

    /**
     * 部件
     */
    private void showDialog(String gridId, String objId, String objName, String communityName) {
        if (!this.isFinishing()) {
            new AlertControlDialog.Builder().setContext(this).setTitle("提示").setMessage("部件所在网格：" + gridId + "\r\n部件ID：" + objId + "\r\n部件种类：" + objName + "\r\n确认提交？").setNegativeButton("取消").setPositiveButton("确定").setOnDialogButtonClickListener(new AlertControlDialog.OnDialogButtonClickListener() {
                @Override
                public void onConfirmClick() {
                    Intent intent = new Intent();
                    intent.putExtra("latitude", clickPoint.getY());
                    intent.putExtra("longitude", clickPoint.getX());
                    intent.putExtra("community", communityName);
                    intent.putExtra("gridId", gridId);
                    setResult(RESULT_OK, intent);
                    finish();
                }

                @Override
                public void onCancelClick() {

                }
            }).build().show();
        }
    }

    /**
     * 事件
     */
    private void showDialog(String gridId, String communityName) {
        if (!this.isFinishing()) {
            new AlertControlDialog.Builder().setContext(this).setTitle("提示").setMessage("事件所在网格：" + gridId + "\r\n所在社区：" + communityName + "\r\n确认选择？").setNegativeButton("取消").setPositiveButton("确定").setOnDialogButtonClickListener(new AlertControlDialog.OnDialogButtonClickListener() {
                @Override
                public void onConfirmClick() {
                    Intent intent = new Intent();
                    intent.putExtra("latitude", clickPoint.getY());
                    intent.putExtra("longitude", clickPoint.getX());
                    intent.putExtra("community", communityName);
                    intent.putExtra("gridId", gridId);
                    setResult(RESULT_OK, intent);
                    finish();
                }

                @Override
                public void onCancelClick() {

                }
            }).build().show();
        }
    }

    /**
     * //[116.598359, 28.247870, 0.000000, NaN] SR: 4326
     */
    private void addMarker(Point clickPoint) {
        SimpleMarkerSymbol simpleMarkerSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbol.Style.CIRCLE, Color.BLUE, 10);
        if (overlayGraphics != null && graphicsOverlays != null) {
            overlayGraphics.clear();
            graphicsOverlays.clear();
        }
        Graphic graphic = new Graphic(clickPoint, simpleMarkerSymbol);
        overlayGraphics.add(graphic);
        graphicsOverlays.add(mGraphicsOverlay);
    }

    private void addPictureMarker(Point point) {
        Bitmap caseBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.on_line);
        BitmapDrawable caseDrawable = new BitmapDrawable(getResources(), caseBitmap);
        PictureMarkerSymbol pictureMarker = new PictureMarkerSymbol(caseDrawable);
        pictureMarker.setWidth(64);
        pictureMarker.setHeight(42);
        pictureMarker.loadAsync();

        Graphic graphic = new Graphic(point, pictureMarker);
        GraphicsOverlay mGraphicsOverlay = new GraphicsOverlay();
        ListenableList<Graphic> overlayGraphics = mGraphicsOverlay.getGraphics();
        ListenableList<GraphicsOverlay> graphicsOverlays = binding.mapView.getGraphicsOverlays();
        overlayGraphics.add(graphic);
        graphicsOverlays.add(mGraphicsOverlay);
    }

    @Override
    public void onClick(View v) {
        int id = v.getId();
        if (id == R.id.expandMapView) {
            binding.mapView.setViewpointScaleAsync(binding.mapView.getMapScale() * 0.5);
        } else if (id == R.id.minusMapView) {
            binding.mapView.setViewpointScaleAsync(binding.mapView.getMapScale() * 2);
        } else if (id == R.id.removeToLocalView) {
            LoadingDialog.show(this, "定位中，请稍后");
            LocationHelper.get().getCurrentLocation(this, new ILocationListener() {

                @Override
                public void onAMapLocationGet(AMapLocation aMapLocation) {
                    if (aMapLocation != null) {
                        double[] gcjToWgs = LocationHelper.get().gcjToWgs(aMapLocation.getLongitude(), aMapLocation.getLatitude());
                        Point point = new Point(gcjToWgs[0], gcjToWgs[1], SpatialReferences.getWgs84());
                        addPictureMarker(point);
                        binding.mapView.setViewpointCenterAsync(point, 2800);
                        LoadingDialog.dismiss();
                    }
                }
            }, true);
        }
    }

    protected void onResume() {
        super.onResume();
        binding.mapView.resume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        binding.mapView.pause();
    }

    @Override
    protected void onDestroy() {
        binding.mapView.dispose();
        super.onDestroy();
    }
}