package com.capacitorjs.liveupdates;

import com.getcapacitor.JSObject;
import com.getcapacitor.Logger;
import com.getcapacitor.PluginConfig;
import io.ionic.liveupdates.LiveUpdateManager;
import io.ionic.liveupdates.Strategy;
import org.json.JSONException;
import org.json.JSONObject;

public class LiveUpdateConfig {

    private String appId;
    private String channel;
    private String autoUpdateMethod;
    private Integer maxVersions;
    private String key;
    private String urlToken;
    private Strategy updateStrategy;
    private boolean enabled;

    JSObject toJson() {
        JSObject obj = new JSObject();
        obj.put("appId", appId);
        obj.put("channel", channel);
        obj.put("autoUpdateMethod", autoUpdateMethod);
        obj.put("maxVersions", maxVersions);
        obj.put("strategy", updateStrategy.name());
        obj.put("enabled", enabled);
        return obj;
    }

    boolean update(JSObject jsObject) {
        boolean isUpdated = false;

        String appId = jsObject.getString("appId", this.appId);
        if (appId != null && !appId.equals(this.appId) && !appId.isEmpty()) {
            this.appId = appId;
            isUpdated = true;
        }

        String channel = jsObject.getString("channel", this.channel);
        if (channel != null && !channel.equals(this.channel) && !channel.isEmpty()) {
            this.channel = channel;
            isUpdated = true;
        }

        String autoUpdateMethod = jsObject.getString("autoUpdateMethod", this.autoUpdateMethod);
        if (autoUpdateMethod != null && !autoUpdateMethod.equals(this.autoUpdateMethod) && !this.autoUpdateMethod.isEmpty()) {
            this.autoUpdateMethod = autoUpdateMethod;
            isUpdated = true;
        }

        Integer maxVersions = jsObject.getInteger("maxVersions");
        if (maxVersions != null && !maxVersions.equals(this.maxVersions)) {
            this.maxVersions = maxVersions;
            isUpdated = true;
        }

        String strategy = jsObject.getString("strategy");
        if (strategy != null && !strategy.isEmpty()) {
            try {
                this.updateStrategy = Strategy.valueOf(strategy.toUpperCase());
                isUpdated = true;
            } catch (Exception e) {
                // do nothing, invalid strategy was provided
            }
        }

        Boolean enabled = jsObject.getBoolean("enabled", this.enabled);
        if (enabled != null && !enabled.equals(this.enabled)) {
            this.enabled = enabled;
            isUpdated = true;
        }

        return isUpdated;
    }

    public static LiveUpdateConfig create(JSONObject liveUpdateJson) {
        try {
            LiveUpdateConfig liveUpdateConfig = new LiveUpdateConfig();
            String appId = liveUpdateJson.getString("appId");
            String channel = liveUpdateJson.getString("channel");
            String autoUpdateMethod = liveUpdateJson.getString("autoUpdateMethod");
            Strategy updateStrategy = Strategy.DIFFERENTIAL;

            if (liveUpdateJson.has("strategy")) {
                String updateStrategyConfig = liveUpdateJson.getString("strategy");
                try {
                    updateStrategy = Strategy.valueOf(updateStrategyConfig.toUpperCase());
                } catch (Exception e) {
                    // do nothing, default Strategy applies
                    Logger.error(
                        "Config error: Strategy " + updateStrategyConfig + " is invalid. Defaulting to " + Strategy.DIFFERENTIAL.name()
                    );
                }
            }

            boolean isEnabled = true;
            if (liveUpdateJson.has("enabled")) {
                isEnabled = liveUpdateJson.getBoolean("enabled");
            }

            Integer maxVersions = LiveUpdateManager.INSTANCE.getMaxVersions();
            if (liveUpdateJson.has("maxVersions")) {
                maxVersions = liveUpdateJson.getInt("maxVersions");
            }

            String key = null;
            if (liveUpdateJson.has("key")) {
                key = liveUpdateJson.getString("key");
            }

            String urlToken = null;
            if (liveUpdateJson.has("urlToken")) {
                urlToken = liveUpdateJson.getString("urlToken");
            }

            liveUpdateConfig.setAppId(appId);
            liveUpdateConfig.setChannel(channel);
            liveUpdateConfig.setAutoUpdateMethod(autoUpdateMethod);
            liveUpdateConfig.setUpdateStrategy(updateStrategy);
            liveUpdateConfig.setEnabled(isEnabled);
            liveUpdateConfig.setMaxVersions(maxVersions);

            if (key != null) {
                liveUpdateConfig.setKey(key);
            }

            if (urlToken != null) {
                liveUpdateConfig.setUrlToken(urlToken);
            }

            return liveUpdateConfig;
        } catch (JSONException e) {
            e.printStackTrace();
        }

        return null;
    }

    public static LiveUpdateConfig create(PluginConfig pluginConfig) {
        return create(pluginConfig.getConfigJSON());
    }

    public String getAppId() {
        return appId;
    }

    public void setAppId(String appId) {
        this.appId = appId;
    }

    public String getChannel() {
        return channel;
    }

    public void setChannel(String channel) {
        this.channel = channel;
    }

    public String getAutoUpdateMethod() {
        return autoUpdateMethod;
    }

    public void setAutoUpdateMethod(String autoUpdateMethod) {
        this.autoUpdateMethod = autoUpdateMethod;
    }

    public Strategy getUpdateStrategy() {
        return updateStrategy;
    }

    public void setUpdateStrategy(Strategy updateStrategy) {
        this.updateStrategy = updateStrategy;
    }

    public Integer getMaxVersions() {
        return maxVersions;
    }

    public void setMaxVersions(Integer maxVersions) {
        this.maxVersions = maxVersions;
    }

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }

    public boolean isEnabled() {
        return enabled;
    }

    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }

    public void setUrlToken(String token) {
        this.urlToken = token;
    }

    public String getUrlToken() {
        return urlToken;
    }
}
