import ngModule from '../../module';
import Component from '../../lib/component';
import './style.scss';

/**
 * A simple component to show non-obstructive notifications to the user.
 */
export default class Controller extends Component {
    constructor($element, $) {
        super($element, $);
        this.snackbar = $element[0].firstChild;
        this.$snackbar = angular.element(this.snackbar);
    }

    /**
     * It creates a new snackbar notification
     * @param {Object} data Snackbar data
     * @return {Object} Created snackbar shape
     */
    createShape(data) {
        let shape = Object.assign({
            nMessages: 1
        }, data);

        let element = document.createElement('div');
        element.className = 'shape';
        setTimeout(() => element.classList.add('shown'), 30);
        shape.element = element;

        if (shape.type)
            element.classList.add(shape.type);

        let button = document.createElement('button');
        button.addEventListener('click', () => this.onButtonClick(shape));
        element.appendChild(button);

        let buttonText = shape.actionText || this.$t('Hide');
        buttonText = document.createTextNode(buttonText);
        button.appendChild(buttonText);

        let shapeText = document.createElement('div');
        shapeText.setAttribute('class', 'text');
        element.appendChild(shapeText);

        let text = document.createTextNode(shape.message);
        shapeText.appendChild(text);

        let chip = document.createElement('vn-chip');
        chip.className = 'warning small';
        chip.style.visibility = 'hidden';

        let chipWrapper = document.createElement('div');
        chip.append(chipWrapper);

        let span = document.createElement('span');
        chipWrapper.append(span);

        let chipText = document.createTextNode(shape.nMessages);
        span.append(chipText);

        shapeText.appendChild(chip);

        let parent = this.snackbar.querySelector('.shape');

        if (parent)
            this.snackbar.insertBefore(element, parent);
        else
            this.snackbar.appendChild(element);

        return shape;
    }

    /**
     * Shows a notification.
     *
     * @param {Object} data The message data
     */
    show(data) {
        let shape = this.lastShape;

        const isEqual = shape
            && shape.type == data.type
            && shape.message == data.message;

        if (isEqual) {
            shape.nMessages++;

            const chip = shape.element.querySelector('.text vn-chip');
            chip.style.visibility = 'visible';

            const span = chip.querySelector('span');
            span.innerHTML = shape.nMessages;
        } else
            shape = this.createShape(data);

        clearTimeout(shape.hideTimeout);
        shape.hideTimeout = setTimeout(
            () => this.hide(shape), shape.timeout || 3000);

        this.lastShape = shape;
    }

    /**
     * Shows an error.
     *
     * @param {Object} data The message data
     */
    showError(data) {
        data.type = 'error';
        this.show(data);
    }

    /**
     * Shows a success.
     *
     * @param {Object} data The message data
     */
    showSuccess(data) {
        data.type = 'success';
        this.show(data);
    }

    /**
     * Hides the snackbar.
     * @param {Object} shape Snackbar element
     */
    hide(shape) {
        if (this.lastShape == shape)
            this.lastShape = null;

        shape.element.classList.remove('shown');
        setTimeout(() => shape.element.remove(), 250);
    }

    onSnackbarClick(event) {
        this.event = event;
    }

    onButtonClick(shape) {
        if (shape.actionHandler)
            shape.actionHandler();
        else
            this.hide(shape);
    }
}

ngModule.vnComponent('vnSnackbar', {
    template: require('./snackbar.html'),
    controller: Controller
});