import { msgBus } from "../events/MsgBus.js";
import { $iq, $pres, Strophe } from 'strophe.js';
import { saveBookmarks } from '../dialogs/Dialogs.js';
import { login } from "../xmpp/handlers.js";
import { setPreference } from "../utils/prefs.js";
import { DataTip } from "../ui/data-tip.js";
import { LiveConfig } from "../config.js";
import { Application } from "../app-state.js";

Application.log = function(text) {
    console.log("Application.log:", text);
};

function onPresenceCheck(item) {
    if (item.xmpp === 'available') {
        Application.XMPPConn.send($pres());
    } else {
        Application.XMPPConn.send($pres().c('show', 'away').up().c('status',
                item.xmpp));
    }
    Ext.getCmp("presenceUI").setText(item.text);
}

Application.Control = {
    region : 'west',
    title : 'Weather.IM Live',
    collapsible : true,
    width : 200,
    split : true,
    layout : 'accordion',
    layoutConfig : {
        autoWidth : false
    },
    autoScroll : true,
    tbar : [{
        text : "Actions",
        menu : [{
                    checked : false,
                    text : 'Show Offline Buddies',
                    checkHandler(item, checked) {

                        Ext.getCmp('buddies').getRootNode().cascade(function(n) {
                                    if (checked) {
                                        n.set('hidden', false);
                                    } else {
                                        if (n.data.presence === 'offline') {
                                            n.set('hidden', true);
                                        }
                                    }
                                });
                    }
                }, {
                    xtype : 'menuitem',
                    text : 'Chat with User',
                    handler() {
                        Application.CreatePrivateChat.show();
                    }
                }, {
                    xtype : 'menuitem',
                    text : 'Add Buddy...',
                    handler() {
                        Application.buildAddBuddy(null,null,null);
                    }
                },{
                    xtype : 'menuitem',
                    text : 'Join Group Chat',
                    handler() {
                        Application.JoinChatroomDialog.show();
                    }
                }, {
                    text : 'Msg Text Color',
                    menu : {
                        items : [
                            new Ext.ColorPalette({
                                id : 'fgcolor',
                                value : '000000',
                                listeners : {
                                    select(cp,color){
                                        setPreference('fgcolor', color);
                                    }
                                }
                            })
                        ]
                    }
                },{
                    text : 'Msg Background Color',
                    menu : {
                        items : [
                            new Ext.ColorPalette({
                                id : 'bgcolor',
                                value : 'FFFFFF',
                                listeners : {
                                    select(cp,color){
                                        setPreference('bgcolor', color);
                                    }
                                }
                            })
                        ]
                    }
                },{
                    xtype : 'menuitem',
                    text : 'Show Debug Window',
                    handler() {
                        Ext.getCmp("debug").show();

                    }
                },{
                    xtype : 'menuitem',
                    text : 'Log Out',
                    handler() {
                        /* Don't try to reconnect */
                        Application.log("Manual logout requested.");
                        Application.manualLogout = true;
                        Application.RECONNECT = false;
                        Application.XMPPConn.disconnect();
                    }
                }]
    }, {
        xtype : 'tbseparator'
    }, {
        text : 'Available',
        id : 'presenceUI',
        menu : {
            items : [{
                        text : 'Available',
                        xmpp : 'available',
                        checked : true,
                        group : 'presence',
                        checkHandler : onPresenceCheck
                    }, {
                        text : 'Be Right Back',
                        xmpp : 'Be Right Back',
                        checked : false,
                        group : 'presence',
                        checkHandler : onPresenceCheck
                    }, {
                        text : 'Away',
                        xmpp : 'away',
                        checked : false,
                        group : 'presence',
                        checkHandler : onPresenceCheck
                    }]
        }
    }, {
        xtype : 'splitbutton',
        id : 'sound',
        scale : 'medium',
        soundOn : true,
        handler(btn) {
            if (btn.soundOn) {
                btn.setIcon('icons/mute.png');
                Application.audioMuted = true;
                btn.soundOn = false;
            } else {
                btn.setIcon('icons/volume.png');
                Application.audioMuted = false;
                btn.soundOn = true;
                msgBus.fire("soundevent", "default");
            }
        },
        arrowHandler() {
            Application.soundPrefs.show();
        },
        icon : 'icons/volume.png'
    }, {
        xtype : 'tbfill'
    }, {
        xtype : 'tbtext',
        id : 'connection-status-text',
        text : 'Status: Signed out'
    }],
    items : [{
                flex : 1,
                xtype : 'treepanel',
                id : 'buddies',
                title : 'Buddies',
                collapsed : false,
                rootVisible : false,
                lines : false,
                autoScroll : true,
                containerScroll: true,
                plugins: new DataTip({
                    tpl: new Ext.XTemplate(
                    '<tpl if="typeof(resources) !== &quot;undefined&quot; && resources && resources.items">',
                    '<div>',
                    '<tpl for="resources.items">',
                        '<p><b>Resource:</b> {resource} <b>Status:</b> {status}</p>',
                    '</tpl>',
                    '</div>',
                    '</tpl>'
                    )
                }),
                listeners : {
                    // In ExtJS 6, itemclick event for tree panels
                    itemclick : (_view, record) => {
                        let cp = Ext.getCmp("chatpanel").getChat( record.data.barejid );
                        if (! cp){
                            cp = Ext.getCmp("chatpanel").addChat( record.data.barejid );
                        }
                        Ext.getCmp("chatpanel").setActiveTab(cp);
                    }
                },
                root : {}
            }, {
                flex : 1,
                xtype : 'treepanel',
                id : 'bookmarks',
                title : 'Chatroom Bookmarks',
                collapsed : false,
                rootVisible : false,
                enableDD : true,
                lines : false,
                containerScroll: true,
                autoScroll : true,
                plugins: new DataTip({
                    tpl: '<div>Anonymous: {anonymous}<br />Autojoin: {autojoin}</div>'
                }),
                contextMenu : new Ext.menu.Menu({
                            items : [{
                                id : 'delete-node',
                                icon : 'icons/close.png',
                                text : 'Delete Bookmark'
                            }],
                            listeners : {}
                        }),
                viewConfig: {
                    listeners: {
                        itemcontextmenu(view, record, item, index, e) {
                            e.preventDefault();
                            view.getSelectionModel().select(record);
                            const c = view.ownerCt.contextMenu;
                            c.contextNode = record;
                            setTimeout(() => {
                                c.showAt(e.getXY());
                                if (c.el && c.el.dom) {
                                    c.el.dom.focus();
                                }
                                // Add direct click handler to menu item for actual delete logic
                                const menuItem = c.items && c.items.items && c.items.items[0];
                                if (menuItem && !menuItem._debugClickAttached) {
                                    menuItem._debugClickAttached = true;
                                    menuItem.on('click', function() {
                                        const ctxRecord = c.contextNode;
                                        if (!ctxRecord) {
                                            return;
                                        }
                                        if (!ctxRecord.parentNode) {
                                            return;
                                        }
                                        ctxRecord.remove();
                                        saveBookmarks();
                                    });
                                }
                            }, 10);
                        }
                    }
                },
                listeners : {
                    movenode(){
                        saveBookmarks();
                    },
                    itemclick(_view, record) {  // this
                        Application.JoinChatroomDialog.show(null, function(){
                            const form = this.items.items[0].getForm();
                            form.findField("roomname").setValue(Strophe.getNodeFromJid(record.data.jid));
                            form.findField("roomhandle").setValue(record.data.handle);
                            form.findField("bookmark").enable();
                            form.findField("anonymous").setValue(record.data.anonymous);
                            form.findField("autojoin").setValue(record.data.autojoin);
                            form.findField("roomalias").setValue(record.data.alias);
                            });
                        }
                },
                root : {
                    text: "Bookmarks",
                    expanded: true,
                    children: [],
                    listeners: {
                        beforeappend(parentNode, node) {
                            /* Ensure that we are appending a unique node */
                            const oldnode = parentNode.findChild('jid', node.data.jid);
                            if (oldnode) {
                                Application.log("Replacing MUC bookmark: "+ node.data.jid );
                                parentNode.removeChild(oldnode, true);
                            }
                            return true; /* lets be safe */
                        }
                    }
                }
            }, {
                flex : 2,
                xtype : 'treepanel',
                id : 'chatrooms',
                title : 'Chatrooms',
                collapsed : false,
                rootVisible : false,
                lines : false,
                autoScroll : true,
                containerScroll: true,
                listeners : {
                    itemclick(_view, record) {  // this
                        Application.JoinChatroomDialog.show(null, function(){
                            const form = this.items.items[0].getForm();
                            const defaultHandle = Application.USERNAME ||
                                (Application.XMPPConn && Application.XMPPConn.jid
                                    ? Strophe.getNodeFromJid(Application.XMPPConn.jid)
                                    : "");
                            form.findField("roomname").setValue(Strophe.getNodeFromJid(record.data.jid));
                            form.findField("roomhandle").setValue(defaultHandle);
                            form.findField("bookmark").enable();
                            form.findField("anonymous").setValue(false);
                            form.findField("autojoin").setValue(false);
                            form.findField("roomalias").setValue(Strophe.getNodeFromJid(record.data.jid));
                            });
                    }
                },
                root : {}
            }]
};

function doLogin() {
    Application.lastLoginMode = "password";
    Application.manualLogout = false;
    Application.RECONNECT = false;
    Application.ATTEMPTS += 1;
    if (Application.ATTEMPTS > 11){
        Application.log("Application Login Limit Reached!");
        return;
    }

    // Get username from HTML input or ExtJS component
    const usernameField = Ext.getCmp('username') || document.getElementById('username');
    let username = usernameField.getValue ? usernameField.getValue() : usernameField.value;

    if (username.indexOf("@") > 0) {
        username = Strophe.getNodeFromJid(username);
    }
    username = username.toLowerCase();
    username = username.replace(/^\s+|\s+$/g, '');

    // Get password from HTML input or ExtJS component
    const passwordField = Ext.getCmp('password') || document.getElementById('password');
    const password = passwordField.getValue ? passwordField.getValue() : passwordField.value;

    if (username === "") {
        Application.log("Invalid Username");
        return;
    }
    if (password === "") {
        Application.log("Invalid Password");
        return;
    }

    const loginPanel = Ext.getCmp("loginpanel");
    if (loginPanel && loginPanel.clearMessage) {
        loginPanel.clearMessage();
    }

    login(username, password);
};


Application.ServiceGuard = {
    skipFirst : true,
    pingInFlight : false,
    pingTimeoutMs : 15000,
    run() {
        if (this.skipFirst) {
            this.skipFirst = false;
            return;
        }
        if (!Application.XMPPConn) {
            return;
        }
        // if (!Application.XMPPConn.authenticated &&
        // Application.log("Encountered Unaccounted for disconnect!");
        // msgBus.fire('loggingout');
        // }
        if (Application.XMPPConn.authenticated) {
            if (this.pingInFlight) {
                return;
            }

            this.pingInFlight = true;
            const guard = this;
            const stanza = $iq({
                type: 'get',
                to: LiveConfig.XMPPHOST,
                id: `svc-ping-${Date.now()}`,
            }).c('ping', {
                xmlns: 'urn:xmpp:ping',
            });

            Application.XMPPConn.sendIQ(
                stanza,
                function () {
                    guard.pingInFlight = false;
                },
                function () {
                    guard.pingInFlight = false;
                },
                this.pingTimeoutMs,
            );
        }
    },
    interval : 55000
};

export { doLogin };
