package net.pokeranalytics.android.ui.fragment

import android.os.Bundle
import android.view.*
import android.view.animation.OvershootInterpolator
import android.widget.Toast
import androidx.interpolator.view.animation.FastOutSlowInInterpolator
import io.realm.kotlin.where
import kotlinx.android.synthetic.main.fragment_session.*
import net.pokeranalytics.android.R
import net.pokeranalytics.android.model.LiveData
import net.pokeranalytics.android.model.extensions.SessionState
import net.pokeranalytics.android.model.extensions.getState
import net.pokeranalytics.android.model.realm.Session
import net.pokeranalytics.android.ui.activity.EditableDataActivity
import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity
import net.pokeranalytics.android.ui.adapter.components.RowRepresentableAdapter
import net.pokeranalytics.android.ui.adapter.components.RowRepresentableDelegate
import net.pokeranalytics.android.ui.fragment.components.DateTimePickerManager
import net.pokeranalytics.android.ui.fragment.components.PokerAnalyticsFragment
import net.pokeranalytics.android.ui.fragment.components.bottomsheet.BottomSheetDelegate
import net.pokeranalytics.android.ui.fragment.components.bottomsheet.BottomSheetFragment
import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.SessionRow
import net.pokeranalytics.android.ui.view.SmoothScrollLinearLayoutManager
import net.pokeranalytics.android.util.toast
import timber.log.Timber
import java.util.*

class SessionFragment : PokerAnalyticsFragment(), RowRepresentableDelegate, BottomSheetDelegate {

	private lateinit var currentSession: Session
	private lateinit var sessionAdapter: RowRepresentableAdapter
	private var sessionMenu: Menu? = null


	override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
		return inflater.inflate(R.layout.fragment_session, container, false)
	}

	override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
		super.onViewCreated(view, savedInstanceState)
		initUI()
	}

	override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) {
		inflater?.inflate(R.menu.session_toolbar, menu)
		this.sessionMenu = menu
		updateSessionUI()
		super.onCreateOptionsMenu(menu, inflater)
	}

	override fun onOptionsItemSelected(item: MenuItem?): Boolean {
		when (item!!.itemId) {
			R.id.restart -> toast("Restart is clicked!")
			R.id.delete -> {
				currentSession.delete()
				activity?.finish()
			}
		}
		return true
	}


	override fun onRowSelected(row: RowRepresentable) {
		val data = currentSession.getBottomSheetData(row)
		when (row) {
			SessionRow.START_DATE -> DateTimePickerManager.create(
				requireContext(),
				row,
				this,
				currentSession.timeFrame?.startDate
			)
			SessionRow.END_DATE -> DateTimePickerManager.create(
				requireContext(),
				row,
				this,
				currentSession.timeFrame?.endDate
			)
			else -> BottomSheetFragment.create(fragmentManager, row, this, data)
		}
	}

	override fun onActionSelected(row: RowRepresentable) {
		Toast.makeText(requireContext(), "Action for row: $row", Toast.LENGTH_SHORT).show()
	}

	override fun clickOnAdd(row: RowRepresentable) {
		when (row) {
			SessionRow.GAME -> EditableDataActivity.newInstance(requireContext(), LiveData.GAME.ordinal)
			SessionRow.BANKROLL -> EditableDataActivity.newInstance(requireContext(), LiveData.BANKROLL.ordinal)
			SessionRow.LOCATION -> EditableDataActivity.newInstance(requireContext(), LiveData.LOCATION.ordinal)
		}
	}

	override fun clickOnClear(row: RowRepresentable) {
		currentSession.updateValue(null, row)
		sessionAdapter.refreshRow(row)
		when (row) {
			SessionRow.START_DATE, SessionRow.END_DATE -> updateSessionUI()
		}
	}

	override fun setValue(value: Any?, row: RowRepresentable) {
		currentSession.updateValue(value, row)
		sessionAdapter.refreshRow(row)
		when (row) {
			SessionRow.START_DATE, SessionRow.END_DATE -> updateSessionUI()
		}
	}

	/**
	 * Init UI
	 */
	private fun initUI() {

		val activity = activity as PokerAnalyticsActivity

		// Avoid a bug during setting the title
		toolbar.title = ""

		activity.setSupportActionBar(toolbar)
		activity.supportActionBar?.setDisplayHomeAsUpEnabled(true)
		setHasOptionsMenu(true)

		val viewManager = SmoothScrollLinearLayoutManager(requireContext())
		recyclerView.apply {
			setHasFixedSize(true)
			layoutManager = viewManager
		}

		bottomAppBar.inflateMenu(R.menu.session_bottom_app_bar)
		bottomAppBar.menu.findItem(R.id.stop).isVisible = false

		bottomAppBar.setOnMenuItemClickListener { item ->
			when (item.itemId) {
				R.id.stop -> {
					currentSession.stopSession()
					updateSessionUI()
				}
			}
			false
		}

		floatingActionButton.setOnClickListener {
			manageSessionState()
		}

	}

	/**
	 * Update the UI with the session data
	 * Should be called after the initialization of the session
	 */
	private fun updateSessionUI() {

		when (currentSession.getState()) {
			SessionState.PENDING -> {
				sessionMenu?.findItem(R.id.restart)?.isVisible = false
				floatingActionButton.setImageResource(R.drawable.ic_outline_play)
				bottomAppBar.menu.findItem(R.id.stop).isVisible = false
				floatingActionButton.animate().scaleX(1f).scaleY(1f).alpha(1f)
					.setInterpolator(OvershootInterpolator()).start()
			}
			SessionState.STARTED -> {
				sessionMenu?.findItem(R.id.restart)?.isVisible = true
				floatingActionButton.setImageResource(R.drawable.ic_outline_pause)
				bottomAppBar.menu.findItem(R.id.stop).isVisible = true
				floatingActionButton.animate().scaleX(1f).scaleY(1f).alpha(1f)
					.setInterpolator(OvershootInterpolator()).start()
			}
			SessionState.PAUSED -> {
				sessionMenu?.findItem(R.id.restart)?.isVisible = true
				floatingActionButton.setImageResource(R.drawable.ic_outline_play)
				bottomAppBar.menu.findItem(R.id.stop).isVisible = true
				floatingActionButton.animate().scaleX(1f).scaleY(1f).alpha(1f)
					.setInterpolator(OvershootInterpolator()).start()
			}
			SessionState.FINISHED -> {
				sessionMenu?.findItem(R.id.restart)?.isVisible = true
				bottomAppBar.menu.findItem(R.id.stop).isVisible = false
				floatingActionButton.animate().scaleX(0f).scaleY(0f).alpha(0f)
					.setInterpolator(FastOutSlowInInterpolator()).start()
			}
		}

		sessionAdapter.updateRows(currentSession.adapterRows())
		recyclerView.smoothScrollToPosition(0)
	}

	/**
	 * Update the state of the session (start / pause)
	 */
	private fun manageSessionState() {
		when (currentSession.getState()) {
			SessionState.PENDING -> {
				currentSession.startSession()
			}
			SessionState.STARTED -> {
				currentSession.pauseSession()
			}
			SessionState.PAUSED -> {
				currentSession.startSession()
			}
		}

		updateSessionUI()
	}

	/**
	 * Set fragment data
	 */
	fun setData(isTournament: Boolean, sessionId: String) {
		toolbar.title = if (isTournament) getString(R.string.tournament) else getString(R.string.cash_game)

		val realm = getRealm()
		val sessionRealm = realm.where<Session>().equalTo("id", sessionId).findFirst()
		if (sessionRealm != null) {
			currentSession = sessionRealm
		} else {
			realm.beginTransaction()
			currentSession = realm.createObject(Session::class.java, UUID.randomUUID().toString())
			realm.commitTransaction()
		}

		sessionAdapter = RowRepresentableAdapter(currentSession, this)
		recyclerView.adapter = sessionAdapter

		updateSessionUI()
		Timber.d("Session state: ${currentSession.getState()}")
	}

}