package net.pokeranalytics.android.ui.view

import android.content.Context
import net.pokeranalytics.android.R
import net.pokeranalytics.android.model.LiveData
import net.pokeranalytics.android.model.extensions.SessionState
import net.pokeranalytics.android.ui.fragment.components.bottomsheet.BottomSheetType

/**
 * An interface to easily localize any object
 */
interface Localizable {
	/**
	 * The resource identifier of the localized title
	 */
	val resId: Int?
		get() {
			return null
		}

	/**
	 * The localized title of the row
	 */
	fun localizedTitle(context: Context): String {
		this.resId?.let {
			return context.getString(it)
		}
		return "LOCALISATION NOT FOUND"
	}
}

/**
 * An interface used so that enums values can be represented visually
 *  as rows in RecyclerViews
 */
interface RowRepresentable : Localizable {
	/**
	 * The type of view associated with the row
	 */
	val viewType: Int
		get() {
			return 0
		}

	/**
	 * The type of bottom sheet displayed when the row is clicked on
	 */
	val bottomSheetType: BottomSheetType
		get() {
			return BottomSheetType.NONE
		}

	val relatedResultsRepresentable: LiveData?
		get() {
			return null
		}
}

enum class SessionRow : RowRepresentable {

	DURATION,
	NET_HOURLY_RATE,
	BANKROLL_VARIATION,

	CASHED_OUT,
	BUY_IN,
	TIPS,

	GAME,
	BLINDS,
	LOCATION,
	BANKROLL,
	TABLE_SIZE,
	START_DATE,
	END_DATE,

	BREAK_TIME,
	COMMENT;

	companion object {
		/**
		 * Return the rows to display for the current session state
		 */
		fun getRowsForState(sessionState: SessionState): ArrayList<RowRepresentable> {
			return when (sessionState) {
				SessionState.PENDING -> {
					arrayListOf(GAME, BLINDS, LOCATION, BANKROLL, TABLE_SIZE, START_DATE, END_DATE)
				}
				SessionState.STARTED -> {
					arrayListOf(
						CASHED_OUT, BUY_IN, TIPS,
						GAME, BLINDS, LOCATION, BANKROLL, TABLE_SIZE, START_DATE, END_DATE, BREAK_TIME, COMMENT
					)
				}
				SessionState.PAUSED -> {
					arrayListOf(
						CASHED_OUT, BUY_IN, TIPS,
						GAME, BLINDS, LOCATION, BANKROLL, TABLE_SIZE, START_DATE, END_DATE, BREAK_TIME, COMMENT
					)
				}
				SessionState.FINISHED -> {
					arrayListOf(
						DURATION, NET_HOURLY_RATE, BANKROLL_VARIATION,
						CASHED_OUT, BUY_IN, TIPS,
						GAME, BLINDS, LOCATION, BANKROLL, TABLE_SIZE, START_DATE, END_DATE, BREAK_TIME, COMMENT
					)
				}
				else -> arrayListOf()
			}
		}
	}

	override val resId: Int?
		get() {
			return when (this) {

				DURATION -> R.string.duration
				NET_HOURLY_RATE -> R.string.hour_rate_without_pauses
				BANKROLL_VARIATION -> R.string.bankroll_variation

				CASHED_OUT -> R.string.cashed_out
				BUY_IN -> R.string.buyin
				TIPS -> R.string.tips

				GAME -> R.string.game
				BLINDS -> R.string.blinds
				LOCATION -> R.string.location
				BANKROLL -> R.string.bankroll
				TABLE_SIZE -> R.string.table_size
				START_DATE -> R.string.start_date
				END_DATE -> R.string.end_date
				BREAK_TIME -> R.string.break_time
				COMMENT -> R.string.comment
			}
		}

	override val viewType: Int
		get() {
			return when (this) {
				DURATION, NET_HOURLY_RATE, BANKROLL_VARIATION,
				CASHED_OUT, BUY_IN, TIPS,
				GAME, BLINDS, LOCATION, BANKROLL, TABLE_SIZE, COMMENT, START_DATE, END_DATE, BREAK_TIME -> RowViewType.TITLE_VALUE.ordinal
			}
		}

	override val bottomSheetType: BottomSheetType
		get() {
			return when (this) {
				CASHED_OUT, BREAK_TIME -> BottomSheetType.EDIT_TEXT
				BUY_IN, TIPS -> BottomSheetType.SUM
				BLINDS -> BottomSheetType.DOUBLE_EDIT_TEXT
				GAME -> BottomSheetType.LIST_GAME
				LOCATION, BANKROLL -> BottomSheetType.LIST
				TABLE_SIZE -> BottomSheetType.GRID
				COMMENT -> BottomSheetType.EDIT_TEXT
				else -> BottomSheetType.NONE
			}
		}
}

enum class SimpleRow : RowRepresentable {
	NAME;

	override val resId: Int? = R.string.name
	override val viewType: Int = RowViewType.TITLE_VALUE.ordinal
	override val bottomSheetType: BottomSheetType = BottomSheetType.EDIT_TEXT
}

enum class BankrollRow : RowRepresentable {
	LIVE,
	CURRENCY;

	override val resId: Int?
		get() {
			return when (this) {
				LIVE -> R.string.live
				CURRENCY -> R.string.currency
			}
		}

	override val viewType: Int
		get() {
			return when (this) {
				LIVE, CURRENCY -> RowViewType.TITLE_VALUE.ordinal
			}
		}

	override val bottomSheetType: BottomSheetType
		get() {
			return when (this) {
				LIVE -> BottomSheetType.NONE
				CURRENCY -> BottomSheetType.LIST
			}
		}
}

enum class GameRow : RowRepresentable {
	SHORT_NAME;

	override val resId: Int?
		get() {
			return when (this) {
				SHORT_NAME -> R.string.short_name
			}
		}

	override val viewType: Int
		get() {
			return when (this) {
				SHORT_NAME -> RowViewType.TITLE_VALUE.ordinal
			}
		}

	override val bottomSheetType: BottomSheetType
		get() {
			return when (this) {
				SHORT_NAME -> BottomSheetType.EDIT_TEXT
			}
		}
}

enum class LocationRow : RowRepresentable {
	LOCATION_STATUS;

	override val resId: Int?
		get() {
			return when (this) {
				LOCATION_STATUS -> R.string.short_name
			}
		}

	override val viewType: Int
		get() {
			return when (this) {
				LOCATION_STATUS -> RowViewType.TITLE.ordinal
			}
		}

	override val bottomSheetType: BottomSheetType
		get() {
			return when (this) {
				LOCATION_STATUS -> BottomSheetType.NONE
			}
		}
}

enum class TransactionTypeRow : RowRepresentable {
}

enum class TournamentFeatureRow : RowRepresentable {
}

enum class SettingRow : RowRepresentable {
	BANKROLL,
	GAME,
	LOCATION,
	TOURNAMENT_FEATURE,
	TRANSACTION_TYPE;

	override val resId: Int?
		get() {
			this.relatedResultsRepresentable?. let {
				return it.resId
			} ?: run {
				return super.resId
			}
		}

	override val viewType: Int = RowViewType.TITLE.ordinal

	override val relatedResultsRepresentable: LiveData?
		get() {
			return when (this) {
				BANKROLL -> LiveData.BANKROLL
				GAME -> LiveData.GAME
				LOCATION -> LiveData.LOCATION
				TOURNAMENT_FEATURE -> LiveData.TOURNAMENT_FEATURE
				TRANSACTION_TYPE -> LiveData.TRANSACTION_TYPE
			}
		}
}