package org.mercury_im.messenger.android;

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

import org.jivesoftware.smack.android.AndroidSmackInitializer;
import org.jivesoftware.smackx.ping.android.ServerPingWithAlarmManager;
import org.mercury_im.messenger.android.di.component.DaggerAppComponent;
import org.mercury_im.messenger.android.util.AndroidLoggingHandler;
import org.mercury_im.messenger.core.Messenger;
import org.mercury_im.messenger.core.data.repository.AccountRepository;
import org.mercury_im.messenger.android.di.component.AppComponent;
import org.mercury_im.messenger.android.di.module.AppModule;
import org.mercury_im.messenger.entity.Account;
import org.mercury_im.messenger.android.service.MercuryForegroundService;
import org.mercury_im.messenger.core.connection.CsiManager;

import java.util.List;

import javax.inject.Inject;

import io.reactivex.disposables.CompositeDisposable;


public class MercuryImApplication extends Application {

    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();
        AndroidSmackInitializer.initialize(getApplicationContext());
        AndroidLoggingHandler.reset(new AndroidLoggingHandler());
        INSTANCE = this;
        appComponent = createAppComponent();
        appComponent.inject(this);

        setupClientStateIndication();
        ServerPingWithAlarmManager.onCreate(this);

        Notifications.initializeNotificationChannels(this);

        subscribeForegroundServiceToActiveAccounts();

    }

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

    /**
     * Create the Dependency Injection graph.
     */
    private 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(), MercuryForegroundService.class);
        startIntent.setAction(MercuryForegroundService.ACTION_START);
        if (Build.VERSION.SDK_INT < 26) {
            startService(startIntent);
        } else {
            startForegroundService(startIntent);
        }
    }

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