package edu.whs.spin2018.baoapp.presenter;

import android.util.Log;

import java.util.ArrayList;
import java.util.List;

import edu.whs.spin2018.baoapp.model.Benutzer;
import edu.whs.spin2018.baoapp.model.benutzerinfo.SharedPrefZugriff;
import edu.whs.spin2018.baoapp.model.remote.lobby.LobbyRemoteDataSource;
import edu.whs.spin2018.baoapp.views.lobby.BenutzerAdapter;
import edu.whs.spin2018.baoapp.views.lobby.LobbyContract;

public class LobbyPresenter implements LobbyContract.Presenter {

    private static final String TAG = "LobbyPresenterTAG";
    private final ArrayList<Benutzer> benutzerListe;
    private final LobbyContract.View lobbyView;
    private final SharedPrefZugriff benutzerInfo;
    private boolean herausforderungImGange;
    private LobbyRemoteDataSource interactor;

    public LobbyPresenter(LobbyContract.View lobbyView, SharedPrefZugriff benutzerInfo) {
        benutzerListe = new ArrayList<>();
        this.lobbyView = lobbyView;
        this.benutzerInfo = benutzerInfo;
        this.lobbyView.setzePresenter(this);
        lobbyView.initView();
    }

    @Override
    public int gibLobbyBenutzerItemAnzahl() {
        return benutzerListe.size();
    }
    
    @Override
    public void ladeBenutzerInLobby() {
        interactor.ladeBenutzerInLobby();
        lobbyView.zeigeBenutzerWerdenGeladen();
    }

    @Override
    public void onBindBenutzerItemView(int pos, BenutzerAdapter.BenutzerViewHolder holder) {
        Benutzer benutzer = benutzerListe.get(pos);
        holder.setzeBenutzernamen(benutzer.gibBenutzernamen());
        holder.setzeUUID(benutzer.gibUUID());
    }

    @Override
    public void beendeDialog() {
        interactor.verlasseAktuellenRaum();
        interactor.ladeBenutzerInLobby();
        herausforderungImGange = false;
    }

    @Override
    public void sendeHerausforderung(int pos) {
        if (!herausforderungImGange) {
            //Daten des herausgeforderten Benutzers holen
            Benutzer herausgeforderter = benutzerListe.get(pos);

            //Herausforderungsevent an den anderen Benutzer senden
            interactor.sendeHerausforderung(herausgeforderter.gibUUID(), benutzerInfo.gibBenutzer());

            //Lobby verlassen und dem neuen Raum fuer die Herausforderung beitreten
            interactor.verlasseLobby();
            interactor.geheInNeuenRaum(benutzerInfo.gibUUID());

            //Dialog fuer die Herausforderung anzeigen
            lobbyView.zeigeAusgehendeHerausforderung(herausgeforderter);
            herausforderungImGange = true;
        }
    }

    /**
     * Wird aufgerufen, wenn der Benutzer den Herausforderung - Abbrechen Button im Dialog geklickt
     * hat. Sendet dem Gegner die Nachricht, dass die Herausforderung abgebrochen wurde.
     *
     * @param gegnerUUID - UUID, an die die Nachricht gesendet werden soll
     */
    @Override
    public void lehneHerausforderungAb(String gegnerUUID) {
        //An den Gegner senden, dass die Herausforderung beendet wurde
        interactor.lehneHerausforderungAb(gegnerUUID);
        interactor.verlasseAktuellenRaum();
        interactor.ladeBenutzerInLobby();
        herausforderungImGange = false;
//        Log.d(TAG, "lehneHerausforderungAb: ");
    }

    @Override
    public void onHerausforderungErhalten(Benutzer absender) {
        interactor.verlasseLobby();
        interactor.geheInNeuenRaum(absender.gibUUID());
        lobbyView.zeigeEingehendeHerausforderung(absender);
        lobbyView.entferneBenutzerAusAnzeigeliste(benutzerListe.indexOf(absender),
                benutzerListe.size() - benutzerListe.indexOf(absender));
//        Log.d(TAG, "onHerausforderungErhalten: Benutzerliste" + benutzerListe);
        herausforderungImGange = true;
    }

    @Override
    public void onHerausforderungBeendetErhalten() {
        if (herausforderungImGange) {
            lobbyView.zeigeHerausforderungBeendet();
        }
    }

    @Override
    public void onHerausforderungAngenommenErhalten() {
        if (herausforderungImGange) {
            lobbyView.zeigeHerausforderungAngenommen();
        }
    }

    @Override
    public void onBenutzerVerlaesstRaumErhalten(Benutzer benutzer) {
        Log.d(TAG, "onBenutzerVerlaesstRaumErhalten: Benutzer der entfernt werden soll: " + benutzer);
        int pos = benutzerListe.indexOf(benutzer);
        Log.d(TAG, "onBenutzerVerlaesstRaumErhalten: Position von Benutzer " + pos);
        benutzerListe.remove(benutzer);
        Log.d(TAG, "onBenutzerVerlaesstRaumErhalten: Benutzerliste nach raumVerlassen: " + benutzerListe);

        lobbyView.entferneBenutzerAusAnzeigeliste(pos, benutzerListe.size());
        //Letzter Benutzer hat die Lobby verlassen
        if (benutzerListe.size() == 0) {
            lobbyView.zeigeLobbyIstLeer();
        }
    }

    @Override
    public void onBenutzerTrittRaumBeiErhalten(Benutzer benutzer) {
        if (!benutzer.equals(benutzerInfo.gibBenutzer())) {
            if (benutzerListe.size() == 0) {
                lobbyView.versteckeLadeAnzeige();
            }
            benutzerListe.add(benutzer);
            lobbyView.zeigeNeuenBenutzerInListe(benutzerListe.indexOf(benutzer));
        }
    }

    @Override
    public void onBenutzerlisteErhalten(List<Benutzer> benutzerliste) {
        interactor.geheInLobby();
//        Log.d(TAG, "onBenutzerlisteErhalten: " + benutzerliste.toString() + "/");
        lobbyView.leereListe(this.benutzerListe.size());
        this.benutzerListe.clear();

        lobbyView.versteckeLadeAnzeige();
        if (benutzerliste.size() > 0) {
            this.benutzerListe.addAll(benutzerliste);
            this.lobbyView.zeigeErhaltendeBenutzer();
        } else {
            lobbyView.zeigeLobbyIstLeer();
        }

    }

    /**
     * Wird aufgerufen wenn der Benutzer (ich) die Herausforderung annimmt.
     *
     * @param gegnerUUID - UUID an die die Nachricht zugestellt werden soll
     */
    @Override
    public void nimmHerausforderungAn(String gegnerUUID) {
        interactor.nimmHerausforderungAn(gegnerUUID);
    }

    @Override
    public void stop() {
        interactor.entferneRegistrierteListener();
        interactor.verlasseLobby();
    }

    @Override
    public void setzeServiceInteractor(LobbyRemoteDataSource interactor) {
        this.interactor = interactor;
        this.interactor.setzeListener(this);
        ladeBenutzerInLobby();
    }
}
