import AJS from 'aui';
import $ from 'jquery';
import skate from 'skate';

/**
 * @param {BBPanel} el - The bb-panel to search for an anchor
 * @returns {Element|null} - The anchor element for this panel if it exists, or {@like null}
 */
function getAnchor(el) {
    return document.getElementById(el.getAttribute('anchor-to'));
}

/**
 * @param {BBPanel} el - A BBPanel
 * @param {Function<Element>} callback - The callback to call with the anchor.
 */
function doIfAnchor(el, callback) {
    const anchor = getAnchor(el);

    if (anchor) {
        callback(anchor);
    }
}

/**
 * Asks layer manager to display the panel
 *
 * @param {BBPanel} el - A BBPanel
 */
function showPanel(el) {
    doIfAnchor(el, anchor => {
        // TODO consider the window resizing...
        const $anchor = $(anchor);
        const offset = $anchor.offset();
        const xOffset = Math.floor(offset.left);
        const yOffset = Math.floor(offset.top + $anchor.outerHeight());
        el.style.transform = `translate3d(${xOffset}px, ${yOffset}px, 0)`;
    });

    AJS.layer(el).show();
}

/**
 * Requests layer manager hides the panel
 *
 * @param {BBPanel} el - The bb-panel to hide
 */
function hidePanel(el) {
    AJS.layer(el).hide();
}

function updateShowing(el, showing) {
    if (showing) {
        showPanel(el);
    } else {
        hidePanel(el);
    }
}

const BBPanel = skate('bb-panel', {
    properties: {
        // Used by AUI Layer Manager to hide the panel when it wants to hide the layer.
        'aria-hidden': skate.properties.string({
            attribute: true,
            default: 'true',
            set(el, change) {
                el.open = change.newValue === 'false';
            },
        }),

        // Main attribute/property used to control the state of the panel
        'open': skate.properties.boolean({
            attribute: true,
            default: false,
            set(el, change) {
                if (change.oldValue !== change.newValue && document.body.contains(el)) {
                    updateShowing(el, change.newValue);
                }
            },
        }),
    },
    attached: function(el) {
        const isInitalizing = !el.hasAttribute('aria-hidden');
        const shouldBeOpen = el.hasAttribute('open');
        if (isInitalizing || el.open !== shouldBeOpen) {
            updateShowing(el, shouldBeOpen);
        }
    },
    render: function(element) {
        $(element)
            .addClass('aui-layer');
    },
});

export default BBPanel;
