package net.pokeranalytics.android.model.extensions

import net.pokeranalytics.android.model.realm.Session
import java.util.*

enum class SessionState {
	PENDING,
	PLANNED,
	STARTED,
	PAUSED,
	FINISHED;

	var hasStarted: Boolean = false
		get() {
			return when (this) {
				STARTED, PAUSED, FINISHED -> true
				else -> false
			}
		}
}

/**
 * Return the current state of a session
 * For example: STARTED, PAUSED, FINISHED
 */
fun Session.getState(): SessionState {

	val start = this.startDate
	if (start == null) {
		return SessionState.PENDING
	} else {
		if (start > Date()) {
			return SessionState.PLANNED
		} else if (this.endDate != null) {
			return SessionState.FINISHED
		} else if (this.pauseDate != null) {
			return SessionState.PAUSED
		} else {
			return SessionState.STARTED
		}
	}

}

val AbstractList<Session>.hourlyDuration: Double
	get() {
		val intervals = mutableListOf<TimeInterval>()
		this.forEach {
			val interval = TimeInterval(it.startDate!!, it.endDate!!, it.breakDuration)
			intervals.update(interval)
		}
		return intervals.sumByDouble { it.hourlyDuration }
	}

class TimeInterval(var start: Date, var end: Date, var breakDuration: Long) {

	val hourlyDuration: Double
		get() {
			val netDuration = end.time - start.time - breakDuration
			return (netDuration / 3600000).toDouble()
		}
}

fun MutableList<TimeInterval>.update(timeInterval: TimeInterval): MutableList<TimeInterval> {

	val overlapped = this.filter {

		(it.start.before(timeInterval.start) && it.end.after(timeInterval.start)) ||
				(it.start.before(timeInterval.end) && it.end.after(timeInterval.end)) ||
				(it.start.after(timeInterval.start) && it.end.before(timeInterval.end))

	}

	if (overlapped.size == 0) { // add
		this.add(timeInterval)
	} else { // update

		var start = timeInterval.start
		var end = timeInterval.end
		var breakDuration = timeInterval.breakDuration

		overlapped.forEach {
			if (it.start.before(start)) {
				start = it.start
			}
			if (it.end.after(end)) {
				end = it.end
			}
			breakDuration = kotlin.math.max(it.breakDuration, breakDuration)
		}

		this.removeAll(overlapped)
		this.add(TimeInterval(start, end, breakDuration))

	}

	return this
}