const Client           = require('../base/client');
const BinarySocket     = require('../base/socket');
const State            = require('../../_common/storage').State;
const updateTabDisplay = require('../../_common/tab_selector').updateTabDisplay;
const MetaTrader       = require('../../app/pages/user/metatrader/metatrader');

/*
    data-show attribute controls element visibility based on
        - current landing company
        - metatrader availability
        - logged in status

    attribute value is a list of comma separated
        - landing company shortcodes
        - 'mtcompany' code that stands for metatrader availability
        - 'default' code that describes logged out users

    Examples:
        Show only for logged in clients with costarica landing company:
            data-show='costarica'

        Show for costarica and malta:
            data-show='costarica, malta'

        Hide for costarica:
            data-show='-costarica'

        Hide for malta and maltainvest:
            data-show='-malta, -maltainvest'

    Prohibited values:
        Cannot mix includes and excludes:
            data-show='costarica, -malta' -> throws error
        Shortcodes are case sensitive:
            data-show='Costarica'         -> throws error
*/

const ContentVisibility = (() => {
    const init = () => {
        if (Client.isLoggedIn()) {
            BinarySocket.wait('authorize', 'landing_company').then(() => {
                controlVisibility(
                    State.getResponse('authorize.landing_company_name'),
                    MetaTrader.isEligible()
                );
            });
        } else {
            controlVisibility('default', true);
        }
    };

    const generateParsingErrorMessage = (reason, attr_str) => (
        `Invalid data-show attribute value! ${reason} Given value: '${attr_str}'.`
    );

    const parseAttributeString = (attr_str) => {
        if (!/^[a-z,-\s]+$/.test(attr_str)) {
            throw new Error(generateParsingErrorMessage('Invalid character used.', attr_str));
        }
        let names = attr_str.split(',').map(name => name.trim());
        if (names.some(name => name.length === 0)) {
            throw new Error(generateParsingErrorMessage('No empty names allowed.', attr_str));
        }
        const is_exclude = names.every(name => name.charAt(0) === '-');
        const is_include = names.every(name => name.charAt(0) !== '-');
        if (!is_exclude && !is_include) {
            throw new Error(generateParsingErrorMessage('No mixing of includes and excludes allowed.', attr_str));
        }
        if (is_exclude) {
            names = names.map(name => name.slice(1));
        }
        return {
            is_exclude,
            names,
        };
    };

    const controlVisibility = (current_landing_company_shortcode, client_has_mt_company) => {
        const visible_classname = 'data-show-visible';
        const mt_company_rule   = 'mtcompany';

        document.querySelectorAll('[data-show]').forEach(el => {
            const attr_str              = el.dataset.show;
            const { is_exclude, names } = parseAttributeString(attr_str);
            const rule_set              = new Set(names);

            const rule_set_has_current = rule_set.has(current_landing_company_shortcode);
            const rule_set_has_mt      = rule_set.has(mt_company_rule);

            let show_element = false;

            if (client_has_mt_company && rule_set_has_mt) show_element = !is_exclude;
            else if (is_exclude !== rule_set_has_current) show_element = true;

            if (show_element) {
                el.classList.add(visible_classname);
            } else {
                const open_tab_url = new RegExp(`\\?.+_tabs=${el.id}`, 'i');
                // check if we hide a tab that's open
                // then redirect to the url without query
                if (el.classList.contains('tm-li') && open_tab_url.test(window.location.href)) {
                    const { origin, pathname } = window.location;
                    window.location.href = origin + pathname;
                }
            }
        });

        updateTabDisplay();
    };

    return {
        init,
    };
})();

module.exports = ContentVisibility;
@@ -1425,16 +1425,34 @@
 company'
+, 'mt5_login_list'
 ).then((
@@ -1609,16 +1609,74 @@
 igible()
+,%0A                    State.getResponse('mt5_login_list'),
 %0A       
@@ -2758,32 +2758,214 @@
 (1));%0A        %7D%0A
+%0A        const mt5_rules = names%0A            .filter(name =%3E isMT5Rule(name))%0A            .map(rule =%3E parseMT5Rule(rule));%0A%0A        names = names.filter(name =%3E !isMT5Rule(name));%0A%0A
         return %7B
@@ -3008,16 +3008,39 @@
  names,%0A
+            mt5_rules,%0A
         
@@ -3042,32 +3042,136 @@
      %7D;%0A    %7D;%0A%0A
+    const isMT5Rule = (rule) =%3E /%5Emt5:/.test(rule);%0A%0A    const parseMT5Rule = (rule) =%3E rule.slice(4);%0A%0A
     const contro
@@ -3241,16 +3241,32 @@
 _company
+, mt5_login_list
 ) =%3E %7B%0A 
@@ -3464,24 +3464,16 @@
 tr      
-        
 = el.dat
@@ -3514,20 +3514,71 @@
 exclude,
- nam
+%0A                    names,%0A                    mt5_rul
 es %7D = p
@@ -3640,24 +3640,16 @@
 et      
-        
 = new Se
@@ -3838,33 +3838,486 @@
     
-let show_element = false;
+const mt5_rules_matches = mt5_rules.map((rule) =%3E %7B%0A                const rule_regex = new RegExp(rule);%0A                return mt5_login_list.some(mt5_login =%3E rule_regex.test(mt5_login.group));%0A            %7D);%0A%0A            let show_element = false;%0A%0A            if (mt5_rules.length) %7B%0A                if (is_exclude) show_element = mt5_rules_matches.every(is_match =%3E !is_match);%0A                else show_element = mt5_rules_matches.some(is_match =%3E is_match);%0A            %7D
 %0A%0A  
@@ -4476,24 +4476,25 @@
 nt = true;%0A%0A
+%0A
             

add metatrader rules to data-show