package com.tofly.ghrq_route.module.dasData.ui;

import android.annotation.SuppressLint;
import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.os.Handler;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import androidx.annotation.NonNull;

import com.esri.arcgisruntime.concurrent.ListenableFuture;
import com.esri.arcgisruntime.geometry.Geometry;
import com.esri.arcgisruntime.geometry.GeometryEngine;
import com.esri.arcgisruntime.geometry.Point;
import com.esri.arcgisruntime.mapping.view.Graphic;
import com.esri.arcgisruntime.mapping.view.GraphicsOverlay;
import com.esri.arcgisruntime.mapping.view.MapView;
import com.esri.arcgisruntime.symbology.MarkerSymbol;
import com.google.android.material.bottomsheet.BottomSheetBehavior;
import com.mgq.base.utils.progressdialog.ProgressManager;
import com.mgq.base.utils.toast.ToastUtil;
import com.tofly.ghrq_route.R;
import com.tofly.ghrq_route.base.BaseApp;
import com.tofly.ghrq_route.base.ui.BaseMapFileActivity;
import com.tofly.ghrq_route.common.ui.view.MyAudioRecordButton;
import com.tofly.ghrq_route.common.util.dialog.DialogUtil;
import com.tofly.ghrq_route.module.dasData.DasDataTool;
import com.tofly.ghrq_route.module.dasData.controller.DasDataCallBack;
import com.tofly.ghrq_route.module.dasData.domain.DasData;
import com.tofly.ghrq_route.module.dasData.ui.view.BottomSheetDasDataSelect;
import com.tofly.ghrq_route.module.trouble.domain.TroubleBean;
import com.tofly.ghrq_route.common.util.ArcgisUtils.ArcgisUtils;
import com.tofly.ghrq_route.common.util.ArcgisUtils.SizeMarkerSymbol;
import com.tofly.ghrq_route.common.util.Location.LocationUtil;
import com.tofly.ghrq_route.common.util.Location.LocationUtil_xu;
import com.tofly.latte_core.base.IPresenter;

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

import butterknife.BindView;

/**
 * Created by Amu on 2020/8/10.
 */
public class UiDasData extends BaseMapFileActivity {
    @BindView(R.id.mapview)
    MapView mapView;
    @BindView(R.id.maptool_location_ll)
    LinearLayout layoutLocation;
    @BindView(R.id.bottom_sheet_detail_header)
    RelativeLayout layoutBottomSheetHeader;
    @BindView(R.id.layout_bottom_sheet_detail)
    BottomSheetDasDataSelect bottomSheetDasDataSelect;

    private DasDataTool dasDataTool;

    private List<DasData> mDasDatas = new ArrayList<>();

    private LocationUtil_xu.CoordinateClass mTappedCoordinate = null;

    private String mTappedAddr = "";

    private BitmapDrawable imageLoc;

    private GraphicsOverlay deviceGraphicOverlay;

    private Map<DasData, Graphic> graphicMap;

    private int mSelectType = 0;    // 0: 新建 1： 查看 2： 更新

    public static final int SELECT_DEVICE_REQUEST_CODE = 0x100;

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_danger_report, menu);
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        if (item.getItemId() == R.id.action_next) {

        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    public void initView() {
        super.initView();
        // Initialize the helper class to use the Toolkit
        setDarkStatusBar();

        if (mapView != null) {
            double DEFAULTSCALE = 20000;
            mapView.setViewpointScaleAsync(DEFAULTSCALE);
            mapView.setBackgroundColor(Color.WHITE);
        }

        imageLoc = (BitmapDrawable) getResources().getDrawable(R.mipmap.danger_location);

        initBottomSheet();
    }

    @Override
    public void initNet() {
        super.initNet();

        dasDataTool = DasDataTool.getInstance();

        initListener();

        showBottomSheetDetail();
    }


    @SuppressLint("ClickableViewAccessibility")
    private void initListener() {

    }

    private void initBottomSheet() {
        BottomSheetBehavior bottomSheetBehavior = BottomSheetBehavior.from(bottomSheetDasDataSelect);
        bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HALF_EXPANDED);
        bottomSheetBehavior.addBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
            @Override
            public void onStateChanged(@NonNull View bottomSheet, int newState) {
                if (newState == BottomSheetBehavior.STATE_EXPANDED) {
                    setBottomSheetBehavior(bottomSheet);
                } else if (newState == BottomSheetBehavior.STATE_COLLAPSED) {
                    setBottomSheetBehavior(bottomSheet);
                }
            }

            @Override
            public void onSlide(@NonNull View bottomSheet, float slideOffset) {

            }
        });
    }

    private void setBottomSheetBehavior(View bottomSheet) {
        BottomSheetBehavior bottomSheetBehavior = BottomSheetBehavior.from(bottomSheetDasDataSelect);
        if (bottomSheetBehavior != null) {
            if (bottomSheetBehavior.getState() == BottomSheetBehavior.STATE_EXPANDED) {

            } else if (bottomSheetBehavior.getState() == BottomSheetBehavior.STATE_COLLAPSED) {

            } else if (bottomSheetBehavior.getState() == BottomSheetBehavior.STATE_HALF_EXPANDED) {

            }
        }
    }

    private void showBottomSheetDetail() {
        bottomSheetDasDataSelect.initBottomSheetDetail(photoHelper);
        BottomSheetBehavior bottomSheetBehavior = BottomSheetBehavior.from(bottomSheetDasDataSelect);
        //bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HALF_EXPANDED);
        bottomSheetBehavior.setHideable(false);
        bottomSheetDasDataSelect.setEditable(mSelectType != TroubleBean.TROUBLE_SELECT_DEVICE_CHECK);

        bottomSheetDasDataSelect.onDeviceAdded(() -> {
            List<DasData> dasDatas = bottomSheetDasDataSelect.getDasData();
            mDasDatas = dasDatas;
            renderDevicesOnMap();

            bottomSheetDasDataSelect.onItemClicked((item, position) -> {
                DasData dasData = item;
                if (graphicMap.containsKey(dasData)) {
                    Graphic graphic = graphicMap.get(dasData);
                    if (graphic != null) {
                        boolean expanded = bottomSheetDasDataSelect.expand_state == BottomSheetBehavior.STATE_EXPANDED;
                        renderSelectPointOnMap(dasData, graphic, expanded);
                    }
                }
            });
        });

        bottomSheetDasDataSelect.setOnDeviceClearListener(view -> {
            onDeviceCleared();
        });

        bottomSheetDasDataSelect.onDeviceSelectConfirm(view -> {
            onDeviceConfirm();
        });
    }

    private void onDeviceCleared() {
        mDasDatas.clear();
        if (graphicMap != null) {
            graphicMap.clear();
        }

        if (deviceGraphicOverlay != null) {
            deviceGraphicOverlay.getGraphics().clear();
        }
    }

    private void onDeviceConfirm() {
        List<DasData> selectDatas = new ArrayList<>();
        if (bottomSheetDasDataSelect != null) {
            selectDatas = bottomSheetDasDataSelect.getSelectedDasData();
        }

        if (selectDatas.isEmpty() && selectDatas.isEmpty()) {
            ToastUtil.showToast(this, "没有选中的管点");
        }else {
            onSelectDeviceForUpdate(selectDatas);
        }
    }

    private void onSelectDeviceForUpdate(List<DasData> dasDatas) {
        uploadDasData(dasDatas);
    }

    private void renderDevicesOnMap() {
        graphicMap = new HashMap<>();
        List<Geometry> geometries = new ArrayList<>();

        if (mDasDatas != null) {
            if (deviceGraphicOverlay == null) {
                deviceGraphicOverlay = new GraphicsOverlay();
                mapView.getGraphicsOverlays().add(deviceGraphicOverlay);
            }else
                deviceGraphicOverlay.getGraphics().clear();

            for (DasData dasData : mDasDatas) {
                Graphic graphic = renderPointOnMap(dasData);
                graphicMap.put(dasData, graphic);

                Point geometry = dasData.getGeometry(mapView.getSpatialReference());
                if (geometry != null) {
                    geometries.add(geometry);
                }
            }
        }

        if (geometries.size() > 0) {
            try {
                Handler handler = new Handler(getMainLooper());
                handler.postDelayed(() -> {
                    Geometry geometry = GeometryEngine.union(geometries);
                    if (geometry != null && !geometry.getExtent().isEmpty()) {
                        ListenableFuture<Boolean> future = mapView.setViewpointGeometryAsync(geometry, ArcgisUtils.render_padding);
                        future.addDoneListener(() -> {
                            try {
                                Boolean isSuccess = future.get();
                                if (isSuccess) {
                                    double scale = mapView.getMapScale();
                                    Point center = geometry.getExtent().getCenter();
                                    int offset = BaseApp.dip2px(150);
                                    Point dstPoint =  ArcgisUtils.pointAddOffset(mapView, center, 0, offset);
                                    mapView.setViewpointCenterAsync(center, scale);
                                }
                            } catch (ExecutionException | InterruptedException e) {
                                e.printStackTrace();
                            }
                        });
                    }
                }, 500);
            }catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }

    private Graphic renderPointOnMap(DasData dasData) {
        Graphic graphic = null;
        if (mapView != null && dasData != null) {
            if (dasData.getLng() > 0 && dasData.getLat() > 0) {
                MarkerSymbol symbol = SizeMarkerSymbol.sizeSymbol(imageLoc, 18, 18);
                Point point = dasData.getGeometry(mapView.getSpatialReference());
                Graphic deviceGraphic = new Graphic(point, symbol);
                deviceGraphicOverlay.getGraphics().add(deviceGraphic);
                graphic = deviceGraphic;
            }
        }
        return graphic;
    }

    private void renderSelectPointOnMap(DasData dasData, Graphic deviceGraphic, boolean expanded) {
        if (mapView != null && dasData != null) {
            if (deviceGraphicOverlay != null) {
                deviceGraphicOverlay.clearSelection();
                List<Graphic> graphics = new ArrayList<>();
                graphics.add(deviceGraphic);
                deviceGraphicOverlay.selectGraphics(graphics);
            }
            if (dasData.getLng() > 0 && dasData.getLat() > 0) {
                double lng = dasData.getLng();
                double lat = dasData.getLat();
                Point center = new Point(lng, lat, mapView.getSpatialReference());
                android.graphics.Point screenPoint = mapView.locationToScreen(center);
                int offset = expanded ? 300 : 150;
                screenPoint.y = screenPoint.y + BaseApp.dip2px(offset);
                Point locPoint = mapView.screenToLocation(screenPoint);
                if (locPoint != null)
                    mapView.setViewpointCenterAsync(locPoint);
            }
        }
    }

    private TroubleBean collectData() {
        TroubleBean troubleUpdate = new TroubleBean();
        /*隐患地址*/
        if (mTappedCoordinate != null) {
            String lng = LocationUtil.formatLocation(mTappedCoordinate.Longtitude);
            troubleUpdate.setLocationX(lng);
            String lat = LocationUtil.formatLocation(mTappedCoordinate.Latitude);
            troubleUpdate.setLocationY(lat);
            String addr = mTappedAddr;
            troubleUpdate.setAddress(addr);
        }

        List<DasData> selectedDatas = bottomSheetDasDataSelect.getSelectedDasData();
        return troubleUpdate;
    }

    private void uploadDasData(List<DasData> dasDatas) {
        String strUploading = getString(R.string.uploading_data);
        ProgressManager.getInstance().showProgress(this, null, strUploading, false);

        dasDataTool.uploadDasDataBatch(this, dasDatas, new DasDataCallBack() {
            @Override
            public void onSetData(boolean isSuccess, int errorCode, String errMsg) {
                super.onSetData(isSuccess, errorCode, errMsg);
                ProgressManager.getInstance().cancelProgress();
                if (isSuccess) {
                    showUpdatedFinishedDialog();
                }
            }
        });
    }

    private void showUpdatedFinishedDialog() {
        int title = R.string.das_data_title;
        int msg = R.string.das_data_upload_ok;
        DialogUtil.showAlertWithConfirmButton(this, title, msg, false, (dialogInterface, i) -> {
            onDeviceCleared();
            bottomSheetDasDataSelect.clearDasData();
        });
    }

    @Override
    public void onBaseMapLoaded() {
        deviceGraphicOverlay = null;
    }

    @Override
    protected IPresenter createPresenter() {
        return null;
    }

    @Override
    public int setLayout() {
        return R.layout.ui_das_data;
    }

    @Override
    public boolean enableLoadMap() {
        return true;
    }

    @Override
    public boolean enableMoveMapListener() {
        return false;
    }

    @Override
    public boolean enableArcgisLocating() {
        return false;
    }

    @Override
    public boolean enableAmapLocationListener() {
        return true;
    }

    @Override
    public boolean enableMapMoveToLocation() {
        return true;
    }

    @Override
    public TextView getTextAddrView() {
        return null;
    }

    @Override
    public Button getAddPhotoBtn() {
        return null;
    }

    @Override
    public LinearLayout getPhotoGallery() {
        return null;
    }

    @Override
    public MyAudioRecordButton getAudioRecordBtn() {
        return null;
    }

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