package com.hbb20;

import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.graphics.Color;
import android.graphics.PointF;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.text.TextUtils;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.LinearSmoothScroller;
import androidx.recyclerview.widget.RecyclerView;

import com.github.promeg.pinyinhelper.Pinyin;
import com.mao.sortletterlib.SortLetterView;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;

import io.openim.android.ouicore.utils.Common;
import io.openim.android.ouicore.widget.SearchView;
import io.openim.android.ouicore.widget.StickyDecoration;

/**
 * Created by hbb20 on 11/1/16.
 */
class CountryCodeDialog2 {
    private static final Field sEditorField, sCursorDrawableField, sCursorDrawableResourceField;
    static Dialog dialog;
    static Context context;
    private static CountryCodeAdapter2 cca;
    private static String mLetters = "↑ABCDEFGHIJKLMNOPQRSTUVWXYZ#";//默认字符
    private static LinearLayoutManager mLayoutManager;

    static {
        Field editorField = null;
        Field cursorDrawableField = null;
        Field cursorDrawableResourceField = null;
        boolean exceptionThrown = false;
        try {
            cursorDrawableResourceField = TextView.class.getDeclaredField("mCursorDrawableRes");
            cursorDrawableResourceField.setAccessible(true);
            final Class<?> drawableFieldClass;
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
                drawableFieldClass = TextView.class;
            } else {
                editorField = TextView.class.getDeclaredField("mEditor");
                editorField.setAccessible(true);
                drawableFieldClass = editorField.getType();
            }
            cursorDrawableField = drawableFieldClass.getDeclaredField("mCursorDrawable");
            cursorDrawableField.setAccessible(true);
        } catch (Exception e) {
            exceptionThrown = true;
        }
        if (exceptionThrown) {
            sEditorField = null;
            sCursorDrawableField = null;
            sCursorDrawableResourceField = null;
        } else {
            sEditorField = editorField;
            sCursorDrawableField = cursorDrawableField;
            sCursorDrawableResourceField = cursorDrawableResourceField;
        }
    }

    public static void openCountryCodeDialog(final CountryCodePicker codePicker) {
        openCountryCodeDialog(codePicker, null);
    }

    public static void openCountryCodeDialog(final CountryCodePicker codePicker, final String countryNameCode) {
        context = codePicker.getContext();
        dialog = new Dialog(context);
        codePicker.refreshCustomMasterList();
        codePicker.refreshPreferredCountries();
//        List<CCPCountry> masterCountries = CCPCountry.getCustomMasterCountryList(context, codePicker);
        getList(codePicker);

        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.getWindow().setContentView(R.layout.layout_picker_dialog2);
        // 设置对话框全屏
        dialog.getWindow().setBackgroundDrawable(ContextCompat.getDrawable(context, io.openim.android.ouicore.R.color.white));
        dialog.getWindow().setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {//5.0 全透明实现
            Window window = dialog.getWindow();
            window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            window.setStatusBarColor(Color.TRANSPARENT);

            WindowManager.LayoutParams lp = dialog.getWindow().getAttributes();
            lp.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
            dialog.getWindow().setAttributes(lp);

        } else {//4.4 全透明状态栏
            dialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        }


        //dialog views
        RecyclerView recyclerView_countryDialog = (RecyclerView) dialog.findViewById(R.id.recycler_countryDialog);
        final SearchView editText_search = (SearchView) dialog.findViewById(R.id.searchView);
        LinearLayout dialogRoot = (LinearLayout) dialog.findViewById(R.id.cardViewRoot);
        ImageView imgDismiss = (ImageView) dialog.findViewById(R.id.back);
        SortLetterView sortView = (SortLetterView) dialog.findViewById(R.id.sort_view);

        //keyboard
        if (codePicker.isSearchAllowed() && codePicker.isDialogKeyboardAutoPopup()) {
            editText_search.requestFocus();
            dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
        } else {
            dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
        }

        imgDismiss.setOnClickListener(view -> dialog.dismiss());


        //clear button color and title color
        if (codePicker.getDialogTextColor() != 0) {
            int textColor = codePicker.getDialogTextColor();
            imgDismiss.setColorFilter(textColor);
        }


        //this will make dialog compact
        if (!codePicker.isSearchAllowed()) {
            RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) recyclerView_countryDialog.getLayoutParams();
            params.height = RecyclerView.LayoutParams.WRAP_CONTENT;
            recyclerView_countryDialog.setLayoutParams(params);
        }
        recyclerView_countryDialog.setLayoutManager(mLayoutManager = new LinearLayoutManager(context) {
            @Override
            public void smoothScrollToPosition(RecyclerView recyclerView,
                                               RecyclerView.State state, int position) {
                LinearSmoothScroller linearSmoothScroller =
                        new LinearSmoothScroller(recyclerView.getContext()) {
                            @Override
                            protected int calculateTimeForScrolling(int dx) {
                                // 此函数计算滚动dx的距离需要多久，当要滚动的距离很大时，比如说52000，
                                // 经测试，系统会多次调用此函数，每10000距离调一次，所以总的滚动时间
                                // 是多次调用此函数返回的时间的和，所以修改每次调用该函数时返回的时间的
                                // 大小就可以影响滚动需要的总时间，可以直接修改些函数的返回值，也可以修改
                                // dx的值，这里暂定使用后者.
                                // (See LinearSmoothScroller.TARGET_SEEK_SCROLL_DISTANCE_PX)
                                if (dx > 1500) {
                                    dx = 1500;
                                }
                                return super.calculateTimeForScrolling(dx);
                            }

                            @Override
                            public PointF computeScrollVectorForPosition(int targetPosition) {
                                return mLayoutManager.computeScrollVectorForPosition(targetPosition);
                            }
                        };
                linearSmoothScroller.setTargetPosition(position);
                startSmoothScroll(linearSmoothScroller);
            }
        });
        cca = new CountryCodeAdapter2(context, codePicker, editText_search.getEditText(), dialog);
        recyclerView_countryDialog.setAdapter(cca);
        recyclerView_countryDialog.addItemDecoration(new StickyDecoration(context,
                position -> cca.getItems().get(position).sortLetter));
        sortView.setLetters(mLetters);
        sortView.setOnLetterChangedListener((letter, position) -> {
            if (letter.equals("↑")) {
                Common.smoothMoveToPosition(recyclerView_countryDialog, 0);
                return;
            }
            for (int i = 0; i < cca.getItems().size(); i++) {
                CCPCountry exUserInfo = cca.getItems().get(i);
                if (exUserInfo.sortLetter.equalsIgnoreCase(letter)) {
                    Common.smoothMoveToPosition(recyclerView_countryDialog, i);
                    return;
                }
            }
        });

        recyclerView_countryDialog.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                if (Common.mShouldScroll && RecyclerView.SCROLL_STATE_IDLE == newState) {
                    Common.mShouldScroll = false;
                    Common.smoothMoveToPosition(recyclerView_countryDialog, Common.mToPosition);
                }
            }
        });

        dialog.setOnDismissListener(dialogInterface -> {
            hideKeyboard(context);
            if (codePicker.getDialogEventsListener() != null) {
                codePicker.getDialogEventsListener().onCcpDialogDismiss(dialogInterface);
            }
        });

        dialog.setOnCancelListener(dialogInterface -> {
            hideKeyboard(context);
            if (codePicker.getDialogEventsListener() != null) {
                codePicker.getDialogEventsListener().onCcpDialogCancel(dialogInterface);
            }
        });

        //auto scroll to mentioned countryNameCode
        if (countryNameCode != null) {
            boolean isPreferredCountry = false;
            if (codePicker.preferredCountries != null) {
                for (CCPCountry preferredCountry : codePicker.preferredCountries) {
                    if (preferredCountry.nameCode.equalsIgnoreCase(countryNameCode)) {
                        isPreferredCountry = true;
                        break;
                    }
                }
            }

        }

        dialog.show();
        if (codePicker.getDialogEventsListener() != null) {
            codePicker.getDialogEventsListener().onCcpDialogOpen(dialog);
        }
    }

    private static void getList(CountryCodePicker codePicker) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                List<CCPCountry> masterCountries = CCPCountry.getCustomMasterCountryList(context, codePicker);
                List<CCPCountry> exInfos = new ArrayList<>();
                //不在24个字母中的开头
                List<CCPCountry> otInfos = new ArrayList<>();
                for (CCPCountry datum : masterCountries) {
                    CCPCountry exUserInfo = datum;
                    String letter = "";
                    try {
                        String str = exUserInfo.getName();
                        letter = String.valueOf(Pinyin.toPinyin(str.charAt(0)).charAt(0));
                        letter = letter.toUpperCase(Locale.ROOT);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    if (TextUtils.isEmpty(letter) || !Common.isAlpha(letter)) {
                        exUserInfo.sortLetter = "#";
                        otInfos.add(exUserInfo);
                    } else {
                        exUserInfo.sortLetter = letter;
                        exInfos.add(exUserInfo);
                    }
                }
                List<CCPCountry> all = new ArrayList<>();
                all.addAll(exInfos);
                all.addAll(otInfos);
                Collections.sort(all, new PinyinComparator());
                Handler handler = new Handler(Looper.getMainLooper());
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        cca.setItems(all);
                    }
                });
            }
        }).start();

    }

    public static class PinyinComparator implements Comparator<CCPCountry> {

        public int compare(CCPCountry o1, CCPCountry o2) {
            //根据ABCDEFG...来排序
            if (o1.sortLetter.equals("#")) {
                return 1;
            } else if (o2.sortLetter.equals("#")) {
                return -1;
            } else {
                return o1.sortLetter.compareTo(o2.sortLetter);
            }
        }
    }

    private static void hideKeyboard(Context context) {
        if (context instanceof Activity) {
            Activity activity = (Activity) context;
            InputMethodManager imm = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
            //Find the currently focused view, so we can grab the correct window token from it.
            View view = activity.getCurrentFocus();
            //If no view currently has focus, create a new one, just so we can grab a window token from it
            if (view == null) {
                view = new View(activity);
            }
            imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
        }
    }

    static void setCursorColor(EditText editText, int color) {
        if (sCursorDrawableField == null) {
            return;
        }
        try {
            final Drawable drawable = getDrawable(editText.getContext(),
                    sCursorDrawableResourceField.getInt(editText));
            drawable.setColorFilter(color, PorterDuff.Mode.SRC_IN);
            sCursorDrawableField.set(Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN
                    ? editText : sEditorField.get(editText), new Drawable[]{drawable, drawable});
        } catch (Exception ignored) {

        }
    }

    static void clear() {
        if (dialog != null) {
            dialog.dismiss();
        }
        dialog = null;
        context = null;
    }

    private static Drawable getDrawable(Context context, int id) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
            return context.getResources().getDrawable(id);
        } else {
            return context.getDrawable(id);
        }
    }
}
