package de.sebse.fuplanner.services.kvv;

import android.content.Context;
import android.os.Build;
import android.text.Html;
import android.text.Spanned;

import de.sebse.fuplanner.services.kvv.types.Modules;
import de.sebse.fuplanner.tools.NewAsyncQueue;
import de.sebse.fuplanner.tools.network.NetworkCallback;
import de.sebse.fuplanner.tools.network.NetworkErrorCallback;

abstract class PartModules<T> extends Part<Modules.Module> {
    private final NewAsyncQueue mQueue = new NewAsyncQueue();

    PartModules(Login login, ModulesList list, Context context) {
        super(login, list, context);
    }

    @Override
    protected void recv(final Modules.Module module, final NetworkCallback<Modules.Module> callback, final NetworkErrorCallback errorCallback, final boolean forceRefresh, final int retries) {
        mQueue.add(() -> {
            if (getPart(module) != null && !forceRefresh) {
                callback.onResponse(module);
                mQueue.next();
                return;
            }
            upgrade(module.getID(), success -> {
                if (setPart(module, success)) {
                    this.mList.store();
                }
                callback.onResponse(module);
                mQueue.next();
            }, error -> {
                if (retries >= 0 && (error.getHttpStatus() == 401 || error.getHttpStatus() == 403)) {
                    mLogin.refreshLogin(success -> {
                        recv(module, callback, errorCallback, forceRefresh, retries-1);
                        mQueue.next();
                    }, error1 -> {
                        errorCallback.onError(error1);
                        mQueue.next();
                    });
                    return;
                }
                errorCallback.onError(error);
                mQueue.next();
            });
        });
    }

    @SuppressWarnings("deprecation")
    static Spanned fromHtml(String html){
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            return Html.fromHtml(html, Html.FROM_HTML_MODE_LEGACY);
        } else {
            return Html.fromHtml(html);
        }
    }

    protected abstract T getPart(Modules.Module module);

    protected abstract boolean setPart(Modules.Module module, T part);

    protected abstract void upgrade(final String ID, final NetworkCallback<T> callback, final NetworkErrorCallback errorCallback);
}
