package net.pokeranalytics.android.calculus.bankroll

import net.pokeranalytics.android.calculus.interfaces.DatableValue
import net.pokeranalytics.android.model.realm.Bankroll
import net.pokeranalytics.android.model.realm.Transaction
import java.util.*
import kotlin.collections.HashMap

/**
 * A class describing the parameters required to launch a bankroll report
 *
 */
class BankrollReportSetup(bankroll: Bankroll?, from: Date? = null, to: Date? = null) {
	/**
	 * The bankroll to compute. If null, the virtual global bankroll
	 */
	val bankroll = bankroll

	/**
	 * The start of the report
	 */
	val from = from

	/**
	 * The end of the report
	 */
	val to = to

}

class TransactionBucket(useRate: Boolean = false) {
	var transactions: MutableList<Transaction> = mutableListOf()
		private set
	var total: Double = 0.0
		private set
	var useRate: Boolean = useRate
		private set

	fun addTransaction(transaction: Transaction) {

		this.transactions.add(transaction)
		var rate = 1.0
		if (this.useRate) {
			rate = transaction.bankroll?.currency?.rate ?: 1.0
		}

		val ratedAmount = rate * transaction.amount
		this.total += ratedAmount

	}

}

class BRGraphPoint {

	var value: Double = 0.0
	var variation: Double = 0.0
	var date: Date? = null

}

class BankrollReport(setup: BankrollReportSetup) {

	/**
	 * The setup used to compute the report
	 */
	var setup: BankrollReportSetup = setup

	/**
	 * The value of the bankroll
	 */
	var total: Double = 0.0
		private set

	/**
	 * The net result from poker computables
	 */
	var netResult: Double = 0.0
		private set

	/**
	 * The difference between withdrawals and deposits
	 */
	var netBanked: Double = 0.0
		private set

	/**
	 * The risk of ruin
	 */
	var riskOfRuin: Double = 0.0
		private set

	var transactions: List<Transaction> = mutableListOf()
		private set

	var transactionBuckets: HashMap<String, TransactionBucket> = HashMap()

	var evolutionPoints: Array<BRGraphPoint> = arrayOf()
	var evolutionItems: Array<DatableValue> = arrayOf()

	fun addTransaction(transaction: Transaction) {

		transaction.type?.let { type ->

			var bucket = this.transactionBuckets[type.id]

			if (bucket == null) {
				val b = TransactionBucket(this.setup.bankroll == null)
				this.transactionBuckets[type.id] = b
				bucket = b
			}

			bucket.addTransaction(transaction)

		} ?: run {
			throw Exception("Transaction has no type")
		}

	}


}