package ch.threema.app.emojireactions

import android.os.Bundle
import android.os.Parcelable
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import ch.threema.app.R
import ch.threema.app.preference.service.PreferenceService
import ch.threema.app.services.ContactService
import ch.threema.app.services.MessageService
import ch.threema.app.ui.InsetSides
import ch.threema.app.ui.SpacingValues
import ch.threema.app.ui.applyDeviceInsetsAsPadding
import ch.threema.app.utils.logScreenVisibility
import ch.threema.base.utils.getThreemaLogger
import ch.threema.data.IdentityProvider
import ch.threema.data.models.EmojiReactionData
import ch.threema.logging.logAndReportError
import ch.threema.storage.models.AbstractMessageModel
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.launch
import org.koin.android.ext.android.inject

private const val RECYCLER_VIEW_STATE = "recyclerViewState"

private val logger = getThreemaLogger("EmojiReactionsOverviewFragment")

class EmojiReactionsOverviewFragment(
    val emojiSequence: String? = null,
    val messageModel: AbstractMessageModel,
) : Fragment(), EmojiReactionsOverviewListAdapter.OnItemClickListener {
    init {
        logScreenVisibility(logger)
    }

    private val messageService: MessageService by inject()
    private val contactService: ContactService by inject()
    private val identityProvider: IdentityProvider by inject()
    private val preferenceService: PreferenceService by inject()

    private val emojiReactionsViewModel: EmojiReactionsViewModel by activityViewModels()
    private lateinit var emojiReactionsOverviewListAdapter: EmojiReactionsOverviewListAdapter
    private lateinit var recyclerView: RecyclerView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        @Suppress("DEPRECATION")
        retainInstance = true
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?,
    ): View? {
        val view = inflater.inflate(R.layout.fragment_emojireactions_overview, container, false)
        recyclerView = view.findViewById(R.id.emoji_reactions_list)

        return view
    }

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

        emojiReactionsOverviewListAdapter = EmojiReactionsOverviewListAdapter(
            messageService = messageService,
            contactService = contactService,
            identityProvider = identityProvider,
            messageModel = messageModel,
            preferenceService = preferenceService,
            onItemClickListener = this,
        )
        recyclerView.layoutManager = LinearLayoutManager(context)
        recyclerView.adapter = emojiReactionsOverviewListAdapter
        recyclerView.setHasFixedSize(true)
        recyclerView.isNestedScrollingEnabled = true

        val targetEmojiSequence = emojiSequence
        viewLifecycleOwner.lifecycleScope.launch {
            viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
                emojiReactionsViewModel.viewState.filterNotNull().collect { viewState ->
                    val emojiReactionsForSequence =
                        viewState.emojiReactions.filter { it.emojiSequence == targetEmojiSequence }
                    emojiReactionsOverviewListAdapter.submitList(emojiReactionsForSequence)
                }
            }
        }

        recyclerView.applyDeviceInsetsAsPadding(
            insetSides = InsetSides.bottom(),
            ownPadding = SpacingValues.vertical(R.dimen.grid_unit_x1),
        )
    }

    override fun onRemoveClick(data: EmojiReactionData, position: Int) {
        CoroutineScope(Dispatchers.Default).launch {
            runCatching {
                messageService.sendEmojiReaction(
                    messageModel,
                    data.emojiSequence,
                    messageService.getMessageReceiver(messageModel),
                    false,
                )
            }.onFailure { throwable ->
                logger.logAndReportError("Could not send emoji reaction", throwable)
            }
        }
    }

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        outState.putParcelable(
            RECYCLER_VIEW_STATE,
            recyclerView.layoutManager?.onSaveInstanceState(),
        )
    }

    override fun onViewStateRestored(savedInstanceState: Bundle?) {
        super.onViewStateRestored(savedInstanceState)
        @Suppress("DEPRECATION")
        savedInstanceState?.getParcelable<Parcelable>(RECYCLER_VIEW_STATE)?.let {
            recyclerView.layoutManager?.onRestoreInstanceState(it)
        }
    }
}
