package org.torproject.artitoyvpn.ui.home;

import android.Manifest;
import android.app.Application;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import android.text.format.Formatter;

import androidx.annotation.RequiresApi;
import androidx.core.content.ContextCompat;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;

import org.torproject.artitoyvpn.R;
import org.torproject.artitoyvpn.utils.PreferenceHelper;
import org.torproject.artitoyvpn.vpn.DataUsage;
import org.torproject.artitoyvpn.vpn.VpnStatusObservable;
import org.torproject.onionmasq.events.BootstrapEvent;
import org.torproject.onionmasq.events.OnionmasqEvent;

import java.util.Locale;

public class HomeViewModel extends AndroidViewModel {

    final MutableLiveData<String> stateText;
    final MutableLiveData<String> buttonText;
    final MutableLiveData<String> progressText;
    final MutableLiveData<Boolean> isButtonEnabled;

    private final MutableLiveData<String> throughputText;
    private final MutableLiveData<String> throughputTextOverall;

    private final PreferenceHelper preferenceHelper;

    public HomeViewModel(Application application) {
        super(application);
        stateText = new MutableLiveData<>();
        buttonText = new MutableLiveData<>();
        progressText = new MutableLiveData<>();
        isButtonEnabled = new MutableLiveData<>();
        throughputText = new MutableLiveData<>();
        throughputTextOverall = new MutableLiveData<>();
        preferenceHelper = new PreferenceHelper(application);
    }

    public LiveData<String> getText() {
        return stateText;
    }

    public LiveData<String> getButtonText() {
        return buttonText;
    }

    public LiveData<Boolean> isButtonEnabled() {
        return isButtonEnabled;
    }

    public LiveData<String> getProgressText() {
        return progressText;
    }

    public LiveData<String> getThroughputText() {
        return throughputText;
    }

    public LiveData<String> getOverallThroughputText() {
        return throughputTextOverall;
    }

    public void updateDataUsage(Context context, DataUsage dataUsage) {
        String received = Formatter.formatFileSize(context, dataUsage.downstreamDataPerSec);
        String sent = Formatter.formatFileSize(context, dataUsage.upstreamDataPerSec);
        String receivedOverall = Formatter.formatFileSize(context, dataUsage.downstreamData);
        String sentOverall = Formatter.formatFileSize(context, dataUsage.upstreamData);

        throughputTextOverall.postValue(context.getString(R.string.bandwidth_stats, receivedOverall, sentOverall));
        throughputText.postValue(context.getString(R.string.bandwidth_stats_per_sec, received, sent));
    }
    public void update(OnionmasqEvent onionmasqEvent, Context context) {
        if (onionmasqEvent instanceof BootstrapEvent) {
            BootstrapEvent event = (BootstrapEvent) onionmasqEvent;
            if (event.bootstrapStatus != null) {
                progressText.postValue(event.bootstrapStatus);
            } else {
                progressText.postValue(context.getString(R.string.bootstrap_at, (event.bootstrapPercent + "%")));
            }
        }
    }

    public void update(VpnStatusObservable.Status status, Context context) {
        switch (status) {
            case STARTING:
                stateText.postValue(context.getString(R.string.state_description_starting));
                buttonText.postValue(context.getString(R.string.stop));
                isButtonEnabled.postValue(false);
                break;
            case RUNNING:
                stateText.postValue(context.getString(R.string.state_description_running));
                buttonText.postValue(context.getString(R.string.stop));
                isButtonEnabled.postValue(true);
                progressText.postValue(null);
                break;
            case STOPPING:
                stateText.postValue(context.getString(R.string.state_description_stopping));
                buttonText.postValue(context.getString(R.string.stop));
                isButtonEnabled.postValue(false);
                progressText.postValue(null);
                break;
            case STOPPED:
                stateText.postValue(context.getString(R.string.state_description_off));
                buttonText.postValue(context.getString(R.string.start));
                isButtonEnabled.postValue(true);
                progressText.postValue(null);
                break;
            case ERROR:
                stateText.postValue(context.getString(R.string.state_description_error));
                buttonText.postValue(context.getString(R.string.start));
                isButtonEnabled.postValue(true);
                progressText.postValue(null);
                break;
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.TIRAMISU)
    public boolean askForNotificationPermission() {
        return ContextCompat.checkSelfPermission(this.getApplication(), Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED;
    }

    public String getExitNodeCountry() {
        String cc = preferenceHelper.getExitNodeCountry();
        if (cc == null) {
            return "any";
        }
        Locale[] locales = Locale.getAvailableLocales();
        for (Locale locale : locales) {
            if (cc.equals(locale.getCountry())) {
                return locale.getDisplayCountry();
            }
        }

        return "unknown";
    }
}