import ngModule from '../module';
import template from './smart-table.html';
import './smart-table.scss';

/**
 * Directive to hide/show selected columns of a table, don't use with rowspan.
 * Property smart-table-ignore ignores one or more vn-th with prop field.
 */
directive.$inject = ['$http', '$compile', 'vnApp', '$translate'];
export function directive($http, $compile, vnApp, $translate) {
    function getHeaderList($element, $scope) {
        let filtrableHeaders = $element[0].querySelectorAll('vn-th[field]:not([smart-table-ignore])');
        let headerList = Array.from(filtrableHeaders);
        let ids = [];
        let titles = {};

        headerList.forEach(header => {
            let id = header.getAttribute('field');
            ids.push(id);
            titles[id] = header.innerText || id.charAt(0).toUpperCase() + id.slice(1);
        });

        $scope.fields = ids;
        $scope.titles = titles;
        $scope.allHeaders = Array.from($element[0].querySelectorAll('vn-th'));

        return headerList;
    }

    function getTableConfig(tableCode) {
        return $http.get(`UserConfigViews/getConfig?tableCode=${tableCode}`);
    }

    function createViewConfig(config, fields) {
        fields.forEach(field => {
            if (config.configuration[field] == null)
                config.configuration[field] = true;
        });
    }

    function addHideClass($scope, headerList, userConfig) {
        let selectors = [];
        Object.keys(userConfig.configuration).forEach(key => {
            let index;
            if (userConfig.configuration[key] === false) {
                index = $scope.allHeaders.findIndex(el => {
                    return el.getAttribute('field') == key;
                });

                let baseSelector = `vn-table[vn-smart-table=${userConfig.tableCode}] > div`;
                selectors.push(`${baseSelector} vn-thead > vn-tr > vn-th:nth-child(${index + 1})`);
                selectors.push(`${baseSelector} vn-tbody > vn-tr > vn-td:nth-child(${index + 1})`);
                selectors.push(`${baseSelector} vn-tbody > .vn-tr > vn-td:nth-child(${index + 1})`);
            }
        });

        if (document.querySelector('style[id="smart-table"]')) {
            let child = document.querySelector('style[id="smart-table"]');
            child.parentNode.removeChild(child);
        }

        if (selectors.length) {
            let rule = selectors.join(', ') + '{display: none;}';
            $scope.css = document.createElement('style');
            $scope.css.setAttribute('id', 'smart-table');
            document.head.appendChild($scope.css);
            $scope.css.appendChild(document.createTextNode(rule));
        }

        $scope.$on('$destroy', () => {
            if ($scope.css && document.querySelector('style[id="smart-table"]')) {
                let child = document.querySelector('style[id="smart-table"]');
                child.parentNode.removeChild(child);
            }
        });
    }

    function saveConfiguration(tableConfiguration) {
        tableConfiguration.configuration = JSON.parse(JSON.stringify(tableConfiguration.configuration));
        return $http.post(`UserConfigViews/save`, tableConfiguration);
    }

    return {
        restrict: 'A',
        link: async function($scope, $element, $attrs) {
            let cTemplate = $compile(template)($scope)[0];
            $scope.$ctrl.showSmartTable = event => {
                event.preventDefault();
                event.stopImmediatePropagation();
                $scope.smartTable.show(event.target);
            };

            let tableCode = $attrs.vnSmartTable.trim();
            let headerList = getHeaderList($element, $scope);

            let defaultConfigView = {tableCode: tableCode, configuration: {}};
            let userView = await getTableConfig(tableCode);
            let config = userView.data || defaultConfigView;

            $scope.tableConfiguration = config;
            createViewConfig(config, $scope.fields);

            addHideClass($scope, headerList, config);

            let table = document.querySelector(`vn-table[vn-smart-table=${tableCode}]`);

            table.insertBefore(cTemplate, table.firstChild);
            $scope.$ctrl.saveConfiguration = async tableConfiguration => {
                let newConfig = await saveConfiguration(tableConfiguration);
                vnApp.showSuccess($translate.instant('Data saved!'));
                addHideClass($scope, headerList, newConfig.data);
                $scope.smartTable.hide();
            };
        }
    };
}
ngModule.directive('vnSmartTable', directive);