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

import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;

import androidx.appcompat.widget.Toolbar;

import com.esri.arcgisruntime.concurrent.ListenableFuture;
import com.esri.arcgisruntime.data.Feature;
import com.esri.arcgisruntime.data.FeatureQueryResult;
import com.esri.arcgisruntime.data.FeatureTable;
import com.esri.arcgisruntime.data.Field;
import com.esri.arcgisruntime.data.QueryParameters;
import com.esri.arcgisruntime.geometry.Point;
import com.esri.arcgisruntime.layers.FeatureLayer;
import com.esri.arcgisruntime.mapping.view.Callout;
import com.esri.arcgisruntime.mapping.view.DefaultMapViewOnTouchListener;
import com.esri.arcgisruntime.mapping.view.MapView;
import com.mgq.base.utils.progressdialog.ProgressManager;
import com.tofly.ghrq_route.R;
import com.tofly.ghrq_route.base.BaseApp;
import com.tofly.ghrq_route.base.ui.BaseMapActivity;
import com.tofly.ghrq_route.module.planPointRepair.controller.PointRepairCallBack;
import com.tofly.ghrq_route.module.planPointRepair.controller.PointRepairController;
import com.tofly.ghrq_route.module.planPointRepair.domain.PlanPointRepair;
import com.tofly.ghrq_route.module.user.domain.UserBean;
import com.tofly.ghrq_route.common.ui.adapter.PipeCalloutViewAdapter;
import com.tofly.latte_core.base.IPresenter;

import org.greenrobot.eventbus.Subscribe;

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

import butterknife.BindArray;
import butterknife.BindView;
import butterknife.OnClick;

/**
 * Created by Amu on 2017/6/5.
 */

public class UiRepairMapStep extends BaseMapActivity {
    @BindView(R.id.main_toolbar)
    Toolbar mainToolbar;
    @BindView(R.id.mapview)
    MapView mapView;
    @BindView(R.id.imageview_location)
    ImageView imageviewLocation;
    @BindView(R.id.text_my_addr)
    TextView textMyAddr;
    @BindView(R.id.progress_my_addr)
    ProgressBar progressMyAddr;
    @BindView(R.id.text_point_no)
    TextView textPointNo;
    @BindView(R.id.text_point_type)
    TextView textPointType;
    @BindView(R.id.text_point_code)
    TextView textPointCode;
    @BindView(R.id.text_point_lnt)
    TextView textPointLnt;
    @BindView(R.id.text_point_lat)
    TextView textPointLat;
    @BindView(R.id.text_point_addr)
    TextView textPointAddr;
    @BindView(R.id.layout_point_info)
    LinearLayout layoutPointInfo;
    @BindView(R.id.text_point_hint)
    TextView textPointHint;
    @BindView(R.id.btn_next_step)
    Button btnNextStep;
    @BindArray(R.array.repair_layers)
    String[] repairLayers;
    @BindArray(R.array.repair_layers_name)
    String[] repairLayersName;

    private UserBean mUser;

    private PlanPointRepair mPointRepair;

    private PointRepairController repairController;

    private Map<String, String> tableNameMap = new HashMap<>();

    @Subscribe
    public void onMessageEvent(PointRepairEvent event) {
        if (event.message.equals(POINT_REPAIR_REMOVED) || event.message.equals(POINT_REPAIR_UPDATED)) {
            finish();
        }
    }

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

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

        mUser = BaseApp.getInstance().getLoginUser();
        mPointRepair = new PlanPointRepair();

        textMyAddr.setText("正在定位...");

        for (int i = 0; i < repairLayers.length; i++) {
            tableNameMap.put(repairLayers[i], repairLayersName[i]);
        }
    }

    @SuppressLint("ClickableViewAccessibility")
    public void initListener() {
        mapView.setOnTouchListener(new DefaultMapViewOnTouchListener(this, mapView){
            @Override
            public boolean onDoubleTouchDrag(MotionEvent event) {
                if (event.getAction() == MotionEvent.ACTION_UP) {
                    android.graphics.Point screenPoint =
                            new android.graphics.Point(Math.round(event.getX()), Math.round(event.getY()));
                    FeatureLayer featureLayer = null;
                    Feature feature = null;
                    boolean hasFeature = false;
                    for (String tableName : repairLayers) {
                        //判断类型：中压A管线，调压设备，阀门，高压A管线,"管网管线"之一
                        try {
                            Object[] objects = new Object[2];
                            getFeatureFromPoint(screenPoint.x, screenPoint.y, tableName, objects);
                            FeatureLayer dstFeaLayer = (FeatureLayer) objects[0];
                            Feature dstFeature = (Feature) objects[1];
                            if (dstFeaLayer != null && dstFeature != null) {
                                hasFeature = true;
                                featureLayer = dstFeaLayer;
                                feature = dstFeature;
                                break;
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                    if (hasFeature) {
                        FeatureTable table = featureLayer.getFeatureTable();
                        List<Field> fields = table.getFields();
                        View view = getCalloutFromFeature(feature, fields);
                        getArcgisUtils().hideArcgisMapCallout();
                        Point geometry = mapView.screenToLocation(screenPoint);
                        Callout callout = mapView.getCallout();
                        callout.show(view, geometry); //显示弹出框
                        setDeviceData(feature, table, geometry);
                        layoutPointInfo.setVisibility(View.VISIBLE);
                        textPointHint.setVisibility(View.INVISIBLE);
                    } else {
                        mPointRepair.setPoint_id("");
                        getArcgisUtils().hideArcgisMapCallout();
                        layoutPointInfo.setVisibility(View.INVISIBLE);
                        textPointHint.setVisibility(View.VISIBLE);
                        textPointHint.setText("未选中设备");
                    }
                }
                return true;
            }
        });
    }

    private void getFeatureFromPoint(float x, float y, String tableName, final Object[] objects) {
        final FeatureLayer featureLayer = getArcgisUtils().getFeaureLayer(tableName);
        if (featureLayer != null && featureLayer.getName().equals(tableName)) {
            featureLayer.clearSelection();
            QueryParameters parameters = new QueryParameters();
            parameters.setGeometry(new Point(x, y));
            final ListenableFuture<FeatureQueryResult> query =
                    featureLayer.selectFeaturesAsync(parameters, FeatureLayer.SelectionMode.NEW);
            query.addDoneListener(() -> {
                try {
                    Feature feature = null;
                    FeatureQueryResult result = query.get();
                    if (result.iterator().hasNext()){
                        feature = result.iterator().next();
                    }
                    objects[0] = featureLayer;
                    objects[1] = feature;
                } catch (ExecutionException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            });
        }
    }

    @SuppressLint("InflateParams")
    private View getCalloutFromFeature(Feature feature, List<Field> fieldList) {
        LayoutInflater inflater = LayoutInflater.from(this);
        View rootView = inflater.inflate(R.layout.pipe_callout, null);//管线详情布局
        ListView listView = rootView.findViewById(R.id.feature_attrs_recyclerview);
        ImageView imageView = rootView.findViewById(R.id.imageview_feature_close);
        Map<String, Object> attrsMap = feature.getAttributes();
        PipeCalloutViewAdapter adapter = new PipeCalloutViewAdapter(this, attrsMap, fieldList);
        listView.setAdapter(adapter);
        imageView.setOnClickListener(v -> getArcgisUtils().hideArcgisMapCallout());
        return rootView;
    }

    @SuppressLint("DefaultLocale")
    private void setDeviceData(Feature feature, FeatureTable table, Point geometry) {
        if (feature != null) {
            Map<String, Object> attrsMap = feature.getAttributes();
            String tableName = table.getTableName();
            if (attrsMap != null) {
                /*部分SID没有数据，暂时使用OBJECTID*/
                Object object = attrsMap.get("SID");
                String sidPointId = "";
                String sid = "";
                if (object != null) {
                    if (tableNameMap != null) {
                        String sidTableName = tableNameMap.get(tableName);
                        if (sidTableName != null && !sidTableName.isEmpty()) {
                            sidPointId = sidTableName + "-" + object.toString();
                        }
                    } else {
                        sidPointId = object.toString();
                    }
                    sid = object.toString();
                }
                textPointNo.setText(sid);
                mPointRepair.setPoint_id(sidPointId);

                object = attrsMap.get("SUBTYPE");
                String pointType = "";
                if (object != null) {
                    pointType = object.toString();
                    textPointType.setText(pointType);
                } else {
                    textPointType.setText("无");
                }

                object = attrsMap.get("CODE");
                String pointCode;
                if (object != null) {
                    pointCode = object.toString();
                    textPointCode.setText(pointCode);
                } else {
                    textPointCode.setText("无");
                }

                object = attrsMap.get("ADDR");
                String pointAddr = "";
                if (object != null) {
                    pointAddr = object.toString();
                }
                textPointAddr.setText(pointAddr);
                mPointRepair.setAddress(pointAddr);
            }
        }
        if (geometry != null) {
            double lnt = geometry.getX();
            mPointRepair.setLng(lnt);
            String result = String.format("%.3f", lnt);
            textPointLnt.setText(result);
            double lat = geometry.getY();
            mPointRepair.setLat(lat);
            result = String.format("%.3f", lat);
            textPointLat.setText(result);
        }
    }

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

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == R.id.action_history) {
            Intent intent = new Intent();
            intent.setClass(this, UiRepairHistory.class);
            startActivity(intent);
        }
        return super.onOptionsItemSelected(item);
    }

    @OnClick({R.id.btn_next_step})
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.btn_next_step: {
                if (checkValid()) {
                    uploadPointRepair();
                }
            }
            break;
        }
    }

    private boolean checkValid() {
        boolean isValid = false;
        if (mPointRepair != null) {
            String sid = mPointRepair.getPoint_id();
            double lnt = mPointRepair.getLng();
            double lat = mPointRepair.getLat();
            if ((sid != null && !sid.isEmpty()) && lnt > 0 && lat > 0) {
                isValid = true;
            }
        }

        if (!isValid)
            showToast("当前设备录入点不可用.");

        return isValid;
    }

    private void uploadPointRepair() {
        if (mPointRepair != null) {
            if (repairController == null)
                repairController = new PointRepairController(this);
            String strUploading = getString(R.string.repair_map_uploading);
            ProgressManager.getInstance().showProgress(this, null, strUploading, false);
            repairController.addPointRepair(mUser.getToken(), mPointRepair, new PointRepairCallBack() {
                @Override
                public void onAddPointRepair(boolean isSuccess, int errorCode, String errMsg, PlanPointRepair pointRepair) {
                    super.onAddPointRepair(isSuccess, errorCode, errMsg, pointRepair);
                    ProgressManager.getInstance().cancelProgress();
                    if (isSuccess) {
                        if (pointRepair != null) {
                            Intent intent = new Intent();
                            intent.setClass(UiRepairMapStep.this, UiRepairUpdateStep.class);
                            Bundle bundle = new Bundle();
                            bundle.putSerializable("point_repair", pointRepair);
                            bundle.putBoolean("is_update", false);
                            intent.putExtras(bundle);
                            startActivity(intent);
                        }
                    } else {
                        showToast(errMsg);
                    }
                }
            });
        }
    }

    public final static String POINT_REPAIR_UPDATED = "pointRepairUpdated";
    public final static String POINT_REPAIR_REMOVED = "pointRepairRemoved";
/*    public final static String REPAIR_ROUTE_SAVED = "pointRepairRouteSaved";
    public final static String REPAIR_ROUTE_UPLOADED = "pointRepairRouteUploaded";*/

    public static class PointRepairEvent {
        public String message;
        public Object arg;

        public PointRepairEvent(String message, Object obj) {
            this.message = message;
            this.arg = obj;
        }
    }

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

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

    @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 textMyAddr;
    }

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