package co.pixelbeard.theanfieldwrap.customView;

import android.animation.Animator;
import android.animation.TimeInterpolator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.annotation.RequiresApi;
import androidx.core.content.ContextCompat;

import com.google.android.material.textfield.TextInputLayout;

import co.pixelbeard.theanfieldwrap.R;

/**
 * Created by Michael Stoddart
 * 25/09/2018.
 */
public class PBInputField extends LinearLayout {

    private LinearLayout llParent;
    private TextView txtTooltip;
    private TextInputLayout textInputLayout;
    private EditText editText;
    private ImageView imgIcon;
    private View underline;

    private Context mContext;

    private int mTooltipTextColor = 0;
    private int mToolTipTextPadding = 0;
    private int mToolTipBackground = 0;

    private int mEtTextSize = 0;
    private int mEtTextColor = 0;
    private int mEtTextColorHint = 0;
    private String mEtTextHint = "";
    private String mEtText = "";

    private int mUnderlineColor = 0;
    private boolean mUnderlineVisible = true;
    private int mUnderlineErrorColor = 0;
    private int mUnderlineAcceptColor = 0;
    private boolean mIconVisible = true;

    private Drawable mRegIcon = null;
    private Drawable mErrorIcon = null;
    private Drawable mAcceptIcon = null;

    private boolean error = false, accepted = false;

    public PBInputField(Context context) {
        super(context);
        this.mContext = context;
        init(null);
    }

    public PBInputField(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.mContext = context;
        init(attrs);
    }

    public PBInputField(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.mContext = context;
        init(attrs);
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public PBInputField(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        this.mContext = context;
        init(attrs);
    }

    private void init(AttributeSet attrs) {

        initView();
        parseAttributes(attrs);

        setData();
    }

    private void initView() {
        LayoutInflater inflater;
        inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        View mView = inflater.inflate(R.layout.pb_input_field, this);

        llParent = mView.findViewById(R.id.ll_parent);
        txtTooltip = mView.findViewById(R.id.txt_tooltip);
        textInputLayout = mView.findViewById(R.id.text_input);
        editText = mView.findViewById(R.id.edittext);
        imgIcon = mView.findViewById(R.id.img_icon);
        underline = mView.findViewById(R.id.underline);

    }

    private void parseAttributes(AttributeSet attrs) {
        TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.PBInputField, 0, 0);

        try {

            mTooltipTextColor = a.getInteger(R.styleable.PBInputField_tooltipTextColor, Color.WHITE);
            mToolTipTextPadding = a.getDimensionPixelSize(R.styleable.PBInputField_tooltipTextPadding, 0);
            mToolTipBackground = a.getInteger(R.styleable.PBInputField_tooltipBackground, Color.RED);

            mEtTextSize = a.getDimensionPixelSize(R.styleable.PBInputField_etTextSize, 0);
            mEtTextColor = a.getInteger(R.styleable.PBInputField_etTextColor, Color.BLACK);
            mEtTextColorHint = a.getInteger(R.styleable.PBInputField_etTextColorHint, Color.BLACK);
            mEtText = a.getString(R.styleable.PBInputField_etText);
            mEtTextHint = a.getString(R.styleable.PBInputField_etTextHint);

            mUnderlineColor = a.getInteger(R.styleable.PBInputField_underlineColor, Color.GRAY);
            mUnderlineErrorColor = a.getInteger(R.styleable.PBInputField_underlineErrorColor, Color.RED);
            mUnderlineAcceptColor = a.getInteger(R.styleable.PBInputField_underlineAcceptColor, Color.GREEN);
            mUnderlineVisible = a.getBoolean(R.styleable.PBInputField_underlineVisible, true);

            mIconVisible = a.getBoolean(R.styleable.PBInputField_iconVisible, true);

            mRegIcon = a.getDrawable(R.styleable.PBInputField_regIcon);
            mErrorIcon = a.getDrawable(R.styleable.PBInputField_errorIcon);
            mAcceptIcon = a.getDrawable(R.styleable.PBInputField_acceptIcon);
        } finally {
            a.recycle();
        }
    }

    private void setData() {
        txtTooltip.setTextColor(mTooltipTextColor);
        txtTooltip.setPadding(mToolTipTextPadding, mToolTipTextPadding, mToolTipTextPadding, mToolTipTextPadding);
        txtTooltip.setBackgroundColor(mToolTipBackground);

        editText.setTextSize(TypedValue.COMPLEX_UNIT_PX, mEtTextSize);
        editText.setTextColor(mEtTextColor);
        editText.setHintTextColor(mEtTextColorHint);
        if (mEtText != null) {
            editText.setText(mEtText);
        }

        if (mEtTextHint != null) {
            textInputLayout.setHint(mEtTextHint);
        }

        underline.setBackgroundColor(mUnderlineColor);

        if (!mUnderlineVisible) {
            underline.setVisibility(INVISIBLE);
        }

        if (!mIconVisible) {
            imgIcon.setVisibility(GONE);
        } else {
            imgIcon.setVisibility(VISIBLE);
        }

        imgIcon.setImageDrawable(mRegIcon);

        editText.setOnFocusChangeListener((v, hasFocus) -> {
            if (hasFocus) {
                underline.setBackgroundColor(ContextCompat.getColor(mContext, R.color.black1B1B1B));
            } else {
                underline.setBackgroundColor(mUnderlineColor);

            }
        });
    }


    public void showError(String errorText) {
        error = true;
        txtTooltip.setText(errorText);
        txtTooltip.setVisibility(VISIBLE);
        animateError(txtTooltip);
        imgIcon.setImageDrawable(mErrorIcon);
        underline.setBackgroundColor(mUnderlineErrorColor);
        editText.setHint("");
        textInputLayout.setHint("");
    }

    private void animateError(final View view) {
        final float FREQ = 3f;
        final float DECAY = 2f;
        // interpolator that goes 1 -> -1 -> 1 -> -1 in a sine wave pattern.
        TimeInterpolator decayingSineWave = input -> {
            double raw = Math.sin(FREQ * input * 2 * Math.PI);
            return (float) (raw * Math.exp(-input * DECAY));
        };

        view.animate()
                .xBy(-20)
                .setInterpolator(decayingSineWave)
                .setDuration(500).setListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {
                view.setTranslationX(0);
            }

            @Override
            public void onAnimationEnd(Animator animation) {
                view.setTranslationX(0);
            }

            @Override
            public void onAnimationCancel(Animator animation) {
            }

            @Override
            public void onAnimationRepeat(Animator animation) {
            }
        }).start();
    }

    public void resetError() {
        if (error || accepted) {
            error = false;
            accepted = false;
            txtTooltip.setVisibility(INVISIBLE);
            textInputLayout.setHint(mEtTextHint);
            imgIcon.setImageDrawable(mRegIcon);
            underline.setBackgroundColor(mUnderlineColor);
        }
    }

    public void showAcceptedState() {
        accepted = true;
        txtTooltip.setVisibility(INVISIBLE);
        textInputLayout.setHint(mEtTextHint);
        imgIcon.setImageDrawable(mAcceptIcon);
        underline.setBackgroundColor(mUnderlineAcceptColor);
    }

    public void setInputType(int inputType) {
        editText.setInputType(inputType);
    }

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

    public void setText(String s) {
        mEtText = s;
        editText.setText(s);
    }

    public void disable() {
        editText.setEnabled(false);
        textInputLayout.setEnabled(false);
        txtTooltip.setEnabled(false);
        editText.setFocusable(false);
        editText.setFocusableInTouchMode(false);
        txtTooltip.setFocusable(false);
        txtTooltip.setFocusableInTouchMode(false);
        textInputLayout.setFocusable(false);
        textInputLayout.setFocusableInTouchMode(false);
    }

    public void enable() {
        editText.setEnabled(false);
        textInputLayout.setEnabled(false);
        txtTooltip.setEnabled(false);
        editText.setFocusable(false);
        editText.setFocusableInTouchMode(false);
        txtTooltip.setFocusable(false);
        txtTooltip.setFocusableInTouchMode(false);
        textInputLayout.setFocusable(false);
        textInputLayout.setFocusableInTouchMode(false);
    }

    public void setTextWatcher(TextWatcher watcher) {
        editText.addTextChangedListener(watcher);
    }

    public void setIconClickListener(OnClickListener listener) {
        imgIcon.setOnClickListener(listener);
    }

    public void setImeActionListener(TextView.OnEditorActionListener listener) {
        editText.setOnEditorActionListener(listener);
    }

    public void requestTheFocus() {
        editText.requestFocus();
    }

    public void setSingleLine(boolean singleLine) {
        editText.setSingleLine(singleLine);
    }

    public void setTooltipTypeface(Typeface typeface) {
        txtTooltip.setTypeface(typeface);
    }

    public void setEditTextTypeface(Typeface typeface) {
        editText.setTypeface(typeface);
    }

    public void setTextInputTypeface(Typeface typeface) {
        textInputLayout.setTypeface(typeface);
    }

    public void setTooltipTextColor(int mTooltipTextColor) {
        this.mTooltipTextColor = mTooltipTextColor;
        txtTooltip.setTextColor(mTooltipTextColor);
    }

    public void setToolTipTextPadding(int mToolTipTextPadding) {
        this.mToolTipTextPadding = mToolTipTextPadding;
        txtTooltip.setPadding(mToolTipTextPadding, mToolTipTextPadding, mToolTipTextPadding, mToolTipTextPadding);
    }

    public void setToolTipBackground(int mToolTipBackground) {
        this.mToolTipBackground = mToolTipBackground;
        txtTooltip.setBackgroundResource(mToolTipBackground);
    }

    public void setEtTextSize(int mEtTextSize) {
        this.mEtTextSize = mEtTextSize;
        editText.setTextSize(mEtTextSize);
    }

    public void setEtTextColorHint(int textColorHint) {
        this.mEtTextColorHint = textColorHint;
        editText.setHintTextColor(textColorHint);
//        textInputLayout.setColor
    }

    public void setEtTextColor(int mEtTextColor) {
        this.mEtTextColor = mEtTextColor;
        editText.setTextColor(mEtTextColor);
    }

    public void setEtTextHint(String mEtTextHint) {
        this.mEtTextHint = mEtTextHint;
        editText.setHint(mEtTextHint);
        textInputLayout.setHint(mEtTextHint);
    }

    public void setUnderlineColor(int mUnderlineColor) {
        this.mUnderlineColor = mUnderlineColor;
        underline.setBackgroundResource(mUnderlineColor);
    }

    public void setUnderlineVisible(boolean mUnderlineVisible) {
        this.mUnderlineVisible = mUnderlineVisible;
        if (mUnderlineVisible) {
            underline.setVisibility(VISIBLE);
        } else {
            underline.setVisibility(INVISIBLE);
        }
    }

    public EditText getEditText() {
        return editText;
    }

//    @Override
//    public void setOnClickListener(@Nullable OnClickListener l) {
////        super.setOnClickListener(l);
//        llParent.setClickable(true);
//        llParent.setOnClickListener(l);
//        txtTooltip.setOnClickListener(l);
//        textInputLayout.setOnClickListener(l);
//        editText.setOnClickListener(l);
//        imgIcon.setOnClickListener(l);
//        underline.setOnClickListener(l);
//    }

    public void setUnderlineErrorColor(int mUnderlineErrorColor) {
        this.mUnderlineErrorColor = mUnderlineErrorColor;
    }

    public void setUnderlineAcceptColor(int mUnderlineAcceptColor) {
        this.mUnderlineAcceptColor = mUnderlineAcceptColor;
    }

    public void setIconVisible(boolean mIconVisible) {
        this.mIconVisible = mIconVisible;

        if (mIconVisible) {
            imgIcon.setVisibility(VISIBLE);
        } else {
            imgIcon.setVisibility(INVISIBLE);
        }
    }

    public void setRegIcon(Drawable mRegIcon) {
        this.mRegIcon = mRegIcon;
        imgIcon.setImageDrawable(mRegIcon);
    }

    public void setErrorIcon(Drawable mErrorIcon) {
        this.mErrorIcon = mErrorIcon;
    }

    public void setAcceptIcon(Drawable mAcceptIcon) {
        this.mAcceptIcon = mAcceptIcon;
    }
}

