package org.mercury_im.messenger.cli;

import org.jivesoftware.smack.util.StringUtils;
import org.jxmpp.jid.DomainBareJid;
import org.jxmpp.jid.EntityBareJid;
import org.jxmpp.jid.impl.JidCreate;
import org.jxmpp.jid.parts.Localpart;
import org.jxmpp.stringprep.XmppStringprepException;
import org.mercury_im.messenger.cli.di.component.CliComponent;
import org.mercury_im.messenger.cli.di.component.DaggerCliComponent;
import org.mercury_im.messenger.core.Messenger;
import org.mercury_im.messenger.core.viewmodel.account.LoginViewModel;
import org.mercury_im.messenger.core.connection.MercuryConnection;

import java.util.List;

import javax.inject.Inject;

import io.reactivex.disposables.Disposable;

public class MercuryCli {

    private final UserInterface userInterface;
    Disposable connectionStateDisposable;

    @Inject
    Messenger messenger;

    @Inject
    LoginViewModel loginViewModel;

    public static void main(String[] args) {
        MercuryCli cli = new MercuryCli();
        cli.loginDialog();
        System.out.println("Login successful.");
        cli.loop();
    }

    /**
     * Create the Dependency Injection graph.
     */
    public CliComponent createCliComponent() {
        CliComponent cliComponent = DaggerCliComponent.builder()
                .build();

        cliComponent.inject(this);

        return cliComponent;
    }

    public MercuryCli() {
        createCliComponent();
        userInterface = ConsoleUserInterface.isSupported() ? new ConsoleUserInterface() : new ScannerUserInterface();
    }

    private void loginDialog() {
        System.out.println("Format is 'Username'@'Service'.");

        String username = promptForUsername();
        DomainBareJid service = promptForServiceDomain();
        String password = promptForPassword();

        EntityBareJid jid = JidCreate.entityBareFrom(Localpart.formUnescapedOrNull(username), service);

        loginViewModel.onLoginUsernameChanged(jid.toString());
        loginViewModel.onLoginPasswordChanged(password);

        loginViewModel.login();
    }

    private String promptForPassword() {
        System.out.println("Enter password:");
        String password = userInterface.readPassword();
        if (StringUtils.isNullOrEmpty(password)) {
            System.out.println("Password too short.");
            return promptForPassword();
        }
        return password;
    }

    private DomainBareJid promptForServiceDomain() {
        System.out.println("Enter service:");
        String service = userInterface.readText();
        try {
            return JidCreate.domainBareFrom(service);
        } catch (XmppStringprepException e) {
            System.out.println("Invalid service domain.");
            return promptForServiceDomain();
        }
    }

    private String promptForUsername() {
        System.out.println("Please enter username:");
        String username = userInterface.readText();
        try {
            Localpart.from(username);
        } catch (XmppStringprepException e) {
            System.out.println("Invalid username.");
            return promptForUsername();
        }
        return username;
    }

    private void loop() {
        String input = userInterface.readText();
        if (StringUtils.isNullOrEmpty(input)) {
            loop();
            return;
        }

        String[] command = input.split(" ");
        switch (command[0]) {
            case "/exit":
                System.out.println("Shutting down.");
                messenger.getConnectionManager().doShutdownAllConnections();
                connectionStateDisposable.dispose();
                return;

            case "/contacts":
                List<MercuryConnection> connectionList = messenger.getConnectionManager().getConnections();


                break;

            case "/msg":
                break;
        }
        loop();
    }

}
