package de.sebse.fuplanner.services.kvv;

import android.content.Context;

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

import de.sebse.fuplanner.services.kvv.types.Event;
import de.sebse.fuplanner.services.kvv.types.EventList;
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 ModulesEvents extends PartModules<EventList> {

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

    @Override
    protected EventList getPart(Modules.Module module) {
        return module.events;
    }

    @Override
    protected boolean setPart(Modules.Module module, EventList part) {
        boolean changed = module.events == null || module.events.hashCode() != part.hashCode();
        module.events = part;
        return changed;
    }

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

            for (int i = 0; i < sites.length(); i++) {
                try {
                    JSONObject site = sites.getJSONObject(i);
                    String id = site.getString("eventId");
                    String type = site.getString("type");
                    String title = site.getString("title");
                    String siteId = site.getString("siteId");
                    long duration = site.getLong("duration");
                    long firstTime = site.getJSONObject("firstTime").getLong("time");
                    String location = site.getString("location");
                    events.add(new Event(id, type, title, duration, firstTime, siteId, location));
                } catch (JSONException e) {
                    log.e(new NetworkError(101405, 403, "Cannot parse events!"));
                    e.printStackTrace();
                    log.e("ID:", i, "JSON:", sites);
                    return;
                }
            }

            // Empty events *may be* because token is invalid -> check
            if (events.size() == 0)
                mLogin.testLoginToken(token -> callback.onResponse(events), errorCallback);
            else
                callback.onResponse(events);
        }, error -> errorCallback.onError(new NetworkError(101403, error.networkResponse.statusCode, "Cannot get events!")));
    }
}
