package com.casic.dcms.view.streetlight;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;

import com.amap.api.location.AMapLocation;
import com.casic.dcms.R;
import com.casic.dcms.databinding.ActivityLampBoxMapBinding;
import com.casic.dcms.model.ActionResultBean;
import com.casic.dcms.model.LampBoxDetailBean;
import com.casic.dcms.model.MapLampBoxBean;
import com.casic.dcms.utils.ArcGisMapCreator;
import com.casic.dcms.utils.LocaleConstant;
import com.casic.dcms.utils.LocationHelper;
import com.casic.dcms.utils.ViewGroupKit;
import com.casic.dcms.utils.callback.ILocationListener;
import com.casic.dcms.vm.LampBoxViewModel;
import com.esri.arcgisruntime.concurrent.ListenableFuture;
import com.esri.arcgisruntime.geometry.Point;
import com.esri.arcgisruntime.geometry.SpatialReferences;
import com.esri.arcgisruntime.mapping.ArcGISMap;
import com.esri.arcgisruntime.mapping.Basemap;
import com.esri.arcgisruntime.mapping.BasemapStyle;
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.IdentifyGraphicsOverlayResult;
import com.esri.arcgisruntime.symbology.PictureMarkerSymbol;
import com.esri.arcgisruntime.util.ListenableList;
import com.pengxh.androidx.lite.base.AndroidxBaseActivity;
import com.pengxh.androidx.lite.kit.StringKit;
import com.pengxh.androidx.lite.utils.LoadState;
import com.pengxh.androidx.lite.utils.LoadingDialog;
import com.pengxh.androidx.lite.utils.WeakReferenceHandler;
import com.pengxh.androidx.lite.widget.TitleBarView;
import com.qmuiteam.qmui.util.QMUIDisplayHelper;
import com.qmuiteam.qmui.widget.popup.QMUIPopup;
import com.qmuiteam.qmui.widget.popup.QMUIPopups;
import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;

public class LampBoxOnMapActivity extends AndroidxBaseActivity<ActivityLampBoxMapBinding> implements Handler.Callback {

    private static final String TAG = "LampBoxOnMapActivity";
    private final Context context = this;
    private final WeakReferenceHandler weakReferenceHandler = new WeakReferenceHandler(this);
    private LampBoxViewModel lampBoxViewModel;
    private List<MapLampBoxBean.DataBean> dataBeans = new ArrayList<>();
    private ListenableList<GraphicsOverlay> graphicsOverlays;
    private ListenableList<Graphic> graphics;
    private double DELTA_L = LocaleConstant.DELTA_LNG_75;
    private boolean isControlLampBox = false;
    private boolean isGetLampBoxDetail = false;

    @Override
    protected void setupTopBarLayout() {
        ViewGroupKit.initImmersionBar(binding.rootView, this, true, R.color.white);
        binding.titleView.setOnClickListener(new TitleBarView.OnClickListener() {
            @Override
            public void onLeftClick() {
                finish();
            }

            @Override
            public void onRightClick() {

            }
        });
    }

    @Override
    protected void observeRequestState() {
        lampBoxViewModel.loadState.observe(this, new Observer<LoadState>() {
            @Override
            public void onChanged(LoadState loadState) {
                if (isControlLampBox) {
                    if (loadState == LoadState.Loading) {
                        LoadingDialog.show(LampBoxOnMapActivity.this, "处理中，请稍后...");
                    } else {
                        LoadingDialog.dismiss();
                    }
                } else if (isGetLampBoxDetail) {
                    if (loadState == LoadState.Loading) {
                        LoadingDialog.show(LampBoxOnMapActivity.this, "路灯详情获取中，请稍后...");
                    } else {
                        LoadingDialog.dismiss();
                    }
                } else {
                    if (loadState == LoadState.Loading) {
                        LoadingDialog.show(LampBoxOnMapActivity.this, "数据加载中，请稍后...");
                    } else {
                        LoadingDialog.dismiss();
                    }
                }
            }
        });
    }

    @Override
    protected void initOnCreate(@Nullable Bundle savedInstanceState) {
        binding.mapView.setAttributionTextVisible(false);//去掉左下角属性标识
        ArcGISMap arcGISMap = new ArcGISMap(BasemapStyle.ARCGIS_STREETS);
        Basemap basemap = new Basemap(ArcGisMapCreator.createBaseLayer());
        arcGISMap.setBasemap(basemap);
        Point point = new Point(LocaleConstant.DEFAULT_LNG, LocaleConstant.DEFAULT_LAT, SpatialReferences.getWgs84());
        binding.mapView.setViewpointCenterAsync(point, 2800);//标注到指定经纬度并放大地图显示
        binding.mapView.setMap(arcGISMap);
        //Marker相关Layer
        graphicsOverlays = binding.mapView.getGraphicsOverlays();

        //数据
        lampBoxViewModel = new ViewModelProvider(this).get(LampBoxViewModel.class);
        lampBoxViewModel.mapLampBoxResult.observe(this, new Observer<MapLampBoxBean>() {
            @Override
            public void onChanged(MapLampBoxBean resultBean) {
                if (resultBean.getCode() == 200) {
                    dataBeans = resultBean.getData();

                    //转为地图Point
                    List<Point> points = new ArrayList<>();
                    for (MapLampBoxBean.DataBean dataBean : dataBeans) {
                        String longitude = dataBean.getLongitude();
                        String latitude = dataBean.getLatitude();
                        if (!longitude.isEmpty() && !latitude.isEmpty()) {
                            Point point = new Point(Double.parseDouble(longitude), Double.parseDouble(latitude), SpatialReferences.getWgs84());
                            points.add(point);
                        }
                    }
                    addPictureMarker(points);
                }
            }
        });
        lampBoxViewModel.getLampBoxes(this);

        lampBoxViewModel.lampBoxDetailResult.observe(this, new Observer<LampBoxDetailBean>() {
            @Override
            public void onChanged(LampBoxDetailBean resultBean) {
                isGetLampBoxDetail = false;

                View popupView = LayoutInflater.from(context).inflate(R.layout.popu_lamp_box_on_map, null);

                TextView lampBoxCodeView = popupView.findViewById(R.id.lampBoxCodeView);
                TextView lampBoxNameView = popupView.findViewById(R.id.lampBoxNameView);
                TextView deptView = popupView.findViewById(R.id.deptView);
                TextView electricityView = popupView.findViewById(R.id.electricityView);
                TextView voltageView = popupView.findViewById(R.id.voltageView);
                TextView powerView = popupView.findViewById(R.id.powerView);
                TextView updateTimeView = popupView.findViewById(R.id.updateTimeView);
                TextView roadView = popupView.findViewById(R.id.roadView);
                TextView addressView = popupView.findViewById(R.id.addressView);
                QMUIRoundButton turnOffLampButton = popupView.findViewById(R.id.turnOffLampButton);
                QMUIRoundButton turnOnLampButton = popupView.findViewById(R.id.turnOnLampButton);

                LampBoxDetailBean.DataModel data = resultBean.getData();
                lampBoxCodeView.setText(data.getLampboxCode());
                lampBoxNameView.setText(data.getLampboxName());
                deptView.setText(data.getDeptName());
                electricityView.setText(String.format("%s/%s/%s", data.getElecA(), data.getElecB(), data.getElecC()));
                voltageView.setText(String.format("%s/%s/%s", data.getVolA(), data.getVolB(), data.getVolC()));
                powerView.setText(String.format("%s/%s/%s", data.getPowerA(), data.getPowerB(), data.getPowerC()));
                updateTimeView.setText(data.getUpTime());
                roadView.setText(data.getStreetName());
                addressView.setText(data.getAddress());

                QMUIPopups.popup(context, QMUIDisplayHelper.dp2px(context, 280))
                        .preferredDirection(QMUIPopup.DIRECTION_BOTTOM).view(popupView)
                        .edgeProtection(QMUIDisplayHelper.dp2px(context, 20))
                        .dimAmount(0.6f).animStyle(QMUIPopup.ANIM_GROW_FROM_CENTER)
                        .onDismiss(null).show(binding.mapView);

                turnOffLampButton.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        isControlLampBox = true;
                        lampBoxViewModel.controlLampBox(context, data.getLampboxId(), "0");
                    }
                });

                turnOnLampButton.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        isControlLampBox = true;
                        lampBoxViewModel.controlLampBox(context, data.getLampboxId(), "1");
                    }
                });
            }
        });

        lampBoxViewModel.controlResult.observe(this, new Observer<ActionResultBean>() {
            @Override
            public void onChanged(ActionResultBean resultBean) {
                if (resultBean.getCode() == 200) {
                    isControlLampBox = false;
                    StringKit.show(context, "指令发送成功");
                }
            }
        });
    }

    @SuppressLint("ClickableViewAccessibility")
    @Override
    protected void initEvent() {
        binding.expandMapView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                binding.mapView.setViewpointScaleAsync(binding.mapView.getMapScale() * 0.5);
                //计算比例尺
                DELTA_L -= 0.0001;
                if (DELTA_L < 0) {
                    DELTA_L = 0;
                }
            }
        });

        binding.minusMapView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                binding.mapView.setViewpointScaleAsync(binding.mapView.getMapScale() * 2);
                //计算比例尺
                DELTA_L += 0.0001;
                if (DELTA_L > 0.01) {
                    DELTA_L = LocaleConstant.DELTA_LNG_75;
                }
            }
        });

        binding.removeToLocalView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                LoadingDialog.show(LampBoxOnMapActivity.this, "定位中，请稍后");
                LocationHelper.get().getCurrentLocation(context, new ILocationListener() {

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

        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()));
                final ListenableFuture<List<IdentifyGraphicsOverlayResult>> overlaysAsync = mMapView.identifyGraphicsOverlaysAsync(screenPoint, 10.0, false, 1);
                overlaysAsync.addDoneListener(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            List<IdentifyGraphicsOverlayResult> overlayResultList = overlaysAsync.get();
                            if (overlayResultList.isEmpty()) {
                                weakReferenceHandler.sendEmptyMessage(2021062402);
                            } else {
                                IdentifyGraphicsOverlayResult identifyResult = overlayResultList.get(0);
                                Point point = identifyResult.getGraphicsOverlay().getExtent().getCenter();
                                for (MapLampBoxBean.DataBean dataBean : dataBeans) {
                                    String longitude = dataBean.getLongitude();
                                    String latitude = dataBean.getLatitude();
                                    if (!longitude.isEmpty() && !latitude.isEmpty()) {
                                        if (Math.abs(Double.parseDouble(longitude) - point.getX()) <= LocaleConstant.DELTA_LNG_10
                                                && Math.abs(Double.parseDouble(latitude) - point.getY()) <= LocaleConstant.DELTA_LAT_10) {
                                            Message message = weakReferenceHandler.obtainMessage();
                                            message.what = 2021062401;
                                            message.obj = dataBean.getId();
                                            weakReferenceHandler.sendMessage(message);
                                        }
                                    }
                                }
                            }
                        } catch (InterruptedException | ExecutionException e) {
                            e.printStackTrace();
                        }
                    }
                });
                return super.onSingleTapConfirmed(e);
            }
        });
    }

    @Override
    public boolean handleMessage(@NonNull Message msg) {
        switch (msg.what) {
            case 2021062401:
                String lampId = (String) msg.obj;
                if (TextUtils.isEmpty(lampId)) {
                    StringKit.show(context, "错误，路灯编号为空");
                    return true;
                }

                isGetLampBoxDetail = true;
                lampBoxViewModel.getLampBoxDetail(context, lampId);
                break;
            case 2021062402:
                StringKit.show(context, "此附近无路灯，请重新选点");
                break;
            default:
                break;
        }
        return true;
    }

    private void addPictureMarker(List<Point> points) {
        Bitmap caseBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.location_verify);
        for (Point point : points) {
            BitmapDrawable caseDrawable = new BitmapDrawable(getResources(), caseBitmap);
            PictureMarkerSymbol pictureMarker = new PictureMarkerSymbol(caseDrawable);
            pictureMarker.setWidth(24);
            pictureMarker.setHeight(24);
            pictureMarker.loadAsync();
            GraphicsOverlay graphicsOverlay = new GraphicsOverlay();
            graphics = graphicsOverlay.getGraphics();
            graphics.add(new Graphic(point, pictureMarker));
            graphicsOverlays.add(graphicsOverlay);
        }
    }

    private void clearPictureMarker() {
        if (graphics != null && graphicsOverlays != null) {
            graphics.clear();
            graphicsOverlays.clear();
        }
    }

    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();
    }
}
