package com.usai.redant.CommonEditor.EnumSelectAndSort;

import android.content.Context;
import android.content.Intent;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

import com.usai.redant.CommonEditor.EnumSlectActivity;
import com.usai.redant.redantmobile.R;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.Serializable;

public class EnumSelectAndSortActivity extends AppCompatActivity {


    static String MAX_SELECT = "max_select";
    static String GROUP_POSITION = "group";
    static String CHILD_POSITION = "child";
    static String CADEDATE = "cadedate";
    static String SINGLE_SELECT = "single_select";
    static String TITLE = "title";
    static String AUTO_CLOSE = "auto_close";

    public static class Builder {
        public Intent build(Context context, String title, int max_select, int group, int child, String cadedate, boolean single_select, boolean auto_close) {
            if (context == null) {
                return null;
            }

            Intent intent = new Intent(context,EnumSelectAndSortActivity.class);

            intent.putExtra(MAX_SELECT,max_select);
            intent.putExtra(GROUP_POSITION,group);
            intent.putExtra(CHILD_POSITION,child);
            if (cadedate != null) {
                intent.putExtra(CADEDATE,(Serializable) cadedate);
            }
            intent.putExtra(SINGLE_SELECT,single_select);
            if (title != null) {
                intent.putExtra(TITLE,title);
            }
            intent.putExtra(AUTO_CLOSE,auto_close);

            return intent;
        }
    }

    public class SearchBarWatcher implements TextWatcher {

        Context mCtx;
        EditText textView;

        public SearchBarWatcher(Context ctx,EditText textView) {
            this.mCtx = ctx;
            this.textView = textView;


        }

        String origin_text;
        String string;
        int start_position;
        int change_length; // 修改原文长度
        int new_string_length;


        /**
         * s        改变前的内容
         * start    增加内容前光标位置，删除内容后光标位置 （起始位置）
         * count    选中s中的内容长度（发生改变的原内容长度），未选中为0
         * after    新添加的内容长度，删除为0
         * */
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
//            Log.d("TextChange", "before Text Changed: " + s + " Start: " + start + " Count: " + count + " After: " + after);

            origin_text = s.toString();
            start_position = start;
            change_length = count;
            new_string_length = after;
        }

        /**
         * s        改变后的内容
         * start    增加内容前光标位置，删除内容后光标位置 （起始位置）
         * before   选中s中的内容长度（发生改变的原内容长度），未选中为0
         * count    增加内容长度，删除内容为0
         * */
        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
//            Log.d("TextChange", "on Text Changed: " + s + " Start: " + start + " Before: " + before + " Count: " + count);
        }

        @Override
        public void afterTextChanged(Editable s) {

            /**
             * 文本处理
             * */
            if (new_string_length == 0) {
                string = "";
            } else {
                string = s.toString().substring(start_position,start_position + new_string_length);
            }

            if (change_length == 0) { // 新加内容

            } else { // 替换原文或删除原文

            }

            /**
             * 业务逻辑
             * */

            if (string.equals("\n") || string.equals("\r") || string.equals("\r\n")) {
                textView.setText(origin_text);
                return;
            }

            mKeywords = s.toString();
            adapter.notifyDataSetChanged();

            if (mKeywords.isEmpty()) {
                enum_list_view.canDrag =  true;
            } else {
                enum_list_view.canDrag = false;
            }

        }
    }




    private int maxSelect;
    private int mGroup;
    private int mChild;
    private boolean mSingleSelect;
    private String mTitle;
    private boolean mAuto_close;
    private JSONObject mCadedate;
    private boolean mDirty;

    private String mKeywords;
    private int filter_count;

    private DragListView enum_list_view;
    private EnumAdapter adapter;
    private Context mCtx;

    private EditText searchBar;
//    private boolean isEditing = false;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_enum_select_and_sort);

        init();

        setTitle(mTitle);

        searchBar = (EditText)findViewById(R.id.common_editor_enum_select_sort_search_bar);
        searchBar.addTextChangedListener(new SearchBarWatcher(mCtx,searchBar));

        enum_list_view = (DragListView) findViewById(R.id.enum__select_sort_list_view);

        adapter = new EnumAdapter(mCtx);
        enum_list_view.setAdapter(adapter);

        enum_list_view.setOnItemClickListener(new CellClickListener(mCtx));

    }

//    @Override
//    public boolean onCreateOptionsMenu(Menu menu) {
//        getMenuInflater().inflate(R.menu.enum_select_sort_menu,menu);
//        return true;
//    }
//
//    @Override
//    public boolean onOptionsItemSelected(MenuItem item) {
//
////        if (item.getItemId() == R.id.enum_menu_sort) {
////            if (isEditing) {
////                isEditing = false;
////                item.setTitle("Sort");
////            } else {
////                isEditing = true;
////                item.setTitle("End Sort");
////            }
////
////            adapter.notifyDataSetChanged();
////        }
//        return true;
//    }

    @Override
    public void finish() {

        if (mDirty != false) {
            Intent intent = new Intent();
            intent.putExtra(CADEDATE,mCadedate.toString());
            intent.putExtra(GROUP_POSITION,mGroup);
            intent.putExtra(CHILD_POSITION,mChild);

            setResult(RESULT_OK,intent);
        }


        super.finish();
    }

    private void init() {
        mCtx = this;
        Intent intent = getIntent();
        String cadedate_str = intent.getStringExtra(CADEDATE);
        try {
            mCadedate = new JSONObject(cadedate_str);
        } catch (Exception e) {
            e.printStackTrace();
        }
        mSingleSelect = intent.getBooleanExtra(SINGLE_SELECT,true);
        mGroup = intent.getIntExtra(GROUP_POSITION,0);
        mChild = intent.getIntExtra(CHILD_POSITION,0);
        mTitle = intent.getStringExtra(TITLE);
        maxSelect = intent.getIntExtra(MAX_SELECT,0);
        mAuto_close = intent.getBooleanExtra(AUTO_CLOSE,true);


    }

    private class CellClickListener implements AdapterView.OnItemClickListener {

        private Context ctx;
        public CellClickListener(Context ctx) {
            this.ctx = ctx;
        }

        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

//            if (isEditing) {
//                return;
//            }

            mDirty = true;

            try {
                if (mSingleSelect) {

                    boolean is_worked = false;

                    if (mKeywords == null || mKeywords.isEmpty()) {

                        for (int i = 0; i < mCadedate.optInt("count"); i++) {
                            JSONObject val_json = mCadedate.optJSONObject("val_" + i);

                            if (i == position) {
                                int select = val_json.optInt("check");
                                if (select == 0) {
                                    val_json.put("check","1");
                                } else {
                                    val_json.put("check","0");
                                }
                                is_worked = select == 0;
                            } else {
                                val_json.put("check","0");
                            }
                            mCadedate.put("val_" + i,val_json);



                        } // for

                    } // keywords null
                    else {


                        JSONObject val_json = null;
                        int count = 0;
                        boolean getIt = false;
                        for (int cc = 0; cc < mCadedate.optInt("count"); cc++) {

                            JSONObject search_json = mCadedate.optJSONObject("val_" + cc);
                            String value = search_json.optString("value");
                            boolean contain = value.toUpperCase().contains(mKeywords.toUpperCase());
                            if (contain && count < filter_count) {
                                count++;
                            }

                            val_json = search_json;
                            if (!getIt && count - 1 == position) {
                                getIt = true;

                                //==========
                                int select = val_json.optInt("check");
                                if (select != 0) {
                                    val_json.put("check","0");
                                } else {
                                    val_json.put("check","1");
                                }
                                is_worked = select == 0;

                            } else  {
                                val_json.put("check","0");
                            }

                            mCadedate.put("val_" + cc,val_json);
                        } // for cc

//                        for (int sc = 0; sc < mCadedate.optInt("count"); sc++) {
//
//                            JSONObject sc_json = mCadedate.optJSONObject("val_" + sc);
//
//                            if (sc_json.optString("value").equals(val_json.optString("value"))) {
//                                sc_json.put("check","1");
//                            } else {
//                                sc_json.put("check","0");
//                            }
//                            mCadedate.put("val_" + sc,sc_json);
//
//                        } // for sc


                    }

                    if (is_worked) {
                        if (mAuto_close) {
                            finish();
                        } else {
                            adapter.notifyDataSetChanged();
                        }
                    } else {
                        adapter.notifyDataSetChanged();
                    }


                } // single select
                else {

                    int index = position;
                    JSONObject val_json = null;
                    if (mKeywords == null || mKeywords.isEmpty()) {
                        val_json = mCadedate.optJSONObject("val_" + position);
                    } else {
                        int count = 0;
                        for (int i = 0; i < mCadedate.optInt("count"); i++) {
                            if (count >= filter_count) {
                                break;
                            }
                            JSONObject search_json = mCadedate.optJSONObject("val_" + i);
                            String value = search_json.optString("value");
                            boolean contain = value.toUpperCase().contains(mKeywords.toUpperCase());
                            if (contain) {
                                count++;
                            }

                            if (count - 1 == position) {
                                val_json = search_json;
                                index = i;
                                break;
                            }
                        }
                    }

                    int check = val_json.optInt("check");
                    if (check == 1) {
                        val_json.put("check","0");
                    } else {
                        if (check_count() >= maxSelect && maxSelect > 0) {
                            new AlertDialog.Builder(this.ctx)
                                    .setTitle("Max count reached")
                                    .setMessage(maxSelect + " items at most for this field.")
                                    .setPositiveButton("OK",null)
                                    .show();
                            return;

                        }
                        val_json.put("check","1");
                    }
                    mCadedate.put("val_" + index,val_json);

                }
                adapter.notifyDataSetChanged();

            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    }

    public int check_count() {

        int check_count = 0;
        for (int i = 0; i < mCadedate.optInt("count"); i++) {
            JSONObject val_json = mCadedate.optJSONObject("val_" + i);
            int check = val_json.optInt("check");
            if (check == 1) {
                check_count++;
            }
        }
        return check_count;
    }


    private class EnumAdapter extends DragListView.DragListAdapter {

        public class Holder {
            public TextView value_tv;
            public ImageView check_iv;
            public ImageView drag_iv;

            public Holder(View cell) {
                if (cell == null) {
                    return;
                }
                value_tv = (TextView)cell.findViewById(R.id.enum_value_tv);
                check_iv = (ImageView)cell.findViewById(R.id.enum_check_iv);
                check_iv.setClickable(false);
                check_iv.setFocusable(false);
                drag_iv = (ImageView)cell.findViewById(R.id.drag_list_item_image);

                cell.setTag(this);

            }
        }


        private Context ctx;
        public EnumAdapter(Context context) {
            this.ctx = context;
        }

        @Override
        public int getCount() {

            if (mCadedate == null) {
                return 0;
            }

            if (mKeywords == null || mKeywords.isEmpty()) {
                filter_count = 0;
                return mCadedate.optInt("count");
            }

            int count = 0;
            for (int i = 0; i < mCadedate.optInt("count"); i++) {
                JSONObject val_json = mCadedate.optJSONObject("val_" + i);
                String value = val_json.optString("value");
                boolean contain = value.toUpperCase().contains(mKeywords.toUpperCase());
                if (contain) {
                    count++;
                }
            }
            filter_count = count;
            return count;
        }

        @Override
        public Object getItem(int position) {
            JSONObject val_json = null;
            if (mKeywords == null || mKeywords.isEmpty()) {
                val_json = mCadedate.optJSONObject("val_" + position);
            } else {
                int count = 0;
                for (int i = 0; i < mCadedate.optInt("count"); i++) {
                    if (count >= filter_count) {
                        break;
                    }
                    JSONObject search_json = mCadedate.optJSONObject("val_" + i);
                    String value = search_json.optString("value");
                    boolean contain = value.toUpperCase().contains(mKeywords.toUpperCase());
                    if (contain) {
                        count++;
                    } else {
                        continue;
                    }

                    if (count - 1 == position) {
                        val_json = search_json;
                        break;
                    }

                }
            }
            return val_json;
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            JSONObject val_json = (JSONObject) getItem(position);
//            if (mKeywords == null || mKeywords.isEmpty()) {
//                val_json = mCadedate.optJSONObject("val_" + position);
//            } else {
//                val_json = (JSONObject) getItem(position);
//            }

            EnumAdapter.Holder holder;
            if (convertView == null) {

                convertView = LayoutInflater.from(this.ctx).inflate(R.layout.enum_select_sort_cell,null);
                holder = new EnumAdapter.Holder(convertView);

            } else {
                holder = (EnumAdapter.Holder) convertView.getTag();
            }

            String value = val_json.optString("value");
            holder.value_tv.setText(value);

            int check = val_json.optInt("check");
            if (check == 1) {
                holder.check_iv.setVisibility(View.VISIBLE);
            } else {
                holder.check_iv.setVisibility(View.INVISIBLE);
            }


//            if (isEditing) {
//                holder.check_iv.setVisibility(View.INVISIBLE);
//                holder.drag_iv.setVisibility(View.VISIBLE);
//                holder.drag_iv.setFocusable(false);
//                holder.drag_iv.setClickable(false);
//            } else {
//                if (check == 1) {
//                    holder.check_iv.setVisibility(View.VISIBLE);
//                } else {
//                    holder.check_iv.setVisibility(View.INVISIBLE);
//                }
//                holder.drag_iv.setFocusable(false);
//                holder.drag_iv.setClickable(false);
//                holder.drag_iv.setVisibility(View.INVISIBLE);
//            }

            return convertView;
        }

        @Override
        public void insert(Object object,int position) {

            int count = getCount();

            mDirty = true;
            if (position >= count) {
                if (position > count) {
                    position = count;
                }

                JSONObject val_json = (JSONObject)object;
                try {
                    mCadedate.put("val_" + position, val_json);
                    mCadedate.put("count", count+1);
                } catch (JSONException e) {
                    e.printStackTrace();
                }


            } else {
                if (position < 0) {
                    position = 0;
                }

                try {
                    for (int i = count - 1; i >= position; i--) {
                        JSONObject val_json = mCadedate.getJSONObject("val_" + i);
                        mCadedate.put("val_" + (i + 1),val_json);
                    }

                    JSONObject val_json = (JSONObject)object;
                    mCadedate.put("val_" + position, val_json);
                    mCadedate.put("count", count+1);

                } catch (JSONException e) {
                    e.printStackTrace();
                }

            }
        }

        @Override
        public void remove(Object object) {

            int count = getCount();
            if (count <= 0) {
                return;
            }

            mDirty = true;
            try {
                int remove_index = count;
                for (int i = 0; i < count; i++) {
                    JSONObject val_json = mCadedate.getJSONObject("val_" + i);
                    if (val_json.equals(object)) {
                        remove_index = i;
                    }
                    if (remove_index < count) { // 有删除
                        if (i > remove_index) {
                            mCadedate.put("val_" + (i - 1),val_json);
                        }

                        if (i == count - 1) { // 清除末尾
                            mCadedate.put("val_" + i,null);
                        }
                        mCadedate.put("count",count - 1);
                    }
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }

        }
    }



}
