package it.integry.integrywmsnative.view.bottom_sheet__base;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.constraintlayout.widget.ConstraintLayout;

import com.google.android.material.bottomsheet.BottomSheetBehavior;

import it.integry.integrywmsnative.core.utility.UtilityLogger;
import it.integry.integrywmsnative.view.bottom_sheet__base.exceptions.BottomSheetFragmentViewNotInitializedException;

public abstract class BottomSheetFragmentBaseView extends ConstraintLayout {

    protected Context mContext;
    protected View parentView;

    protected BottomSheetBehavior mBottomSheetBehavior;

    public BottomSheetFragmentBaseView(Context context) {
        this(context, null);
    }

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

    public BottomSheetFragmentBaseView(Context context, AttributeSet attrs, int defStyleAttr) {
        this(context, attrs);
    }

    public BottomSheetFragmentBaseView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        this(context, attrs);
    }


    public void init(View view, View backgroundView) {
        this.parentView = view;
        this.mBottomSheetBehavior = BottomSheetBehavior.from(this.parentView);

        this.mBottomSheetBehavior.addBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
            @Override
            public void onStateChanged(@NonNull View bottomSheet, int newState) {
                if (newState == BottomSheetBehavior.STATE_COLLAPSED && backgroundView != null)
                    backgroundView.setVisibility(View.GONE);

                onStateChangedCallback(mapState(newState));
            }

            @Override
            public void onSlide(@NonNull View bottomSheet, float slideOffset) {
                if(backgroundView != null) {
                    backgroundView.setVisibility(View.VISIBLE);
                    backgroundView.setAlpha(slideOffset);
                }

                onSlideCallback(1 - slideOffset);
            }
        });
    }

    public void expand() {
        if(this.mBottomSheetBehavior == null) {
            UtilityLogger.errorMe(new BottomSheetFragmentViewNotInitializedException());
            return;
        }

        this.mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
    }

    public void collapse() {
        if(this.mBottomSheetBehavior == null) {
            UtilityLogger.errorMe(new BottomSheetFragmentViewNotInitializedException());
            return;
        }

        this.mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
    }

    public boolean isExpanded() {
        return this.getState() == State.EXPANDED;
    }

    public boolean isCollapsed() {
        return this.getState() == State.COLLAPSED;
    }


    public State getState() {
        if(this.mBottomSheetBehavior == null) {
            UtilityLogger.errorMe(new BottomSheetFragmentViewNotInitializedException());
            return null;
        }

        return mapState(this.mBottomSheetBehavior.getState());
    }

    public void toggle() {
        if(isExpanded()) collapse();
        else expand();
    }

    protected State mapState(int stateInt) {
        if(stateInt == BottomSheetBehavior.STATE_DRAGGING) return State.DRAGGING;
        if(stateInt == BottomSheetBehavior.STATE_SETTLING) return State.SETTLING;
        if(stateInt == BottomSheetBehavior.STATE_EXPANDED) return State.EXPANDED;
        if(stateInt == BottomSheetBehavior.STATE_COLLAPSED) return State.COLLAPSED;
        if(stateInt == BottomSheetBehavior.STATE_HIDDEN) return State.HIDDEN;
        if(stateInt == BottomSheetBehavior.STATE_HALF_EXPANDED) return State.HALF_EXPANDED;

        return null;
    }

    protected abstract void onStateChangedCallback(State newState);

    protected abstract void onSlideCallback(float slideOffset);

    public enum State {
        DRAGGING,
        SETTLING,
        EXPANDED,
        COLLAPSED,
        HIDDEN,
        HALF_EXPANDED
    }
}
