package com.tofly.ghrq_route.common.ui.activity;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.appcompat.widget.AppCompatTextView;

import com.esri.arcgisruntime.concurrent.ListenableFuture;
import com.esri.arcgisruntime.geometry.Point;
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.MapView;
import com.esri.arcgisruntime.symbology.MarkerSymbol;
import com.tofly.ghrq_route.R;
import com.tofly.ghrq_route.base.ui.BaseMapActivity;
import com.tofly.ghrq_route.base.C;
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.concurrent.ExecutionException;

import butterknife.BindView;
import butterknife.OnClick;

@SuppressLint("NonConstantResourceId")
public class UiCheckAddr extends BaseMapActivity {
    @BindView(R.id.mapview)
    MapView mapView;
    @BindView(R.id.text_trouble_addr)
    AppCompatTextView textAddr;
    @BindView(R.id.marker)
    ImageView imageMarker;
    @BindView(R.id.btn_confirm)
    TextView btnConfirm;

    private Point devicePoint;

    private MarkerSymbol deviceSymbol;

    private GraphicsOverlay deviceGraphicOverlay = null;

    private LocationUtil_xu.CoordinateClass mTappedCoordinate = new LocationUtil_xu.CoordinateClass();

    private SELECT_MODE mSelectMode = SELECT_MODE.TROUBLE_SELECT_ADDR_NEW;    // 0: 新建 1： 查看

    private boolean isFirstLoc = true;

    public static final String SELECT_ADDR_TYPE_KEY = "select_addr_type";

    public enum SELECT_MODE {
        TROUBLE_SELECT_ADDR_NEW,
        TROUBLE_SELECT_ADDR_CHECK,
        TROUBLE_SELECT_ADDR_UPDATE
    }

    public static void startActivityForResult(Activity activity, SELECT_MODE mode, LocationUtil_xu.CoordinateClass location) {
        Intent intent = new Intent(activity, UiCheckAddr.class);
        Bundle bundle = new Bundle();
        if (mode == SELECT_MODE.TROUBLE_SELECT_ADDR_UPDATE || mode == SELECT_MODE.TROUBLE_SELECT_ADDR_CHECK) {
            if (location != null && location.Longtitude != null && location.Latitude != null) {
                bundle.putSerializable(UiCheckAddr.SELECT_ADDR_TYPE_KEY, mode);
                bundle.putSerializable(LocationUtil.CURRENT_LOCATION_KEY, location);
            } else {
                bundle.putSerializable(UiCheckAddr.SELECT_ADDR_TYPE_KEY, SELECT_MODE.TROUBLE_SELECT_ADDR_NEW);
            }
        }else {
            bundle.putSerializable(UiCheckAddr.SELECT_ADDR_TYPE_KEY, SELECT_MODE.TROUBLE_SELECT_ADDR_NEW);
        }
        intent.putExtras(bundle);
        activity.startActivityForResult(intent, C.REQUEST_CODE.SELECT_ADDR_REQUEST_CODE);
        activity.overridePendingTransition(R.anim.anim_rightin, R.anim.anim_leftout);
    }

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

        setDarkStatusBar();

        initDeviceSymbol();

        textAddr.setText("成都市青羊区");
    }

    private void initDeviceSymbol() {
        BitmapDrawable imageLoc = (BitmapDrawable) getResources().getDrawable(R.mipmap.danger_location);
        deviceSymbol = SizeMarkerSymbol.sizeSymbol(imageLoc, 32, 32);
    }

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

        initData();
        initListener();
    }

    public void initData() {
        Intent intent = getIntent();
        Bundle bundle = intent.getExtras();
        if (bundle != null) {
            mSelectMode = (SELECT_MODE) bundle.getSerializable(SELECT_ADDR_TYPE_KEY);
            if (mSelectMode != SELECT_MODE.TROUBLE_SELECT_ADDR_NEW) {
                if (bundle.containsKey(LocationUtil.CURRENT_LOCATION_KEY)) {
                    mTappedCoordinate =
                            (LocationUtil_xu.CoordinateClass) bundle.getSerializable(LocationUtil.CURRENT_LOCATION_KEY);
                    if (mTappedCoordinate != null) {
                        textAddr.setText(mTappedCoordinate.addr);
                        if (mTappedCoordinate.Longtitude > 0 && mTappedCoordinate.Latitude > 0) {
                            devicePoint = new Point(mTappedCoordinate.Longtitude, mTappedCoordinate.Latitude);
                        }
                    }
                }
            }
        }

        amapLocationHelper.startLocating();
    }

    public void initListener() {
        amapLocationHelper.setMapLocationListener((location, addr, projLoc) -> {
            if (mSelectMode == SELECT_MODE.TROUBLE_SELECT_ADDR_NEW || !isFirstLoc) {
                mTappedCoordinate.Longtitude = projLoc.getX();
                mTappedCoordinate.Latitude = projLoc.getY();
                mTappedCoordinate.addr = addr;
                mapView.setViewpointCenterAsync(projLoc, 5000);
            }
            isFirstLoc = false;
        });

        amapLocationHelper.setReserveLocListener((isSuccess, addr) -> {
            mTappedCoordinate.addr = addr;
            textAddr.setText(addr);
        });

        mapView.setOnTouchListener(new DefaultMapViewOnTouchListener(this, mapView) {
            @Override
            public boolean onUp(MotionEvent event) {
                if (mSelectMode != SELECT_MODE.TROUBLE_SELECT_ADDR_CHECK) {
                    Point pcenter = ArcgisUtils.getMapCenter(mapView);
                    if (pcenter != null) {
                        mTappedCoordinate.Longtitude = pcenter.getX();
                        mTappedCoordinate.Latitude = pcenter.getY();
                        Point location = ArcgisUtils.projectLocationDefault(pcenter.getX(), pcenter.getY());
                        if (location != null)
                            amapLocationHelper.reserveLocation(location.getX(), location.getY());
                    }
                }
                return true;
            }
        });
    }

    @OnClick({R.id.btn_back, R.id.btn_confirm})
    void onClicked(View view) {
        switch (view.getId()) {
            case R.id.btn_back: {
                Intent intent = new Intent();
                setResult(Activity.RESULT_OK, intent);
                this.finish();
            }
            break;
            case R.id.btn_confirm: {
                Intent intent = new Intent();
                intent.putExtra(LocationUtil.CURRENT_LOCATION_KEY, mTappedCoordinate);
                setResult(Activity.RESULT_OK, intent);
                finish();
            }
            break;
            default:
                break;
        }
    }

    private void renderPointOnMap() {
        if (mapView != null && devicePoint != null) {
            double lng = devicePoint.getX();
            double lat = devicePoint.getY();
            Point point = new Point(lng, lat, mapView.getSpatialReference());
            if (mSelectMode == SELECT_MODE.TROUBLE_SELECT_ADDR_CHECK) {
                Graphic deviceGraphic = new Graphic(point, deviceSymbol);
                deviceGraphicOverlay = new GraphicsOverlay();
                deviceGraphicOverlay.getGraphics().add(deviceGraphic);
                mapView.getGraphicsOverlays().add(deviceGraphicOverlay);
            }
            ListenableFuture<Boolean> future = mapView.setViewpointScaleAsync(5000);
            future.addDoneListener(() -> {
                try {
                    Boolean isSuccess = future.get();
                    if (isSuccess) {
                        mapView.setViewpointCenterAsync(point);
                    }
                } catch (ExecutionException | InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }
    }

    @Override
    public void onBaseMapLoaded() {
        if (mSelectMode != SELECT_MODE.TROUBLE_SELECT_ADDR_NEW) {
            renderPointOnMap();
        }
    }

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

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

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

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

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

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

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

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

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