package de.sebse.fuplanner.services.kvv;

import android.content.Context;

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

import java.util.ArrayList;

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

public class ModulesGradebook extends PartModules<ArrayList<Grade>> {

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

    @Override
    protected ArrayList<Grade> getPart(Modules.Module module) {
        return module.gradebook;
    }

    @Override
    protected boolean setPart(Modules.Module module, ArrayList<Grade> part) {
        boolean changed = module.gradebook == null || module.gradebook.hashCode() != part.hashCode();
        module.gradebook = part;
        return changed;
    }

    @Override
    protected void upgrade(final String ID, final NetworkCallback<ArrayList<Grade>> callback, final NetworkErrorCallback errorCallback) {
        if (!mLogin.isInOnlineMode() || mLogin.getLoginToken() == null) {
            errorCallback.onError(new NetworkError(101504, 500, "Currently running in offline mode!"));
            return;
        }
        super.get(String.format("https://kvv.imp.fu-berlin.de/direct/gradebook/site/%s.json", ID), mLogin.getLoginToken().getCookies(), response -> {
            String body = response.getParsed();
            if (body == null) {
                errorCallback.onError(new NetworkError(101501, 403, "No gradebook retrieved!"));
                return;
            }
            ArrayList<Grade> gradebook = new ArrayList<>();
            JSONArray sites;
            try {
                JSONObject json = new JSONObject(body);
                sites = json.getJSONArray("assignments");
            } catch (JSONException e) {
                e.printStackTrace();
                errorCallback.onError(new NetworkError(101502, 403, "Cannot parse gradebook!"));
                return;
            }

            for (int i = 0; i < sites.length(); i++) {
                try {
                    JSONObject site = sites.getJSONObject(i);
                    double grade = site.optDouble("grade", 0);
                    String itemName = site.optString("itemName", null);
                    double maxPoints = site.optDouble("points", -1);

                    gradebook.add(0, new Grade(itemName, grade, maxPoints));
                } catch (JSONException e) {
                    log.e(new NetworkError(101505, 403, "Cannot parse gradebook!"));
                    log.e("ID:", i, "JSON:", sites);
                    e.printStackTrace();
                    return;
                }
            }
            callback.onResponse(gradebook);
        }, error -> errorCallback.onError(new NetworkError(101503, error.networkResponse.statusCode, "Cannot get gradebook!")));
    }
}
