package it.integry.integrywmsnative.view.bottom_sheet__base;

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

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

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

import it.integry.integrywmsnative.R;
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 View backgroundView;
    protected int backgroundViewId;

    protected BottomSheetBehavior<?> mBottomSheetBehavior;


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

        int backgroundViewId = attrs.getAttributeResourceValue("http://schemas.android.com/apk/res-auto", "backgroundView", -1);
        int parentViewId = attrs.getAttributeResourceValue("http://schemas.android.com/apk/res-auto", "parentView", -1);

//        if(backgroundViewId == -1)
//            throw new RuntimeException("Please declare app:backgroundView on BottomSheet");

        if (parentViewId == -1)
            throw new RuntimeException("Please declare app:parentView on BottomSheet");


        this.init(
                getRootView().findViewById(parentViewId),
                null,
                backgroundViewId);

    }

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

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

    private void init(View parentView, View backgroundView, int backgroundViewId) {
        this.parentView = parentView;
//        this.backgroundView = backgroundView;
//        this.backgroundViewId = backgroundViewId;
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();

        this.mBottomSheetBehavior = AutoCloseBottomSheetBehavior.from(this.parentView);

        this.mBottomSheetBehavior.addBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
            @Override
            public void onStateChanged(@NonNull View bottomSheet, int newState) {
//                if(backgroundViewId != -1) {
//                    backgroundView = ((View) getParent()).findViewById(backgroundViewId);
//                }

                if (backgroundView == null) {
                    var rootView = getRootParent((ViewGroup) getParent());
                    backgroundView = rootView.findViewById(R.id.bottom_sheet__background);
                    backgroundView.setOnClickListener(v -> {
                        collapse();
                    });

//                    backgroundView = new View(mContext, null);
//                    backgroundView.setBackgroundColor(getResources().getColor(R.color.bottom_sheet_background_color));
//                    backgroundView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
//                    backgroundView.setElevation(UtilityDimension.convertDpToPixel(0, mContext));
//                    backgroundView.setAlpha(0.6f);

//                    rootView.addView(backgroundView, 0);
                }

                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);
            }
        });
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();


    }


    private ViewGroup getRootParent(ViewGroup viewGroup) {
        if (viewGroup.getParent() != null && viewGroup.getParent() instanceof ViewGroup) {
            var parent = (ViewGroup) viewGroup.getParent();

            if (parent != null)
                return getRootParent(parent);
        }

        return viewGroup;
    }

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

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

    public void collapse() {
        if (this.mBottomSheetBehavior == null) {
            UtilityLogger.error(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.error(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
    }
}
