package edu.whs.spin2018.baoapp.model.remote;

import edu.whs.spin2018.baoapp.service.BaoService;
import io.socket.emitter.Emitter;

/**
 * Klasse um dem Presenter das Interagieren mit dem Service zu ermöglichen. Damit ist primär das
 * absenden und empfangen von Events gemeint.
 */
public abstract class ServiceInteractor implements BaseInteractorInterface {

    public static final String TAG = "ServiceInteractorTAG";
    private final BaoService service;

    public ServiceInteractor(BaoService service) {
        this.service = service;
        registriereNachrichtenListener();
    }

    /**
     * Meldet sich beim Listener fuer das Nachtichten Event an.
     */

    private void registriereNachrichtenListener() {
        service.registriereNachrichtenListener(this::onNeueNachricht);
    }

    @Override
    public void registriereNachrichtenListener(Emitter.Listener listener) {
        service.registriereNachrichtenListener(listener);
    }

    @Override
    public void registriereBenutzerVerlaesstRaumListener(Emitter.Listener listener) {
        service.registriereBenutzerVerlaesstRaumListener(listener);
    }

    @Override
    public void registriereBenutzerTrittRaumBeiListener(Emitter.Listener listener) {
        service.registriereBenutzerTrittRaumBeiListener(listener);
    }

    @Override
    public void registriereVerbundenListener(Emitter.Listener listener) {
        service.registriereVerbundenListener(listener);
    }

    @Override
    public void registriereBenutzerListeErhaltenListener(Emitter.Listener listener) {
        service.registriereBenutzerListeErhaltenListener(listener);
    }

    /**
     * Baut die Verbindung zum Server auf
     */
    @Override
    public void verbinden(String benutzername, String uuid) {
        service.verbinden(benutzername, uuid);
    }

    /**
     * Trennt die Verbindung zum Server.
     */
    @Override
    public void trennen() {
        service.trennen();
    }

    /**
     * Betritt einen Raum auf dem Server. Broadcasts in diesem Raum koennen danach empfangen werden.
     * Andere Raeume werden nicht automatisch verlassen.
     *
     * @param raum - Raum, der betreten wird
     */
    @Override
    public void raumBetreten(String raum) {
        service.raumBetreten(raum);
    }

    /**
     * Verlaesst einen Raum. Broadcasts in diesem Raum werden danach nicht mehr empfangen.
     *
     * @param raum
     */
    @Override
    public void raumVerlassen(String raum) {
        service.raumVerlassen(raum);
    }

    /**
     * Fordert eine Liste mit allen Clients aus einem Raum auf dem Server an.
     * <p>
     * Wenn der Server diese Anfrage beantwortet, wird an alle, die Broadcasts vom BaoService
     * erhalten, ein Broadcast gesendet. In dem Intent, den man erhaelt ist unter "inhalt" ein
     * JSONObject (data). In data ist unter dem Extra "inhalt" ein JSONArray (benutzerArray). In
     * jedem Feld von benutzerArray ist ein JSONObject (jsonUser). Jeder jsonUser hat die Felder
     * "benutzername" und "UUID".
     *
     * @param raum - Der Raum, dessen Clients gesendet werden sollen.
     */
    @Override
    public void zeigeBenutzerImRaum(String raum) {
        service.zeigeBenutzerImRaum(raum);
    }

    /**
     * Sendet eine Nachricht an genau einen Empfaenger, der auch mit dem Server verbunden ist.
     *
     * @param inhalt         - Inhalt der Nachricht
     * @param typ            - Eine Beschreibung der Nachricht (z.B. "Spielzug")
     * @param empfaengerUUID - UUID, ueber die der Empfaenger identifiziert werden kann.
     */
    @Override
    public void sendeNachricht(String inhalt, String typ, String empfaengerUUID) {
        service.sendeNachricht(inhalt, typ, empfaengerUUID);
    }

    /**
     * Sendet wie sendeNachricht eine Nachricht an den Server, aber nicht nur an einen Benutzer als
     * Empfaenger, sondern an alle Benutzer, die sich in einem angegebenen Raum befinden.
     *
     * @param inhalt - Inhalt der Nachricht
     * @param typ    - Beschreibung der Nachricht
     * @param raum   - Alle Benutzer dieses Raumes erhalten die Nachricht.
     */
    @Override
    public void sendeBroadcast(String inhalt, String typ, String raum) {
        service.sendeBroadcast(inhalt, typ, raum);
    }



    /**
     * Entfernt einen aktuelle registrierten Listener.
     *
     * @param event    - Event auf das der zu enfternende Listener hoert.
     * @param listener - zu entfernender Listener
     */
    @Override
    public void entferneListener(String event, Emitter.Listener listener) {
        service.entferneListener(event, listener);
    }
}
