package com.airbnb.lottie.samples

import android.animation.ValueAnimator
import android.annotation.SuppressLint
import android.app.AlertDialog
import android.graphics.Color
import android.graphics.Typeface
import android.os.Bundle
import android.util.Log
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.widget.EditText
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.view.children
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.lifecycle.Lifecycle
import androidx.transition.AutoTransition
import androidx.transition.TransitionManager
import com.airbnb.epoxy.EpoxyController
import com.airbnb.epoxy.EpoxyRecyclerView
import com.airbnb.lottie.FontAssetDelegate
import com.airbnb.lottie.L
import com.airbnb.lottie.LottieAnimationView
import com.airbnb.lottie.LottieComposition
import com.airbnb.lottie.RenderMode
import com.airbnb.lottie.model.KeyPath
import com.airbnb.lottie.samples.databinding.PlayerFragmentBinding
import com.airbnb.lottie.samples.model.CompositionArgs
import com.airbnb.lottie.samples.utils.viewBinding
import com.airbnb.lottie.samples.views.BottomSheetItemView
import com.airbnb.lottie.samples.views.BottomSheetItemViewModel_
import com.airbnb.lottie.samples.views.ControlBarItemToggleView
import com.airbnb.mvrx.BaseMvRxFragment
import com.airbnb.mvrx.fragmentViewModel
import com.airbnb.mvrx.withState
import com.github.mikephil.charting.components.LimitLine
import com.github.mikephil.charting.components.YAxis
import com.github.mikephil.charting.data.Entry
import com.github.mikephil.charting.data.LineData
import com.github.mikephil.charting.data.LineDataSet
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.snackbar.Snackbar
import kotlin.math.abs
import kotlin.math.min
import kotlin.math.roundToInt

class PlayerFragment : BaseMvRxFragment(R.layout.player_fragment) {
    private val binding: PlayerFragmentBinding by viewBinding()
    private val viewModel: PlayerViewModel by fragmentViewModel()

    private val transition = AutoTransition().apply { duration = 175 }
    private val renderTimesBehavior by lazy {
        BottomSheetBehavior.from(binding.bottomSheetRenderTimes.root).apply {
            peekHeight = resources.getDimensionPixelSize(R.dimen.bottom_bar_peek_height)
        }
    }
    private val warningsBehavior by lazy {
        BottomSheetBehavior.from(binding.bottomSheetWarnings.root).apply {
            peekHeight = resources.getDimensionPixelSize(R.dimen.bottom_bar_peek_height)
        }
    }
    private val keyPathsBehavior by lazy {
        BottomSheetBehavior.from(binding.bottomSheetKeyPaths.root).apply {
            peekHeight = resources.getDimensionPixelSize(R.dimen.bottom_bar_peek_height)
        }
    }
    private val lineDataSet by lazy {
        val entries = ArrayList<Entry>(101)
        repeat(101) { i -> entries.add(Entry(i.toFloat(), 0f)) }
        LineDataSet(entries, "Render Times").apply {
            mode = LineDataSet.Mode.CUBIC_BEZIER
            cubicIntensity = 0.3f
            setDrawCircles(false)
            lineWidth = 1.8f
            color = Color.BLACK
        }
    }

    private val animatorListener = AnimatorListenerAdapter(
        onStart = { binding.controlBarPlayerControls.playButton.isActivated = true },
        onEnd = {
            binding.controlBarPlayerControls.playButton.isActivated = false
            binding.animationView.performanceTracker?.logRenderTimes()
            updateRenderTimesPerLayer()
        },
        onCancel = {
            binding.controlBarPlayerControls.playButton.isActivated = false
        },
        onRepeat = {
            binding.animationView.performanceTracker?.logRenderTimes()
            updateRenderTimesPerLayer()
        }
    )

    @SuppressLint("SetTextI18n")
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        (requireActivity() as AppCompatActivity).setSupportActionBar(binding.toolbar)
        (requireActivity() as AppCompatActivity).supportActionBar?.setDisplayShowTitleEnabled(false)
        setHasOptionsMenu(true)

        binding.controlBarPlayerControls.lottieVersionView.text = getString(R.string.lottie_version, BuildConfig.VERSION_NAME)

        binding.animationView.setFontAssetDelegate(object : FontAssetDelegate() {
            override fun fetchFont(fontFamily: String?): Typeface {
                return Typeface.DEFAULT
            }
        })

        val args = arguments?.getParcelable<CompositionArgs>(EXTRA_ANIMATION_ARGS)
            ?: throw IllegalArgumentException("No composition args specified")
        args.animationData?.bgColorInt?.let {
            binding.controlBarBackgroundColor.backgroundButton1.setBackgroundColor(it)
            binding.animationContainer.setBackgroundColor(it)
            invertColor(it)
        }

        args.animationDataV2?.bgColorInt?.let {
            binding.controlBarBackgroundColor.backgroundButton1.setBackgroundColor(it)
            binding.animationContainer.setBackgroundColor(it)
            invertColor(it)
        }

        binding.controlBarTrim.minFrameView.setOnClickListener { showMinFrameDialog() }
        binding.controlBarTrim.maxFrameView.setOnClickListener { showMaxFrameDialog() }
        viewModel.selectSubscribe(PlayerState::minFrame, PlayerState::maxFrame) { minFrame, maxFrame ->
            binding.animationView.setMinAndMaxFrame(minFrame, maxFrame)
            // I think this is a lint bug. It complains about int being <ErrorType>
            //noinspection StringFormatMatches
            binding.controlBarTrim.minFrameView.setText(resources.getString(R.string.min_frame, binding.animationView.minFrame.toInt()))
            //noinspection StringFormatMatches
            binding.controlBarTrim.maxFrameView.setText(resources.getString(R.string.max_frame, binding.animationView.maxFrame.toInt()))
        }

        viewModel.fetchAnimation(args)
        viewModel.asyncSubscribe(PlayerState::composition, onFail = {
            Snackbar.make(binding.coordinatorLayout, R.string.composition_load_error, Snackbar.LENGTH_LONG).show()
            Log.w(L.TAG, "Error loading composition.", it)
        }) {
            binding.loadingView.isVisible = false
            onCompositionLoaded(it)
        }

        binding.controlBar.borderToggle.setOnClickListener { viewModel.toggleBorderVisible() }
        viewModel.selectSubscribe(PlayerState::borderVisible) {
            binding.controlBar.borderToggle.isActivated = it
            binding.controlBar.borderToggle.setImageResource(
                if (it) R.drawable.ic_border_on
                else R.drawable.ic_border_off
            )
            binding.animationView.setBackgroundResource(if (it) R.drawable.outline else 0)
        }

        binding.controlBar.hardwareAccelerationToggle.setOnClickListener {
            val renderMode = if (binding.animationView.renderMode == RenderMode.HARDWARE) {
                RenderMode.SOFTWARE
            } else {
                RenderMode.HARDWARE
            }
            binding.animationView.renderMode = renderMode
            binding.controlBar.hardwareAccelerationToggle.isActivated = binding.animationView.renderMode == RenderMode.HARDWARE
        }

        binding.controlBar.enableApplyingOpacityToLayers.setOnClickListener {
            val isApplyingOpacityToLayersEnabled = !binding.controlBar.enableApplyingOpacityToLayers.isActivated
            binding.animationView.setApplyingOpacityToLayersEnabled(isApplyingOpacityToLayersEnabled)
            binding.controlBar.enableApplyingOpacityToLayers.isActivated = isApplyingOpacityToLayersEnabled
        }

        viewModel.selectSubscribe(PlayerState::controlsVisible) { binding.controlBarPlayerControls.controlsContainer.animateVisible(it) }

        viewModel.selectSubscribe(PlayerState::controlBarVisible) { binding.controlBar.root.animateVisible(it) }

        binding.controlBar.renderGraphToggle.setOnClickListener { viewModel.toggleRenderGraphVisible() }
        viewModel.selectSubscribe(PlayerState::renderGraphVisible) {
            binding.controlBar.renderGraphToggle.isActivated = it
            binding.controlBarPlayerControls.renderTimesGraphContainer.animateVisible(it)
            binding.controlBarPlayerControls.renderTimesPerLayerButton.animateVisible(it)
            binding.controlBarPlayerControls.lottieVersionView.animateVisible(!it)
        }

        binding.controlBar.masksAndMattesToggle.setOnClickListener { viewModel.toggleOutlineMasksAndMattes() }
        viewModel.selectSubscribe(PlayerState::outlineMasksAndMattes) {
            binding.controlBar.masksAndMattesToggle.isActivated = it
            binding.animationView.setOutlineMasksAndMattes(it)
        }

        binding.controlBar.backgroundColorToggle.setOnClickListener { viewModel.toggleBackgroundColorVisible() }
        binding.controlBarBackgroundColor.closeBackgroundColorButton.setOnClickListener { viewModel.setBackgroundColorVisible(false) }
        viewModel.selectSubscribe(PlayerState::backgroundColorVisible) {
            binding.controlBar.backgroundColorToggle.isActivated = it
            binding.controlBarBackgroundColor.backgroundColorContainer.animateVisible(it)
        }

        binding.controlBar.scaleToggle.setOnClickListener { viewModel.toggleScaleVisible() }
        binding.controlBarScale.closeScaleButton.setOnClickListener { viewModel.setScaleVisible(false) }
        viewModel.selectSubscribe(PlayerState::scaleVisible) {
            binding.controlBar.scaleToggle.isActivated = it
            binding.controlBarScale.scaleContainer.animateVisible(it)
        }

        binding.controlBar.trimToggle.setOnClickListener { viewModel.toggleTrimVisible() }
        binding.controlBarTrim.closeTrimButton.setOnClickListener { viewModel.setTrimVisible(false) }
        viewModel.selectSubscribe(PlayerState::trimVisible) {
            binding.controlBar.trimToggle.isActivated = it
            binding.controlBarTrim.trimContainer.animateVisible(it)
        }

        binding.controlBar.mergePathsToggle.setOnClickListener { viewModel.toggleMergePaths() }
        viewModel.selectSubscribe(PlayerState::useMergePaths) {
            binding.animationView.enableMergePathsForKitKatAndAbove(it)
            binding.controlBar.mergePathsToggle.isActivated = it
        }

        binding.controlBar.speedToggle.setOnClickListener { viewModel.toggleSpeedVisible() }
        binding.controlBarSpeed.closeSpeedButton.setOnClickListener { viewModel.setSpeedVisible(false) }
        viewModel.selectSubscribe(PlayerState::speedVisible) {
            binding.controlBar.speedToggle.isActivated = it
            binding.controlBarSpeed.speedContainer.isVisible = it
        }
        viewModel.selectSubscribe(PlayerState::speed) {
            binding.animationView.speed = it
            binding.controlBarSpeed.speedButtonsContainer
                .children
                .filterIsInstance<ControlBarItemToggleView>()
                .forEach { toggleView ->
                    toggleView.isActivated = toggleView.getText().replace("x", "").toFloat() == binding.animationView.speed
                }
        }
        binding.controlBarSpeed.speedButtonsContainer
            .children
            .filterIsInstance(ControlBarItemToggleView::class.java)
            .forEach { child ->
                child.setOnClickListener {
                    val speed = (it as ControlBarItemToggleView)
                        .getText()
                        .replace("x", "")
                        .toFloat()
                    viewModel.setSpeed(speed)
                }
            }


        binding.controlBarPlayerControls.loopButton.setOnClickListener { viewModel.toggleLoop() }
        viewModel.selectSubscribe(PlayerState::repeatCount) {
            binding.animationView.repeatCount = it
            binding.controlBarPlayerControls.loopButton.isActivated = binding.animationView.repeatCount == ValueAnimator.INFINITE
        }

        binding.controlBarPlayerControls.playButton.isActivated = binding.animationView.isAnimating

        binding.controlBarPlayerControls.seekBar.setOnSeekBarChangeListener(OnSeekBarChangeListenerAdapter(
            onProgressChanged = { _, progress, _ ->
                if (binding.controlBarPlayerControls.seekBar.isPressed && progress in 1..4) {
                    binding.controlBarPlayerControls.seekBar.progress = 0
                    return@OnSeekBarChangeListenerAdapter
                }
                if (binding.animationView.isAnimating) return@OnSeekBarChangeListenerAdapter
                binding.animationView.progress = progress / binding.controlBarPlayerControls.seekBar.max.toFloat()
            }
        ))

        binding.animationView.addAnimatorUpdateListener {
            binding.controlBarPlayerControls.currentFrameView.text = updateFramesAndDurationLabel(binding.animationView)

            if (binding.controlBarPlayerControls.seekBar.isPressed) return@addAnimatorUpdateListener
            binding.controlBarPlayerControls.seekBar.progress =
                ((it.animatedValue as Float) * binding.controlBarPlayerControls.seekBar.max).roundToInt()
        }
        binding.animationView.addAnimatorListener(animatorListener)
        binding.controlBarPlayerControls.playButton.setOnClickListener {
            if (binding.animationView.isAnimating) binding.animationView.pauseAnimation() else binding.animationView.resumeAnimation()
            binding.controlBarPlayerControls.playButton.isActivated = binding.animationView.isAnimating
            postInvalidate()
        }

        binding.animationView.setOnClickListener {
            // Click the animation view to re-render it for debugging purposes.
            binding.animationView.invalidate()
        }

        binding.controlBarScale.scaleSeekBar.setOnSeekBarChangeListener(OnSeekBarChangeListenerAdapter(
            onProgressChanged = { _, progress, _ ->
                val minScale = minScale()
                val maxScale = maxScale()
                val scale = minScale + progress / 100f * (maxScale - minScale)
                binding.animationView.scale = scale
                binding.controlBarScale.scaleText.text = "%.0f%%".format(scale * 100)
            }
        ))

        arrayOf(
            binding.controlBarBackgroundColor.backgroundButton1,
            binding.controlBarBackgroundColor.backgroundButton2,
            binding.controlBarBackgroundColor.backgroundButton3,
            binding.controlBarBackgroundColor.backgroundButton4,
            binding.controlBarBackgroundColor.backgroundButton5,
            binding.controlBarBackgroundColor.backgroundButton6
        ).forEach { bb ->
            bb.setOnClickListener {
                binding.animationContainer.setBackgroundColor(bb.getColor())
                invertColor(bb.getColor())
            }
        }

        binding.controlBarPlayerControls.renderTimesGraph.apply {
            setTouchEnabled(false)
            axisRight.isEnabled = false
            xAxis.isEnabled = false
            legend.isEnabled = false
            description = null
            data = LineData(lineDataSet)
            axisLeft.setDrawGridLines(false)
            axisLeft.labelCount = 4
            val ll1 = LimitLine(16f, "60fps")
            ll1.lineColor = Color.RED
            ll1.lineWidth = 1.2f
            ll1.textColor = Color.BLACK
            ll1.textSize = 8f
            axisLeft.addLimitLine(ll1)

            val ll2 = LimitLine(32f, "30fps")
            ll2.lineColor = Color.RED
            ll2.lineWidth = 1.2f
            ll2.textColor = Color.BLACK
            ll2.textSize = 8f
            axisLeft.addLimitLine(ll2)
        }

        binding.controlBarPlayerControls.renderTimesPerLayerButton.setOnClickListener {
            updateRenderTimesPerLayer()
            renderTimesBehavior.state = BottomSheetBehavior.STATE_COLLAPSED
        }

        binding.bottomSheetRenderTimes.closeRenderTimesBottomSheetButton.setOnClickListener {
            renderTimesBehavior.state = BottomSheetBehavior.STATE_HIDDEN
        }
        renderTimesBehavior.state = BottomSheetBehavior.STATE_HIDDEN

        binding.controlBar.warningsButton.setOnClickListener {
            withState(viewModel) { state ->
                if (state.composition()?.warnings?.isEmpty() != true) {
                    warningsBehavior.state = BottomSheetBehavior.STATE_COLLAPSED

                }
            }
        }

        binding.bottomSheetWarnings.closeWarningsBottomSheetButton.setOnClickListener {
            warningsBehavior.state = BottomSheetBehavior.STATE_HIDDEN
        }
        warningsBehavior.state = BottomSheetBehavior.STATE_HIDDEN

        binding.controlBar.keyPathsToggle.setOnClickListener {
            keyPathsBehavior.state = BottomSheetBehavior.STATE_COLLAPSED
        }

        binding.bottomSheetKeyPaths.closeKeyPathsBottomSheetButton.setOnClickListener {
            keyPathsBehavior.state = BottomSheetBehavior.STATE_HIDDEN
        }
        keyPathsBehavior.state = BottomSheetBehavior.STATE_HIDDEN
    }

    private fun showMinFrameDialog() {
        val minFrameView = EditText(context)
        minFrameView.setText(binding.animationView.minFrame.toInt().toString())
        AlertDialog.Builder(context)
            .setTitle(R.string.min_frame_dialog)
            .setView(minFrameView)
            .setPositiveButton("Load") { _, _ ->
                viewModel.setMinFrame(minFrameView.text.toString().toIntOrNull() ?: 0)
            }
            .setNegativeButton("Cancel") { dialog, _ -> dialog.dismiss() }
            .show()
    }

    private fun showMaxFrameDialog() {
        val maxFrameView = EditText(context)
        maxFrameView.setText(binding.animationView.maxFrame.toInt().toString())
        AlertDialog.Builder(context)
            .setTitle(R.string.max_frame_dialog)
            .setView(maxFrameView)
            .setPositiveButton("Load") { _, _ ->
                viewModel.setMaxFrame(maxFrameView.text.toString().toIntOrNull() ?: 0)
            }
            .setNegativeButton("Cancel") { dialog, _ -> dialog.dismiss() }
            .show()
    }

    private fun View.animateVisible(visible: Boolean) {
        beginDelayedTransition()
        isVisible = visible
    }

    private fun invertColor(color: Int) {
        val isDarkBg = color.isDark()
        binding.animationView.isActivated = isDarkBg
        binding.toolbar.isActivated = isDarkBg
    }

    private fun Int.isDark(): Boolean {
        val y = (299 * Color.red(this) + 587 * Color.green(this) + 114 * Color.blue(this)) / 1000
        return y < 128
    }

    override fun onDestroyView() {
        binding.animationView.removeAnimatorListener(animatorListener)
        super.onDestroyView()
    }

    override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
        inflater.inflate(R.menu.fragment_player, menu)
        super.onCreateOptionsMenu(menu, inflater)
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        if (item.isCheckable) item.isChecked = !item.isChecked
        when (item.itemId) {
            android.R.id.home -> requireActivity().finish()
            R.id.info -> Unit
            R.id.visibility -> {
                viewModel.setDistractionFree(item.isChecked)
                val menuIcon = if (item.isChecked) R.drawable.ic_eye_teal else R.drawable.ic_eye_selector
                item.icon = ContextCompat.getDrawable(requireContext(), menuIcon)
            }
        }
        return true
    }

    private fun onCompositionLoaded(composition: LottieComposition?) {
        composition ?: return

        // If the composition is missing any images, return the original image or null.
        if (composition.images.any { (_, asset) -> !asset.hasBitmap() }) {
            binding.animationView.setImageAssetDelegate { it.bitmap }
        }

        binding.animationView.setComposition(composition)
        binding.controlBar.hardwareAccelerationToggle.isActivated = binding.animationView.renderMode == RenderMode.HARDWARE
        binding.animationView.setPerformanceTrackingEnabled(true)
        var renderTimeGraphRange = 4f
        binding.animationView.performanceTracker?.addFrameListener { ms ->
            if (lifecycle.currentState != Lifecycle.State.RESUMED) return@addFrameListener
            lineDataSet.getEntryForIndex((binding.animationView.progress * 100).toInt()).y = ms
            renderTimeGraphRange = renderTimeGraphRange.coerceAtLeast(ms * 1.2f)
            binding.controlBarPlayerControls.renderTimesGraph.setVisibleYRange(0f, renderTimeGraphRange, YAxis.AxisDependency.LEFT)
            binding.controlBarPlayerControls.renderTimesGraph.invalidate()
        }

        // Scale up to fill the screen
        binding.controlBarScale.scaleSeekBar.progress = 50

        binding.bottomSheetKeyPaths.keyPathsRecyclerView.buildModelsWith(object : EpoxyRecyclerView.ModelBuilderCallback {
            override fun buildModels(controller: EpoxyController) {
                binding.animationView.resolveKeyPath(KeyPath("**")).forEachIndexed { index, keyPath ->
                    BottomSheetItemViewModel_()
                        .id(index)
                        .text(keyPath.keysToString())
                        .addTo(controller)
                }
            }
        })

        updateWarnings()
    }

    override fun invalidate() {
    }

    private fun updateRenderTimesPerLayer() {
        binding.bottomSheetRenderTimes.renderTimesContainer.removeAllViews()
        binding.animationView.performanceTracker?.sortedRenderTimes?.forEach {
            val view = BottomSheetItemView(requireContext()).apply {
                set(
                    it.first!!.replace("__container", "Total"),
                    "%.2f ms".format(it.second!!)
                )
            }
            binding.bottomSheetRenderTimes.renderTimesContainer.addView(view)
        }
        binding.animationView.performanceTracker?.clearRenderTimes()
    }

    private fun updateWarnings() = withState(viewModel) { state ->
        // Force warning to update
        binding.bottomSheetWarnings.warningsContainer.removeAllViews()

        val warnings = state.composition()?.warnings ?: emptySet<String>()
        if (!warnings.isEmpty() && warnings.size == binding.bottomSheetWarnings.warningsContainer.childCount) return@withState

        binding.bottomSheetWarnings.warningsContainer.removeAllViews()
        warnings.forEach {
            val view = BottomSheetItemView(requireContext()).apply {
                set(it)
            }
            binding.bottomSheetWarnings.warningsContainer.addView(view)
        }

        val size = warnings.size
        binding.controlBar.warningsButton.setText(resources.getQuantityString(R.plurals.warnings, size, size))
        binding.controlBar.warningsButton.setImageResource(
            if (warnings.isEmpty()) R.drawable.ic_sentiment_satisfied
            else R.drawable.ic_sentiment_dissatisfied
        )
    }

    private fun minScale() = 0.05f

    private fun maxScale(): Float = withState(viewModel) { state ->
        val screenWidth = resources.displayMetrics.widthPixels.toFloat()
        val screenHeight = resources.displayMetrics.heightPixels.toFloat()
        val bounds = state.composition()?.bounds
        return@withState min(
            screenWidth / (bounds?.width()?.toFloat() ?: screenWidth),
            screenHeight / (bounds?.height()?.toFloat() ?: screenHeight)
        ) * 2f
    }

    private fun beginDelayedTransition() = TransitionManager.beginDelayedTransition(binding.container, transition)

    companion object {
        const val EXTRA_ANIMATION_ARGS = "animation_args"

        fun forAsset(args: CompositionArgs): Fragment {
            return PlayerFragment().apply {
                arguments = Bundle().apply {
                    putParcelable(EXTRA_ANIMATION_ARGS, args)
                }
            }
        }
    }

    private fun updateFramesAndDurationLabel(animation: LottieAnimationView): String {
        val currentFrame = animation.frame.toString()
        val totalFrames = ("%.0f").format(animation.maxFrame)

        val animationSpeed: Float = abs(animation.speed)

        val totalTime = ((animation.duration / animationSpeed) / 1000.0)
        val totalTimeFormatted = ("%.1f").format(totalTime)

        val progress = (totalTime / 100.0) * ((animation.progress * 100.0).roundToInt())
        val progressFormatted = ("%.1f").format(progress)

        return "$currentFrame/$totalFrames\n$progressFormatted/$totalTimeFormatted"
    }
}
