package com.casic.dcms.ui;

import android.annotation.SuppressLint;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.RadioButton;
import android.widget.RadioGroup;

import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;

import com.casic.dcms.R;
import com.casic.dcms.base.BaseActivity;
import com.casic.dcms.bean.CaseCheckBean;
import com.casic.dcms.bean.CaseHandleBean;
import com.casic.dcms.bean.CaseVerifyBean;
import com.casic.dcms.bean.PointDataBean;
import com.casic.dcms.mvp.presenter.CaseCheckPresenterImpl;
import com.casic.dcms.mvp.presenter.CaseHandleListPresenterImpl;
import com.casic.dcms.mvp.presenter.CaseVerifyPresenterImpl;
import com.casic.dcms.mvp.view.ICaseCheckView;
import com.casic.dcms.mvp.view.ICaseHandleListView;
import com.casic.dcms.mvp.view.ICaseVerifyView;
import com.casic.dcms.utils.ColorHelper;
import com.casic.dcms.utils.Constant;
import com.casic.dcms.utils.ToastHelper;
import com.esri.arcgisruntime.concurrent.ListenableFuture;
import com.esri.arcgisruntime.data.ServiceFeatureTable;
import com.esri.arcgisruntime.geometry.Point;
import com.esri.arcgisruntime.layers.ArcGISTiledLayer;
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.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.mapping.view.MapView;
import com.esri.arcgisruntime.symbology.PictureMarkerSymbol;
import com.esri.arcgisruntime.util.ListenableList;
import com.qmuiteam.qmui.widget.QMUITopBarLayout;
import com.qmuiteam.qmui.widget.dialog.QMUIDialog;
import com.qmuiteam.qmui.widget.dialog.QMUIDialogAction;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutionException;

import butterknife.BindView;

public class CaseOnMapActivity extends BaseActivity implements RadioGroup.OnCheckedChangeListener,
        ICaseHandleListView, ICaseVerifyView, ICaseCheckView {

    private static final String TAG = "CaseOnMapActivity";
    @BindView(R.id.caseTopLayout)
    QMUITopBarLayout caseTopLayout;
    @BindView(R.id.mapView)
    MapView mapView;
    @BindView(R.id.radioGroup)
    RadioGroup radioGroup;
    @BindView(R.id.handleRadioButton)
    RadioButton handleRadioButton;
    @BindView(R.id.verifyRadioButton)
    RadioButton verifyRadioButton;
    @BindView(R.id.checkRadioButton)
    RadioButton checkRadioButton;

    private CaseHandleListPresenterImpl caseHandleListPresenter;
    private CaseVerifyPresenterImpl caseVerifyPresenter;
    private CaseCheckPresenterImpl caseCheckPresenter;
    private ListenableList<Graphic> graphics;
    private ListenableList<GraphicsOverlay> graphicsOverlays;
    private List<PointDataBean> casePointList = new ArrayList<>();
    private WeakReferenceHandler weakReferenceHandler;

    @Override
    public int initLayoutView() {
        return R.layout.activity_map_case;
    }

    @Override
    protected void setupTopBarLayout() {
        caseTopLayout.setTitle("案卷查看").setTextColor(ContextCompat.getColor(this, R.color.white));
        caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.mainThemeColor));
        caseTopLayout.addLeftImageButton(R.drawable.ic_left_white, 1).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });
    }

    @Override
    public void initData() {
        mapView.setAttributionTextVisible(false);//去掉左下角属性标识
        mapView.setViewpointScaleAsync(64000);

        ArcGISMap arcGISMap = new ArcGISMap(BasemapStyle.ARCGIS_STREETS);
        //创建底图、并设置底图图层
        ArcGISTiledLayer baseLayer = new ArcGISTiledLayer(Constant.BASE_MAP_NO_SERVICE_URL);
        Basemap basemap = new Basemap(baseLayer);
        arcGISMap.setBasemap(basemap);
        mapView.setMap(arcGISMap);

        ServiceFeatureTable communityFeatureTable = new ServiceFeatureTable(Constant.BASE_MAP_SERVICE_URL + "/13");
        communityFeatureTable.setFeatureRequestMode(ServiceFeatureTable.FeatureRequestMode.ON_INTERACTION_NO_CACHE);
        FeatureLayer communityLayer = new FeatureLayer(communityFeatureTable);

        ServiceFeatureTable pointFeatureTable = new ServiceFeatureTable(Constant.COMPONENT_SERVICE_URL + "/0");
        pointFeatureTable.setFeatureRequestMode(ServiceFeatureTable.FeatureRequestMode.ON_INTERACTION_NO_CACHE);
        FeatureLayer pointLayer = new FeatureLayer(pointFeatureTable);

        arcGISMap.getOperationalLayers().addAll(Arrays.asList(communityLayer, pointLayer));
        mapView.setMap(arcGISMap);

        caseHandleListPresenter = new CaseHandleListPresenterImpl(this);
        caseVerifyPresenter = new CaseVerifyPresenterImpl(this);
        caseCheckPresenter = new CaseCheckPresenterImpl(this);

        //默认加载处置中数据
        caseHandleListPresenter.onReadyRetrofitRequest(null, null, 1000, 1);

        //Marker相关Layer
        graphicsOverlays = mapView.getGraphicsOverlays();

        //handler弱饮用，防止内存泄漏
        weakReferenceHandler = new WeakReferenceHandler(this);
    }

    @SuppressLint("ClickableViewAccessibility")
    @Override
    public void initEvent() {
        radioGroup.setOnCheckedChangeListener(this);
        mapView.setOnTouchListener(new DefaultMapViewOnTouchListener(this, 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()) {
                                IdentifyGraphicsOverlayResult identifyResult = overlayResultList.get(0);
                                Point point = identifyResult.getGraphicsOverlay().getExtent().getCenter();
                                for (PointDataBean dataBean : casePointList) {
                                    double parseLng = Double.parseDouble(dataBean.getLng());
                                    double parseLat = Double.parseDouble(dataBean.getLat());
                                    if (Math.abs(parseLng - point.getX()) <= Constant.DELTA_LNG_10 &&
                                            Math.abs(parseLat - point.getY()) <= Constant.DELTA_LAT_10) {
                                        Message message = weakReferenceHandler.obtainMessage();
                                        message.what = 2021051401;
                                        message.obj = dataBean.getId();
                                        weakReferenceHandler.sendMessage(message);
                                    }
                                }
                            } else {
                                weakReferenceHandler.sendEmptyMessage(2021051402);
                            }
                        } catch (InterruptedException | ExecutionException e) {
                            e.printStackTrace();
                        }
                    }
                });
                return super.onSingleTapConfirmed(e);
            }
        });
    }

    private static class WeakReferenceHandler extends Handler {
        private WeakReference<CaseOnMapActivity> reference;

        private WeakReferenceHandler(CaseOnMapActivity activity) {
            reference = new WeakReference<>(activity);
        }

        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            CaseOnMapActivity onMapActivity = reference.get();
            switch (msg.what) {
                case 2021051401:
                    String caseId = (String) msg.obj;
                    new QMUIDialog.MessageDialogBuilder(onMapActivity)
                            .setTitle("提示")
                            .setMessage("已选择案卷：" + caseId + "\r\n确认查看详情？")
                            .setCanceledOnTouchOutside(false)
                            .addAction("取消", (dialog, index) -> dialog.dismiss())
                            .addAction("确定", new QMUIDialogAction.ActionListener() {
                                @Override
                                public void onClick(QMUIDialog dialog, int index) {
                                    dialog.dismiss();
                                    Intent intent = new Intent(onMapActivity, CaseDetailActivity.class);
                                    intent.putExtra("id", caseId);
                                    onMapActivity.startActivity(intent);
                                }
                            })
                            .create().show();
                    break;
                case 2021051402:
                    ToastHelper.showToast("此附近无案卷，请重新选点", ToastHelper.WARING);
                    break;
                default:
                    break;
            }
        }
    }

    @Override
    public void onCheckedChanged(RadioGroup group, int checkedId) {
        switch (checkedId) {
            case R.id.handleRadioButton:
                resetRadioButton(0);
                break;
            case R.id.verifyRadioButton:
                resetRadioButton(1);
                break;
            case R.id.checkRadioButton:
                resetRadioButton(2);
                break;
            default:
                break;
        }
    }

    private void resetRadioButton(int index) {
        switch (index) {
            case 0:
                handleRadioButton.setTextColor(ColorHelper.getResourcesColor(this, R.color.white));
                verifyRadioButton.setTextColor(ColorHelper.getResourcesColor(this, R.color.textColor));
                checkRadioButton.setTextColor(ColorHelper.getResourcesColor(this, R.color.textColor));

                //请求处置中数据
                caseHandleListPresenter.onReadyRetrofitRequest(null, null, 1000, 1);
                break;
            case 1:
                verifyRadioButton.setTextColor(ColorHelper.getResourcesColor(this, R.color.white));
                handleRadioButton.setTextColor(ColorHelper.getResourcesColor(this, R.color.textColor));
                checkRadioButton.setTextColor(ColorHelper.getResourcesColor(this, R.color.textColor));

                //请求待核实数据
                caseVerifyPresenter.onReadyRetrofitRequest(1000, 1);
                break;
            case 2:
                checkRadioButton.setTextColor(ColorHelper.getResourcesColor(this, R.color.white));
                verifyRadioButton.setTextColor(ColorHelper.getResourcesColor(this, R.color.textColor));
                handleRadioButton.setTextColor(ColorHelper.getResourcesColor(this, R.color.textColor));

                //请求待核查数据
                caseCheckPresenter.onReadyRetrofitRequest(1000, 1);
                break;
            default:
                break;
        }
    }

    /**
     * 处理中
     */
    @Override
    public void obtainCaseHandleList(CaseHandleBean resultBean) {
//        Log.d(TAG, "obtainCaseHandleList: " + new Gson().toJson(resultBean));
        clearPictureMarker();
        if (resultBean.isSuccess()) {
            List<CaseHandleBean.DataBean.RowsBean> rowsBeans = resultBean.getData().getRows();
            if (rowsBeans.size() >= 1) {
                List<PointDataBean> list = new ArrayList<>();
                List<Point> pointList = new ArrayList<>();
                for (CaseHandleBean.DataBean.RowsBean bean : rowsBeans) {
                    String lng = bean.getLng();
                    String lat = bean.getLat();
                    if (TextUtils.isEmpty(lng) || TextUtils.isEmpty(lat)) {
                        Log.d(TAG, "案卷经纬度异常");
                        continue;
                    }
                    relatePointToCase(list, bean.getId(), lng, lat);

                    Point point = new Point(Double.parseDouble(lng), Double.parseDouble(lat), mapView.getSpatialReference());
                    pointList.add(point);
                }
                addPictureMarker(pointList, Constant.CASE_HANDLE);
            } else {
                ToastHelper.showToast("当前没有[处理中]的案卷", ToastHelper.ERROR);
            }
        }
    }

    /**
     * 关联Marker和案卷
     *
     * @param list 临时数据集合
     */
    private void relatePointToCase(List<PointDataBean> list, String id, String lng, String lat) {
        PointDataBean casePoint = new PointDataBean();
        casePoint.setId(id);
        casePoint.setLng(lng);
        casePoint.setLat(lat);
        list.add(casePoint);
        casePointList = list;
    }

    /**
     * 待核实
     */
    @Override
    public void obtainVerifyListResult(CaseVerifyBean resultBean) {
//        Log.d(TAG, "obtainVerifyListResult: " + new Gson().toJson(resultBean));
        clearPictureMarker();
        if (resultBean.isSuccess()) {
            List<CaseVerifyBean.DataBean.RowsBean> rowsBeans = resultBean.getData().getRows();
            if (rowsBeans.size() >= 1) {
                List<PointDataBean> list = new ArrayList<>();
                List<Point> pointList = new ArrayList<>();
                for (CaseVerifyBean.DataBean.RowsBean bean : rowsBeans) {
                    String lng = bean.getLng();
                    String lat = bean.getLat();
                    if (TextUtils.isEmpty(lng) || TextUtils.isEmpty(lat)) {
                        Log.d(TAG, "案卷经纬度异常");
                        continue;
                    }
                    relatePointToCase(list, bean.getId(), lng, lat);

                    Point point = new Point(Double.parseDouble(lng), Double.parseDouble(lat), mapView.getSpatialReference());
                    pointList.add(point);
                }
                addPictureMarker(pointList, Constant.CASE_VERIFY);
            } else {
                ToastHelper.showToast("当前没有[待核实]的案卷", ToastHelper.ERROR);
            }
        }
    }

    /**
     * 待核查
     */
    @Override
    public void obtainCheckListResult(CaseCheckBean resultBean) {
//        Log.d(TAG, "obtainCheckListResult: " + new Gson().toJson(resultBean));
        clearPictureMarker();
        if (resultBean.isSuccess()) {
            List<CaseCheckBean.DataBean.RowsBean> rowsBeans = resultBean.getData().getRows();
            if (rowsBeans.size() >= 1) {
                List<PointDataBean> list = new ArrayList<>();
                List<Point> pointList = new ArrayList<>();
                for (CaseCheckBean.DataBean.RowsBean bean : rowsBeans) {
                    String lng = bean.getLng();
                    String lat = bean.getLat();
                    if (TextUtils.isEmpty(lng) || TextUtils.isEmpty(lat)) {
                        Log.d(TAG, "案卷经纬度异常");
                        continue;
                    }
                    relatePointToCase(list, bean.getId(), lng, lat);

                    Point point = new Point(Double.parseDouble(lng), Double.parseDouble(lat), mapView.getSpatialReference());
                    pointList.add(point);
                }
                addPictureMarker(pointList, Constant.CASE_CHECK);
            } else {
                ToastHelper.showToast("当前没有[待核查]的案卷", ToastHelper.ERROR);
            }
        }
    }

    private void addPictureMarker(List<Point> points, int caseStatus) {
        Bitmap caseBitmap;
        switch (caseStatus) {
            case Constant.CASE_HANDLE:
                caseBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.location_handle);
                break;
            case Constant.CASE_VERIFY:
                caseBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.location_verify);
                break;
            case Constant.CASE_CHECK:
                caseBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.location_check);
                break;
            default:
                caseBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.location_case);
                break;
        }
        for (Point point : points) {
            BitmapDrawable caseDrawable = new BitmapDrawable(getResources(), caseBitmap);
            PictureMarkerSymbol pictureMarker = new PictureMarkerSymbol(caseDrawable);
            pictureMarker.setHeight(24);
            pictureMarker.setWidth(24);
            pictureMarker.loadAsync();//异步加载Marker，防止阻塞

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

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

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mapView.dispose();
        if (caseHandleListPresenter != null) {
            caseHandleListPresenter.disposeRetrofitRequest();
        }
        if (caseVerifyPresenter != null) {
            caseVerifyPresenter.disposeRetrofitRequest();
        }
        if (caseCheckPresenter != null) {
            caseCheckPresenter.disposeRetrofitRequest();
        }
    }
}
