'use strict';

import {Select} from '../common/select.js';
import { getLang } from '../../lang.js';

export function SettingsBlock(url){
    let l = getLang(config["lang"] == "russian" ? config["lang"] : "english");
    let setting = {},
    connecting = {
        'loginPBX' : '',
        'passwordPBX' : '',
        'server' : '',
        'port' : '',
        'domain' : '',
        'rkey' : '',
        'SIPnumber' : '',
        'SIPpassword' : ''
    },
    arrTables = [],
    arrUsers = [],
    arrLandline = [],
    result,
    tableId = -1,
    userId = -1,
    landlineId = -1,
    _ua,
    dataHere = false,
    linkConversationRecordsTable,
    tablist,
    fieldlist,
    userlist,
    badMessage,
    requestOptionsPatch = {
        method: 'PATCH',
        credentials: "include",
    };
    if (window.x_auth_token) {
        requestOptionsPatch.headers = {
            'X-Auth-Token' : window.x_auth_token,
            'Content-Type': 'application/vnd.api+json'
        }
    };
    setting['saveSetting'] = false;
    setting['tableCallAddOrEdit'] = false;
    setting['addUser'] = false;
    setting['addLandline'] = false;
    setting['accountEdit'] = false;

    function sortByField(field) {
        return (a, b) => a[field] > b[field] ? 1 : -1;
    }
    function login(New) {
        // console.log("on login");

        let socket = new JsSIP.WebSocketInterface(`${connecting['server']}:${connecting['port']}`);

        _ua = new JsSIP.UA(
            {
                uri: "sip:" + connecting['SIPnumber'] + "@" + connecting['domain'],
                password: connecting['SIPpassword'],
                display_name: connecting['SIPnumber'],
                sockets: [socket],
                session_timers: false
            });

        // соединяемся с астером
        _ua.on('connecting', () => {
            // console.log("UA connecting");
        });

        // соединились с астером
        _ua.on('connected', () => {
            // console.log("UA connected");
        });

        // астер нас зарегал, теперь можно звонить и принимать звонки
        _ua.on('registered', async () => {
            // console.log("UA registered");
            setting['saveSetting'] = true;
            if (!New) {
                registerSuccess = true;
                registerMessage = l.registration_was_successful;
                arrUsers.push({
                    'cb_user' : userId.id,
                    'displayUserName' : userId.fio,
                    'sip_number' : connecting.SIPnumber,
                    'sip_password' : connecting.SIPpassword
                });
            }
            result.data.attributes.value.personal_account_details = connecting;
            result.data.attributes.value.call_tables = arrTables;
            result.data.attributes.value.users = arrUsers;
            result.data.attributes.value.land_line_info = arrLandline;
            let requestOptions = {
                method: 'PATCH',
                body: JSON.stringify(result)
            };
            let setData = await fetch(`./${url}`, requestOptions)
            logout();
        });
        // астер про нас больше не знает
        _ua.on('unregistered', () => {
            // console.log("UA unregistered");
        });

        // астер не зарегал нас, что то не то, скорее всего неверный логин или пароль
        _ua.on('registrationFailed', (data) => {
            console.error("UA registrationFailed", data.cause);
            registerSuccess = false;
            registerMessage = l.registration_failed;
        });
    }

    function logout() {
        // console.log("on logout");
        // закрываем всё, вылогиниваемся из астера, закрываем коннект
        _ua.unregister();
    }

    function accountSettingComponent() {
        return {
            view: (vnode) => {
                return setting['accountEdit'] ? m('div', {
                        style: 'margin: auto;'
                    }, [
                        m('div', {
                            class: 'setting-block--SIP-elements'
                        }, [
                            m('label', {
                                for: 'loginPBX',
                                class: 'setting-block--SIP-elements--label',
                            }, l.login_pbx + ':'),
                            m('input', {
                                type: 'text',
                                class: 'form-control form-control-160',
                                id: 'loginPBX',
                                name: 'loginPBX',
                                value: connecting.loginPBX,
                                onchange: function() {
                                    connecting.loginPBX = this.value;
                                }
                            })
                        ]),
                        m('div', {
                            class: 'setting-block--SIP-elements'
                        }, [
                            m('label', {
                                for: 'passwordPBX',
                                class: 'setting-block--SIP-elements--label',
                            }, l.password_pbx + ':'),
                            m('input', {
                                type: 'text',
                                class: 'form-control form-control-160',
                                id: 'passwordPBX',
                                name: 'passwordPBX',
                                value: connecting.passwordPBX,
                                onchange: function() {
                                    connecting.passwordPBX = this.value;
                                }
                            })
                        ]),
                        m('div', {
                            class: 'setting-block--SIP-elements'
                        }, [
                            m('label', {
                                for: 'server',
                                class: 'setting-block--SIP-elements--label',
                            }, l.Server + ':'),
                            m('input', {
                                type: 'text',
                                class: 'form-control form-control-160',
                                id: 'server',
                                name: 'server',
                                value: connecting.server,
                                onchange: function() {
                                    connecting.server = this.value;
                                }
                            })
                        ]),
                        m('div', {
                            class: 'setting-block--SIP-elements'
                        }, [
                            m('label', {
                                for: 'server',
                                class: 'setting-block--SIP-elements--label',
                            }, l.Port + ':'),
                            m('input', {
                                type: 'text',
                                class: 'form-control form-control-160',
                                id: 'port',
                                name: 'port',
                                value: connecting.port,
                                onchange: function() {
                                    connecting.port = this.value;
                                }
                            })
                        ]),
                        m('div', {
                            class: 'setting-block--SIP-elements'
                        }, [
                            m('label', {
                                for: 'domain',
                                class: 'setting-block--SIP-elements--label',
                            }, l.Domain + ':'),
                            m('input', {
                                type: 'text',
                                class: 'form-control form-control-160',
                                id: 'domain',
                                name: 'domain',
                                value: connecting.domain,
                                onchange: function() {
                                    connecting.domain = this.value;
                                }
                            })
                        ]),
                        m('div', {
                            class: 'setting-block--SIP-elements'
                        }, [
                            m('label', {
                                for: 'rkey',
                                class: 'setting-block--SIP-elements--label',
                            }, l.secret_key + ':'),
                            m('input', {
                                type: 'text',
                                class: 'form-control form-control-160',
                                id: 'rkey',
                                name: 'rkey',
                                value: connecting.rkey,
                                onchange: function() {
                                    connecting.rkey = this.value;
                                }
                            })
                        ]),
                        m('button', {
                            class: 'btn-save',
                            onclick: async function() {
                                setting['accountEdit'] = false;
                                setting['tableCallAddOrEdit'] = false;
                                setting['addUser'] = false;
                                setting['addLandline'] = false;
                                let isNew = false
                                if (arrTables.length == 0 && Object.keys(connecting).length == 0 && arrUsers.length == 0 && arrLandline.length == 0) {
                                    isNew = true;
                                }
                                result.data.attributes.value.personal_account_details = connecting;
                                result.data.attributes.value.call_tables = arrTables;
                                result.data.attributes.value.conversation_records_table = linkConversationRecordsTable;
                                result.data.attributes.value.users = arrUsers;
                                result.data.attributes.value.land_line_info = arrLandline;
                                requestOptionsPatch['body'] = JSON.stringify(result, null, 4);
                                let setData = await fetch(`./${url}`, requestOptionsPatch);
                                let resultPatch = setData.json();
                                if (resultPatch) {
                                    if (isNew) {
                                        displayNotification(l.registration_was_successful,1);
                                        arrUsers.push({
                                            'cb_user' : userId.id,
                                            'displayUserName' : userId.fio,
                                            'sip_number' : connecting.SIPnumber,
                                            'sip_password' : connecting.SIPpassword
                                        });
                                        setting['saveSetting'] = true;
                                    } else {
                                        displayNotification(l.settings_saved, 1);
                                    }
                                } else {
                                    displayNotification(l.settings_not_saved, 2);
                                }
                                m.redraw();
                            }
                        }, l.Save)
                    ]
                ) : null;
            }
        }
    }

    function tableSettingComponent() {
        let table_id = -1,
            editTableName = '',
            editTablePriority = '',
            editTableTelephone = '',
            editTableTelephoneName = '',
            editTableAdditionalField1 = '',
            editTableAdditionalField2 = '',
            editTableAdditionalField3 = '',
            displayTableName = '',
            displayPhoneFieldName = '',
            tableInfo = {
                'table' : editTableName,
                'priority' : editTablePriority,
                'phone_field' : editTableTelephone,
                'name_field' : editTableTelephoneName,
                'additonal_field_1' : editTableAdditionalField1,
                'additonal_field_2' : editTableAdditionalField2,
                'additonal_field_3' : editTableAdditionalField3,
                'displayTableName' : displayTableName,
                'displayPhoneFieldName' : displayPhoneFieldName
            },
            tableDontSave = false,
            tableBadMessage = '';
        function fillValues(table_id){
            for(let key in arrTables){
                if (arrTables[key]['id'] == table_id) {
                    table_id = key;
                    break;
                }
            }
            editTableName = table_id == -1 ? '' : arrTables[table_id]['table'];
            editTablePriority = table_id == -1 ? '' : arrTables[table_id]['priority'];
            editTableTelephone = table_id == -1 ? '' : arrTables[table_id]['phone_field'];
            editTableTelephoneName = table_id == -1 ? '' : arrTables[table_id]['name_field'];
            editTableAdditionalField1 = table_id == -1 ? '' : arrTables[table_id]['additonal_field_1'];
            editTableAdditionalField2 = table_id == -1 ? '' : arrTables[table_id]['additonal_field_2'];
            editTableAdditionalField3 = table_id == -1 ? '' : arrTables[table_id]['additonal_field_3'];
            displayTableName = table_id == -1 ? '' : arrTables[table_id]['displayTableName'];
            displayPhoneFieldName = table_id == -1 ? '' : arrTables[table_id]['displayPhoneFieldName'];
            for(let key in arrTables[table_id]){
                tableInfo[key] = arrTables[table_id][key];
            }
        }
        return {
            view: (vnode) => {
                if(vnode.attrs.tableId != table_id && setting['tableCallAddOrEdit']){
                    table_id = vnode.attrs.tableId;
                    fillValues(vnode.attrs.tableId)
                }
                return setting['tableCallAddOrEdit'] ? m('div', {
                        style: 'margin: auto;'
                    }, [
                    m('div', {
                        class: 'setting-block--TableSetting-elements',
                    },[
                        m('label', {
                            class: 'setting-block--TableSetting-elements--label',
                        }, l.Table + ':'),
                        m(Select, {
                            name: 'tableName',
                            class: 'form-control form-control-160',
                            onchange: function() {
                                displayTableName = this.selectedOptions[0].textContent;
                                editTableName = this.value;
                                displayTableName = ''
                                tableInfo['table'] = this.value;
                                tableInfo['displayTableName'] = this.selectedOptions[0].textContent;
                                editTablePriority = '';
                                editTableTelephone = '';
                                editTableTelephoneName = '';
                                editTableAdditionalField1 = '';
                                editTableAdditionalField2 = '';
                                editTableAdditionalField3 = '';
                                m.redraw();
                            }
                        }, tablist.map((item) =>
                            m('option', {
                                value: item.id,
                                selected: (editTableName == item.id)
                            }, item.name)
                        ))
                    ]),
                    m('div', {
                        class: 'setting-block--TableSetting-elements',
                    },[
                        m('label', {
                            class: 'setting-block--TableSetting-elements--label',
                        }, l.Priority + ':'),
                        m(Select, {
                            name: 'tablePriority',
                            class: 'form-control form-control-160',
                            onchange: function() {
                                editTablePriority = this.value;
                                tableInfo['priority'] = this.value;
                            }
                        }, [
                            m('option', {
                                value: '',
                            }, ''),
                            m('option', {
                                value: 'upper',
                                selected: (editTablePriority == 'upper')
                            }, l.Upper),
                            m('option', {
                                value: 'middle',
                                selected: (editTablePriority == 'middle')
                            }, l.Middle),
                            m('option', {
                                value: 'lower',
                                selected: (editTablePriority == 'lower')
                            }, l.Lower),
                        ])
                    ]),
                    m('div', {
                        class: 'setting-block--TableSetting-elements',
                    },[
                        m('label', {
                            class: 'setting-block--TableSetting-elements--label',
                        }, l.Field_with_telephone + ':'),
                        m(Select, {
                            name: 'tableTelephone',
                            class: 'form-control form-control-160',
                            onchange: function() {
                                editTableTelephone = this.value;
                                tableInfo['phone_field'] = this.value;
                                tableInfo['displayPhoneFieldName'] = this.selectedOptions[0].textContent;
                            }
                        },
                        [
                            m('option', {
                                value: '',
                            }, ''),
                            editTableName
                                ? fieldlist[editTableName].map((item) =>
                                    (item.type == 3 || item.type == 1)
                                        ? m('option', {
                                                value: item.id,
                                                selected: (editTableTelephone == item.id)
                                            }, item.name): null)
                                : null
                        ])
                    ]),
                    m('div', {
                        class: 'setting-block--TableSetting-elements',
                    },[
                        m('label', {
                            class: 'setting-block--TableSetting-elements--label',
                        },  l.Field_Telephone_Name + ':'),
                        m(Select, {
                            name: 'tableTelephoneName',
                            class: 'form-control form-control-160',
                            onchange: function() {
                                editTableTelephoneName = this.value;
                                tableInfo['name_field'] = this.value;
                            }
                        }, [
                            m('option', {
                                value: '',
                            }, ''),
                            editTableName
                                ? fieldlist[editTableName].map((item) =>
                                    m('option', {
                                        value: item.id,
                                        selected: (editTableTelephoneName == item.id)
                                    }, item.name))
                                : null
                        ])
                    ]),
                    m('div', {}, l.display_3_fields + ':'),
                    m('div', {
                        class: 'setting-block--TableSetting-elements',
                    },[
                        m('label', {
                            class: 'setting-block--TableSetting-elements--label',
                        }, l.Additional_field + ' 1:'),
                        m(Select, {
                            name: 'tableAdditionalField1',
                            class: 'form-control form-control-160',
                            onchange: function() {
                                editTableAdditionalField1 = this.value;
                                tableInfo['additonal_field_1'] = this.value;
                            }
                        }, [
                            m('option', {
                                value: '',
                            }, ''),
                            editTableName
                                ? fieldlist[editTableName].map((item) =>
                                    m('option', {
                                        value: item.id,
                                        selected: (editTableAdditionalField1 == item.id)
                                    }, item.name))
                                : null
                        ])
                    ]),
                    m('div', {
                        class: 'setting-block--TableSetting-elements',
                    },[
                        m('label', {
                            class: 'setting-block--TableSetting-elements--label',
                        }, l.Additional_field + ' 2:'),
                        m(Select, {
                            name: 'tableAdditionalField2',
                            class: 'form-control form-control-160',
                            onchange: function() {
                                editTableAdditionalField2 = this.value;
                                tableInfo['additonal_field_2'] = this.value;
                            }
                        }, [
                            m('option', {
                                value: '',
                            }, ''),
                            editTableName
                                ? fieldlist[editTableName].map((item) =>
                                    m('option', {
                                        value: item.id,
                                        selected: (editTableAdditionalField2 == item.id)
                                    }, item.name))
                                : null
                        ])
                    ]),
                    m('div', {
                        class: 'setting-block--TableSetting-elements',
                    },[
                        m('label', {
                            class: 'setting-block--TableSetting-elements--label',
                        }, l.Additional_field + ' 3:'),
                        m(Select, {
                            name: 'tableAdditionalField3',
                            class: 'form-control form-control-160',
                            onchange: function() {
                                editTableAdditionalField3 = this.value;
                                tableInfo['additonal_field_3'] = this.value;
                            }
                        }, [
                            m('option', {
                                value: '',
                            }, ''),
                            editTableName
                                ? fieldlist[editTableName].map((item) =>
                                    m('option', {
                                        value: item.id,
                                        selected: (editTableAdditionalField3 == item.id)
                                    }, item.name))
                                : null
                        ])
                    ]),
                    tableDontSave ? m('div', {
                        class: 'setting-block--TableSetting-elements',
                        style: 'text-align: center;color: red;'
                    },tableBadMessage) : null,
                    m('button', {
                        class: 'btn-save',
                        onclick: async function() {
                            if (editTableName == '' || editTablePriority == '' || editTableTelephone == '' || editTableTelephoneName == '') {
                                tableDontSave = true;
                                tableBadMessage = l.Fields_are_not_filled;
                                return false;
                            } else {
                                tableDontSave = false;
                                tableBadMessage = '';
                            }
                            for(let key in arrTables){
                                if (arrTables[key]['id'] == table_id) {
                                    table_id = key;
                                    break;
                                }
                            }
                            setting['accountEdit'] = false;
                            setting['tableCallAddOrEdit'] = false;
                            setting['addUser'] = false;
                            setting['addLandline'] = false;
                            if (table_id == -1) {
                                tableInfo['id'] = arrTables.length;
                                arrTables.push(tableInfo);
                            } else {
                                arrTables[table_id] = tableInfo;
                            }
                            table_id = -1;
                            tableId = -1;
                            editTableName = '';
                            editTablePriority = '';
                            editTableTelephone = '';
                            editTableTelephoneName = '';
                            editTableAdditionalField1 = '';
                            editTableAdditionalField2 = '';
                            editTableAdditionalField3 = '';
                            displayTableName = '';
                            displayPhoneFieldName = '';
                            tableInfo = {};
                            arrTables.sort(sortByField('displayPhoneFieldName'));
                            result.data.attributes.value.personal_account_details = connecting;
                            result.data.attributes.value.call_tables = arrTables;
                            result.data.attributes.value.conversation_records_table = linkConversationRecordsTable;
                            result.data.attributes.value.users = arrUsers;
                            result.data.attributes.value.land_line_info = arrLandline;
                            requestOptionsPatch['body'] = JSON.stringify(result, null, 4);
                            let setData = await fetch(`./${url}`, requestOptionsPatch);
                            let resultPatch = setData.json();
                            if (resultPatch) {
                                displayNotification(l.settings_saved, 1);
                            } else {
                                displayNotification(l.settings_not_saved, 2);
                            }
                            m.redraw();
                        }
                    }, l.Save)
                ]) : null;
            }
        }
    }
    function addUserComponent() {
        // ----- локальное состояние компонента -----
        let currentKey = -1; // ключ (индекс/ид) в arrUsers, с которым сейчас работаем
        let editUser = '';
        let editSipLogin = '';
        let editSipPassword = '';
        let editShortSipNumber = '';
        let displayUserName = '';
        let userInfo = {
            cb_user: editUser,
            sip_number: editSipLogin,
            sip_password: editSipPassword,
            short_sip_number: editShortSipNumber,
            displayUserName: displayUserName
        };
        let sipNumberDontSave = false;
        let sipNumberBadMessage = '';

        // ----- утилиты -----
        const hasOwn = (obj, k) => Object.prototype.hasOwnProperty.call(obj, k);
        const isArrayUsers = () => Array.isArray(arrUsers);

        // Нормализуем входной userId в строку (часто ключи объектов строковые)
        function normalizeId(val) {
            if (val == null || val === -1 || val === "-1") return null;
            return String(val);
        }

        // Найти "ключ" в arrUsers разными способами:
        // 1) прямой ключ;
        // 2) поиск по значению поля cb_user (как строке).
        function findUserKeyById(idLike) {
            if (!arrUsers) return null;

            const sought = normalizeId(idLike);
            if (!sought) return null;

            if (isArrayUsers()) {
            // массив: ключ — числовой индекс
            const idx = Number(sought);
            return Number.isInteger(idx) && arrUsers[idx] ? String(idx) : null;
            } else {
            // объект: ключ — строка
            if (hasOwn(arrUsers, sought)) return sought;
            }

            // поиск по cb_user
            for (const k in arrUsers) {
            if (!hasOwn(arrUsers, k)) continue;
            const u = arrUsers[k];
            if (u && String(u.cb_user) === sought) return k;
            }
            return null;
        }

        // Сброс локального состояния
        function resetState() {
            editUser = '';
            editSipLogin = '';
            editSipPassword = '';
            editShortSipNumber = '';
            displayUserName = '';
            userInfo = {
            cb_user: '',
            sip_number: '',
            sip_password: '',
            short_sip_number: '',
            displayUserName: ''
            };
        }

        // Заполнить локальное состояние из arrUsers по ключу
        function fillFromKey(key) {
            if (!arrUsers || key == null || !hasOwn(arrUsers, key) || !arrUsers[key]) {
            resetState();
            currentKey = -1;
            return;
            }
            const u = arrUsers[key];
            editUser = u?.cb_user ?? '';
            editSipLogin = u?.sip_number ?? '';
            editSipPassword = u?.sip_password ?? '';
            editShortSipNumber = u?.short_sip_number ?? '';
            displayUserName = u?.displayUserName ?? '';
            userInfo = { ...u }; // копия, чтобы не мутировать оригинал до сохранения
            currentKey = key;
        }

        // Публичный метод заполнения значений (переписан безопасно)
        function fillValues(inputUserId) {
            if (!arrUsers) {
            resetState();
            currentKey = -1;
            return;
            }
            const key = findUserKeyById(inputUserId);
            if (key == null) {
            // пользователь не найден — чистим поля
            resetState();
            currentKey = -1;
            return;
            }
            fillFromKey(key);
        }

        // Обновить userInfo из локальных полей (перед сохранением)
        function rebuildUserInfo() {
            userInfo = {
            cb_user: editUser ?? '',
            sip_number: editSipLogin ?? '',
            sip_password: editSipPassword ?? '',
            short_sip_number: editShortSipNumber ?? '',
            displayUserName: displayUserName ?? ''
            };
        }

        // Безопасное применение патча на сервере
        async function saveSettings() {
            try {
            requestOptionsPatch.body = JSON.stringify(result, null, 4);
            const resp = await fetch(`./${url}`, requestOptionsPatch);
            const json = await resp.json().catch(() => null);
            if (json) {
                displayNotification(l.settings_saved, 1);
            } else {
                displayNotification(l.settings_not_saved, 2);
            }
            } catch (e) {
            displayNotification(l.settings_not_saved, 2);
            }
        }

        return {
            view: (vnode) => {
            // Если пришёл новый userId — подгрузим его данные
            if (vnode?.attrs?.userId !== currentKey) {
                fillValues(vnode?.attrs?.userId);
            }

            if (!setting['addUser']) return null;

            return m('div', { class: 'setting-block--Users-elements--addBlock' }, [
                // --- User select ---
                m('div', { class: 'setting-block--Users-elements--addBlock-element' }, [
                m('label', { class: 'setting-block--Users-elements--addBlock-element--label' }, l.User + ':'),
                m(Select, {
                    class: 'form-control form-control-160',
                    onchange: function () {
                    // обновляем отображаемое имя и id
                    displayUserName = this.selectedOptions?.[0]?.textContent ?? '';
                    editUser = this.value ?? '';
                    // и userInfo
                    rebuildUserInfo();
                    }
                }, userlist.map((item) =>
                    m.fragment({}, [
                    m('option', {
                        value: item.id,
                        selected: String(editUser) === String(item.id)
                    }, item.name)
                    ])
                ))
                ]),

                // --- SIP number ---
                m('div', { class: 'setting-block--Users-elements--addBlock-element' }, [
                m('label', { class: 'setting-block--Users-elements--addBlock-element--label' }, l.SIP_number + ':'),
                m('input', {
                    class: 'form-control form-control-160',
                    value: editSipLogin,
                    oninput: function () {
                    editSipLogin = this.value;
                    rebuildUserInfo();
                    }
                })
                ]),

                // --- SIP password ---
                m('div', { class: 'setting-block--Users-elements--addBlock-element' }, [
                m('label', { class: 'setting-block--Users-elements--addBlock-element--label' }, l.SIP_password + ':'),
                m('input', {
                    class: 'form-control form-control-160',
                    value: editSipPassword,
                    oninput: function () {
                    editSipPassword = this.value;
                    rebuildUserInfo();
                    }
                })
                ]),

                // --- Short SIP number ---
                m('div', { class: 'setting-block--Users-elements--addBlock-element' }, [
                m('label', { class: 'setting-block--Users-elements--addBlock-element--label' }, l.Short_SIP_number + ':'),
                m('input', {
                    class: 'form-control form-control-160',
                    value: editShortSipNumber,
                    oninput: function () {
                    editShortSipNumber = this.value;
                    rebuildUserInfo();
                    }
                })
                ]),

                // --- Ошибки валидации ---
                sipNumberDontSave
                ? m('div', {
                    class: 'setting-block--Users-elements--addBlock-element',
                    style: 'text-align: center;color: red;'
                    }, sipNumberBadMessage)
                : null,

                // --- Кнопка Сохранить ---
                m('button', {
                class: 'setting-block-elements btn-save',
                onclick: async function () {
                    // простая валидация
                    if (!editUser || !editSipLogin || !editSipPassword || !editShortSipNumber) {
                    sipNumberDontSave = true;
                    sipNumberBadMessage = l.Fields_are_not_filled;
                    m.redraw();
                    return false;
                    } else {
                    sipNumberDontSave = false;
                    sipNumberBadMessage = '';
                    }

                    // Пересобираем userInfo из текущих полей
                    rebuildUserInfo();

                    // Определяем ключ записи, которую сохраняем
                    // Сначала пробуем текущий, затем — поиск по cb_user
                    let keyToSave = (currentKey != null && hasOwn(arrUsers, currentKey)) ? currentKey : findUserKeyById(editUser);

                    // Обновляем UI-флаги
                    setting['accountEdit'] = false;
                    setting['tableCallAddOrEdit'] = false;
                    setting['addUser'] = false;
                    setting['addLandline'] = false;

                    // Сохраняем в общий список
                    if (keyToSave == null) {
                    // новая запись
                    if (isArrayUsers()) {
                        arrUsers.push(userInfo);
                        keyToSave = String(arrUsers.length - 1);
                    } else {
                        // объект — используем cb_user как ключ
                        arrUsers[String(editUser)] = userInfo;
                        keyToSave = String(editUser);
                    }
                    } else {
                    // обновление существующей записи
                    arrUsers[keyToSave] = userInfo;
                    }

                    // Сброс локального состояния
                    currentKey = -1;
                    if (typeof userId !== 'undefined') userId = -1; // если глобалка существует — синхронизируем
                    resetState();

                    // Обновляем result-структуру перед отправкой
                    result.data.attributes.value.personal_account_details = connecting;
                    result.data.attributes.value.call_tables = arrTables;
                    result.data.attributes.value.conversation_records_table = linkConversationRecordsTable;
                    result.data.attributes.value.users = arrUsers;
                    result.data.attributes.value.land_line_info = arrLandline;

                    await saveSettings();
                    m.redraw();
                }
                }, l.Save)
            ]);
            }
        };
        }
    function addLandlineComponent() {
        let landline_id = -1,
            editLandline = '',
            editSipNumberLL = '',
            landlineInfo = {
                'land_line' : editLandline,
                'assigned_sip_number' : editSipNumberLL,
            },
            landlineDontSave = false,
            landlineBadMessage = '';
        function fillValues(landline_id){
            editLandline = landline_id == -1 ? '' : arrLandline[landline_id]['land_line'];
            editSipNumberLL = landline_id == -1 ? '' : arrLandline[landline_id]['assigned_sip_number'];
            for(let key in arrLandline[landlineId]){
                landlineInfo[key] = arrLandline[landlineId][key];
            }
        }
        return {
            view: (vnode) => {
                if(vnode.attrs.landlineId != landline_id){
                    landline_id = vnode.attrs.landlineId;
                    fillValues(vnode.attrs.landlineId)
                }
                return setting['addLandline'] ? m('div', {
                        class: 'setting-block--Users-elements--addBlock'
                    }, [
                    m('div', {
                        class: 'setting-block--Users-elements--addBlock-element',
                    },[
                        m('label', {
                            class: 'setting-block--Users-elements--addBlock-element--label',
                        }, l.Landline_phone_number + ':'),
                        m('input', {
                            class: 'form-control form-control-160',
                            value: editLandline,
                            onchange: function() {
                                editLandline = this.value;
                                landlineInfo['land_line'] = this.value;
                            }
                        })
                    ]),
                    m('div', {
                        class: 'setting-block--Users-elements--addBlock-element',
                    },[
                        m('label', {
                            class: 'setting-block--Users-elements--addBlock-element--label',
                        }, l.SIP_number + ':'),
                        m('input', {
                            class: 'form-control form-control-160',
                            value: editSipNumberLL,
                            onchange: function() {
                                editSipNumberLL = this.value;
                                landlineInfo['assigned_sip_number'] = this.value;
                            }
                        })
                    ]),
                    landlineDontSave ? m('div', {
                        class: 'setting-block--Users-elements--addBlock-element',
                        style: 'text-align: center;color: red;'
                    }, landlineBadMessage) : null,
                    m('button', {
                        class: 'setting-block-elements btn-save',
                        onclick: async function() {
                            if (editLandline == '' || editSipNumberLL == '') {
                                landlineDontSave = true;
                                landlineBadMessage = l.Fields_are_not_filled;
                                return false;
                            } else {
                                landlineDontSave = false;
                                landlineBadMessage = '';
                            }
                            setting['accountEdit'] = false;
                            setting['tableCallAddOrEdit'] = false;
                            setting['addUser'] = false;
                            setting['addLandline'] = false;
                            if (landline_id == -1) {
                                arrLandline.push(landlineInfo);
                            } else {
                                arrLandline[landline_id] = landlineInfo;
                            }
                            landline_id = -1;
                            landlineId = -1;
                            editLandline = '';
                            editSipNumberLL = '';
                            landlineInfo = {};
                            result.data.attributes.value.personal_account_details = connecting;
                            result.data.attributes.value.call_tables = arrTables;
                            result.data.attributes.value.conversation_records_table = linkConversationRecordsTable;
                            result.data.attributes.value.users = arrUsers;
                            result.data.attributes.value.land_line_info = arrLandline;
                            requestOptionsPatch['body'] = JSON.stringify(result, null, 4);
                            let setData = await fetch(`./${url}`, requestOptionsPatch);
                            let resultPatch = setData.json();
                            if (resultPatch) {
                                displayNotification(l.settings_saved, 1);
                            } else {
                                displayNotification(l.settings_not_saved, 2);
                            }
                            m.redraw();
                        }
                    }, l.Save)
                ]) : null
            }
        }
    }
    return {
        oninit: async function() {
          /**
           * Рекурсивно получить всех активных пользователей.
           * @param {Array<Object>} arr   массив(хранилище) активных пользователей
           * @param {Number} offset       смещение
           * @returns {Object}            jsonapi объект
           */
          async function getAllActiveUsers(arr = [], offset = 0) {
            let response = await fetch(`./api/dev/users/?page[limit]=50&page[offset]=${offset}`, {
              "headers": { "x-auth-token": CB.globals.x_auth_token },
              "method": "GET",
              "credentials": "include"
            });
            let result = await response.json();
            if (result.data.length > 0) {
              let temp = [];
              result.data.forEach(i => {
                if (i?.attributes?.arc == 0) {
                  temp.push(i);
                }
              });
              arr = [...arr, ...temp];
              return await getAllActiveUsers(arr, (offset+=50));
            } else {
              return {data: arr};
            }
          }


            let requestOptions = {
                method: 'GET',
                credentials: "include"
            };
            if (window.x_auth_token) {
                requestOptions.headers = {
                    'X-Auth-Token' : window.x_auth_token
                }
            }

            let setData = await fetch(`./${url}`, requestOptions);
                result = await setData.json();
                delete(result.data.attributes.name);
            let tablesAndFields = await fetch("./api/dev/metadataset", requestOptions),
                tablesAndFieldsResult = await tablesAndFields.json(),
                usersResult = await getAllActiveUsers([], 0),
                fldIds = {},
                fldNms = {};
                tablist = Object.keys(tablesAndFieldsResult.tables).reduce(function(total,key){
                    total.push({id:tablesAndFieldsResult.tables[key].id,name:tablesAndFieldsResult.tables[key].name});
                    return total;
                },[{id:'',name:''}]);
                fieldlist = Object.keys(tablesAndFieldsResult.fields).reduce(function(total,key){
                    var result = Object.keys(tablesAndFieldsResult.fields[key]).reduce(function(tot,k){
                        var fi = tablesAndFieldsResult.fields[key][k];
                        tot.push({id:fi.db_name_field,name:fi.name,num:fi.num,type:fi.type});
                        return tot;
                    },[]);
                    result.sort(function(a,b){return (a.name==b.name)?0:((a.name>b.name)?+1:-1)});
                    fldIds[key] = Object.keys(tablesAndFieldsResult.fields[key]).reduce(function(tot,k){
                        tot[tablesAndFieldsResult.fields[key][k].name] = tablesAndFieldsResult.fields[key][k].db_name_field;
                        tot[tablesAndFieldsResult.fields[key][k].db_name_field] = tablesAndFieldsResult.fields[key][k].db_name_field;
                        tot[tablesAndFieldsResult.fields[key][k].id] = tablesAndFieldsResult.fields[key][k].db_name_field;
                        return tot;
                    },{});
                    fldNms[key] = Object.keys(tablesAndFieldsResult.fields[key]).reduce(function(tot,k){
                        tot[tablesAndFieldsResult.fields[key][k].name] = tablesAndFieldsResult.fields[key][k].name;
                        tot[tablesAndFieldsResult.fields[key][k].db_name_field] = tablesAndFieldsResult.fields[key][k].name;
                        tot[tablesAndFieldsResult.fields[key][k].id] = tablesAndFieldsResult.fields[key][k].name;
                        return tot;
                    },{});
                    total[key] = result;
                    return total;
                },{});
                userlist = usersResult.data.reduce(function(total,key){
                    total.push({id:key.id,name:key.attributes.fio});
                    return total;
                },[{id:'',name:''}]);
            if (result.data.attributes.value) {
                if (result.data.attributes.value.personal_account_details) {
                    connecting = {
                        'loginPBX' : result.data.attributes.value.personal_account_details.loginPBX ? result.data.attributes.value.personal_account_details.loginPBX : '',
                        'passwordPBX' : result.data.attributes.value.personal_account_details.passwordPBX ? result.data.attributes.value.personal_account_details.passwordPBX : '',
                        'server' : result.data.attributes.value.personal_account_details.server ? result.data.attributes.value.personal_account_details.server : '',
                        'port' : result.data.attributes.value.personal_account_details.port ? result.data.attributes.value.personal_account_details.port : '',
                        'domain' : result.data.attributes.value.personal_account_details.domain ? result.data.attributes.value.personal_account_details.domain : '',
                        'rkey' : result.data.attributes.value.personal_account_details.rkey ? result.data.attributes.value.personal_account_details.rkey : '',
                        'SIPnumber' : result.data.attributes.value.personal_account_details.SIPnumber ? result.data.attributes.value.personal_account_details.SIPnumber : '',
                        'SIPpassword' : result.data.attributes.value.personal_account_details.SIPpassword ? result.data.attributes.value.personal_account_details.SIPpassword : ''
                    }
                };
                if (result.data.attributes.value.call_tables.length > 0) {
                    for (let i = 0; i < result.data.attributes.value.call_tables.length; i++) {
                        arrTables[i] = {};
                        for(let key in result.data.attributes.value.call_tables[i]){
                            arrTables[i][key] = result.data.attributes.value.call_tables[i][key];
                        }
                        arrTables[i]['displayTableName'] = tablist.filter(function(el) {
                            return el.id == arrTables[i]['table'];
                        })[0]?.name || "";
                        tableId = arrTables[i]['table'];
                    }
                };
                if (result.data.attributes.value.users.length > 0) {
                  let all_users = new Array();
                  result.data.attributes.value.users.forEach((item) => {
                    if (item !== null) {
                      all_users.push(item);
                    }
                  });

                    for (let i = 0; i < all_users.length; i++) {
                        arrUsers[i] = {};
                        for(let key in result.data.attributes.value.users[i]){
                            arrUsers[i][key] = result.data.attributes.value.users[i][key];
                        }
                        arrUsers[i]['displayUserName'] = userlist.filter(function(el) {
                            return el.id == arrUsers[i]['cb_user'];
                        })[0]?.name || "";
                        userId = arrUsers[i]['cb_user'];
                    }
                };
                if (result.data.attributes.value.land_line_info.length > 0) {
                    for (let i = 0; i < result.data.attributes.value.land_line_info.length; i++) {
                        arrLandline[i] = {};
                        for(let key in result.data.attributes.value.land_line_info[i]){
                            arrLandline[i][key] = result.data.attributes.value.land_line_info[i][key];
                        }
                        userId = i;
                    }
                };
                if (result.data.attributes.value.conversation_records_table != 0) {
                    linkConversationRecordsTable = result.data.attributes.value.conversation_records_table;
                }
                setting['saveSetting'] = true;
                dataHere = true;
                m.redraw();
            } else {
                badMessage = 'This is bad';
            }
        },
        view: function(){
            return  !dataHere ? m('div', {
                style: 'text-align: center;'
            }, badMessage ? badMessage: [
                m('img', {
                    src: `./stocks/telephony/images/preloader.gif`,
                    alt: 'preloader'
                })
            ]) :
            m('div', {
                class: 'setting-block'
            }, [
                m('div', {
                    class: 'setting-block-elements setting-block--SIP'
                },
                [
                    m('div', {
                        class: 'setting-block-element-header'
                    }, l.SIP_account),
                    m('div', {class: "setting-block-element--content"}, [
                        m('div', {
                            class: 'setting-block--Table-elements'
                        }, (connecting.loginPBX != '') ? connecting.loginPBX : l.Not_chosen),
                        m('span', {
                            class: 'setting-block--Table-elements setting-block--Table-elements--span',
                            onclick: function() {
                                setting['accountEdit'] = setting['accountEdit'] ? false : true;
                            }
                        }, l.edit)
                    ]),
                    m(accountSettingComponent, {})
                ]),
                setting['saveSetting'] ? m('div', {
                    class: 'setting-block-elements'
                },
                [
                    m('div', {
                        class: 'setting-block-element-header'
                    }, l.Contact_records_tables),
                    m('div', {
                        class: 'setting-block--Table'
                    }, arrTables.map((item, index) => m.fragment({},[
                        m('div', {class: "setting-block-element--content"}, [
                            m('div', {
                                class: 'setting-block--Table-elements'
                            },(item['displayPhoneFieldName'] && item['displayPhoneFieldName'] != '') ? (item['displayTableName'] + ' / ' + item['displayPhoneFieldName']) : item['displayTableName']),
                            m('span', {
                                class: 'setting-block--Table-elements setting-block--Table-elements--span',
                                onclick: function() {
                                    if (tableId == item['id'] && setting['tableCallAddOrEdit']) {
                                        setting['tableCallAddOrEdit'] = false;
                                    } else {
                                        tableId = item['id'];
                                        setting['tableCallAddOrEdit'] = true;
                                    }
                                }
                            }, l.edit),
                            m('span', {}, '|'),
                            m('span', {
                                class: 'setting-block--Table-elements setting-block--Table-elements--span',
                                onclick: async function() {
                                    arrTables.splice(index, 1);
                                    result.data.attributes.value.personal_account_details = connecting;
                                    result.data.attributes.value.call_tables = arrTables;
                                    result.data.attributes.value.conversation_records_table = linkConversationRecordsTable;
                                    result.data.attributes.value.users = arrUsers;
                                    result.data.attributes.value.land_line_info = arrLandline;
                                    requestOptionsPatch['body'] = JSON.stringify(result, null, 4);
                                    let setData = await fetch(`./${url}`, requestOptionsPatch);
                                    let resultPatch = setData.json();
                                    if (resultPatch) {
                                        displayNotification(l.settings_saved, 1);
                                    } else {
                                        displayNotification(l.settings_not_saved, 2);
                                    }
                                }
                            }, l.delete)
                        ])
                    ]))),
                    m('div', {
                        class: 'setting-block--TableSetting-add',
                        onclick: function() {
                            tableId = -1;
                            if (setting['tableCallAddOrEdit']) {
                                setting['tableCallAddOrEdit'] = false;
                            } else {
                                setting['tableCallAddOrEdit'] = true;
                            }
                        }
                    }, l.Add),
                    m(tableSettingComponent, {tableId})
                ]) : null,
                setting['saveSetting'] ? m('div', {
                    class: 'setting-block-elements'
                },
                [
                    m('div', {
                        class: 'setting-block-element-header'
                    }, l.Call_records_table),
                    m('a', {
                        target: "_blank",
                        href: "./fields.php?table=" + linkConversationRecordsTable,
                        class: 'setting-block--TableCalls-link'
                    }, l.Open_table)
                ]) : null,
                setting['saveSetting'] ? m('div', {
                    class: 'setting-block-elements'
                },
                [
                    m('div', {
                        class: 'setting-block-element-header'
                    }, l.Users),
                    m('div', {
                        class: 'setting-block--Users-elements--list'
                    }, [
                        m('div', {
                            class: 'setting-block--Users-elements--list-elem',
                        },[
                            arrUsers.map((item, index) => m.fragment({},[
                                m('div', {class: "setting-block-element--content"},
                                [
                                    m('div', {}, item.displayUserName),
                                    m('div', {
                                        class: 'setting-block--Users-elements--list-elem--edit',
                                        onclick: function() {
                                            if (userId == item.cb_user && setting['addUser']) {
                                                setting['addUser'] = false;
                                            } else {
                                                userId = item.cb_user;
                                                setting['addUser'] = true;
                                            }
                                        }
                                    }, l.edit),
                                    m('div', {}, ' | '),
                                    m('div', {
                                        class: 'setting-block--Users-elements--list-elem--edit',
                                        onclick: async function() {
                                            arrUsers.splice(index, 1);
                                            result.data.attributes.value.personal_account_details = connecting;
                                            result.data.attributes.value.call_tables = arrTables;
                                            result.data.attributes.value.conversation_records_table = linkConversationRecordsTable;
                                            result.data.attributes.value.users = arrUsers;
                                            result.data.attributes.value.land_line_info = arrLandline;
                                            requestOptionsPatch['body'] = JSON.stringify(result, null, 4);
                                            let setData = await fetch(`./${url}`, requestOptionsPatch);
                                            let resultPatch = setData.json();
                                            if (resultPatch) {
                                                displayNotification(l.settings_saved, 1);
                                            } else {
                                                displayNotification(l.settings_not_saved, 2);
                                            }
                                        }
                                    }, l.delete)
                                ])
                            ]))
                        ])
                    ]),
                    m('div', {
                        class: 'setting-block--Users-elements--add',
                        onclick: function () {
                            userId = -1;
                            if (setting['addUser']) {
                                setting['addUser'] = false;
                            } else {
                                setting['addUser'] = true;
                            }
                        }
                    }, l.Add),
                    m(addUserComponent, {userId})
                ]) : null,
                setting['saveSetting'] ? m('div', {
                    class: 'setting-block-elements'
                },
                [
                    m('div', {
                        class: 'setting-block-element-header'
                    }, l.Land_line),
                    m('div', {
                        class: 'setting-block--Users-elements--list'
                    }, [
                        m('div', {
                            class: 'setting-block--Users-elements--list-elem',
                        },[
                            arrLandline.map((item, index) => m.fragment({},[
                                m('div', {class: "setting-block-element--content"},
                                [
                                    m('div', {}, item.land_line),
                                    m('div', {
                                        class: 'setting-block--Users-elements--list-elem--edit',
                                        onclick: function() {
                                            if (landlineId == index && setting['addLandline']) {
                                                setting['addLandline'] = false;
                                            } else {
                                                landlineId = index;
                                                setting['addLandline'] = true;
                                            }
                                        }
                                    }, l.edit),
                                    m('div', {}, ' | '),
                                    m('div', {
                                        class: 'setting-block--Users-elements--list-elem--edit',
                                        onclick: async function() {
                                            arrLandline.splice(index, 1);
                                            result.data.attributes.value.personal_account_details = connecting;
                                            result.data.attributes.value.call_tables = arrTables;
                                            result.data.attributes.value.conversation_records_table = linkConversationRecordsTable;
                                            result.data.attributes.value.users = arrUsers;
                                            result.data.attributes.value.land_line_info = arrLandline;
                                            requestOptionsPatch['body'] = JSON.stringify(result, null, 4);
                                            let setData = await fetch(`./${url}`, requestOptionsPatch);
                                            let resultPatch = setData.json();
                                            if (resultPatch) {
                                                displayNotification(l.settings_saved, 1);
                                            } else {
                                                displayNotification(l.settings_not_saved, 2);
                                            }
                                        }
                                    }, l.delete)
                                ])
                            ]))
                        ])
                    ]),
                    m('div', {
                        class: 'setting-block--Users-elements--add',
                        onclick: function () {
                            landlineId = -1;
                            if (setting['addLandline']) {
                                setting['addLandline'] = false;
                            } else {
                                setting['addLandline'] = true;
                            }
                        }
                    }, l.Add),
                    m(addLandlineComponent, {landlineId})
                ]) : null
            ]);
        }
    }
}
