package app.furmeet.events.brasilfurfest.schedule.adapters

import android.app.Activity
import android.content.Intent
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AlertDialog
import androidx.recyclerview.widget.DiffUtil
import com.adlerosn.brasilfurfest.R
import app.furmeet.events.brasilfurfest.helper.*
import app.furmeet.events.brasilfurfest.schedule.EventActivity
import app.furmeet.events.brasilfurfest.schedule.abstractDataTypes.convention.Event
import app.furmeet.events.brasilfurfest.schedule.abstractDataTypes.dataholder.PeekableEvent
import app.furmeet.events.brasilfurfest.schedule.abstractDataTypes.managed.AttendeeConFavorite
import app.furmeet.events.brasilfurfest.schedule.managers.ScheduleManagerGetter
import app.furmeet.events.brasilfurfest.schedule.viewHolders.RecyclerViewHolder
import kotlinx.android.synthetic.main.listitem_schedule_eventlist_subitem_item.view.*

class DayHourEventsAdapter(
        private var events: List<Event>,
        private var customFavorites: List<AttendeeConFavorite>,
        private val activity: Activity
) : RecyclerViewAdapter() {
    override fun getItemCount(): Int = events.size + customFavorites.size
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerViewHolder =
            RecyclerViewHolder(parent.context.layoutInflater.inflate(R.layout.listitem_schedule_eventlist_subitem_item, parent, false))

    override fun onBindViewHolder(holder: RecyclerViewHolder, position: Int) =
            when (position < events.size) {
                true -> onBindViewHolderConbook(holder, position)
                false -> onBindViewHolderCustom(holder, position - events.size)
            }


    init {
        setHasStableIds(true)
    }

    override fun getItemId(position: Int): Long = (events + customFavorites).hashCode().toLong()

    fun onDataChanged(newEvents: List<Event>, newCustomFavorites: List<AttendeeConFavorite>) {
        val newData = newEvents + newCustomFavorites
        val oldData = events + customFavorites
        val diff = DiffUtil.calculateDiff(ListDiffCallback(oldData, newData))
        activity.runOnUiThread {
            events = newEvents
            customFavorites = newCustomFavorites
            diff.dispatchUpdatesTo(this)
        }
    }

    private fun onBindViewHolderConbook(holder: RecyclerViewHolder, position: Int) {
        val view = holder.itemView
        val event = events[position]
        val scheduleManager = ScheduleManagerGetter.get()
        view.startText.text = event.timeRange.start.timeInMillis.formatAsHoursAndMinutes()
        view.finishText.text = event.timeRange.finish.timeInMillis.formatAsHoursAndMinutes()
        view.eventTitle.text = event.titles.solved
        val subTitle = event.subtitles.solved!!.let { subtitle ->
            if (!subtitle.isEmpty())
                subtitle
            else
                event.places.map { place -> place.names.solved!! }.textuallyJoined
        }
        view.eventSubtitle.text = subTitle
        if (event !in scheduleManager.attendeeFavorites) {
            view.star.setImageResource(R.drawable.ic_star_border_black_24dp)
        }
        if (scheduleManager.attendeeFavorites.registrationTier.level !in event.attendableBy.map { it.level }) {
            view.star.visibility = View.INVISIBLE
        } else {
            view.star.visibility = View.VISIBLE
        }
        if (event.language == null) {
            view.flag.visibility = View.GONE
        } else {
            view.flag.visibility = View.VISIBLE
            view.flag.setImageResource(event.language.drawableId)
        }
        if (view.star.visibility == View.VISIBLE) {
            view.starButton.setOnClickListener { _ ->
                val existing = scheduleManager.attendeeFavorites.find(event)
                if (existing == null) {
                    scheduleManager.attendeeFavorites.add(
                            AttendeeConFavorite(
                                    scheduleManager.convention,
                                    event
                            )
                    )
                    view.star.setImageResource(R.drawable.ic_star_black_24dp)
                } else {
                    scheduleManager.attendeeFavorites.remove(existing)
                    view.star.setImageResource(R.drawable.ic_star_border_black_24dp)
                }
            }
        }
        view.setOnClickListener {
            activity.startActivity(
                    Intent(activity, EventActivity::class.java).apply {
                        putExtra("favorite", AttendeeConFavorite(
                                scheduleManager.convention,
                                event
                        )
                        )
                        putExtra("offerStar", true)
                    }
            )
        }
        view.isLongClickable = true
        bindPeekAndPop(
                activity,
                view as ViewGroup,
                view,
                if (view.star.visibility == View.VISIBLE) scheduleManager.attendeeFavorites.find(event) != null else null,
                { view.starButton.callOnClick() },
                { view.callOnClick() },
                PeekableEvent(event)
        )
    }


    private fun onBindViewHolderCustom(holder: RecyclerViewHolder, position: Int) {
        val view = holder.itemView
        val favorite = customFavorites[position]
        val scheduleManager = ScheduleManagerGetter.get()
        view.startText.text = favorite.timeRange.start.timeInMillis.formatAsHoursAndMinutes()
        view.finishText.text = favorite.timeRange.finish.timeInMillis.formatAsHoursAndMinutes()
        view.flag.visibility = View.GONE
        view.eventTitle.text = favorite.getString()
        view.eventSubtitle.text = favorite.getSecondaryString()
        view.starButton.setOnClickListener {
            val dialog = AlertDialog.Builder(activity).create()
            dialog.setTitle(activity.getString(R.string.schedule_action_interest_remove))
            dialog.setButton(AlertDialog.BUTTON_NEUTRAL, activity.getString(R.string.dialog_cancel)) { dialogInterface, _ ->
                dialogInterface.dismiss()
            }
            dialog.setButton(AlertDialog.BUTTON_NEGATIVE, activity.getString(R.string.list_action_remove)) { dialogInterface, _ ->
                scheduleManager.attendeeFavorites.remove(favorite)
                dialogInterface.dismiss()
            }
            dialog.show()
        }
        view.setOnClickListener {
            activity.startActivity(
                    Intent(activity, EventActivity::class.java).apply {
                        putExtra("favorite", favorite)
                        putExtra("offerStar", true)
                    }
            )
        }
        bindPeekAndPop(
                activity,
                view as ViewGroup,
                view,
                if (view.star.visibility == View.VISIBLE) scheduleManager.attendeeFavorites.find(favorite) != null else null,
                { view.starButton.callOnClick() },
                { view.callOnClick() },
                PeekableEvent(favorite)
        )
    }
}