package de.sebse.fuplanner.services.kvv.types;

import android.content.Context;

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

import java.io.IOException;
import java.io.Serializable;
import java.util.HashMap;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import de.sebse.fuplanner.services.fulogin.AccountGeneral;
import de.sebse.fuplanner.tools.CustomAccountManager;
import de.sebse.fuplanner.tools.logging.Logger;

/**
 * Created by sebastian on 29.10.17.
 */

public class LoginToken implements Serializable {
    static Logger log = new Logger("LoginToken");
    private static final String FILE_NAME = "LoginTokenSaving";

    private final String username;
    private final String shibsessionKey;
    private final String shibsessionName;
    private final String JSESSIONID;
    @Nullable private String fullName;
    @Nullable private String email;

    public LoginToken(String username, String shibsessionKey, String shibsessionName, String JSESSIONID) {
        this.username = username;
        this.shibsessionKey = shibsessionKey;
        this.shibsessionName = shibsessionName;
        this.JSESSIONID = JSESSIONID;
    }

    @Nullable
    public static void load(CustomAccountManager manager, LoginTokenInterface callback) {
        if (!manager.hasAccounts(AccountGeneral.ACCOUNT_TYPE)) {
            callback.run(null);
            return;
        }
        manager.getTokenByType(AccountGeneral.ACCOUNT_TYPE, AccountGeneral.AUTHTOKEN_TYPE_KVV, tokenString -> {
            if (tokenString == null) {
                callback.run(null);
                return;
            }
            callback.run(LoginToken.fromJsonString(tokenString));
        });
    }

    public void delete(CustomAccountManager manager) {
        manager.deleteAccount(AccountGeneral.ACCOUNT_TYPE);
    }

    public void setAdditionals(String fullName, String email) {
        this.fullName = fullName;
        this.email = email;
    }

    public String getUsername() {
        return username;
    }

    private String getShibsessionKey() {
        return shibsessionKey;
    }

    private String getShibsessionName() {
        return shibsessionName;
    }

    private String getJSESSIONID() {
        return JSESSIONID;
    }

    @Nullable
    public String getFullName() {
        return fullName;
    }

    @Nullable
    public String getEmail() {
        return email;
    }

    public HashMap<String, String> getCookies() {
        HashMap<String, String> cookies = new HashMap<>();
        cookies.put("JSESSIONID", getJSESSIONID());
        cookies.put(getShibsessionKey(), getShibsessionName());
        cookies.put("pasystem_timezone_ok", "true");
        return cookies;
    }

    public boolean isOtherUser(String username) {
        return !this.getUsername().equals(username);
    }

    @NonNull
    @Override
    public String toString() {
        StringBuilder result = new StringBuilder();
        HashMap<String, String> cookies = this.getCookies();
        for (String header: cookies.keySet()) {
            result.append(header).append("=").append(cookies.get(header)).append(";");
        }
        return result.substring(0, result.length()-1);
    }

    public String toJsonString() {
        JSONObject json = new JSONObject();
        try {
            json.put("username", username);
            json.put("shibsessionKey", shibsessionKey);
            json.put("shibsessionName", shibsessionName);
            json.put("JSESSIONID", JSESSIONID);
            json.put("fullName", fullName);
            json.put("email", email);
        } catch (JSONException e) {
            return null;
        }
        return json.toString();
    }

    public static LoginToken fromJsonString(String tokenString) {
        try {
            JSONObject json = new JSONObject(tokenString);
            LoginToken token = new LoginToken(
                    json.getString("username"),
                    json.getString("shibsessionName"),
                    json.getString("shibsessionName"),
                    json.getString("JSESSIONID"));
            if (!json.isNull("fullName"))
                token.setAdditionals(
                        json.getString("fullName"),
                        json.getString("email")
                );
            return token;
        } catch (JSONException e) {
            e.printStackTrace();
            return null;
        }
    }

    public interface LoginTokenInterface {
        void run(LoginToken token);
    }
}
