package de.froehling.henrik.timekeeper.storage.local

import de.froehling.henrik.timekeeper.domain.repository.ICustomersRepository
import de.froehling.henrik.timekeeper.models.Customer
import de.froehling.henrik.timekeeper.models.Project
import de.froehling.henrik.timekeeper.models.Task
import io.realm.Realm
import io.realm.RealmAsyncTask
import io.realm.Sort
import rx.Observable

class LocalCustomersRepository(private val realm: Realm) : ICustomersRepository {

    override fun getCustomersFilteredByLastName(ascending: Boolean): Observable<List<Customer>> {
        val customers = realm.where(Customer::class.java)
                .findAllSortedAsync("lastName", if (ascending) Sort.ASCENDING else Sort.DESCENDING)

        return customers.asObservable().filter { it.isLoaded }.map { it.toList() }
    }

    override fun getCustomersFilteredByFirstName(ascending: Boolean): Observable<List<Customer>> {
        val customers = realm.where(Customer::class.java)
                .findAllSortedAsync("firstName", if (ascending) Sort.ASCENDING else Sort.DESCENDING)

        return customers.asObservable().filter { it.isLoaded }.map { it.toList() }
    }

    override fun getCustomersFilteredByCompany(ascending: Boolean): Observable<List<Customer>> {
        val customers = realm.where(Customer::class.java)
                .findAllSortedAsync("company", if (ascending) Sort.ASCENDING else Sort.DESCENDING)

        return customers.asObservable().filter { it.isLoaded }.map { it.toList() }
    }

    override fun getCustomerDetails(customerID: String): Observable<Customer> {
        return realm.where(Customer::class.java).equalTo("uuid", customerID)
                .findFirstAsync().asObservable()
    }

    override fun getCustomerProjects(customerID: String): Observable<List<Project>> {
        val projects = realm.where(Customer::class.java).equalTo("uuid", customerID)
                .findFirstAsync().projects.orEmpty()

        return Observable.just(projects).map { it.toList() }
    }

    override fun getCustomerTasks(customerID: String): Observable<List<Task>> {
        val tasks = realm.where(Customer::class.java).equalTo("uuid", customerID)
                .findFirstAsync().tasks.orEmpty()

        return Observable.just(tasks).map { it.toList() }
    }

    override fun getAll(): Observable<List<Customer>> = getCustomersFilteredByLastName(true)

    override fun create(obj: Customer): Observable<RealmAsyncTask> {
        return Observable.just(
                realm.executeTransaction({ realm ->
                    realm.copyToRealmOrUpdate(obj)
                }, null)
        )
    }

    override fun update(obj: Customer): Observable<RealmAsyncTask> {
        return create(obj)
    }

    override fun delete(uuid: String): Observable<RealmAsyncTask> {
        return Observable.just(
                realm.executeTransaction({ realm ->
                    val customer = realm.where(Customer::class.java).equalTo("uuid", uuid).findFirst()
                    customer.removeFromRealm()
                }, null)
        )
    }
}
