package org.mercury_im.messenger;

import android.app.Application;
import android.content.Intent;
import android.os.Build;

import org.mercury_im.messenger.data.repository.AccountRepository;
import org.mercury_im.messenger.di.component.AppComponent;
import org.mercury_im.messenger.di.component.DaggerAppComponent;
import org.mercury_im.messenger.di.module.AppModule;
import org.mercury_im.messenger.entity.Account;
import org.mercury_im.messenger.service.MercuryConnectionService;
import org.mercury_im.messenger.xmpp.CsiManager;

import java.util.List;

import javax.inject.Inject;

import io.reactivex.disposables.CompositeDisposable;


public class MercuryImApplication extends Application {

    static {
        // Initialize Smack etc.
        // new MercuryConfiguration();
    }

    private static MercuryImApplication INSTANCE;
    private AppComponent appComponent;
    private ClientStateHandler clientStateHandler = new ClientStateHandler();
    private final CompositeDisposable disposable = new CompositeDisposable();

    @Inject
    AccountRepository accountRepository;

    @Inject
    Messenger messenger;

    public static MercuryImApplication getApplication() {
        return INSTANCE;
    }


    @Override
    public void onCreate() {
        super.onCreate();
        INSTANCE = this;
        appComponent = createAppComponent();
        appComponent.inject(this);

        setupClientStateIndication();

        Notifications.initializeNotificationChannels(this);

        subscribeForegroundServiceToActiveAccounts();
    }

    private void setupClientStateIndication() {
        clientStateHandler.addClientStateListener(new CsiManager(messenger.getConnectionManager()));
        registerActivityLifecycleCallbacks(clientStateHandler);
    }

    /**
     * Create the Dependency Injection graph.
     */
    public AppComponent createAppComponent() {
        AppComponent appComponent = DaggerAppComponent.builder()
                .appModule(new AppModule(this))
                .build();

        appComponent.inject(this);

        return appComponent;
    }

    public AppComponent getAppComponent() {
        return appComponent;
    }

    private void subscribeForegroundServiceToActiveAccounts() {
        disposable.add(accountRepository.observeAllAccounts()
                .map(this::listContainsActiveAccount)
                .distinctUntilChanged()
                .subscribe(foregroundServiceNeeded -> {
                    if (foregroundServiceNeeded) {
                        startForegroundService();
                    } else {
                        stopForegroundService();
                    }
                }));
    }

    private boolean listContainsActiveAccount(List<Account> accounts) {
        for (Account account : accounts) {
            if (account.isEnabled()) {
                return true;
            }
        }
        return false;
    }

    private void startForegroundService() {
        Intent startIntent = new Intent(getApplicationContext(), MercuryConnectionService.class);
        startIntent.setAction(MercuryConnectionService.ACTION_START);
        if (Build.VERSION.SDK_INT < 26) {
            startService(startIntent);
        } else {
            startForegroundService(startIntent);
        }
    }

    private void stopForegroundService() {
        Intent stopIntent = new Intent(getApplicationContext(), MercuryConnectionService.class);
        stopIntent.setAction(MercuryConnectionService.ACTION_STOP);
        startService(stopIntent);
    }
}
