import bootstrap from "bootstrap.native";
import tpl_login_panel from "./templates/loginpanel.js";
import { Model } from '@converse/skeletor/src/model.js';
import { View } from "@converse/skeletor/src/view";
import { __ } from '../../i18n';
import { _converse, api, converse } from "@converse/headless/core";

const u = converse.env.utils;
const { Strophe } = converse.env;

const REPORTABLE_STATUSES = [
    0, // ERROR'
    1, // CONNECTING
    2, // CONNFAIL
    3, // AUTHENTICATING
    4, // AUTHFAIL
    7, // DISCONNECTING
   10  // RECONNECTING
];

const PRETTY_CONNECTION_STATUS = {
    0: 'Error',
    1: 'Connecting',
    2: 'Connection failure',
    3: 'Authenticating',
    4: 'Authentication failure',
    5: 'Connected',
    6: 'Disconnected',
    7: 'Disconnecting',
    8: 'Attached',
    9: 'Redirect',
   10: 'Reconnecting'
};

const CONNECTION_STATUS_CSS_CLASS = {
   'Error': 'error',
   'Connecting': 'info',
   'Connection failure': 'error',
   'Authenticating': 'info',
   'Authentication failure': 'error',
   'Connected': 'info',
   'Disconnected': 'error',
   'Disconnecting': 'warn',
   'Attached': 'info',
   'Redirect': 'info',
   'Reconnecting': 'warn'
};


export const LoginPanelModel = Model.extend({
   defaults: {
         // Passed-by-reference. Fine in this case because there's
         // only one such model.
         'errors': [],
   }
});


export const LoginPanel = View.extend({
   tagName: 'div',
   id: "converse-login-panel",
   className: 'controlbox-pane fade-in row no-gutters',
   events: {
         'submit form#converse-login': 'authenticate',
         'change input': 'validate'
   },

   initialize () {
         this.listenTo(this.model, 'change', this.render)
         this.listenTo(_converse.connfeedback, 'change', this.render);
         this.render();
   },

   toHTML () {
         const connection_status = _converse.connfeedback.get('connection_status');
         let feedback_class, pretty_status;
         if (REPORTABLE_STATUSES.includes(connection_status)) {
            pretty_status = PRETTY_CONNECTION_STATUS[connection_status];
            feedback_class = CONNECTION_STATUS_CSS_CLASS[pretty_status];
         }
         return tpl_login_panel(
            Object.assign(this.model.toJSON(), {
               '_converse': _converse,
               'ANONYMOUS': _converse.ANONYMOUS,
               'EXTERNAL': _converse.EXTERNAL,
               'LOGIN': _converse.LOGIN,
               'PREBIND': _converse.PREBIND,
               'auto_login': api.settings.get('auto_login'),
               'authentication': api.settings.get("authentication"),
               'connection_status': connection_status,
               'conn_feedback_class': feedback_class,
               'conn_feedback_subject': pretty_status,
               'conn_feedback_message': _converse.connfeedback.get('message'),
               'placeholder_username': (api.settings.get('locked_domain') || api.settings.get('default_domain')) &&
                                       __('Username') || __('user@domain'),
               'show_trust_checkbox': api.settings.get('allow_user_trust_override')
            })
         );
   },

   initPopovers () {
         Array.from(this.el.querySelectorAll('[data-title]')).forEach(el => {
            new bootstrap.Popover(el, {
               'trigger': api.settings.get("view_mode") === 'mobile' && 'click' || 'hover',
               'dismissible': api.settings.get("view_mode") === 'mobile' && true || false,
               'container': this.el.parentElement.parentElement.parentElement
            })
         });
   },

   validate () {
         const form = this.el.querySelector('form');
         const jid_element = form.querySelector('input[name=jid]');
         if (jid_element.value &&
               !api.settings.get('locked_domain') &&
               !api.settings.get('default_domain') &&
               !u.isValidJID(jid_element.value)) {
            jid_element.setCustomValidity(__('Please enter a valid XMPP address'));
            return false;
         }
         jid_element.setCustomValidity('');
         return true;
   },

   /**
      * Authenticate the user based on a form submission event.
      * @param { Event } ev
      */
   authenticate (ev) {
         if (ev && ev.preventDefault) { ev.preventDefault(); }
         if (api.settings.get("authentication") === _converse.ANONYMOUS) {
            return this.connect(_converse.jid, null);
         }
         if (!this.validate()) { return; }

         const form_data = new FormData(ev.target);
         _converse.config.save({'trusted': form_data.get('trusted') && true || false});

         let jid = form_data.get('jid');
         if (api.settings.get('locked_domain')) {
            const last_part = '@' + api.settings.get('locked_domain');
            if (jid.endsWith(last_part)) {
               jid = jid.substr(0, jid.length - last_part.length);
            }
            jid = Strophe.escapeNode(jid) + last_part;
         } else if (api.settings.get('default_domain') && !jid.includes('@')) {
            jid = jid + '@' + api.settings.get('default_domain');
         }
      this.connect(jid, form_data.get('password'));
   },

   connect (jid, password) {
         if (["converse/login", "converse/register"].includes(_converse.router.history.getFragment())) {
            _converse.router.navigate('', {'replace': true});
         }
         _converse.connection && _converse.connection.reset();
         api.user.login(jid, password);
   }
});
