package app.furmeet.events.system.schedule.fragments

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import app.furmeet.events.bff.R
import app.furmeet.events.system.helper.ActivitiesForFragments
import app.furmeet.events.system.helper.dayRange
import app.furmeet.events.system.helper.doAsync
import app.furmeet.events.system.helper.observables.Observer
import app.furmeet.events.system.helper.uiThread
import app.furmeet.events.system.schedule.abstractDataTypes.GregorianCalendarRange
import app.furmeet.events.system.schedule.adapters.DayHoursAdapter
import app.furmeet.events.system.schedule.adapters.EmptyRecyclerViewAdapter
import app.furmeet.events.system.schedule.managers.ScheduleManagerGetter
import app.furmeet.events.bff.databinding.FragmentScheduleDayBinding
import com.brandongogetap.stickyheaders.StickyLayoutManager

class ConventionDayFragment : FragmentWithSafeActivity() {
    companion object {
        fun newInstance(day: GregorianCalendarRange): Fragment {
            return ConventionDayFragment().apply {
                arguments = Bundle().apply {
                    putSerializable("dayRange", day)
                }
            }
        }
    }

    lateinit var binding: FragmentScheduleDayBinding
    private val scheduleManager = ScheduleManagerGetter[safeActivity]
    lateinit var day: GregorianCalendarRange
    lateinit var dayParts: List<GregorianCalendarRange>

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        val rootView = inflater.inflate(R.layout.fragment_schedule_day, container, false)
        binding = FragmentScheduleDayBinding.bind(rootView)
        binding.stickyDays.adapter = EmptyRecyclerViewAdapter()
        binding.stickyDays.layoutManager = LinearLayoutManager(rootView.context)
        doAsync {
            arguments?.apply {
                day = getSerializable("dayRange")!! as GregorianCalendarRange
            }
            dayParts = day.split(
                    scheduleManager.convention.splitDayIn
            ).filter {
                val today = scheduleManager.convention.days.first { conDay ->
                    it in conDay.dayRange
                }.dayRange
                if (scheduleManager.convention.paddingStartOfDayMillis <= scheduleManager.convention.paddingEndOfDayMillis) {
                    val today1 = GregorianCalendarRange(
                            today.start.timeInMillis + scheduleManager.convention.paddingStartOfDayMillis,
                            today.start.timeInMillis + scheduleManager.convention.paddingEndOfDayMillis
                    )
                    it in today1
                } else {
                    val today1 = GregorianCalendarRange(
                            today.start.timeInMillis,
                            today.start.timeInMillis + scheduleManager.convention.paddingEndOfDayMillis
                    )
                    val today2 = GregorianCalendarRange(
                            today.start.timeInMillis + scheduleManager.convention.paddingStartOfDayMillis,
                            today.finish.timeInMillis
                    )
                    it in today1 || it in today2
                }
            }.filter {
                it.start >= scheduleManager.convention.startCalendarOn
            }.filter {
                it.start < scheduleManager.convention.endCalendarOn
            }
            val adapter = DayHoursAdapter(
                    safeActivity,
                    dayParts,
                    scheduleManager
            )
            val layoutManager = StickyLayoutManager(rootView.context, adapter)
            layoutManager.elevateHeaders(3)
            uiThread {
                binding.stickyDays.layoutManager = layoutManager
                binding.stickyDays.adapter = adapter
            }
            scheduleManager.addObserver(Observer { _, _: Any? ->
                doAsync {
                    adapter.onDataChanged()
                }
            })
        }
        return rootView
    }
}