package net.pokeranalytics.android.ui.fragment

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.recyclerview.widget.LinearLayoutManager
import io.realm.Realm
import kotlinx.android.synthetic.main.fragment_stats.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import net.pokeranalytics.android.R
import net.pokeranalytics.android.calculus.Calculator
import net.pokeranalytics.android.calculus.Stat
import net.pokeranalytics.android.model.Criteria
import net.pokeranalytics.android.model.combined
import net.pokeranalytics.android.ui.activity.ReportDetailsActivity
import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter
import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate
import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource
import net.pokeranalytics.android.ui.fragment.components.PokerAnalyticsFragment
import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.rowrepresentable.ReportRow
import timber.log.Timber
import java.util.*
import kotlin.collections.ArrayList

class ReportsFragment : PokerAnalyticsFragment(), StaticRowRepresentableDataSource, RowRepresentableDelegate {

	companion object {

		/**
		 * Create new instance
		 */
		fun newInstance(): ReportsFragment {
			val fragment = ReportsFragment()
			val bundle = Bundle()
			fragment.arguments = bundle
			return fragment
		}

		val rowRepresentation: List<RowRepresentable> by lazy {
			val rows = ArrayList<RowRepresentable>()
			rows.addAll(ReportRow.getRows())
			rows
		}
	}

	private lateinit var reportsAdapter: RowRepresentableAdapter


	// Life Cycle

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

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

	// Rows

	override fun adapterRows(): List<RowRepresentable>? {
		return rowRepresentation
	}

	override fun onRowSelected(position: Int, row: RowRepresentable, fromAction: Boolean) {
		super.onRowSelected(position, row, fromAction)
		if (row is ReportRow) {
			val reportName = row.localizedTitle(requireContext())
			launchComputation(row.criteria, reportName)
		}
	}


	// Business

	/**
	 * Init data
	 */
	private fun initData() {
	}

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

		reportsAdapter = RowRepresentableAdapter(this, this)

		val viewManager = LinearLayoutManager(requireContext())

		recyclerView.apply {
			setHasFixedSize(true)
			layoutManager = viewManager
			adapter = reportsAdapter
		}
	}

	/**
	 * Launch computation
	 */
	private fun launchComputation(criteriaList: List<Criteria>, reportName: String) {

		if (criteriaList.combined().size < 2) {
			Toast.makeText(context, R.string.less_then_2_values_for_display, Toast.LENGTH_LONG).show()
			return
		}

		showLoader()

		GlobalScope.launch {

			val startDate = Date()
			val realm = Realm.getDefaultInstance()

			val requiredStats: List<Stat> = listOf(Stat.NET_RESULT)
			val options = Calculator.Options(
				evolutionValues = Calculator.Options.EvolutionValues.STANDARD,
				stats = requiredStats,
				criterias = criteriaList
			)

			val report = Calculator.computeStats(realm, options = options)

			Timber.d("launchComputation: ${System.currentTimeMillis() - startDate.time}ms")

			launch(Dispatchers.Main) {
				if (!isDetached) {
					hideLoader()
					ReportDetailsActivity.newInstance(requireContext(), report, reportName)
				}
			}
			realm.close()
		}
	}


}