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

import android.support.annotation.NonNull;
import android.util.Log;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.List;

import edu.whs.spin2018.baoapp.model.Benutzer;
import edu.whs.spin2018.baoapp.model.Nachricht;
import edu.whs.spin2018.baoapp.service.BaoService;
import edu.whs.spin2018.baoapp.service.Konstanten;
import edu.whs.spin2018.baoapp.model.remote.ServiceInteractor;
import edu.whs.spin2018.baoapp.service.SocketEvents;
import edu.whs.spin2018.baoapp.utilities.JSONUtils;
import io.socket.emitter.Emitter;

public class MehrspielerServiceInteractor extends ServiceInteractor implements MehrspielerRemoteDataSource {
    private BaoService service;
    private Benutzer spieler;
    private MehrspielerEventListener listener;

    private Emitter.Listener onZeigeBenutzerImRaum = args -> onBenutzerlisteErhalten(JSONUtils
            .gibBenutzerlisteVonJSONObjekt(args[0]));

    public MehrspielerServiceInteractor(@NonNull BaoService service, Benutzer spieler) {
        super(service);
        this.service = service;
        registriereBenoetigteListener();
        this.spieler = spieler;
    }

    /**
     * Wird aufgerufen, wenn die Benutzerliste erhalten wurde.
     *
     * @param benutzerListe - Liste mit allen Benutzern in dem aktuellen Raum.
     */
    private void onBenutzerlisteErhalten(List<Benutzer> benutzerListe) {
        if (benutzerListe.size() > 0) {
            sendeHerausforderung(benutzerListe.get(0).gibUUID(), spieler);
            verlasseWarteschlange();
            onGegnerGefunden(benutzerListe.get(0), spieler.gibUUID());
        }
    }

    /**
     * Sendet eine Herausforderung an den Gegner.
     *
     * @param gegnerUUID - UUID des Gegners
     * @param spieler    - eigene Benutzerdaten
     */
    private void sendeHerausforderung(String gegnerUUID, Benutzer spieler) {
        JSONObject absender = JSONUtils.gibBenutzerAlsJSONObject(
                spieler.gibBenutzernamen(), spieler.gibUUID());
        service.sendeNachricht(absender.toString(), Nachricht.TYP_HERAUSFORDERUNG_NEU, gegnerUUID);
        service.raumBetreten(spieler.gibUUID());

    }

    @Override
    public void trittWarteschlangeBei() {
        service.zeigeBenutzerImRaum("Warteschlange");
        service.raumBetreten("Warteschlange");
    }

    @Override
    public void verlasseWarteschlange() {
        service.raumVerlassen("Warteschlange");
    }

    @Override
    public void setzeListener(MehrspielerEventListener listener) {
        this.listener = listener;
    }

    @Override
    public void registriereBenoetigteListener() {
        registriereBenutzerListeErhaltenListener(onZeigeBenutzerImRaum);
    }

    @Override
    public void entferneRegistrierteListener() {
        entferneListener(SocketEvents.BENUTZERLISTE_ERHALTEN, onZeigeBenutzerImRaum);
    }

    @Override
    public void onNeueNachricht(Object... args) {
        JSONObject data = (JSONObject) args[0];
        String typ = "";
        Log.d(TAG, "onNeueNachricht: " + data);

        try {
            typ = data.getString("type");
        } catch (JSONException e) {
            e.printStackTrace();
        }

        Benutzer benutzer;
        switch (typ) {
            case Nachricht.TYP_HERAUSFORDERUNG_NEU:
                try {
                    benutzer = JSONUtils.gibBenutzerVonJSONObjekt(new JSONObject(data.getString(Konstanten.EXTRA_INHALT)));
                    service.raumBetreten(benutzer.gibUUID());
                    verlasseWarteschlange();
                    onGegnerGefunden(benutzer, benutzer.gibUUID());
                } catch (JSONException e) {
                    e.printStackTrace();
                }
                break;
        }
    }


    @Override
    public void onGegnerGefunden(Benutzer gegner, String raum) {
        listener.onGegnerGefunden(gegner, raum);
    }
}
