package com.tofly.ghrq_route.module.map.service;

import android.content.Context;
import android.text.TextUtils;

import com.esri.arcgisruntime.ArcGISRuntimeException;
import com.esri.arcgisruntime.layers.ArcGISMapImageLayer;
import com.esri.arcgisruntime.mapping.view.MapView;
import com.esri.arcgisruntime.tasks.geoprocessing.GeoprocessingJob;
import com.esri.arcgisruntime.tasks.geoprocessing.GeoprocessingParameter;
import com.esri.arcgisruntime.tasks.geoprocessing.GeoprocessingParameters;
import com.esri.arcgisruntime.tasks.geoprocessing.GeoprocessingString;
import com.esri.arcgisruntime.tasks.geoprocessing.GeoprocessingTask;
import com.mgq.base.utils.string.StringUtil;
import com.mgq.base.utils.toast.ToastUtil;
import com.tofly.ghrq_route.base.url.NetRequestURL;
import com.tofly.ghrq_route.module.map.MapServiceTool;
import com.tofly.ghrq_route.module.map.controller.MapController;
import com.tofly.ghrq_route.module.map.controller.MapServiceCallback;
import com.tofly.ghrq_route.module.pipeAnalyze.domain.PipeAnalysisResultBean;
import com.tofly.ghrq_route.module.pipeAnalyze.domain.PipeAnalyzeStatusBean;

import java.util.List;
import java.util.Map;
import java.util.Timer;


/**
 * 爆管分析 HTTP请求方式工具类
 */
public class MapPointAnalyzeHttpTask {

    public static final String usertoken_text = "usertoken";
    public static final String x_text = "x";
    public static final String y_text = "y";
    public static final String buffer_text = "buffer";
    public static final String summary_text = "summary";
    public static final String pipe_name_text = "layername";
    public static final String pipe_name_value = "pipesectionmp";
    public static final String pipe_id_text = "objectids";
    public static final String by_source_text = "bysource";
    public static final String outpoint_field_text = "outpointfields";
    public static final String outpoint_field_value = "sid";
    public static final String commit_format_text = "f";
    public static final String commit_format_value = "fjson";
    public static final String search_fileds_text = "layerdbname";
    public static final String output_summary = "summary";

    public enum ESRIJOBSTATUS {
        SUBMITTED("esriJobSubmitted"),
        SUCCEEDED("esriJobSucceeded"),
        FAILED("esriJobEFailed");

        ESRIJOBSTATUS(String status){
            jobStatus = status;
        }

        public String getStatus() {
            return jobStatus;
        }

        public static ESRIJOBSTATUS Status(String status){
            switch (status){
                case "esriJobSubmitted":
                    return SUBMITTED;
                case "esriJobSucceeded":
                    return SUCCEEDED;
                case "esriJobError":
                    return FAILED;
                default:
                    return SUBMITTED;
            }
        }

        final String jobStatus;
    }

    private Context mContext;
    private MapView mapView;
    private String mLayerName;
    private List<String> mPipeIds;
    private MapServiceTool mapServiceTool;
    private PipeAnalysisResultBean resultBean = new PipeAnalysisResultBean();
    private MapController.OnGetPipeJobMapResult onGetPipeJobMapResult;
    private boolean mbShowProgress = true;
    private boolean isJobFinished;
    private boolean isJobCanceled;
    private boolean isTaskFinished;
    private boolean isGetJobResut;
    private GeoprocessingJob mGeoTaskJob;
    private Timer analysisTimer = null;

    public interface OnGetPipeJobMapResult{
        void onGetJobHide();
        void onGetJobCanceled();
        void onGetResult(boolean isSuccess, PipeAnalysisResultBean resultBean, ArcGISMapImageLayer layer);
    }

    public MapPointAnalyzeHttpTask(Context context, MapView mapView, List<String> pipeIds, String layerName, MapController.OnGetPipeJobMapResult onGetPipeJobMapResult) {
        this.mContext = context;
        this.mapView = mapView;
        this.mPipeIds = pipeIds;
        this.mLayerName = layerName;
        this.mapServiceTool = MapServiceTool.getInstance();;
        this.onGetPipeJobMapResult = onGetPipeJobMapResult;
        isJobFinished = false;
        isJobCanceled = false;
        isTaskFinished = false;
        isGetJobResut = false;
    }

    public boolean isTaskFinished() {
        return isTaskFinished;
    }

    public boolean isJobFinished() {
        return isJobFinished;
    }

    public boolean isJobFinished(PipeAnalyzeStatusBean statusBean) {
        ESRIJOBSTATUS status = ESRIJOBSTATUS.Status(statusBean.getJobStatus());
        if (status == ESRIJOBSTATUS.FAILED ||
                status == ESRIJOBSTATUS.SUCCEEDED)
            return true;
        else
            return false;
    }

    public boolean isJobCanceled() {
        return isJobCanceled;
    }

    public void cancelJob() {
        hideProgress();
        if (analysisTimer != null) {
            analysisTimer.cancel();
        }
        if (mGeoTaskJob != null)
            mGeoTaskJob.cancel();
        isJobFinished = true;
        isJobCanceled = true;
        isTaskFinished = true;

        if (onGetPipeJobMapResult != null)
            onGetPipeJobMapResult.onGetJobCanceled();
    }

    private void showProgress() {

    }

    private void hideProgress() {

    }

    void onPreExecute() {
        if (mbShowProgress) {
            showProgress();
        }
    }

    public void execute() {
        onPreExecute();

        resultBean.setCode(-1);
        resultBean.setError("没有获取到分析结果！");

        String strIds = StringUtil.listToString(mPipeIds, ',');
        submitPipeAnalyzeJob(MapServiceTool.MAP_DEFAULT_GIS_TOKEN, strIds, mLayerName);
    }

    public void submitPipeAnalyzeJob(String gisToken, String pipeIds, String layerName) {
        String urlQuery = NetRequestURL.ONLINE_FILTER_MAP_GP_EXTERNAL + "/submitJob";
        GeoprocessingTask geoTask = new GeoprocessingTask(urlQuery);
        geoTask.loadAsync();
        geoTask.addDoneLoadingListener(() -> {
            GeoprocessingParameters parameters = new GeoprocessingParameters(GeoprocessingParameters.ExecutionType.ASYNCHRONOUS_SUBMIT);
            Map<String, GeoprocessingParameter> inputs = parameters.getInputs();
            GeoprocessingString geoToken = new GeoprocessingString();
            geoToken.setValue(gisToken);
            inputs.put(usertoken_text, geoToken);

            GeoprocessingString geoPipe = new GeoprocessingString();
            geoPipe.setValue(pipeIds);
            inputs.put(pipe_id_text, geoPipe);

            GeoprocessingString geoName = new GeoprocessingString();
            geoName.setValue(layerName);
            inputs.put(pipe_name_text, geoName);

            GeoprocessingString geoValue = new GeoprocessingString();
            geoValue.setValue(commit_format_value);
            inputs.put(commit_format_text, geoValue);

            GeoprocessingJob geoTaskJob = geoTask.createJob(parameters);
            geoTaskJob.start();
            geoTaskJob.addJobDoneListener(() -> {
                String serverJobId = geoTaskJob.getServerJobId();
                if (serverJobId != null && !TextUtils.isEmpty(serverJobId)) {
                    mGeoTaskJob = geoTaskJob;
                    checkJobStatus(serverJobId);
                }else {
                    ArcGISRuntimeException error = geoTaskJob.getError();
                    if (error != null) {
                        int errorCode = error.getErrorCode();
                        String errMsg = error.getMessage();
                        resultBean.setCode(errorCode);
                        resultBean.setError(errMsg);
                    }

                    onPostExecute();
                }
            });
        });
    }

    void checkJobStatus(String jobId) {
        final String tag = "-pipeAnalyzeGetJobStatus";
        resultBean.setCode(-1);
        resultBean.setError("没有获取到分析结果！");

        try {
            if (!TextUtils.isEmpty(jobId)) {
                getPipeAnalyzeJobStatus(tag, jobId, new MapServiceCallback() {
                    @Override
                    public void onGetPipeAnalyzeJobStatus(boolean isSuccess, int errorCode, String errMsg, PipeAnalyzeStatusBean statusBean) {
                        super.onGetPipeAnalyzeJobStatus(isSuccess, errorCode, errMsg, statusBean);
                        if (isSuccess) {
                            if (statusBean != null && isJobFinished(statusBean)) {
                                isJobFinished = true;
                            }
                        }
                        if (isJobFinished) {
                            ESRIJOBSTATUS job_Status = ESRIJOBSTATUS.Status(statusBean.getJobStatus());
                            isGetJobResut = job_Status == ESRIJOBSTATUS.SUCCEEDED;
                        }

                        if (isGetJobResut) {
                            String summary_url = statusBean.getResults().getSummary().getParamUrl();
                            getPipeAnalyzeResult(jobId, summary_url);
                        }else {
                            onPostExecute();
                        }
                    }
                });
            }
        } catch (Exception e) {
            resultBean.setCode(-1);
            resultBean.setError("解析异常！");
        }
    }

    private void getPipeAnalyzeJobStatus(String tag, String jobId, MapServiceCallback serviceCallback) {
        mapServiceTool.getPipeAnalyzeJobStatus(mContext, tag, jobId, new MapServiceCallback() {
            @Override
            public void onGetPipeAnalyzeJobStatus(boolean isSuccess, int errorCode, String errMsg, PipeAnalyzeStatusBean statusBean) {
                super.onGetPipeAnalyzeJobStatus(isSuccess, errorCode, errMsg, statusBean);

                serviceCallback.onGetPipeAnalyzeJobStatus(isSuccess, errorCode, errMsg, statusBean);
            }
        });
    }

    private void getPipeAnalyzeResult(String jobId, String summary_url) {
        mapServiceTool.getPipeAnalyzeResult(mContext, jobId, summary_url, new MapServiceCallback(){
            @Override
            public void onGetPipeAnalyzeResult(boolean isSuccess, int errorCode, String errMsg, PipeAnalysisResultBean result) {
                super.onGetPipeAnalyzeResult(isSuccess, errorCode, errMsg, result);
                if (isSuccess) {
                    if (result != null && 10000 == result.getCode()) {
                        resultBean = result;
                        resultBean.setJobId(jobId);
                    }else {
                        resultBean.setCode(-1);
                        resultBean.setError("没有获取到分析结果！");
                    }
                }else {
                    resultBean.setCode(-1);
                    resultBean.setError(errMsg);
                }

                onPostExecute();
            }
        });
    }

    void onPostExecute() {
        hideProgress();

        PipeAnalysisResultBean bean = resultBean;
        if (bean.getCode() == 10000) {
            ToastUtil.showToast(mContext, bean.getMessage());
            //pipeResultShowMap(bean, onGetPipeJobMapResult);
        } else {
            String errMsg = bean.getError() != null ? bean.getError().toString() : bean.getMessage();

            if (onGetPipeJobMapResult != null){
                onGetPipeJobMapResult.onGetResult(false, null, null);
            }
        }

        isJobFinished = true;
        isTaskFinished = true;
    }
}
