package de.sebse.fuplanner.services.kvv;

import android.content.Context;

import org.jetbrains.annotations.NotNull;

import java.util.HashMap;

public class Modules {
    private final HashMap<String, Part> mAddons = new HashMap<>();
    private ModulesList mList = null;
    private final Login mLogin;
    private final KVVListener mListener;
    private final Context context;

    Modules(Login login, KVVListener listener, Context context) {
        this.mLogin = login;
        this.mListener = listener;
        this.context = context;
    }

    @NotNull
    public ModulesDetails details() {
        return (ModulesDetails) addAndGet("details", () -> {
            PartModules[] parts = {announcements(), assignments(), events(), gradebook(), resources()};
            return new ModulesDetails(mLogin, list(), context, parts);
        });
    }

    @NotNull
    public ModulesAnnouncements announcements() {
        return (ModulesAnnouncements) addAndGet("announcements", () -> new ModulesAnnouncements(mLogin, list(), context));
    }

    @NotNull
    public ModulesAssignments assignments() {
        return (ModulesAssignments) addAndGet("assignments", () -> new ModulesAssignments(mLogin, list(), context));
    }

    @NotNull
    public ModulesEvents events() {
        return (ModulesEvents) addAndGet("events", () -> new ModulesEvents(mLogin, list(), context));
    }

    @NotNull
    public ModulesGradebook gradebook() {
        return (ModulesGradebook) addAndGet("gradebook", () -> new ModulesGradebook(mLogin, list(), context));
    }

    @NotNull
    public ModulesResources resources() {
        return (ModulesResources) addAndGet("resources", () -> new ModulesResources(mLogin, list(), context));
    }

    @NotNull
    public ModulesList list() {
        if (mList == null) {
            mList = new ModulesList(mLogin, mListener, context);
            mList.addErrorListener("Modules", error -> mListener.onKVVNetworkResponse(error.networkResponse));
            mList.addSuccessListener("Modules", success -> mListener.onKVVNetworkResponse(null));
        }
        return mList;
    }


    @NotNull
    private Part addAndGet(@NotNull String addon, @NotNull ModuleCreatorInterface creatorInterface) {
        Part o = mAddons.get(addon);
        if (o == null) {
            o = creatorInterface.create();
            o.addErrorListener("Modules", error -> mListener.onKVVNetworkResponse(error.networkResponse));
            o.addSuccessListener("Modules", success -> mListener.onKVVNetworkResponse(null));
            mAddons.put(addon, o);
        }
        return o;
    }

    private interface ModuleCreatorInterface {
        @NotNull Part create();
    }
}
