package com.sfs2x.android.connector;

import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

import androidx.appcompat.app.AppCompatActivity;

import com.smartfoxserver.v2.exceptions.SFSException;

import sfs2x.client.SmartFox;
import sfs2x.client.core.BaseEvent;
import sfs2x.client.core.IEventListener;
import sfs2x.client.core.SFSEvent;
import sfs2x.client.entities.Room;
import sfs2x.client.requests.JoinRoomRequest;
import sfs2x.client.requests.LoginRequest;
import sfs2x.client.util.ConfigData;

public class MainActivity extends AppCompatActivity
{
    private static String LOG_TAG = "SFS2X";

    private SmartFox sfs;
    private ConfigData cfg;
    private EditText logView;
    private Button btConnect;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        logView = (EditText) findViewById(R.id.txtLogView);
        btConnect = (Button) findViewById(R.id.btConnect);
    }

    public void onConnectClick(View sourceView)
    {
        if (sfs == null)
        {
            connect();
        }

        else if (sfs.isConnected())
        {
            sfs.disconnect();
        }

        else
            Log.i(LOG_TAG, "Unexpected application state");
    }

    private void connect()
    {
        EditText txtHost = (EditText) findViewById(R.id.txtHostAddress);
        EditText txtPort = (EditText) findViewById(R.id.txtPort);

        String connHost = txtHost.getText().toString();
        int connPort = Integer.valueOf(txtPort.getText().toString());

        // Disable connection button
        btConnect.setEnabled(false);
        logView.setText("Starting SFS2X connection\n");

        // initialize
        initSFS2X(connHost, connPort);
    }

    private void initSFS2X(String host, int port)
    {
        sfs = new SmartFox();
        cfg = new ConfigData();

        cfg.setHost(host);
        cfg.setPort(port);
        cfg.setZone("BasicExamples");
        cfg.setUseBBox(false);
        cfg.setDebug(true);

        sfs.addEventListener(SFSEvent.CONNECTION, this::onConnection);
        sfs.addEventListener(SFSEvent.CONNECTION_LOST, this::onConnectionLost);
        sfs.addEventListener(SFSEvent.LOGIN, this::onLogin);
        sfs.addEventListener(SFSEvent.LOGIN_ERROR, this::onLoginError);
        sfs.addEventListener(SFSEvent.ROOM_JOIN, this::onRoomJoin);

        sfs.connect(cfg);
    }

    // ---------------------------------------------------------------------------------------
    // SFS2X Event Handlers
    // ---------------------------------------------------------------------------------------

    private void onConnection (BaseEvent evt)
    {
        boolean success = (boolean) evt.getArguments().get("success");

        if (success)
        {
            logView.getText().append("Connection Success!\n");

            //Update button state
            ThreadUtil.runUiThread(() -> {
                        btConnect.setText("Disconnect");
                        btConnect.setEnabled(true);
                    }
            );

            // Send Login Request
            sfs.send(new LoginRequest(""));
        }

        else {
            btConnect.setEnabled(true);
            logView.getText().append("Connection failed. Is the server running at " + cfg.getHost() + ":" + cfg.getPort() + "?\n");
        }
    }

    private void onConnectionLost (BaseEvent evt)
    {
        logView.getText().append(":: Connection with server was lost :: \n");

        sfs.removeAllEventListeners();
        sfs = null;

        // Reset button state
        ThreadUtil.runUiThread(() -> {
                    btConnect.setText("Connect");
                    btConnect.setEnabled(true);
                }
        );
    }

    private void onLogin (BaseEvent evt)
    {
        logView.getText().append("Logged in as: " + sfs.getMySelf().getName() + "\n");
        sfs.send(new JoinRoomRequest("The Lobby"));
    }

    private void onLoginError (BaseEvent evt)
    {
        String message = (String) evt.getArguments().get("errorMessage");
        logView.getText().append("Login Error. Cause:" + message + "\n");
    }

    private void onRoomJoin (BaseEvent evt)
    {
        Room room = (Room) evt.getArguments().get("room");
        logView.getText().append("Joined in Room: " + room.getName() + "\n");
    }
}