package kr.co.hanwha.hifive.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import android.text.Editable;
import android.text.InputFilter;
import android.text.InputType;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import java.io.UnsupportedEncodingException;

import kr.co.hanwha.hifive.R;

/**
 * Created by sanghoonkwon on 2018. 1. 24..
 */

public class HFAlertEditTextView extends LinearLayout {
    private TextView mTextViewTitle;
    private EditText mEditText;
    private LinearLayout mLayoutAlert;
    private TextView mTextViewAlert;
    private ImageView mImageViewAlert;
    private ImageButton mImageButtonClear;
    private ImageButton mImageButtonEye;
    private View mViewLine;

    private OnAlertEditTextListener onAlertEditTextListener;

    private boolean mClearVisible = false;
    private boolean mPasswordVisible = false;
    private boolean mEyeVisible = false;

    private String mLastText = "";
    private int mLimitLength = 0;

    public void setOnAlertEditTextListener(OnAlertEditTextListener onAlertEditTextListener) {
        this.onAlertEditTextListener = onAlertEditTextListener;
    }

    public HFAlertEditTextView(Context context) {
        super(context);
        initialize(context, null);
    }

    public HFAlertEditTextView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initialize(context, attrs);
    }

    public HFAlertEditTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initialize(context, attrs);
    }

    private void initialize(Context context, @Nullable AttributeSet attrs) {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        inflater.inflate(R.layout.view_hf_alert_edittext, this, true);

        if (isInEditMode()) return;

        mTextViewTitle = (TextView) findViewById(R.id.title_textView);
        mEditText = (EditText) findViewById(R.id.editText);
        mLayoutAlert = (LinearLayout) findViewById(R.id.alert_linearLayout);
        mTextViewAlert = (TextView) findViewById(R.id.alert_textView);
        mImageViewAlert = (ImageView) findViewById(R.id.alert_imageView);
        mImageButtonClear = (ImageButton) findViewById(R.id.clear_imageButton);
        mImageButtonEye = (ImageButton) findViewById(R.id.eye_imageButton);
        mViewLine = (View) findViewById(R.id.line_view);

        mEditText.setOnEditorActionListener(onEditorActionListener);
        mEditText.addTextChangedListener(textWatcher);
        mEditText.setOnFocusChangeListener(onFocusChangeListener);

        mImageButtonClear.setOnClickListener(onClickListener);
        mImageButtonEye.setOnClickListener(onClickListener);


        if (attrs != null) {
            TypedArray type = null;
            try {
                type = context.obtainStyledAttributes(attrs, R.styleable.AlertEditText);

                String title = type.getString(R.styleable.AlertEditText_editTitle);
                if (TextUtils.isEmpty(title)) {
                    mTextViewTitle.setVisibility(View.GONE);
                } else {
                    mTextViewTitle.setVisibility(View.VISIBLE);
                    mTextViewTitle.setText(title);
                }

                mClearVisible = type.getBoolean(R.styleable.AlertEditText_clearButton, false);
                mImageButtonClear.setVisibility(mClearVisible ? View.VISIBLE : View.GONE);

                mEyeVisible = type.getBoolean(R.styleable.AlertEditText_eyeButton, false);
                mImageButtonEye.setVisibility(mEyeVisible ? View.VISIBLE : View.GONE);

                String hint = type.getString(R.styleable.AlertEditText_editHint);
                if (TextUtils.isEmpty(hint) == false)
                    mEditText.setHint(hint);

                boolean focusable = type.getBoolean(R.styleable.AlertEditText_focusable, true);
                mEditText.setFocusable(focusable);

                String inputType = type.getString(R.styleable.AlertEditText_inputType);
                if (TextUtils.isEmpty(inputType) == false) {
                    if ("textEmailAddress".equals(inputType))
                        mEditText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS);
                    else if ("phone".equals(inputType))
                        mEditText.setInputType(InputType.TYPE_CLASS_PHONE);
                    else if ("numberSigned".equals(inputType))
                        mEditText.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_SIGNED);
                    else if ("password".equals(inputType)) {
                        mEditText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
                    } else if ("numberPassword".equals(inputType)) {
                        mEditText.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_VARIATION_PASSWORD);
                    } else
                        mEditText.setInputType(InputType.TYPE_CLASS_TEXT);
                } else {
                    mEditText.setInputType(InputType.TYPE_CLASS_TEXT);
                }

                String imeOptions = type.getString(R.styleable.AlertEditText_imeOptions);
                if (TextUtils.isEmpty(imeOptions) == false) {
                    if ("actionDone".equals(imeOptions))
                        mEditText.setImeOptions(EditorInfo.IME_ACTION_DONE);
                }

                int maxLength = type.getInteger(R.styleable.AlertEditText_maxLength, 0);
                if (maxLength > 0)
                    setLengthLimit(20);

                boolean lineInvisible = type.getBoolean(R.styleable.AlertEditText_lineInvisible, false);
                mViewLine.setVisibility(lineInvisible ? View.INVISIBLE : View.VISIBLE);

            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (type != null) type.recycle();
            }
        }
    }

    public String getText() {
        return mEditText.getText().toString();
    }

    public void clearText() {
        mEditText.setText("");
    }

    public void setText(@Nullable String text) {
        if (text != null) {
            mEditText.setText(text);
        }
    }

    public boolean setFocus() {
        return mEditText.requestFocus();
    }

    public void setEmailHint(@NonNull String domain) {
        if (TextUtils.isEmpty(domain) == false) {
            mEditText.setText(domain);
            mEditText.setSelection(0);
        }
    }

    public void setSelection(int index) {
        mEditText.setSelection(index);
    }

    /**
     * 바이트로 길이 제한
     *
     * @param byteLength 최대 바이트
     */
    public void setLengthLimitByte(int byteLength) {
        mLimitLength = byteLength;
    }

    /**
     * 문자열 길이 제한
     *
     * @param length 문자열 최대 길이
     */
    public void setLengthLimit(int length) {
        InputFilter[] filters = new InputFilter[1];
        filters[0] = new InputFilter.LengthFilter(length);
        mEditText.setFilters(filters);
    }

    /**
     * 문자열 바이트 길이
     *
     * @param str 문자열
     * @return Length
     */
    private int getByteLength(String str) {
        try {
            return str.getBytes("KSC5601").length;
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return 0;
    }

    /**
     * Alert Message
     *
     * @param message Alert Message From String
     */
    public void setAlertMessage(@Nullable String message) {
        if (TextUtils.isEmpty(message)) {
            if (mEyeVisible) mImageButtonEye.setVisibility(View.VISIBLE);
            if (mClearVisible) mImageButtonClear.setVisibility(View.VISIBLE);

            mTextViewAlert.setText("");
            mLayoutAlert.setVisibility(View.GONE);
            mImageViewAlert.setVisibility(View.GONE);
            mViewLine.setBackgroundColor(ContextCompat.getColor(getContext(), R.color.black));
        } else {
            mImageButtonEye.setVisibility(View.GONE);
            mImageButtonClear.setVisibility(View.GONE);

            mTextViewAlert.setText(message);
            mLayoutAlert.setVisibility(View.VISIBLE);
            mImageViewAlert.setVisibility(View.VISIBLE);
            mViewLine.setBackgroundColor(ContextCompat.getColor(getContext(), R.color.hf_red03));
        }
    }

    /**
     * Alert Message
     *
     * @param strRes Alert Message From Resource
     */
    public void setAlertMessage(@NonNull int strRes) {
        setAlertMessage(getContext().getString(strRes));
    }

    /**
     * 데이터 확인
     *
     * @return TRUE : EMPTY
     */
    public boolean isEmpty() {
        return (TextUtils.isEmpty(getText()));
    }

    /**************************************************
     * OnClickListener
     **************************************************/
    OnClickListener onClickListener = new OnClickListener() {
        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.clear_imageButton:
                    mEditText.setText("");
                    break;
                case R.id.eye_imageButton:
                    mPasswordVisible = !mPasswordVisible;
                    if (mPasswordVisible) {
//                        mEditText.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_SIGNED);
//                        mEditText.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);
                        mEditText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);
                        mEditText.setSelection(getText().length());
                    } else {
//                        mEditText.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_VARIATION_PASSWORD);
                        mEditText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
                        mEditText.setSelection(getText().length());
                    }
                    mImageButtonEye.setSelected(mPasswordVisible);
                    break;
            }
        }
    };

    /**************************************************
     * OnFocusChangeListener
     **************************************************/
    OnFocusChangeListener onFocusChangeListener = new OnFocusChangeListener() {
        @Override
        public void onFocusChange(View view, boolean b) {
            if (onAlertEditTextListener != null)
                onAlertEditTextListener.onFocusChange(HFAlertEditTextView.this, b);
        }
    };

    /**************************************************
     * TextView.OnEditorActionListener
     **************************************************/
    TextView.OnEditorActionListener onEditorActionListener = new TextView.OnEditorActionListener() {
        @Override
        public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
            if (actionId == EditorInfo.IME_ACTION_NEXT) {
                if (onAlertEditTextListener != null)
                    onAlertEditTextListener.onImeActionNext(HFAlertEditTextView.this);
                return true;
            } else if (actionId == EditorInfo.IME_ACTION_DONE) {
                ((InputMethodManager) mEditText.getContext().getSystemService(Context.INPUT_METHOD_SERVICE))
                        .hideSoftInputFromWindow(mEditText.getWindowToken(), 0);
            }
            return false;
        }
    };

    /**************************************************
     * EditText - TextWatcher
     **************************************************/
    TextWatcher textWatcher = new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            mLastText = s.toString();
        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            if (s.length() > 0 && mClearVisible) {
                mImageButtonClear.setVisibility(VISIBLE);
            } else {
                mImageButtonClear.setVisibility(GONE);
            }
        }

        @Override
        public void afterTextChanged(Editable s) {
            if (onAlertEditTextListener != null)
                onAlertEditTextListener.onValueChanged(HFAlertEditTextView.this);

            if (mLimitLength > 0) {
                if (mLimitLength < getByteLength(s.toString())) {
                    mEditText.setText(mLastText);
                    mEditText.setSelection(mLastText.length());
                } else {
                    mLastText = s.toString();
                }
            }
        }
    };

    /**************************************************
     * OnAlertEditTextListener
     **************************************************/
    public interface OnAlertEditTextListener {
        void onFocusChange(@NonNull HFAlertEditTextView v, boolean b);

        void onImeActionNext(@NonNull HFAlertEditTextView v);

        void onValueChanged(@NonNull HFAlertEditTextView v);
    }
}
