import BaseController from './base-controller.js';
import { ConfigData, LogLevel, NetDebugLevel, SFSEvent, EventParam } from 'sfs3-api';
import { LoginRequest } from 'sfs3-api';
import * as bootstrap from 'bootstrap';

export default class LoginController extends BaseController
{
    constructor(app, view, name)
    {
        super(app, view, name);

        // IP address or domain name of the SmartFoxServer instance
        this.host = "127.0.0.1";

        // HTTP listening port of the SmartFoxServer instance
        this.port = 8088;

        // Name of the SmartFoxServer Zone to join
        this.zone = "MMODemo";

        // Display SmartFoxServer client debug messages
        this.debug = false;

        // Client-side SmartFoxServer logging level
        this.logLevel = LogLevel.INFO;

        //------------------------------------------------------

        this.nameInput = view.querySelector('#nameInput');
        this.loginForm = view.querySelector('#loginForm');
        this.loginButton = view.querySelector('#loginButton');
        this.errorAlert = view.querySelector('#errorAlert');
    }

    //----------------------------------------------------------
    // Overridden methods
    //----------------------------------------------------------

    initialize()
    {
        super.initialize();
        
        // Add form submit listener
        this.boundOnLoginFormSubmit = this.onLoginFormSubmit.bind(this);
        this.loginForm.addEventListener('submit', this.boundOnLoginFormSubmit);

        // Enable UI
        this.enableUI(true);

        // Show view
        this.showView();

        // Focus on username input
        this.nameInput.focus();
    }

    destroy()
    {
        super.destroy(); // This also calls removeSmartFoxListeners method!

        // Remove form submit listener
        this.loginForm.removeEventListener('submit', this.boundOnLoginFormSubmit);
    }

    removeSmartFoxListeners()
    {
        if (this.sfs != null)
        {
            this.sfs.removeEventListener(SFSEvent.CONNECTION, this.onConnection);
            this.sfs.removeEventListener(SFSEvent.CONNECTION_LOST, this.onConnectionLost);
            this.sfs.removeEventListener(SFSEvent.LOGIN, this.onLogin);
            this.sfs.removeEventListener(SFSEvent.LOGIN_ERROR, this.onLoginError);
        }
    }

    //----------------------------------------------------------
    // Other methods
    //----------------------------------------------------------

    showErrorMsg(msg = '')
    {
        this.errorAlert.innerText = msg;
        this.errorAlert.hidden = msg.length == 0;
    }

    enableUI(enable)
    {
        this.nameInput.disabled = !enable;
        this.loginButton.disabled = !enable;
    }

    connect()
    {
        // Disable user interface
        this.enableUI(false);

        // Clear any previour error message
        this.showErrorMsg();

        // Set configuration parameters
        const cfg = new ConfigData();
        cfg.host = this.host;
        cfg.port = this.port;
        cfg.zone = this.zone;
        cfg.netDebugLevel = this.debug ? NetDebugLevel.PROTOCOL : NetDebugLevel.OFF;

        // Add event listeners
        this.sfs.addEventListener(SFSEvent.CONNECTION, this.onConnection, this);
        this.sfs.addEventListener(SFSEvent.CONNECTION_LOST, this.onConnectionLost, this);
        this.sfs.addEventListener(SFSEvent.LOGIN, this.onLogin, this);
        this.sfs.addEventListener(SFSEvent.LOGIN_ERROR, this.onLoginError, this);

        // Configure internal logger
        this.sfs.logger.level = this.logLevel;

        // Connect to SmartFoxServer
        this.sfs.connect(cfg);
    }

    //----------------------------------------------------------
    // UI event listeners
    //----------------------------------------------------------

    /**
     * On Login form submit, connect to SmartFoxServer.
     */
    onLoginFormSubmit(e)
    {
        e.preventDefault();

        this.connect();
    }

    //----------------------------------------------------------
    // SmartFoxServer event listeners
    //----------------------------------------------------------
    
    onConnection(evtParams)
    {
        const success = evtParams[EventParam.Success];

        // Check if the conenction was established or not
        if (success)
        {
            this.app.trace("SFS3 API version: " + this.sfs.version);

            // Login
            this.sfs.send(new LoginRequest(this.nameInput.value));
        }
        else
        {
            // Show error message
            this.showErrorMsg('Connection failed; is the server running at all?');

            // Enable user interface
            this.enableUI(true);
        }
    }

    onConnectionLost(evtParams)
    {
        // Enable user interface
        this.enableUI(true);
    }

    onLogin(evtParams)
    {
        // Go to lobby view
        this.app.goToView('lobby');
    }

    onLoginError(evtParams)
    {
        // Disconnect
        // NOTE: this causes a CONNECTION_LOST event with reason "manual"
        this.sfs.disconnect();

        const msg = evtParams[EventParam.ErrorMessage];

        // Show error message
        if (msg != null)
            this.showErrorMsg(`Login failed due to the following error:\n${msg}.`);
        else
            this.showErrorMsg(`Login failed; no reason provided.`);

        // Enable user interface
        this.enableUI(true);
    }
}