package net.pokeranalytics.android.ui.fragment.report

import android.os.Bundle
import android.text.InputType
import android.view.View
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import androidx.appcompat.app.AlertDialog
import androidx.core.content.ContextCompat
import kotlinx.android.synthetic.main.fragment_progress_report.*
import net.pokeranalytics.android.calculus.Report
import net.pokeranalytics.android.model.CustomFieldCriteria
import net.pokeranalytics.android.model.LiveData
import net.pokeranalytics.android.model.realm.ReportSetup
import net.pokeranalytics.android.ui.fragment.data.DataManagerFragment
import net.pokeranalytics.android.util.extensions.findById


abstract class AbstractReportFragment : DataManagerFragment() {

	private lateinit var _selectedReport: Report

	val selectedReport: Report
		get() {
			return this._selectedReport
		}

	fun setReport(report: Report) {
		this._selectedReport = report
		this.primaryKey = report.options.reportSetupId
	}

	protected var reportTitle: String? = null

	override fun onCreate(savedInstanceState: Bundle?) {
		super.onCreate(savedInstanceState)

		this.liveDataType = LiveData.REPORT_SETUP
		this.saveButtonShouldAppear = this._selectedReport.options.userGenerated
		this.deleteButtonShouldAppear = (this.primaryKey != null)
	}

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

		setDisplayHomeAsUpEnabled(true)
		setToolbarTitle(reportTitle)
	}

	override fun saveData() {

		activity?.let {
			val builder = AlertDialog.Builder(it)

			// Get the layout inflater
			val inflater = requireActivity().layoutInflater

			// Inflate and set the layout for the dialog
			// Pass null as the parent view because its going in the dialog layout
			val view = inflater.inflate(net.pokeranalytics.android.R.layout.dialog_edit_text, null)
			val nameEditText = view.findViewById<EditText>(net.pokeranalytics.android.R.id.reportName)
			nameEditText.inputType = InputType.TYPE_TEXT_FLAG_CAP_SENTENCES

			this.primaryKey?.let { id ->
				getRealm().findById<ReportSetup>(id)?.let { reportSetup ->
					nameEditText.hint = reportSetup.name
				}
			}

			builder.setView(view)
				// Add action buttons
				.setPositiveButton(net.pokeranalytics.android.R.string.save) { dialog, _ ->
					saveReport(nameEditText.text.toString())
					dialog.dismiss()
				}
				.setNegativeButton(net.pokeranalytics.android.R.string.cancel) { dialog, _ ->
					dialog.cancel()
				}

			val dialog = builder.create()
			dialog.setOnShowListener {
				nameEditText.requestFocus()
				val s = ContextCompat.getSystemService(requireContext(), InputMethodManager::class.java)
				s?.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0)
			}

			dialog.setOnDismissListener {
				val s = ContextCompat.getSystemService(requireContext(), InputMethodManager::class.java)
				s?.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0)
			}

			dialog.show()

		} ?: throw IllegalStateException("Activity cannot be null")

	}

	private fun saveReport(name: String) {

		getRealm().executeTransaction { realm ->

			val rs = this.item as ReportSetup
			val firstSave = (this.primaryKey == null)
			if (firstSave) {
				val options = this._selectedReport.options
				rs.name = name
				rs.display = options.display.ordinal
				options.stats.forEach {
					rs.statIds.add(it.uniqueIdentifier)
				}
				options.criterias.forEach { criteria ->
					when (criteria) {
						is CustomFieldCriteria -> rs.criteriaCustomFieldIds.add(criteria.customFieldId)
						else -> rs.criteriaIds.add(criteria.uniqueIdentifier)
					}
				}

				options.filterId?.let { id ->
					rs.filter = realm.findById(id)
				}
				realm.copyToRealmOrUpdate(rs)
			} else {
				rs.name = name
				realm.insertOrUpdate(rs)
			}

			this.primaryKey = rs.id

			this.deleteButtonShouldAppear = true
			toolbar.title = name
		}

	}

}