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

import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.Spinner;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

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.GeodatabaseFeatureTable;
import com.esri.arcgisruntime.data.QueryParameters;
import com.google.android.material.bottomsheet.BottomSheetBehavior;
import com.mgq.base.utils.toast.ToastUtil;
import com.tofly.ghrq_route.R;
import com.tofly.ghrq_route.common.ui.adapter.FieldAdapter;
import com.tofly.ghrq_route.common.ui.adapter.PipenetResultAdapter;
import com.tofly.ghrq_route.common.ui.adapter.TableNameAdapter;
import com.tofly.ghrq_route.module.map.service.Container;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnCheckedChanged;
import butterknife.OnClick;
import butterknife.OnItemSelected;
import butterknife.Unbinder;

/**
 * Created by lihualong on 2017/6/22.
 */

public class PipeSearchFragment extends BaseBottomSheetFragment {

    public static final String TAG = PipeSearchFragment.class.getName();
//    @BindView(R.id.image_drawer_option)
//    ImageView imageDrawerOption;
    @BindView(R.id.layout_pipenet_collapse)
    LinearLayout layoutPipenetCollapse;
    @BindView(R.id.damageSpinner)
    Spinner damageSpinner;
    @BindView(R.id.causeSpinner)
    Spinner causeSpinner;
    @BindView(R.id.edit_search_content)
    EditText editSearchContent;
    @BindView(R.id.btn_search)
    ImageView btnSearch;

    @BindView(R.id.layout_header_row)
    LinearLayout layoutHeaderRow;
    @BindView(R.id.pipenet_result_listview)
    RecyclerView pipenetResultListview;
    @BindView(R.id.no_search_result)
    TextView noSearchResult;
    @BindView(R.id.progress_search)
    ProgressBar progressSearch;
    @BindView(R.id.pipenet_search_result_title)
    LinearLayout pipenetSearchResultTitle;
    private Container.HideSearchCallback hideCallback;
    private Unbinder bind;
    private List<FeatureTable> featureTables;
    private PipenetResultAdapter pipenetResultAdapter;
    private FieldAdapter fieldAdapter;
    //    模糊查询
    private boolean mSearchObscureMode = true;
    private Container.OnMapShowListener onMapShowListener;

    public PipeSearchFragment() {
    }

    @Override
    protected void initView(View rootView) {
        bind = ButterKnife.bind(this, rootView);
    }

    @Override
    public void resetView(View rootView) {
        bind = ButterKnife.bind(this, rootView);
    }

    private void initListener() {


    }

    @Override
    protected int getResourceId() {
        return R.layout.fragment_pipenet_search;
    }

    public void setHideCallback(final Container.HideSearchCallback hideCallback) {
        this.hideCallback = hideCallback;

    }

    @Override
    public void dismiss() {
        super.dismiss();
        hideCallback.clossPipeSearchToggle();
    }

    @Override
    public void onStart() {
        super.onStart();
        behavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
            @Override
            public void onStateChanged(@NonNull View bottomSheet, int newState) {
                Log.w(TAG, "onStateChanged: newState = " + newState);
            }

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

            }
        });
        initSearchRequirement();
        initListener();

    }


    @Override
    public void onDestroyView() {
        super.onDestroyView();
        bind.unbind();
    }

    public void initPipeData(List<FeatureTable> allFeatureTable) {
        this.featureTables = allFeatureTable;
    }

    private List<Feature> blurryResult = new ArrayList<>();//模糊查询结果的字符串数组

    private void initSearchRequirement() {
        if (featureTables == null || featureTables.size() == 0)
            return;

        TableNameAdapter tableNameAdapter = new TableNameAdapter(featureTables, mContext);
        damageSpinner.setAdapter(tableNameAdapter);


        FeatureTable featureTable = featureTables.get(0);
        fieldAdapter = new FieldAdapter(mContext, featureTable.getFields());
        causeSpinner.setAdapter(fieldAdapter);

        pipenetResultAdapter = new PipenetResultAdapter(blurryResult, mContext);
        pipenetResultListview.setItemAnimator(new DefaultItemAnimator());
        LinearLayoutManager layoutManager = new LinearLayoutManager(mContext);
        pipenetResultListview.setLayoutManager(layoutManager);
        pipenetResultListview.setAdapter(pipenetResultAdapter);

        if (blurryResult.size() == 0) {
            pipenetSearchResultTitle.setVisibility(View.GONE);
            layoutHeaderRow.setVisibility(View.GONE);
        }

    }


    @OnClick({R.id.pipenet_search_close_iv, R.id.btn_search})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.pipenet_search_close_iv:
                PipeSearchFragment.this.dismiss();
                break;
            case R.id.btn_search:
                searchContent();
                break;

        }
    }

    private void searchContent() {
        final String strInput = editSearchContent.getEditableText().toString();
        if (strInput.isEmpty()) {
            ToastUtil.showToast(mContext, R.string.pipenet_warning_no_keyword);
            return;
        }

        GeodatabaseFeatureTable geoSel = (GeodatabaseFeatureTable) damageSpinner.getSelectedItem();
        Field fieldSel = (Field) causeSpinner.getSelectedItem();
        if (geoSel == null || fieldSel == null) {
            ToastUtil.showToast(mContext, R.string.pipenet_warning_no_table);
            return;
        }

        if (this.featureTables == null || this.featureTables.isEmpty()) {
            ToastUtil.showToast(mContext, R.string.pipenet_warning_no_beanlist);
            return;
        }
        InputMethodManager imm = (InputMethodManager) mContext.getSystemService(Context
                .INPUT_METHOD_SERVICE);
        if (imm != null) {
            imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
        }
        final String tableName = geoSel.getTableName();
        final String fieldSelName = fieldSel.getName();
        Log.w("TAG", "onQueryTextChange: tableName :" + tableName);
        Log.w("TAG", "onQueryTextChange: fieldName :" + fieldSelName);

        if (blurryResult == null) {
            blurryResult = new CopyOnWriteArrayList<>();
        } else {
            if (blurryResult.size() > 0) {
                blurryResult.clear();
            }
        }
        btnSearch.setEnabled(false);
        pipenetSearchResultTitle.setVisibility(View.GONE);
        layoutHeaderRow.setVisibility(View.GONE);
        pipenetResultListview.setVisibility(View.GONE);
        noSearchResult.setVisibility(View.GONE);
        progressSearch.setVisibility(View.VISIBLE);
        Runnable searhRunnable = new Runnable() {
            @Override
            public void run() {
                getBlurryResult(tableName, fieldSelName, strInput, featureTables);
                mHandler.sendEmptyMessage(HAN_SEARCHTEXTCHANGE);

            }
        };
        new Thread(searhRunnable).start();
    }

    private static final int HAN_SEARCHTEXTCHANGE = 10;//模糊搜索结果

    private MyHandler mHandler = new MyHandler(this);
    private static class MyHandler extends Handler {
        WeakReference<PipeSearchFragment> reference;

        private MyHandler (PipeSearchFragment manager) {
            this.reference = new WeakReference<>(manager);
        }
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == HAN_SEARCHTEXTCHANGE) {
                reference.get().onSearchTextChange();
            }
        }
    }

    private void onSearchTextChange() {
        progressSearch.setVisibility(View.GONE);
        if (blurryResult != null && blurryResult.size() > 0) {
            showPipeSearchResult();
        } else {
            closePipeSearchResult();
        }
        btnSearch.setEnabled(true);
    }

    //关闭查询结果列表
    private void closePipeSearchResult() {
        pipenetResultListview.setVisibility(View.GONE);
        pipenetSearchResultTitle.setVisibility(View.VISIBLE);
        layoutHeaderRow.setVisibility(View.GONE);
        noSearchResult.setVisibility(View.VISIBLE);
    }

    //显示管线查询结果列表
    private void showPipeSearchResult() {
//        resultAdapter.clearList();

        pipenetResultAdapter.setDataChanged(blurryResult, -1);
        pipenetResultAdapter.setResultListener(new Container.OnResultClickListener() {
            @Override
            public void showCalloutAtMap(Feature feature, int position) {
                if (behavior.getState() == BottomSheetBehavior.STATE_EXPANDED) {
                    behavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
                }
                if (pipenetResultAdapter != null) {
                    pipenetResultAdapter.setSelected(position);
                }
                if (onMapShowListener != null) {
                    onMapShowListener.showAtMap(feature);
                }
            }
        });
        pipenetResultListview.setVisibility(View.VISIBLE);
        pipenetSearchResultTitle.setVisibility(View.VISIBLE);
        layoutHeaderRow.setVisibility(View.VISIBLE);
        noSearchResult.setVisibility(View.GONE);
    }

    public void getBlurryResult(String tableName, final String fieldName,
                                         final String layName, List<FeatureTable> tableBeanList) {
        for (FeatureTable featureTable : tableBeanList) {
            if (tableName.equals(featureTable.getTableName())) {
                if (featureTable.hasGeometry()) {
                    Log.w("TAG", "getBlurryResult: featureTable = " + featureTable);
                    String where = fieldName + " like '%" + layName + "%'";
                    if (!mSearchObscureMode) {
                        where = fieldName + " = " + layName;
                    }
                    Log.w(TAG, "Search query is: " + where);
                    QueryParameters queryParameters = new QueryParameters();
                    queryParameters.setWhereClause(where);

                    final ListenableFuture<FeatureQueryResult> query = featureTable.queryFeaturesAsync(queryParameters);
                    query.addDoneListener(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                FeatureQueryResult result = query.get();
                                for (Feature feature : result) {
                                    blurryResult.add(feature);
                                }
                            } catch (Exception e) {
                                Log.w("TAG", "getBlurryResult: 查询时出错 e = " + e.getMessage());
                                e.printStackTrace();
                            }
                        }
                    });
                }
            }
        }
    }

    @OnCheckedChanged(R.id.switch_search_mode)
    protected void onChanged(boolean isChecked) {
        mSearchObscureMode = isChecked;
    }

    @OnItemSelected({R.id.damageSpinner})
    public void onItemClicked(int position) {
        List<Field> fields = featureTables.get(position).getFields();
        fieldAdapter = new FieldAdapter(mContext, fields);
        causeSpinner.setAdapter(fieldAdapter);
    }

    public void setOnMapShowListener(Container.OnMapShowListener osl) {
        this.onMapShowListener = osl;
    }

}
