let logs_env = {};
let usrs_env = {};
let log_elem = {};

const load_elem = () => {
    log_elem = Object.freeze({
        table: document.getElementById('table-log'),
        modal: document.getElementById('edit-user-modal'),
        dropdown_action: document.getElementById('dropdown-action'),
        search_inpt: document.getElementById('table-search-usrs'),
        search_clean: document.getElementById('clean-search'),
        checkbox_all: document.getElementById('checkbox-all'),
        count_select: document.getElementById('count-select'),
        alert_danger: document.getElementById('alert-danger'),
        danger_message: document.getElementById('danger-message'),
        alert_info: document.getElementById('alert-info'),
        info_message: document.getElementById('info-message'),
        checkbox_all: document.getElementById('checkbox-all'),
        alert_timeout: 4000,
        user_form: {
            name: document.getElementById('usr-name'),
            fullname: document.getElementById('usr-fullname'),
            email: document.getElementById('usr-email'),
            description: document.getElementById('usr-description'),
            roles: document.getElementById('usr-roles'),
            items: document.getElementById('usr-items'),
            status: document.getElementById('usr-status'),
            current_status: document.getElementById('current-usr-status'),
            isadmin: document.getElementById('usr-isadmin'),
            otp_enabled: document.getElementById('usr-otp-enabled'),
            otp_verified: document.getElementById('usr-otp-verified'),
            otp_defs: document.getElementById('usr-otp-defs'),
        },
    })
};
const set_user_status = (value,color) => {
    if (log_elem.user_form.current_status && log_elem.user_form.status) {
        log_elem.user_form.status.value=value;
        log_elem.user_form.current_status.innerHTML= 
        `<div class="inline-flex items-center"><div class="h-2.5 w-2.5 rounded-full bg-${color}-500 mr-2"></div><div>${value}</div></div>`;
    }
};
const edit_row = (pos) => {
    const id = usrs_env.data && usrs_env.data[pos] ? usrs_env.data[pos] : -1
    console.log(id);
    if (id > -1) {
        edit_usr(`${id}`);
    }
};
const close_usr = () => {
    if (usrs_env.modal.hide) {
        usrs_env.modal.hide();
    }
};
const fill_form = () => {
    log_elem.user_form.name.value = usrs_env.user.name;
    log_elem.user_form.fullname.value = usrs_env.user.fullname;
    log_elem.user_form.email.value = usrs_env.user.email;
    log_elem.user_form.description.value = usrs_env.user.description;
    log_elem.user_form.roles.value = usrs_env.user.roles;
    log_elem.user_form.items.value = usrs_env.user.items;
    log_elem.user_form.status.value = usrs_env.user.status;
    usrs_env.user.isadmin == 1 ?
        log_elem.user_form.isadmin.checked=true :
        log_elem.user_form.isadmin.checked=false;
    usrs_env.user.otp_enabled == 1 ? 
        log_elem.user_form.otp_enabled.checked = true :
        log_elem.user_form.otp_enabled.checked = false;
    usrs_env.user.otp_verified == 1 ? 
        log_elem.user_form.otp_verified.checked = true :
        log_elem.user_form.otp_verified.checked = false ;
    log_elem.user_form.otp_defs.value = usrs_env.user.otp_defs;
    let color = '';
    switch (log_elem.user_form.status.value) {
        case 'Active': 
            color='green';
            break;
        case 'Created':
            color='blue';
            break;
        case 'Pending':
            color='orange';
            break;
        case 'Lock':
            color='red';
            break;
        default:
            color='yellow';
    }
    set_user_status(log_elem.user_form.status.value,color);
};
const collect_form = () => {
    usrs_env.user.name = log_elem.user_form.name.value;
    usrs_env.user.fullname = log_elem.user_form.fullname.value;
    usrs_env.user.email = log_elem.user_form.email.value;
    usrs_env.user.description = log_elem.user_form.description.value;
    usrs_env.user.roles = log_elem.user_form.roles.value;
    usrs_env.user.items = log_elem.user_form.items.value;
    usrs_env.user.status = log_elem.user_form.status.value;
    log_elem.user_form.isadmin.checked ? 
        usrs_env.user.isadmin = true :
        usrs_env.user.isadmin = false; 
    log_elem.user_form.otp_enabled.checked ?
        usrs_env.user.otp_enabled = true : 
        usrs_env.user.otp_enabled = false;
    log_elem.user_form.otp_verified.checked ?
        usrs_env.user.otp_verified = true :
        usrs_env.user.otp_verified = false;
    usrs_env.user.otp_defs = log_elem.user_form.otp_defs.value;
};
const edit_usr = async (id) => {
    if (usrs_env.modal.show) {
        const res = await get_user('id',id);
        if (res.status && res.data.id == id) {
            usrs_env.user = res.data;    
            fill_form();
            usrs_env.modal.show();
        }
    }
};
const save_all_usr = async (ev) => {
    ev.preventDefault();
    if (usrs_env.modal.show && usrs_env.user) {
        collect_form();
        const res = await save_user(usrs_env.user);
        // if (res.status) {
        usrs_env.modal.hide();
    }
};
const on_search = (el) => {
    const tbody = log_elem.table.getElementsByTagName('tbody')[0];
    let total = 0;
    let count_select = 0;
    [...tbody.getElementsByTagName('tr')].forEach(tr => {
        total +=1;
        if (tr.dataset.row && tr.dataset.row.includes(el.value)) {
            tr.classList.remove('hidden');
            count_select +=1;
        } else {
            tr.classList.add('hidden');
        }
    });
    if (log_elem.count_select) {
        if (count_select == total) {
            log_elem.count_select.innerHTML='';
        } else {
            log_elem.count_select.innerHTML=`${count_select} of`;
        }
    }
};
const on_search_keydown = (el,event) => {
    switch (event.key) {
        case 'Delete':
        case 'Home':
            clean_search();
            break;
        case 'Enter':
            break;
        default:
            on_search(el);
    }
}
const clean_search = () => {
    log_elem.search_inpt.value='';
    on_search(log_elem.search_inpt);
};
const load_data = () => {
    const js_data = document.getElementById('js-data');
    if (js_data) { js_data.remove(); }
    logs_env.data = [];
    if (logs_list) {
        try {
            logs_env.data = JSON.parse(logs_list) 
        } catch (error) {
            logs_env.data = [];
        }
        logs_list='';
    }
};
const on_check_all = (el,ev) => {
    ev.preventDefault();
    if (log_elem.checkbox_all) {
        const state = log_elem.checkbox_all.checked;
        [...log_elem.table.getElementsByClassName('col-check')].forEach(it => {
            it.checked = state;
        });
    }
};
const table_sort = (col) => {
    const tbody = log_elem.table.getElementsByTagName('tbody')[0];
    const rows = tbody.getElementsByTagName('tr');
    const arrow_up = document.getElementById(`${col}-arrow-up`);
    const arrow_down = document.getElementById(`${col}-arrow-down`);
    const col_rows = [];
    [...rows].forEach(it => {
        const data=it.dataset.row.split(':');
        switch (col) {
            case 'when':
              col_rows.push({ky: data[0], tr:it})
              break;
            case 'origin':
              col_rows.push({ky: data[1], tr:it})
              break;
            case 'context':
              col_rows.push({ky: data[2], tr:it})
              break;
            case 'request':
              col_rows.push({ky: data[3], tr:it})
              break;
            case 'roles':
              col_rows.push({ky: data[4], tr:it})
              break;
            case 'agent':
              col_rows.push({ky: data[5], tr:it})
              break;
        }
    })
    if (col_rows.length == 0) { return; }
    const is_asc = !logs_env.cols[col].asc;
    logs_env.cols[col].asc = is_asc;
    if (is_asc) {
        if (arrow_up) { arrow_up.classList.remove('hidden'); }
        if (arrow_down) { arrow_down.classList.add('hidden'); }
    } else { 
        if (arrow_up) { arrow_up.classList.add('hidden'); }
        if (arrow_down) { arrow_down.classList.remove('hidden'); }
    }
    col_rows.sort((a,b) => {
        if (is_asc) {
            if (a.ky > b.ky) { return 1; }
            if (a.ky < b.ky) { return -1; }
        } else {
            if (a.ky > b.ky) { return -1; }
            if (a.ky < b.ky) { return 1; }
        }
        // a must be equal to b
        return 0;
    });
    tbody.innerHTM=''; 
    col_rows.forEach(it => tbody.append(it.tr));
};
const alert_danger = (task,message) => {
    if (log_elem.danger_message && log_elem.alert_danger) {
        log_elem.danger_message.innerHTML=message;
        switch (task) {
            case 'show':
                log_elem.alert_danger.classList.remove('hidden');
                setTimeout(() => {
                    log_elem.alert_danger.classList.add('hidden');
                }, log_elem.alert_timeout);
                break;
            default:
                log_elem.alert_danger.classList.add('hidden');
        }
    }
};
const alert_info = (task,message) => {
    if (log_elem.info_message && log_elem.alert_info) {
        log_elem.info_message.innerHTML=message;
        switch (task) {
            case 'show':
                log_elem.alert_info.classList.remove('hidden');
                setTimeout(() => {
                    log_elem.alert_info.classList.add('hidden');
                }, log_elem.alert_timeout);
                break;
            default:
                log_elem.alert_info.classList.add('hidden');
        }
    }
};
const post_fetch = async (source,url = '',source_data) => {
    if (url == '') { return }
    const response = await fetch(url, {
        method: 'POST',
        body: JSON.stringify(source_data),
        headers: {
            'Content-type': 'application/json; charset=UTF-8',
        }
    });
    alert_danger('hide','');
    alert_info('hide','');
    if (response.ok && response.status === 200 ) {
        if (source == 'get_user') {
            const name = source_data.name;
            const value = source_data.value;
            const data = await response.json();
            if (data[name] && data[name] == value){
                return {status: true, data }
            } else {
                alert_danger('show',`No data found for ${name}`)
                return {status: false, data: {}};
            }
        } else {
            const data = await response.text();
            if (data != '') { alert_info('show',data); }
            return {status: true, data }
        }
    } else if ( response.status === 401 ) {
        alert_danger('show','Error connection, SESSION expired ? Try Reload !')
        return {status: false, data: {}};
    } else if ( response.status === 400 ) {
        alert_danger('show','Error connection, bad request. No data found !')
        return {status: false, data: {}};
    } else {
        alert_danger('show','Error connection, no data available')
        return {status: false, data: {}};
    }
};
const get_user = async (name, value) => { 
   if (GETUSER_URL) {
        const data = {
            name,
            value
        };
        return await post_fetch('get_user', GETUSER_URL,data);
    }
};
const save_user = async (data) => { 
    if (SAVEUSER_URL) {
        return await post_fetch('save_user', SAVEUSER_URL,data);
    }
};
const list_act_items = () => {
    let act_items=[];
    if (log_elem.checkbox_all) {
        const state = log_elem.checkbox_all.checked;
        [...log_elem.table.getElementsByClassName('col-check')].forEach(it => {
            if (it.checked && it.dataset.col) {
                if (logs_env && logs_env.data && logs_env.data[it.dataset.col]) {
                    act_items.push({
                        id: logs_env.data[it.dataset.col],
                        src: it,
                    });
                }
            }
        });
    }
    return act_items;
};
const log_delete_lines = async (user_id) => {
    let status = true;
    list_act_items().forEach(async (it) => {
        const res = await post_fetch('act_delete', DELETELOG_URL,{
            name: user_id, value: it.id
        });
        if (res.status) { it.src.checked = false;}
        status = res.status;
    });
    return status;
};
const on_log_delete = async (user_id) => {
    if (DELETELOG_URL) {
        const usrid = user_id == '0' ? '' : user_id;
        if (log_elem.dropdown_action) { log_elem.dropdown_action.classList.add('hidden'); }
        const status = await log_delete_lines(usrid);
        if (log_elem.checkbox_all) { log_elem.checkbox_all.checked=false;}
        setTimeout(() => {
            if (status) { location.reload(); }
        }, log_elem.alert_timeout);
    }
};
const clean_log = async (user_id) => {
    if (DELETELOG_URL) {
        const name = user_id == '0' ? '' : user_id;
        if (log_elem.dropdown_action) { log_elem.dropdown_action.classList.add('hidden'); }
        const res = await post_fetch('act_delete', DELETELOG_URL,{
            name, value: 'ALL'
        });
        if (log_elem.checkbox_all) { log_elem.checkbox_all.checked=false;}
        if (res.status) { location.reload(); }
    }
};

const on_log_info = (elem) => {
    if (elem && elem.children) {
        [...elem.children].forEach((it,idx) => {
            if (idx > 0 ) { it.classList.toggle('hidden'); }
        });
    }
};
window.addEventListener('load', () => {
    load_data();
    load_elem();
    if (log_elem && log_elem.table) {
        logs_env.cols = {};
        const thead = log_elem.table.getElementsByTagName('thead');
        if (thead[0]) {
            [...thead[0].getElementsByTagName('th')].forEach(col => {
                const th = col.dataset.th;
                if (th != 'check') {
                    logs_env.cols[th]={asc: false};
                    col.addEventListener('click', (ev) => {
                        ev.preventDefault();
                        const src = col;
                        const th = src.dataset.th;
                        console.log(`${th}`);
                        table_sort(th);
                    });
                }
            });
        }
    }
    // options with default values
    const options = {
        placement: 'bottom-right',
        backdrop: 'dynamic',
        backdropClasses: 'bg-gray-900 bg-opacity-50 dark:bg-opacity-80 fixed inset-0 z-40',
        closable: true,
        onHide: () => {
            console.log('modal is hidden');
        },
        onShow: () => {
            console.log('modal is shown');
        },
        onToggle: () => {
            console.log('modal has been toggled');
        }
    };
    usrs_env.modal = new Modal(log_elem.modal, options);
});