package co.pixelbeard.theanfieldwrap.data.source.remote;

import android.content.Context;

import com.onesignal.OneSignal;

import java.util.List;

import co.pixelbeard.theanfieldwrap.data.NotificationSetting;
import co.pixelbeard.theanfieldwrap.data.Podcast;
import co.pixelbeard.theanfieldwrap.data.RealmPodcast;
import co.pixelbeard.theanfieldwrap.data.User;
import co.pixelbeard.theanfieldwrap.data.responses.ArticleByIdResponse;
import co.pixelbeard.theanfieldwrap.data.responses.ArticlesResponse;
import co.pixelbeard.theanfieldwrap.data.responses.GenericResponse;
import co.pixelbeard.theanfieldwrap.data.responses.GetDevicesResponse;
import co.pixelbeard.theanfieldwrap.data.responses.GetWalletResponse;
import co.pixelbeard.theanfieldwrap.data.responses.GuestUserResponse;
import co.pixelbeard.theanfieldwrap.data.responses.LoginResponse;
import co.pixelbeard.theanfieldwrap.data.responses.NotificationSettingsResponse;
import co.pixelbeard.theanfieldwrap.data.responses.PodcastByIdResponse;
import co.pixelbeard.theanfieldwrap.data.responses.PodcastsResponse;
import co.pixelbeard.theanfieldwrap.data.responses.RegisterUserResponse;
import co.pixelbeard.theanfieldwrap.data.responses.SubscriptionItemResponse;
import co.pixelbeard.theanfieldwrap.data.responses.VideoByIdResponse;
import co.pixelbeard.theanfieldwrap.data.responses.VideosResponse;
import co.pixelbeard.theanfieldwrap.data.source.DataSource;
import co.pixelbeard.theanfieldwrap.downloader.DownloadManager;
import co.pixelbeard.theanfieldwrap.freeSubscription.ActiveSubscriptionResponse;
import co.pixelbeard.theanfieldwrap.networking.ApiClient;
import co.pixelbeard.theanfieldwrap.networking.ApiInterface;
import co.pixelbeard.theanfieldwrap.utils.PrefKey;
import co.pixelbeard.theanfieldwrap.utils.PrefUtils;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;

public class RemoteRepository implements DataSource {

    private static final String TAG = RemoteRepository.class.getSimpleName();

    private ApiInterface apiService;

    public RemoteRepository() {
        apiService = ApiClient.getApiService();
    }

    @Override
    public Observable<GenericResponse> recordAnalytic(String type, String variable, String secondaryVariable) {
        return apiService.recordAnalytic(PrefUtils.getInstance().getStringPref(PrefKey.AUTH_TOKEN), type, variable, secondaryVariable)
                .subscribeOn(Schedulers.computation())
                .observeOn(Schedulers.computation());
    }

    @Override
    public Observable<LoginResponse> login(String email, String password) {
        return apiService.login(PrefUtils.getInstance().getStringPref(PrefKey.AUTH_TOKEN), email, password, PrefUtils.getInstance().getStringPref(PrefKey.ONESIGNAL_ID), "Android")
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    @Override
    public void saveUserDetails(User user, String authToken) {
        //Local only
    }

    @Override
    public void saveUserDetails(String firstName, String lastName, String userName) {
        //Local only
    }

    @Override
    public Observable<GuestUserResponse> registerGuestUser() {
        return apiService.registerGuestUser()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    @Override
    public void saveGuestUserDetails(String userName, String authToken) {
        //Local only
    }

    @Override
    public Observable<RegisterUserResponse> registerFullUser(String firstName, String lastName, String email, String password, boolean optIn, String username, String country) {
        return apiService.registerFullUser(firstName, lastName, email, password, optIn, username, country)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    @Override
    public Observable<GenericResponse> checkEmailAvailable(String email) {
        return apiService.checkUserEmail(email)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    @Override
    public Observable<GenericResponse> checkUsernameAvailable(String username) {
        return apiService.checkUsername(username)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    @Override
    public Observable<GenericResponse> resendAuthCode(String email) {
        return apiService.resendAuthCode(email)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    @Override
    public Observable<GenericResponse> activateUser(String email, String activationCode) {
        return apiService.activateUser(email, activationCode)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    @Override
    public Observable<GenericResponse> changePassword(String oldPassword, String newPassword) {
        return apiService.changePassword(PrefUtils.getInstance().getStringPref(PrefKey.AUTH_TOKEN), oldPassword, newPassword)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    @Override
    public Observable<NotificationSettingsResponse> getUserSettings() {
        return apiService.getUserSettings(PrefUtils.getInstance().getStringPref(PrefKey.AUTH_TOKEN))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    @Override
    public List<NotificationSetting> getUserSettingsLocal() {
        //Not needed
        return null;
    }

    @Override
    public void saveUserSettings(List<NotificationSetting> settings) {
        //Not needed
    }

    @Override
    public Observable<GenericResponse> updateUserSetting(String type, int value) {
        if (type.equalsIgnoreCase("articles")) {
            OneSignal.deleteTag("writing");
            OneSignal.sendTag("writing", String.valueOf(value));
        } else {
            OneSignal.deleteTag(type);
            OneSignal.sendTag(type, String.valueOf(value));
        }
        return apiService.updateUserSettings(PrefUtils.getInstance().getStringPref(PrefKey.AUTH_TOKEN), type, value)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    @Override
    public Observable<GenericResponse> updateUserEmail(String oldEmail, String newEmail) {
        return apiService.updateUserEmail(PrefUtils.getInstance().getStringPref(PrefKey.AUTH_TOKEN), newEmail, oldEmail)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    @Override
    public Observable<GenericResponse> updateUserDetails(String firstName, String lastName, String userName) {
        return apiService.updateUserDetails(PrefUtils.getInstance().getStringPref(PrefKey.AUTH_TOKEN), firstName, lastName, userName)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    @Override
    public Observable<GenericResponse> requestPasswordReset(String email) {
        return apiService.requestPasswordReset(email)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    @Override
    public Observable<GenericResponse> resetPassword(String email, String recoveryCode, String password) {
        return apiService.resetPassword(email, recoveryCode, password)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    @Override
    public Observable<GenericResponse> logout() {
        return apiService.logout(PrefUtils.getInstance().getStringPref(PrefKey.AUTH_TOKEN), PrefUtils.getInstance().getStringPref(PrefKey.ONESIGNAL_ID))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    @Override
    public void clearAllData(Context context) {
        //Local only
    }

    @Override
    public Observable<PodcastsResponse> getPodcasts(int pageNum) {
        return apiService.getPodcasts(PrefUtils.getInstance().getStringPref(PrefKey.AUTH_TOKEN), pageNum)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    @Override
    public Observable<PodcastByIdResponse> getPodcastByIdRemote(Long podcastId) {
        return apiService.getPodcastById(PrefUtils.getInstance().getStringPref(PrefKey.AUTH_TOKEN), podcastId)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    @Override
    public Observable<ArticlesResponse> getArticles(int pageNum) {
        return apiService.getArticles(PrefUtils.getInstance().getStringPref(PrefKey.AUTH_TOKEN), pageNum)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    @Override
    public Observable<ArticleByIdResponse> getArticleById(Long articleId) {
        return apiService.getArticleById(PrefUtils.getInstance().getStringPref(PrefKey.AUTH_TOKEN), articleId)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    @Override
    public Observable<VideosResponse> getVideos(int pageNum) {
        return apiService.getVideos(PrefUtils.getInstance().getStringPref(PrefKey.AUTH_TOKEN), pageNum)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    @Override
    public Observable<VideoByIdResponse> getVideoById(String videoId) {
        return apiService.getVideoById(PrefUtils.getInstance().getStringPref(PrefKey.AUTH_TOKEN), videoId)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    @Override
    public Observable<LoginResponse> checkUserSubscription() {
        return apiService.checkUserSubscription(PrefUtils.getInstance().getStringPref(PrefKey.AUTH_TOKEN))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    @Override
    public Observable<GenericResponse> convertGuestToFullUser(String firstName, String lastName, String email, String password, boolean optIn, String username, String country) {
        return apiService.convertGuestToFullUser(PrefUtils.getInstance().getStringPref(PrefKey.AUTH_TOKEN), firstName, lastName, email, password, optIn, username, "Country")
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    @Override
    public void getDownloadedPodcasts(DownloadedPodcastCallback callback) {
        //Local only
    }

    @Override
    public void downloadPodcast(Podcast podcast, Context context) {
        DownloadManager.getInstance().download(podcast, context);
    }

    @Override
    public void savePodcast(Podcast podcast, String filePath) {
        //local only
    }

    @Override
    public RealmPodcast getPodcastByIdLocal(long id) {
        //local only
        return null;
    }

    @Override
    public Observable<GetDevicesResponse> getActiveDevices() {
        return apiService.getActiveDevices(PrefUtils.getInstance().getStringPref(PrefKey.AUTH_TOKEN))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    @Override
    public Observable<GenericResponse> unlinkDevice(String userApiToken, int deviceId) {
        return apiService.unlinkDevice(userApiToken, deviceId)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    @Override
    public Observable<GetWalletResponse> getWallet() {
        return apiService.getWallet(PrefUtils.getInstance().getStringPref(PrefKey.AUTH_TOKEN))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    @Override
    public Observable<GetWalletResponse> creditUserAccount(int value, String title, String purchaseToken) {
        return apiService.creditUserAccount(PrefUtils.getInstance().getStringPref(PrefKey.AUTH_TOKEN), value, title, purchaseToken)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    @Override
    public Observable<GetWalletResponse> purchaseItem(String productId) {
        return apiService.purchaseItem(PrefUtils.getInstance().getStringPref(PrefKey.AUTH_TOKEN), productId)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    @Override
    public void getPodcastStates(PodcastStateCallback callback) {
//Local only
    }

    @Override
    public void clearPodcastStates() {
//Local only
    }

    @Override
    public void getPodcastState(long podcastId, int position, PodcastStateCallback callback) {
        //Local only
    }

    @Override
    public Observable<SubscriptionItemResponse> getSubscription() {
        return apiService.getSubscriptionList()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    @Override
    public Observable<ActiveSubscriptionResponse> activeSubscription(String subscription) {
        return apiService.getActiveSubscription(PrefUtils.getInstance().getStringPref(PrefKey.AUTH_TOKEN), subscription)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    @Override
    public Observable<ActiveSubscriptionResponse> activePaidSubscription(String subscription, String planType, int duration, String purchaseToken) {
        return apiService.getActivePaidSubscription(PrefUtils.getInstance().getStringPref(PrefKey.AUTH_TOKEN), subscription, planType, duration, purchaseToken)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    public void onDestroyRepo() {
//        apiService = null;
    }
}
