package net.pokeranalytics.android.ui.fragment.components.bottomsheet

import android.annotation.SuppressLint
import android.app.Activity.RESULT_OK
import android.app.Dialog
import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import androidx.fragment.app.FragmentManager
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import io.realm.RealmObject
import kotlinx.android.synthetic.main.fragment_bottom_sheet.*
import net.pokeranalytics.android.R
import net.pokeranalytics.android.model.LiveData
import net.pokeranalytics.android.ui.activity.EditableDataActivity
import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity
import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate
import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.RowRepresentableEditDescriptor
import net.pokeranalytics.android.ui.view.rowrepresentable.SessionRow
import net.pokeranalytics.android.ui.view.rowrepresentable.TransactionRow
import java.util.*

open class BottomSheetFragment : BottomSheetDialogFragment() {

	lateinit var row: RowRepresentable
	lateinit var delegate: RowRepresentableDelegate
	var currentCurrency: Currency? = null

	private var isClearable: Boolean = true
	private var rowRepresentableEditDescriptors: ArrayList<RowRepresentableEditDescriptor>? = null

	companion object {

		const val REQUEST_CODE_ADD_NEW_OBJECT = 100

		fun create(
			fragmentManager: FragmentManager?,
			row: RowRepresentable,
			delegate: RowRepresentableDelegate,
			rowRepresentableEditDescriptors: ArrayList<RowRepresentableEditDescriptor>?,
			isClearable: Boolean? = true,
			currentCurrency: Currency? = null
		): BottomSheetFragment {
			val bottomSheetFragment = row.bottomSheetType.newInstance()
			bottomSheetFragment.show(fragmentManager, "bottomSheet")
			bottomSheetFragment.row = row
			bottomSheetFragment.delegate = delegate
			bottomSheetFragment.rowRepresentableEditDescriptors = rowRepresentableEditDescriptors
			bottomSheetFragment.isClearable = isClearable ?: true
			bottomSheetFragment.currentCurrency = currentCurrency
			return bottomSheetFragment
		}
	}

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

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


	override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
		super.onActivityResult(requestCode, resultCode, data)

		// If we come from a creation of an object an everything is okay, we call
		// the delegate onRowValueChanged with the newly created object
		if (requestCode == REQUEST_CODE_ADD_NEW_OBJECT && resultCode == RESULT_OK && data != null) {
			val dataType = data.getIntExtra(EditableDataActivity.IntentKey.DATA_TYPE.keyName, 0)
			val primaryKey = data.getStringExtra(EditableDataActivity.IntentKey.PRIMARY_KEY.keyName)
			val pokerAnalyticsActivity = activity as PokerAnalyticsActivity
			val liveDataType = LiveData.values()[dataType]
			val proxyItem: RealmObject? = liveDataType.getData(pokerAnalyticsActivity.getRealm(), primaryKey)
			this.delegate.onRowValueChanged(proxyItem, this.row)
			dismiss()
		}
	}

	@SuppressLint("RestrictedApi")
	override fun setupDialog(dialog: Dialog?, style: Int) {
		super.setupDialog(dialog, style)
		dialog?.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE)
	}

	/**
	 * Init UI
	 */
	private fun initUI() {
		row.let {
			bottomSheetToolbar.title = row.localizedTitle(requireContext())
			bottomSheetToolbar.inflateMenu(R.menu.bottom_sheet_menu)
			bottomSheetToolbar.setOnMenuItemClickListener {
				false
			}
			bottomSheetToolbar.menu.findItem(R.id.actionCheck).isVisible = row.bottomSheetType.validationRequired
			bottomSheetToolbar.menu.findItem(R.id.actionClear).isVisible = row.bottomSheetType.clearRequired
			bottomSheetToolbar.menu.findItem(R.id.actionAdd).isVisible = row.bottomSheetType.addRequired

			// Menu
			bottomSheetToolbar.menu.findItem(R.id.actionClear).setOnMenuItemClickListener {
				delegate.onRowValueChanged(null, row)
				dismiss()
				true
			}
			bottomSheetToolbar.menu.findItem(R.id.actionAdd).setOnMenuItemClickListener {
				when (row) {
					SessionRow.GAME -> EditableDataActivity.newInstanceForResult(
						this,
						LiveData.GAME.ordinal,
						requestCode = REQUEST_CODE_ADD_NEW_OBJECT
					)
					SessionRow.BANKROLL, TransactionRow.BANKROLL -> EditableDataActivity.newInstanceForResult(
						this,
						LiveData.BANKROLL.ordinal,
						requestCode = REQUEST_CODE_ADD_NEW_OBJECT
					)
					SessionRow.LOCATION -> EditableDataActivity.newInstanceForResult(
						this,
						LiveData.LOCATION.ordinal,
						requestCode = REQUEST_CODE_ADD_NEW_OBJECT
					)
					SessionRow.TOURNAMENT_NAME -> EditableDataActivity.newInstanceForResult(
						this,
						LiveData.TOURNAMENT_NAME.ordinal,
						requestCode = REQUEST_CODE_ADD_NEW_OBJECT
					)
					SessionRow.TOURNAMENT_FEATURE -> EditableDataActivity.newInstanceForResult(
						this,
						LiveData.TOURNAMENT_FEATURE.ordinal,
						requestCode = REQUEST_CODE_ADD_NEW_OBJECT
					)
					TransactionRow.TYPE -> EditableDataActivity.newInstanceForResult(
						this,
						LiveData.TRANSACTION_TYPE.ordinal,
						requestCode = REQUEST_CODE_ADD_NEW_OBJECT
					)
				}
				true
			}
			bottomSheetToolbar.menu.findItem(R.id.actionCheck).setOnMenuItemClickListener {
				this.delegate.onRowValueChanged(getValue(), row)
				dismiss()
				true
			}

			bottomSheetToolbar.menu.findItem(R.id.actionClear).isVisible = isClearable
		}
	}

	/**
	 * Return the data list
	 */
	fun getData(): ArrayList<RowRepresentableEditDescriptor>? {
		return this.rowRepresentableEditDescriptors
	}

	open fun getValue(): Any? {
		return null
	}

}