package com.casic.dcms.ui.fragment;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.location.Location;
import android.os.Handler;
import android.os.Message;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;

import com.amap.api.location.AMapLocation;
import com.casic.dcms.R;
import com.casic.dcms.base.AndroidxBaseFragment;
import com.casic.dcms.base.BaseApplication;
import com.casic.dcms.bean.ActionResultBean;
import com.casic.dcms.bean.LightMapBean;
import com.casic.dcms.bean.StreetLightLocalBean;
import com.casic.dcms.databinding.FragmentLightMapBinding;
import com.casic.dcms.greendao.StreetLightLocalBeanDao;
import com.casic.dcms.mvp.presenter.impl.LightControlPresenterImpl;
import com.casic.dcms.mvp.presenter.impl.LightMapPresenterImpl;
import com.casic.dcms.mvp.view.ILightControlView;
import com.casic.dcms.mvp.view.ILightMapView;
import com.casic.dcms.utils.ArcGisMapCreator;
import com.casic.dcms.utils.Constant;
import com.casic.dcms.utils.HttpRequestHelper;
import com.casic.dcms.utils.LocationHelper;
import com.casic.dcms.utils.OtherUtils;
import com.casic.dcms.utils.ToastHelper;
import com.casic.dcms.utils.callback.IHttpRequestListener;
import com.casic.dcms.utils.callback.ILocationListener;
import com.esri.arcgisruntime.concurrent.ListenableFuture;
import com.esri.arcgisruntime.geometry.Point;
import com.esri.arcgisruntime.geometry.SpatialReference;
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.qmuiteam.qmui.util.QMUIDisplayHelper;
import com.qmuiteam.qmui.widget.popup.QMUIPopup;
import com.qmuiteam.qmui.widget.popup.QMUIPopups;

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

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

import okhttp3.ResponseBody;

public class LightOnMapFragment extends AndroidxBaseFragment<FragmentLightMapBinding> implements View.OnClickListener, ILightMapView, ILightControlView {

    private static final String TAG = "LightOnMapFragment";
    private Context context;
    private LightMapPresenterImpl lightMapPresenter;
    private ListenableList<GraphicsOverlay> graphicsOverlays;
    private ListenableList<Graphic> graphics;
    private double DELTA_L = Constant.DELTA_LNG_75;
    private StreetLightLocalBeanDao lightLocalBeanDao;
    private WeakReferenceHandler weakReferenceHandler;
    private LightControlPresenterImpl controlPresenter;

    @Override
    protected void setupTopBarLayout() {
        context = getContext();
        lightLocalBeanDao = BaseApplication.getDaoSession().getStreetLightLocalBeanDao();
        lightMapPresenter = new LightMapPresenterImpl(this);
        weakReferenceHandler = new WeakReferenceHandler(this);
        controlPresenter = new LightControlPresenterImpl(this);
    }

    @Override
    protected void initData() {
        lightMapPresenter.onReadyRetrofitRequest();

        viewBinding.mapView.setAttributionTextVisible(false);//去掉左下角属性标识
        ArcGISMap arcGISMap = new ArcGISMap(BasemapStyle.ARCGIS_STREETS);
        //创建底图、并设置底图图层
        Basemap basemap = new Basemap(ArcGisMapCreator.createBaseLayer());
        arcGISMap.setBasemap(basemap);
        Point point = new Point(Constant.DEFAULT_LNG, Constant.DEFAULT_LAT, SpatialReference.create(4326));
        viewBinding.mapView.setViewpointCenterAsync(point, 2800);//标注到指定经纬度并放大地图显示
        viewBinding.mapView.setMap(arcGISMap);

        //Marker相关Layer
        graphicsOverlays = viewBinding.mapView.getGraphicsOverlays();
        //显示定位点附近路灯
        LocationHelper.obtainCurrentLocationByGD(context, new ILocationListener() {
            @Override
            public void onLocationGet(Location location) {

            }

            @Override
            public void onAMapLocationGet(AMapLocation aMapLocation) {
                if (aMapLocation != null) {
                    double[] gcjToWgs = LocationHelper.gcjToWgs(aMapLocation.getLongitude(), aMapLocation.getLatitude());
                    Point point = new Point(gcjToWgs[0], gcjToWgs[1], SpatialReference.create(4326));
                    viewBinding.mapView.setViewpointCenterAsync(point, 2800);

                    List<StreetLightLocalBean> streetLightBeans = lightLocalBeanDao.loadAll();
                    List<Point> pointList = new ArrayList<>();
                    for (StreetLightLocalBean bean : streetLightBeans) {
                        double longitude = bean.getLongitude();
                        double latitude = bean.getLatitude();
                        if (Math.abs(longitude - gcjToWgs[0]) <= Constant.DELTA_LNG_75 &&
                                Math.abs(latitude - gcjToWgs[1]) <= Constant.DELTA_LAT_75) {
                            pointList.add(new Point(longitude, latitude, SpatialReference.create(4326)));
                        }
//                        if (Math.abs(longitude - Constant.DEFAULT_LNG) <= Constant.DELTA_LNG_75 &&
//                                Math.abs(latitude - Constant.DEFAULT_LAT) <= Constant.DELTA_LAT_75) {
//                            pointList.add(new Point(longitude, latitude, SpatialReference.create(4326)));
//                        }
                    }
                    addPictureMarker(pointList);
                }
            }
        }, true);
    }

    @SuppressLint("ClickableViewAccessibility")
    @Override
    protected void initEvent() {
        viewBinding.mapView.setOnTouchListener(new DefaultMapViewOnTouchListener(context, viewBinding.mapView) {
            @Override
            public boolean onSingleTapConfirmed(MotionEvent e) {
                List<StreetLightLocalBean> lightBeans = lightLocalBeanDao.loadAll();
                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 (StreetLightLocalBean dataBean : lightBeans) {
                                    if (Math.abs(dataBean.getLongitude() - point.getX()) <= Constant.DELTA_LNG_10 &&
                                            Math.abs(dataBean.getLatitude() - point.getY()) <= Constant.DELTA_LAT_10) {
                                        Message message = weakReferenceHandler.obtainMessage();
                                        message.what = 2021062401;
                                        message.obj = dataBean.getLampId();
                                        weakReferenceHandler.sendMessage(message);
                                    }
                                }
                            } else {
                                weakReferenceHandler.sendEmptyMessage(2021062402);
                            }
                        } catch (InterruptedException | ExecutionException e) {
                            e.printStackTrace();
                        }
                    }
                });
                return super.onSingleTapConfirmed(e);
            }
        });
    }

    @Override
    public void showProgress() {
        OtherUtils.showLoadingDialog(context, "处理中，请稍后...");
    }

    @Override
    public void hideProgress() {
        OtherUtils.dismissLoadingDialog();
    }

    @Override
    public void obtainControlResult(ActionResultBean resultBean) {
        if (resultBean.isSuccess()) {
            ToastHelper.showToast("指令发送成功", ToastHelper.SUCCESS);
        }
    }

    @Override
    public void obtainDataFail() {
        ToastHelper.showToast("操作失败", ToastHelper.ERROR);
    }

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

        private WeakReferenceHandler(LightOnMapFragment fragment) {
            reference = new WeakReference<>(fragment);
        }

        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            LightOnMapFragment fragment = reference.get();
            Context context = fragment.context;
            switch (msg.what) {
                case 2021062401:
                    String lampId = (String) msg.obj;

                    View popupView = LayoutInflater.from(context).inflate(R.layout.popu_street_light, null);
                    TextView lightStateView = popupView.findViewById(R.id.lightStateView);
                    TextView lightAddressView = popupView.findViewById(R.id.lightAddressView);
                    TextView lightStreetView = popupView.findViewById(R.id.lightStreetView);
                    TextView lightElecView = popupView.findViewById(R.id.lightElecView);
                    TextView lightVolView = popupView.findViewById(R.id.lightVolView);
                    TextView lightTimeView = popupView.findViewById(R.id.lightTimeView);
                    ImageView lightSwitch = popupView.findViewById(R.id.lightSwitch);

                    OtherUtils.showLoadingDialog(context, "路灯详情获取中，请稍后...");
                    HttpRequestHelper.doRequest(Constant.LIGHT_DETAIL, lampId, new IHttpRequestListener() {
                        @Override
                        public void onSuccess(ResponseBody resultBean) {
                            OtherUtils.dismissLoadingDialog();
                            try {
                                String string = resultBean.string();
                                JSONObject jsonObject = new JSONObject(string);
                                int code = jsonObject.getInt("code");
                                if (code == 200) {
                                    JSONObject dataObject = jsonObject.getJSONObject("data");

                                    String statusName = dataObject.getString("statusName");
                                    lightStateView.setText(statusName);
                                    lightAddressView.setText(dataObject.getString("address"));
                                    lightStreetView.setText(dataObject.getString("streetName"));
                                    lightElecView.setText(String.valueOf(dataObject.getDouble("latestElec")));
                                    lightVolView.setText(String.valueOf(dataObject.getDouble("latestVol")));
                                    lightTimeView.setText(dataObject.getString("latestTime"));

                                    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(fragment.viewBinding.mapView);

                                    lightSwitch.setOnClickListener(new View.OnClickListener() {
                                        @Override
                                        public void onClick(View v) {
                                            List<Long> lampIds = new ArrayList<>();
                                            lampIds.add(Long.parseLong(lampId));

                                            String controlType;
                                            if (statusName.equals("离线")) {
                                                controlType = "1";
                                            } else {
                                                controlType = "0";
                                            }
                                            fragment.controlPresenter.onReadyRetrofitRequest(lampIds, controlType);
                                        }
                                    });
                                } else {
                                    ToastHelper.showToast("服务器异常，请重新选点", ToastHelper.ERROR);
                                }
                            } catch (JSONException | IOException e) {
                                ToastHelper.showToast("解析失败，请重新选点", ToastHelper.ERROR);
                            }
                        }

                        @Override
                        public void onFailure(Throwable throwable) {
                            OtherUtils.dismissLoadingDialog();
                            ToastHelper.showToast("网络连接失败，请重新选点", ToastHelper.ERROR);
                        }
                    });
                    break;
                case 2021062402:
                    ToastHelper.showToast("此附近无路灯，请重新选点", ToastHelper.ERROR);
                    break;
                default:
                    break;
            }
        }
    }

    private void addPictureMarker(List<Point> points) {
        for (Point point : points) {
            Bitmap caseBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.location_verify);
            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();
        }
    }

    @Override
    public void onClick(View v) {
        List<StreetLightLocalBean> lightBeans = lightLocalBeanDao.loadAll();
        int id = v.getId();
        if (id == R.id.expandMapView) {
            viewBinding.mapView.setViewpointScaleAsync(viewBinding.mapView.getMapScale() * 0.5);
            clearPictureMarker();
            //计算比例尺
            DELTA_L -= 0.0001;
            if (DELTA_L < 0) {
                DELTA_L = 0;
            }
//                List<Point> minusList = new ArrayList<>();
//                for (StreetLightLocalBean bean : lightBeans) {
//                    double longitude = bean.getLongitude();
//                    double latitude = bean.getLatitude();
//                    if (Math.abs(longitude - Constant.DEFAULT_LNG) > DELTA_L ||
//                            Math.abs(latitude - Constant.DEFAULT_LAT) > DELTA_L) {
//                        continue;
//                    }
//                    minusList.add(new Point(longitude, latitude, SpatialReference.create(4326)));
//                }
//                addPictureMarker(minusList);
            LocationHelper.obtainCurrentLocationByGD(context, new ILocationListener() {
                @Override
                public void onLocationGet(Location location) {

                }

                @Override
                public void onAMapLocationGet(AMapLocation aMapLocation) {
                    if (aMapLocation != null) {
                        double[] gcjToWgs = LocationHelper.gcjToWgs(aMapLocation.getLongitude(), aMapLocation.getLatitude());
                        Point point = new Point(gcjToWgs[0], gcjToWgs[1], SpatialReference.create(4326));
                        List<Point> minusList = new ArrayList<>();
                        for (StreetLightLocalBean bean : lightBeans) {
                            double longitude = bean.getLongitude();
                            double latitude = bean.getLatitude();
                            if (Math.abs(longitude - gcjToWgs[0]) <= DELTA_L &&
                                    Math.abs(latitude - gcjToWgs[1]) <= DELTA_L) {
                                minusList.add(new Point(longitude, latitude, SpatialReference.create(4326)));
                            }
                        }
                        addPictureMarker(minusList);
                    }
                }
            }, true);
        } else if (id == R.id.minusMapView) {
            viewBinding.mapView.setViewpointScaleAsync(viewBinding.mapView.getMapScale() * 2);
            clearPictureMarker();
            //计算比例尺
            DELTA_L += 0.0001;
            if (DELTA_L > 0.01) {
                DELTA_L = Constant.DELTA_LNG_75;
            }
//                List<Point> expandList = new ArrayList<>();
//                for (StreetLightLocalBean bean : lightBeans) {
//                    double longitude = bean.getLongitude();
//                    double latitude = bean.getLatitude();
//                    if (Math.abs(longitude - Constant.DEFAULT_LNG) > DELTA_L ||
//                            Math.abs(latitude - Constant.DEFAULT_LAT) > DELTA_L) {
//                        continue;
//                    }
//                    expandList.add(new Point(longitude, latitude, SpatialReference.create(4326)));
//                }
//                addPictureMarker(expandList);
            LocationHelper.obtainCurrentLocationByGD(context, new ILocationListener() {
                @Override
                public void onLocationGet(Location location) {

                }

                @Override
                public void onAMapLocationGet(AMapLocation aMapLocation) {
                    if (aMapLocation != null) {
                        double[] gcjToWgs = LocationHelper.gcjToWgs(aMapLocation.getLongitude(), aMapLocation.getLatitude());
                        Point point = new Point(gcjToWgs[0], gcjToWgs[1], SpatialReference.create(4326));
                        List<Point> expandList = new ArrayList<>();
                        for (StreetLightLocalBean bean : lightBeans) {
                            double longitude = bean.getLongitude();
                            double latitude = bean.getLatitude();
                            if (Math.abs(longitude - gcjToWgs[0]) <= DELTA_L &&
                                    Math.abs(latitude - gcjToWgs[1]) <= DELTA_L) {
                                expandList.add(new Point(longitude, latitude, SpatialReference.create(4326)));
                            }
                        }
                        addPictureMarker(expandList);
                    }
                }
            }, true);
        } else if (id == R.id.removeToLocalView) {
            clearPictureMarker();
            OtherUtils.showLoadingDialog(context, "定位中，请稍后");
            LocationHelper.obtainCurrentLocationByGD(context, new ILocationListener() {
                @Override
                public void onLocationGet(Location location) {

                }

                @Override
                public void onAMapLocationGet(AMapLocation aMapLocation) {
                    if (aMapLocation != null) {
                        double[] gcjToWgs = LocationHelper.gcjToWgs(aMapLocation.getLongitude(), aMapLocation.getLatitude());
                        Point point = new Point(gcjToWgs[0], gcjToWgs[1], SpatialReference.create(4326));
                        List<Point> pointList = new ArrayList<>();
                        for (StreetLightLocalBean bean : lightBeans) {
                            double longitude = bean.getLongitude();
                            double latitude = bean.getLatitude();
                            if (Math.abs(longitude - gcjToWgs[0]) <= Constant.DELTA_LNG_75 &&
                                    Math.abs(latitude - gcjToWgs[1]) <= Constant.DELTA_LAT_75) {
                                pointList.add(new Point(longitude, latitude, SpatialReference.create(4326)));
                            }
                        }
                        addPictureMarker(pointList);
                        viewBinding.mapView.setViewpointCenterAsync(point, 3000);
                        OtherUtils.dismissLoadingDialog();
                    }
                }
            }, true);
        }
    }

    @Override
    public void obtainLightResult(LightMapBean resultBean) {
        if (resultBean.isSuccess()) {
            for (LightMapBean.DataBean dataBean : resultBean.getData()) {
                StreetLightLocalBean bean = new StreetLightLocalBean();
                bean.setControllerCode(dataBean.getControllerCode());
                bean.setLampCode(dataBean.getLampCode());
                String lampId = dataBean.getLampId();
                bean.setLampId(lampId);
                bean.setLatitude(dataBean.getLatitude());
                bean.setDeptId(dataBean.getDeptId());
                bean.setStatusName(dataBean.getStatusName());
                bean.setLampName(dataBean.getLampName());
                bean.setLatestTime(dataBean.getLatestTime());
                bean.setLongitude(dataBean.getLongitude());
                bean.setStatus(dataBean.getStatus());

                StreetLightLocalBean uniqueBean = lightLocalBeanDao.queryBuilder()
                        .where(StreetLightLocalBeanDao.Properties.LampId.eq(lampId)).unique();
                if (uniqueBean == null) {
                    lightLocalBeanDao.insert(bean);
                } else {
                    lightLocalBeanDao.update(bean);
                }
            }
        }
    }

    @Override
    public void onDestroyView() {
        viewBinding.mapView.dispose();
        if (lightMapPresenter != null) {
            lightMapPresenter.disposeRetrofitRequest();
        }
        if (controlPresenter != null) {
            controlPresenter.disposeRetrofitRequest();
        }
        super.onDestroyView();
    }
}
