package net.pokeranalytics.android.ui.fragment

import android.os.Bundle
import android.view.LayoutInflater
import android.view.Menu
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.LinearLayoutManager
import io.realm.RealmObject
import kotlinx.android.synthetic.main.fragment_filter_details.*
import kotlinx.android.synthetic.main.fragment_filter_details.view.*
import net.pokeranalytics.android.R
import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity
import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter
import net.pokeranalytics.android.ui.adapter.RowRepresentableDataSource
import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate
import net.pokeranalytics.android.ui.fragment.components.PokerAnalyticsFragment
import net.pokeranalytics.android.ui.fragment.components.bottomsheet.BottomSheetFragment
import net.pokeranalytics.android.ui.helpers.DateTimePickerManager
import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.RowViewType
import net.pokeranalytics.android.ui.view.rowrepresentable.FilterCategoryRow
import net.pokeranalytics.android.ui.view.rowrepresentable.FilterRow
import net.pokeranalytics.android.ui.view.rowrepresentable.FilterSubcategoryRow
import timber.log.Timber
import java.util.*


open class FilterDetailsFragment : PokerAnalyticsFragment(), RowRepresentableDataSource, RowRepresentableDelegate {

	lateinit var parentActivity: PokerAnalyticsActivity
	lateinit var item: RealmObject
	lateinit var rowRepresentableAdapter: RowRepresentableAdapter

	private var rows: ArrayList<RowRepresentable> = ArrayList()
	private var rowsForFilterSubcategory: HashMap<FilterSubcategoryRow, ArrayList<RowRepresentable>> = HashMap()

	private var filterMenu: Menu? = null
	private var filterCategory: FilterCategoryRow? = null


	val selectedRows = ArrayList<RowRepresentable>()


	var isUpdating = false
	var shouldOpenKeyboard = true

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

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

	override fun onBackPressed() {
		super.onBackPressed()
		saveData()
	}

	override fun onRowSelected(position: Int, row: RowRepresentable, fromAction: Boolean) {
		super.onRowSelected(position, row, fromAction)

		val oldRows = ArrayList<RowRepresentable>()
		oldRows.addAll(rows)

		if (selectedRows.contains(row)) {
			selectedRows.remove(row)
		} else {

			val excludedRows = ArrayList<RowRepresentable>()

			// Exclude the rows of the same subcategory if we are an a single row selection
			if (row.subcategoryRow()?.getType() == FilterSubcategoryRow.Type.SINGLE) {
				row.subcategoryRow()?.let { filterSubcategory ->
					rowsForFilterSubcategory[filterSubcategory]?.let { filterRows ->
						excludedRows.addAll(filterRows)
					}
				}
			}

			// Exclude the filter rows of the subcategories
			row.excludedFilterSubcategoryRows()?.let { subcategories ->
				for (subcategory in subcategories) {
					rowsForFilterSubcategory[subcategory]?.let { rows ->
						excludedRows.addAll(rows)
					}
				}
			}

			// Exclude the filter rows
			row.excludedFilterRows()?.let {
				excludedRows.addAll(it)
			}

			for (filterRow in excludedRows) {
				if (selectedRows.contains(filterRow)) {
					selectedRows.remove(filterRow)
					rowRepresentableAdapter.refreshRow(filterRow)
				}
			}

			Timber.d("Row: $row")
			when (row) {
				FilterRow.FROM -> DateTimePickerManager.create(requireContext(), row, this, Date(), onlyDate = true)
				FilterRow.TO -> DateTimePickerManager.create(requireContext(), row, this, Date(), onlyDate = true)
				FilterRow.PAST_DAYS -> {
					val data = row.editingDescriptors(mapOf("defaultValue" to ""))
					BottomSheetFragment.create(fragmentManager, row, this, data, null)
				}
				else -> {
					selectedRows.add(row)
				}
			}

		}
		rowRepresentableAdapter.refreshRow(row)

	}

	override fun isSelected(row: RowRepresentable): Boolean {
		return selectedRows.contains(row)
	}

	override fun onRowValueChanged(value: Any?, row: RowRepresentable) {
		super.onRowValueChanged(value, row)
		selectedRows.add(row)
		rowRepresentableAdapter.refreshRow(row)
	}

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

	override fun rowRepresentableForPosition(position: Int): RowRepresentable? {
		return rows[position]
	}

	override fun numberOfRows(): Int {
		return rows.size
	}

	override fun viewTypeForPosition(position: Int): Int {
		val rowViewType = rowRepresentableForPosition(position)?.viewType ?: -1
		return if (rowViewType != -1) rowViewType else RowViewType.TITLE_CHECK.ordinal
	}

	override fun indexForRow(row: RowRepresentable): Int {
		return rows.indexOf(row)
	}


	/**
	 * Init UI
	 */
	private fun initUI() {
		parentActivity = activity as PokerAnalyticsActivity
		parentActivity.setSupportActionBar(toolbar)
		parentActivity.supportActionBar?.setDisplayHomeAsUpEnabled(true)
		setHasOptionsMenu(true)

		val viewManager = LinearLayoutManager(requireContext())

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

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

		Timber.d("initData")

		this.appBar.toolbar.title = getString(R.string.filter)

		filterCategory?.let {

			this.appBar.toolbar.title = it.localizedTitle(requireContext())

			this.rows.clear()
			this.rowsForFilterSubcategory.clear()

			for (subcategory in it.getSubcategories()) {
				this.rows.add(subcategory)

				val subcategoryRows = subcategory.getFilterRows(getRealm())
				this.rowsForFilterSubcategory.put(subcategory, subcategoryRows)
				this.rows.addAll(subcategoryRows)
			}

			this.rowRepresentableAdapter = RowRepresentableAdapter(this, this)
			this.recyclerView.adapter = rowRepresentableAdapter
		}

	}


	/**
	 * Save data
	 */
	private fun saveData() {

		//TODO: Save filter details data
		Timber.d("Save filter details data")
		finishActivityWithResult("")
	}


	/**
	 * Finish the activity with a result
	 */
	private fun finishActivityWithResult(uniqueIdentifier: String) {
		/*
		val intent = Intent()
		intent.putExtra(EditableDataActivity.IntentKey.DATA_TYPE.keyName, dataType)
		intent.putExtra(EditableDataActivity.IntentKey.PRIMARY_KEY.keyName, uniqueIdentifier)
		activity?.setResult(RESULT_OK, intent)
		*/
		activity?.finish()
	}

	/**
	 * Set fragment data
	 */
	fun setData(filterCategory: Int) {

		this.filterCategory = FilterCategoryRow.values()[filterCategory]

		/*
		this.dataType = dataType
		this.liveDataType = LiveData.values()[dataType]
		this.primaryKey = primaryKey
		*/
	}

}