package ctbrec.ui.sites.stripchat;

import static ctbrec.io.HttpConstants.*;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

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

import ctbrec.Config;
import ctbrec.Model;
import ctbrec.io.HttpException;
import ctbrec.sites.stripchat.Stripchat;
import ctbrec.sites.stripchat.StripchatHttpClient;
import ctbrec.sites.stripchat.StripchatModel;
import ctbrec.ui.SiteUiFactory;
import ctbrec.ui.tabs.PaginatedScheduledService;
import javafx.concurrent.Task;
import okhttp3.HttpUrl;
import okhttp3.Request;
import okhttp3.Response;

public class StripchatFollowedUpdateService extends PaginatedScheduledService {
    private Stripchat stripchat;
    private boolean showOnline = true;

    public StripchatFollowedUpdateService(Stripchat stripchat) {
        this.stripchat = stripchat;
    }

    @Override
    protected Task<List<Model>> createTask() {
        return new Task<List<Model>>() {
            @Override
            public List<Model> call() throws IOException {
                JSONArray favoriteModelIds = loadFavoriteModelIds();
                List<Model> models = loadModels(favoriteModelIds);
                return models;
            }

            private List<Model> loadModels(JSONArray favoriteModelIds) throws IOException {
                List<Model> models = new ArrayList<>();
                HttpUrl.Builder urlBuilder = HttpUrl.parse(stripchat.getBaseUrl() + "/api/front/models/list").newBuilder();
                for (int i = 0; i < favoriteModelIds.length(); i++) {
                    urlBuilder.addQueryParameter("modelIds["+i+"]", Integer.toString(favoriteModelIds.getInt(i)));
                }
                Request request = new Request.Builder()
                        .url(urlBuilder.build())
                        .header(ACCEPT, "*/*")
                        .header(USER_AGENT, Config.getInstance().getSettings().httpUserAgent)
                        .header(REFERER, Stripchat.BASE_URI + "/favorites")
                        .header(CONTENT_TYPE, MIMETYPE_APPLICATION_JSON)
                        .build();
                try (Response response = stripchat.getHttpClient().execute(request)) {
                    if (response.isSuccessful()) {
                        JSONObject json = new JSONObject(response.body().string());
                        if (json.has("models")) {
                            JSONArray users = json.getJSONArray("models");
                            for (int i = 0; i < users.length(); i++) {
                                JSONObject user = users.getJSONObject(i);
                                StripchatModel model = stripchat.createModel(user.optString("username"));
                                model.setDescription(user.optString("description"));
                                model.setPreview(user.optString("previewUrlThumbBig"));
                                boolean online = Objects.equals(user.optString("status"), "public");
                                if (showOnline == online) {
                                    models.add(model);
                                }
                            }
                        }
                    } else {
                        throw new HttpException(response.code(), response.message());
                    }
                }
                return models;
            }

            private JSONArray loadFavoriteModelIds() throws IOException {
                SiteUiFactory.getUi(stripchat).login();
                long userId = ((StripchatHttpClient) stripchat.getHttpClient()).getUserId();
                String url = stripchat.getBaseUrl() + "/api/front/users/" + userId + "/favorites";
                Request request = new Request.Builder()
                        .url(url)
                        .header(ACCEPT, MIMETYPE_APPLICATION_JSON)
                        .header(USER_AGENT, Config.getInstance().getSettings().httpUserAgent)
                        .header(ORIGIN, Stripchat.BASE_URI)
                        .header(REFERER, Stripchat.BASE_URI + "/favorites")
                        .header(CONTENT_TYPE, MIMETYPE_APPLICATION_JSON)
                        .build();
                try (Response response = stripchat.getHttpClient().execute(request)) {
                    if (response.isSuccessful()) {
                        JSONObject json = new JSONObject(response.body().string());
                        if(json.has("userIds")) {
                            JSONArray userIds = json.getJSONArray("userIds");
                            return userIds;
                        } else {
                            return new JSONArray();
                        }
                    } else {
                        throw new HttpException(response.code(), response.message());
                    }
                }
            }
        };
    }

    void showOnline(boolean online) {
        this.showOnline = online;
    }
}
