package com.yidianling.consultant.ui.behavior;

import android.animation.Animator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.GradientDrawable;
import com.google.android.material.appbar.AppBarLayout;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
import androidx.core.view.ViewCompat;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.OverScroller;
import android.widget.RelativeLayout;
import com.ydl.ydlcommon.utils.ColorCalculateUtils;
import com.ydl.ydlcommon.utils.DisplayUtils;
import com.yidianling.consultant.ui.view.DisInterceptNestedScrollView;

import java.lang.reflect.Field;

/**
 * Created by haorui on 2019/3/2.
 * Des:
 */
public class SearchAppBarLayoutBehavior extends AppBarLayout.Behavior {
    private static final String TAG = "overScroll";
    private static final String TAG_TOOLBAR = "toolbar";
    private static final String TAG_TOOLBAR_BG = "toolbar_bg";
    private static final String TAG_TOOLBAR_BG_MASK = "toolbar_bg_mask";
    private static final String TAG_MIDDLE_BUT = "middle_but_layout";
    private static final String TAG_SEARCH_INPUT = "tag_search_input";
    private static final String TAG_SEARCH_INPUT_BG = "tag_search_input_bg";
    private static final String TAG_SEARCH_INPUT_EDIT = "tag_search_input_edit";
    private static final String TAG_SEARCH_INPUT_IMG = "tag_search_input_img";
    private static final float TARGET_HEIGHT = 2500;
    private View mTargetView;
    private int mParentHeight;
    private int mTargetViewHeight;
    private float mTotalDy;
    private float mLastScale;
    private int mLastBottom;
    private boolean isAnimate;
    private View mToolBarBg;
    private ViewGroup middleLayout;//咨询按钮布局
    private RelativeLayout inputLayout;//输入框布局
    private int mMiddleHeight;
    private boolean isRecovering = false;//是否正在自动回弹中

    private float INPUT_LEFT_OFFSET ;//52dp - 15dp
    private float INPUT_RIGHT_OFFSET ;//38dp - 15dp
    private float INPUT_HEIGHT_OFFSET ;//44dp - 32dp
    private float INPUT_ORIGIN_HEIGHT;
    private int inputOriginMargin;


    private View inputLayoutBg;
    private GradientDrawable inputBgDrawable;
    private EditText inputLayoutEdit;
    private ImageView inputLayoutImg;
    private OverScroller mScroller1;
    private float mInputLastScale ;
    private CoordinatorLayout.LayoutParams mLayoutParams;

    private static final int TOP_CHILD_FLING_THRESHOLD = 3;
    private boolean isPositive;
    private View mToolBarBgMask;

    public SearchAppBarLayoutBehavior() {

    }

    public SearchAppBarLayoutBehavior(Context context, AttributeSet attrs) {
        super(context, attrs);
        INPUT_LEFT_OFFSET = DisplayUtils.dp2px(context,23);
        INPUT_RIGHT_OFFSET = DisplayUtils.dp2px(context,37);
        INPUT_HEIGHT_OFFSET = DisplayUtils.dp2px(context,11);
        INPUT_ORIGIN_HEIGHT = DisplayUtils.dp2px(context,44);

        //解决 AppBarLayout v26 弹回Bug
        bindScrollerValue(context);
    }


    @Override
    public boolean onLayoutChild(CoordinatorLayout parent, AppBarLayout abl, int layoutDirection) {
        boolean handled = super.onLayoutChild(parent, abl, layoutDirection);

        if (mToolBarBg == null) {
            mToolBarBg = (View) parent.findViewWithTag(TAG_TOOLBAR_BG);
            mToolBarBgMask = (View) parent.findViewWithTag(TAG_TOOLBAR_BG_MASK);
        }

        if (middleLayout == null) {
            middleLayout = (ViewGroup) parent.findViewWithTag(TAG_MIDDLE_BUT);
        }

        if (inputLayout == null) {
            inputLayout = (RelativeLayout) parent.findViewWithTag(TAG_SEARCH_INPUT);
            inputLayoutBg = parent.findViewWithTag(TAG_SEARCH_INPUT_BG);
            inputLayoutEdit = (EditText) parent.findViewWithTag(TAG_SEARCH_INPUT_EDIT);
            inputLayoutImg = (ImageView) parent.findViewWithTag(TAG_SEARCH_INPUT_IMG);

            inputBgDrawable = (GradientDrawable) inputLayoutBg.getBackground();
            mLayoutParams = (CoordinatorLayout.LayoutParams) inputLayout.getLayoutParams();
            inputOriginMargin = mLayoutParams.leftMargin;
        }

        if (mTargetView == null) {
            mTargetView = parent.findViewWithTag(TAG);
            if (mTargetView != null) {
                initial(abl);
            }
        }

        abl.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {


            @Override
            public final void onOffsetChanged(AppBarLayout appBarLayout, int i) {
                float scale =  Float.valueOf(Math.abs(i)) / Float.valueOf(appBarLayout.getTotalScrollRange());
                mToolBarBg.setAlpha( scale);
                mToolBarBgMask.setAlpha(1- scale);

                inputLayoutBg.setAlpha((float) (1- (0.8*scale)));

                float feltMargin =  inputOriginMargin + (INPUT_LEFT_OFFSET*scale);
                float rightMargin =  inputOriginMargin + (INPUT_RIGHT_OFFSET*scale);
                mLayoutParams.setMargins((int)feltMargin,0,(int) rightMargin,0);
                mLayoutParams.height = (int) (INPUT_ORIGIN_HEIGHT - (scale*INPUT_HEIGHT_OFFSET));
                inputLayout.setLayoutParams(mLayoutParams);

                //设置圆角
                inputBgDrawable.setCornerRadius(12+(40*scale));
                if(Math.abs(scale-mInputLastScale)>0.25) {
                    //设置字体/图标颜色 4次
                    inputLayoutEdit.setHintTextColor(Color.parseColor(ColorCalculateUtils.calculateColor("#FFB3B3B3","#A4FFFFFF",scale)));
                    inputLayoutImg.setColorFilter(Color.parseColor(ColorCalculateUtils.calculateColor("#FFB3B3B3","#FFFFFFFF",scale)));
                    inputLayoutEdit.setTextColor(Color.parseColor(ColorCalculateUtils.calculateColor("#FF444444","#A4FFFFFF",scale)));
                    mInputLastScale  = scale;
                }
                inputLayoutImg.setAlpha((float) (1- (0.4*scale)));
            }

        });
        return handled;
    }

    @Override
    public boolean onStartNestedScroll(CoordinatorLayout parent, AppBarLayout child, View directTargetChild, View target, int nestedScrollAxes, int type) {
        isAnimate = true;
        if (target instanceof DisInterceptNestedScrollView)
            return true;//middleLayout
        return super.onStartNestedScroll(parent, child, directTargetChild, target, nestedScrollAxes,type);
    }

    /**
     * 解决CoordinatorLayout v26 滑动卡顿
     */
    //    @Override
    //    public boolean onNestedFling(@NonNull CoordinatorLayout coordinatorLayout, @NonNull AppBarLayout child, @NonNull View target, float velocityX, float velocityY, boolean consumed) {
    //        if (velocityY > 0 && !isPositive || velocityY < 0 && isPositive) {
    //            velocityY = velocityY * -1;
    //        }
    //        if (target instanceof RecyclerView && velocityY < 0) {
    //            final RecyclerView recyclerView = (RecyclerView) target;
    //            final View firstChild = recyclerView.getChildAt(0);
    //            final int childAdapterPosition = recyclerView.getChildAdapterPosition(firstChild);
    //            consumed = childAdapterPosition > TOP_CHILD_FLING_THRESHOLD;
    //        }
    //        return super.onNestedFling(coordinatorLayout, child, target, velocityX, velocityY, consumed);
    //    }

    /**
     * 解决 AppBarLayout v26 弹回Bug
     * 反射注入Scroller以获取其引用
     *
     * @param context
     */
    private void bindScrollerValue(Context context) {
        if (mScroller1 != null) return;
        mScroller1 = new OverScroller(context);
        try {
            Class<?> clzHeaderBehavior = getClass().getSuperclass().getSuperclass();
            Field fieldScroller = clzHeaderBehavior.getDeclaredField("mScroller");
            fieldScroller.setAccessible(true);
            fieldScroller.set(this, mScroller1);
        } catch (Exception e) {}
    }

    @Override
    public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, int dx, int dy, int[] consumed, int type) {
        // 解决CoordinatorLayout滑动卡顿
        // isPositive = dy > 0;

        // 解决 AppBarLayout v26 弹回Bug
        if (type == ViewCompat.TYPE_NON_TOUCH) {
            //fling上滑appbar然后迅速fling下滑list时, HeaderBehavior的mScroller并未停止, 会导致上下来回晃动
            if (mScroller1.computeScrollOffset()) {
                mScroller1.abortAnimation();
            }
            //当target滚动到边界时主动停止target fling,与下一次滑动产生冲突
            if (getTopAndBottomOffset() == 0) {
                ViewCompat.stopNestedScroll(target, type);
            }
        }

        if(dy>0 && mTotalDy>0) {
            //防止来回滑动抬起时布局错位
            mTotalDy = 0;
        }
        if (!isRecovering) {
            if (mTargetView != null
                    //此处过滤掉fling滑动事件
                    && (dy < 0 && child.getBottom() >= mParentHeight && type== ViewCompat.TYPE_TOUCH)
            ) {
                //放大回弹
                scale(child, target, dy);
                return;
            }
        }
        super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type);

    }

    @Override
    public boolean onNestedPreFling(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, float velocityX, float velocityY) {
        if (velocityY > 100) {
            isAnimate = false;
        }
        return super.onNestedPreFling(coordinatorLayout, child, target, velocityX, velocityY);
    }

    @Override
    public void onStopNestedScroll(CoordinatorLayout coordinatorLayout, AppBarLayout abl, View target, int type) {
        recovery(abl);
        super.onStopNestedScroll(coordinatorLayout, abl, target, type);
    }

    private void initial(AppBarLayout abl) {
        abl.setClipChildren(false);
        mParentHeight = abl.getHeight();
        mTargetViewHeight = mTargetView.getHeight();
        mMiddleHeight = middleLayout.getHeight();
    }

    private void scale(AppBarLayout abl, View target, int dy) {
        mTotalDy += -dy;
        mTotalDy = Math.min(mTotalDy, TARGET_HEIGHT);
        mLastScale = Math.max(1f, 1f + mTotalDy / TARGET_HEIGHT);
        mTargetView.setScaleX(mLastScale);
        mTargetView.setScaleY(mLastScale);
        mLastBottom = mParentHeight + (int) (mTargetViewHeight / 2 * (mLastScale - 1));
        abl.setBottom(mLastBottom);
        target.setScrollY(0);
        middleLayout.setTop(mLastBottom - mMiddleHeight);
        middleLayout.setBottom(mLastBottom);
    }

    private void recovery(final AppBarLayout abl) {
        if (isRecovering)
            return;
        if (mTotalDy > 0) {
            isRecovering = true;
            mTotalDy = 0;
            if (isAnimate) {
                ValueAnimator anim = ValueAnimator.ofFloat(mLastScale, 1f).setDuration(200);
                anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator animation) {
                        float value = (float) animation.getAnimatedValue();
                        mTargetView.setScaleX(value);
                        mTargetView.setScaleY(value);
                        abl.setBottom((int) (mLastBottom - (mLastBottom - mParentHeight) * animation.getAnimatedFraction()));
                        middleLayout.setTop((int) (mLastBottom - (mLastBottom - mParentHeight) * animation.getAnimatedFraction() - mMiddleHeight));
                    }
                });
                anim.addListener(new Animator.AnimatorListener() {
                    @Override
                    public void onAnimationStart(Animator animation) {
                    }

                    @Override
                    public void onAnimationEnd(Animator animation) {
                        isRecovering = false;
                    }

                    @Override
                    public void onAnimationCancel(Animator animation) {
                    }

                    @Override
                    public void onAnimationRepeat(Animator animation) {
                    }
                });
                anim.start();
            } else {
                mTargetView.setScaleX(1f);
                mTargetView.setScaleY(1f);

                abl.setBottom(mParentHeight);
                middleLayout.setTop(mParentHeight - mMiddleHeight);
                middleLayout.setBottom(mParentHeight);
                isRecovering = false;
            }
        }
    }
}