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

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.Bundle
import android.view.*
import androidx.appcompat.widget.Toolbar
import kotlinx.android.synthetic.main.view_selected_filter.view.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import net.pokeranalytics.android.R
import net.pokeranalytics.android.model.realm.Filter
import net.pokeranalytics.android.ui.interfaces.FilterHandler
import net.pokeranalytics.android.ui.interfaces.FilterHandler.Companion.INTENT_FILTER_UPDATE_FILTER_UI
import net.pokeranalytics.android.ui.interfaces.FilterableType
import net.pokeranalytics.android.util.Preferences
import timber.log.Timber


/**
 * A class which define the fragment as Filterable
 * - Add a filter icon menu
 * - Listen for INTENT_FILTER_UPDATE_FILTER_UI
 * -
 */
open class FilterableFragment : RealmFragment(), FilterHandler {

	override var currentFilterable: FilterableType = FilterableType.ALL
        set(value) {
            field = value
            this.currentFilter(this.requireContext(), getRealm())?.let {
                if (this.shouldHideCurrentFilter(it)) {
                    hideSelectedFilter()
                } else {
                    displaySelectedFilter()
                }
            }
        }

	private var filterMenuItem: MenuItem? = null

	private val updateFilterUIBroadcast = object : BroadcastReceiver() {
		override fun onReceive(context: Context?, intent: Intent?) {
			context?.let {
				if (Preferences.getActiveFilterId(context)?.isNotEmpty() == true) {
					applyFilter()
				} else {
					removeFilter()
				}
			}
		}
	}

	override fun onActivityCreated(savedInstanceState: Bundle?) {
		super.onActivityCreated(savedInstanceState)
		parentActivity?.registerReceiver(updateFilterUIBroadcast, IntentFilter(INTENT_FILTER_UPDATE_FILTER_UI))
	}

	override fun onDestroy() {
		super.onDestroy()
		parentActivity?.unregisterReceiver(updateFilterUIBroadcast)
	}

	override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
		setHasOptionsMenu(true)
		return super.onCreateView(inflater, container, savedInstanceState)
	}

	override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) {
		super.onCreateOptionsMenu(menu, inflater)
		view?.findViewById<Toolbar>(R.id.toolbar)?.let { toolbar ->
			toolbar.menu.removeItem(R.id.menu_item_filter)
			filterMenuItem = toolbar.menu?.add(0, R.id.menu_item_filter, 0, R.string.filter)
			filterMenuItem?.setIcon(R.drawable.ic_outline_filter_list)
			filterMenuItem?.setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_IF_ROOM)
		}
	}

	override fun onOptionsItemSelected(item: MenuItem?): Boolean {
		when (item?.itemId) {
			R.id.menu_item_filter -> {
				manageFilters(this)
			}
		}
		return super.onOptionsItemSelected(item)
	}

	override fun applyFilter() {
		updateFilterUI()
	}

	override fun removeFilter() {
		hideSelectedFilter()
	}

	/**
	 * Show or hide the filter UI
	 */
	private fun updateFilterUI() {
		if (Preferences.getActiveFilterId(requireContext())?.isNotEmpty() == true) {
			displaySelectedFilter()
		} else {
			hideSelectedFilter()
		}
	}

	/**
	 * Display the filter UI
	 */
	private fun displaySelectedFilter() {

		currentFilter(requireContext(), getRealm())?.let { filter ->
            if (this.shouldHideCurrentFilter(filter)) {
                return
            }
			view?.findViewById<ViewGroup>(R.id.selectedFilter)?.let { viewGroup ->

				val layoutCurrentFilter = LayoutInflater.from(requireContext()).inflate(R.layout.view_selected_filter, viewGroup, false)
				layoutCurrentFilter.filterName.text = filter.getDisplayName(requireContext())
				layoutCurrentFilter.deselectFilter.setOnClickListener {
					saveFilter(requireContext(), "")
				}

				viewGroup.removeAllViews()
				viewGroup.addView(layoutCurrentFilter)

				GlobalScope.launch(Dispatchers.Main) {
					delay(300)
					viewGroup.visibility = View.VISIBLE
				}
			}
		}
	}

	/**
	 * Hide the filter UI
	 */
    private fun hideSelectedFilter() {
		view?.findViewById<ViewGroup>(R.id.selectedFilter).let {
			GlobalScope.launch(Dispatchers.Main) {
				it?.visibility = View.GONE
			}
		}
	}

    /**
     * Check if the current filter's header should be displayed
     */
    private fun shouldHideCurrentFilter(currentFilter: Filter? = null): Boolean {
        currentFilter?.let {
            return it.filterableType != this.currentFilterable
        }
        return false
    }
}