import ngModule from '../module';

function vnAcl(aclService, $timeout) {
    let acls = [];

    function getMaterialType(className) {
        let type = '';
        if (className) {
            type = className.replace('mdl-', '').replace('__input', '');
            type = type.charAt(0).toUpperCase() + type.slice(1);
        }
        return type;
    }
    function updateMaterial(input) {
        if (input && input.className) {
            let find = input.className.match(/mdl-[\w]+input/g);
            if (find && find.length && find[0]) {
                let type = getMaterialType(find[0]);
                if (type && input.parentNode[`Material${type}`] && input.parentNode[`Material${type}`].updateClasses_)
                    input.parentNode[`Material${type}`].updateClasses_();
            }
        }
    }
    function getDynamicConditions($attrs) {
        let atributes = $attrs.$attr;
        let conditions = {};

        Object.keys(atributes).forEach(atribute => {
            if (atribute.startsWith('aclConditionalTo')) {
                let role = atributes[atribute].split('-').slice(-1)[0];
                conditions[atribute] = {
                    role: role
                };
            }
        });
        return conditions;
    }

    function permissionElement($element, action) {
        if (!aclService.hasAny(acls)) {
            if (action === 'disabled') {
                let input = $element[0];
                let selector = 'input, textarea, button, submit';

                if (!input.matches(selector))
                    input = input.querySelector(selector);

                if (input) {
                    $timeout(() => {
                        input.setAttribute('disabled', 'true');
                        updateMaterial(input);
                    });
                    $element[0].querySelectorAll('vn-drop-down').forEach(element => {
                        element.parentNode.removeChild(element);
                    });
                }
            } else
                $element.remove();
        }
    }

    function updateAcls(role, toAdd) {
        let position = acls.indexOf(role);

        if (!toAdd && position > -1)
            acls.splice(position, 1);
        // todo: add acl and enabled element if previusly was disabled
    }

    return {
        restrict: 'A',
        priority: -1,
        link: function($scope, $element, $attrs) {
            acls = $attrs.vnAcl.split(',').map(i => i.trim());
            let action = $attrs.vnAclAction || 'disabled';
            let conditions = getDynamicConditions($attrs);
            permissionElement($element, action);

            if (Object.keys(conditions).length) {
                let watchConditions = $scope.$watch(() => {
                    Object.keys(conditions).forEach(attrName => {
                        let hasPermission = $scope.$eval($attrs[attrName]);
                        if (!hasPermission) {
                            updateAcls(conditions[attrName].role, hasPermission);
                            permissionElement($element, action);
                            delete conditions[attrName];
                        }
                    });

                    if (Object.keys(conditions).length === 0) {
                        // unWacth
                        watchConditions();
                    }
                });
            }
        }
    };
}
vnAcl.$inject = ['aclService', '$timeout'];

ngModule.directive('vnAcl', vnAcl);