package com.doverfuelingsolutions.issp.view.fragment.router

import android.content.Context
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.OnLifecycleEvent
import com.doverfuelingsolutions.issp.view.fragment.FragmentBasic
import com.doverfuelingsolutions.issp.view.widget.FragmentToolbar

class FragmentRouter(
    private val activity: AppCompatActivity,
    private val fragmentViewId: Int,
) : LifecycleObserver {

    private var fragmentToolbar: FragmentToolbar? = null

    private var isNavigateForward = true
    private var mOnRouteChangeListener: OnRouteChangeListener? = null
    private val fragmentList = arrayListOf<Fragment>()
    private val fragmentEvent = object : FragmentManager.FragmentLifecycleCallbacks() {
        override fun onFragmentAttached(fm: FragmentManager, f: Fragment, context: Context) {
            isNavigateForward = true
            fragmentList.add(f)
            mOnRouteChangeListener?.onRouteForward()

            handleToolbarAsRoute(f as FragmentBasic)
        }

        override fun onFragmentDetached(fm: FragmentManager, f: Fragment) {
            isNavigateForward = false
            val index = fragmentList.indexOf(f)
            fragmentList.remove(f)
            mOnRouteChangeListener?.onRouteBackward(fragmentList.size <= 1)

            if (index >= 1) handleToolbarAsRoute(fragmentList[index - 1] as FragmentBasic)
        }
    }

    init { activity.lifecycle.addObserver(this) }

    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    private fun create() {
        activity.supportFragmentManager.registerFragmentLifecycleCallbacks(fragmentEvent, false)
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    private fun destroy() {
        fragmentToolbar = null
        mOnRouteChangeListener = null
        activity.supportFragmentManager.unregisterFragmentLifecycleCallbacks(fragmentEvent)
    }

    fun push(fragment: FragmentBasic) {
        activity.supportFragmentManager.beginTransaction().run {
            replace(fragmentViewId, fragment)
            if (fragmentList.isNotEmpty()) addToBackStack(fragment.javaClass.simpleName)
            commit()
        }
    }

    fun pop() {
        if (fragmentList.size > 1) {
            activity.supportFragmentManager.popBackStack()
        }
    }

    fun replace(fragment: FragmentBasic) {
        if (fragmentList.size == 1) {
            fragmentList.removeAt(0)
        } else if (fragmentList.size > 1) {
            activity.supportFragmentManager.popBackStackImmediate()
        }
        push(fragment)
    }

    fun setHomeFragment(fragment: FragmentBasic) {
        popBottom()
        replace(fragment)
    }

    fun popBottom() {
        if (fragmentList.size > 1)
            activity.supportFragmentManager.popBackStack(fragmentList[1].javaClass.simpleName, FragmentManager.POP_BACK_STACK_INCLUSIVE)
    }

    fun setOnRouteChangeListener(listener: OnRouteChangeListener) {
        mOnRouteChangeListener = listener
    }

    fun setFragmentToolbar(toolbar: FragmentToolbar) {
        fragmentToolbar = toolbar
        fragmentToolbar?.homeHandler = this::popBottom
        fragmentToolbar?.backHandler = this::pop
    }

    fun stopFragmentToolbarTimer() {
        fragmentToolbar?.stopCountdown()
    }

    fun resumeFragmentToolbarTimer() {
        fragmentToolbar?.resumeCountdown()
    }

    private fun handleToolbarAsRoute(fragment: FragmentBasic) {
        if (fragmentToolbar == null) return

        val isFirst = fragmentList.size == 1
        fragmentToolbar?.visibility =  if (fragment.useActionBar) View.VISIBLE else View.GONE
        fragmentToolbar?.title = fragment.title
        fragmentToolbar?.isBackVisible = !isFirst && fragment.showButtonBack
        fragmentToolbar?.isHomeVisible = !isFirst && fragment.showButtonHome

        val countdownRealTime = if (isFirst) -1 else fragment.countdownTime
        fragmentToolbar?.countdownTime = countdownRealTime
        fragmentToolbar?.startCountdown(countdownRealTime)
    }
}