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.*
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.lottie.*
import com.airbnb.lottie.model.KeyPath
import com.airbnb.lottie.samples.model.CompositionArgs
import com.airbnb.lottie.samples.views.BackgroundColorView
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 kotlinx.android.synthetic.main.bottom_sheet_key_paths.*
import kotlinx.android.synthetic.main.bottom_sheet_render_times.*
import kotlinx.android.synthetic.main.bottom_sheet_warnings.*
import kotlinx.android.synthetic.main.control_bar.*
import kotlinx.android.synthetic.main.control_bar_background_color.*
import kotlinx.android.synthetic.main.control_bar_player_controls.*
import kotlinx.android.synthetic.main.control_bar_scale.*
import kotlinx.android.synthetic.main.control_bar_speed.*
import kotlinx.android.synthetic.main.control_bar_trim.*
import kotlinx.android.synthetic.main.fragment_player.*
import kotlin.math.min
import kotlin.math.roundToInt

class PlayerFragment : BaseMvRxFragment() {

    private val transition = AutoTransition().apply { duration = 175 }
    private val renderTimesBehavior by lazy {
        BottomSheetBehavior.from(renderTimesBottomSheet).apply {
            peekHeight = resources.getDimensionPixelSize(R.dimen.bottom_bar_peek_height)
        }
    }
    private val warningsBehavior by lazy {
        BottomSheetBehavior.from(warningsBottomSheet).apply {
            peekHeight = resources.getDimensionPixelSize(R.dimen.bottom_bar_peek_height)
        }
    }
    private val keyPathsBehavior by lazy {
        BottomSheetBehavior.from(keyPathsBottomSheet).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 = { playButton.isActivated = true },
            onEnd = {
                playButton.isActivated = false
                animationView.performanceTracker?.logRenderTimes()
                updateRenderTimesPerLayer()
            },
            onCancel = {
                playButton.isActivated = false
            },
            onRepeat = {
                animationView.performanceTracker?.logRenderTimes()
                updateRenderTimesPerLayer()
            }
    )

    private val viewModel: PlayerViewModel by fragmentViewModel()

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View =
            inflater.inflate(R.layout.fragment_player, container, false)

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

        L.setTraceEnabled(true)

        lottieVersionView.text = getString(R.string.lottie_version, com.airbnb.lottie.BuildConfig.VERSION_NAME)

        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 {
            backgroundButton1.setBackgroundColor(it)
            animationContainer.setBackgroundColor(it)
            invertColor(it)
        }

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

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

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

        hardwareAccelerationToggle.setOnClickListener {
            val renderMode = if (animationView.layerType == View.LAYER_TYPE_HARDWARE) {
                RenderMode.SOFTWARE
            } else {
                RenderMode.HARDWARE
            }
            animationView.setRenderMode(renderMode)
            hardwareAccelerationToggle.isActivated = animationView.layerType == View.LAYER_TYPE_HARDWARE
        }

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

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

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

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

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

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

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

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

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


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

        playButton.isActivated = animationView.isAnimating

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

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

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

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

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

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

        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)
        }

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

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

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

                }
            }
        }

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

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

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

    private fun showMinFrameDialog() {
        val minFrameView = EditText(context)
        minFrameView.setText(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(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()
        animationView.isActivated = isDarkBg
        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() {
        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

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

        // Scale up to fill the screen
        scaleSeekBar.progress = 100

        keyPathsRecyclerView.buildModelsWith { controller ->
            animationView.resolveKeyPath(KeyPath("**")).forEachIndexed { index, keyPath ->
                BottomSheetItemViewModel_()
                        .id(index)
                        .text(keyPath.keysToString())
                        .addTo(controller)

            }
        }

        updateWarnings()
    }

    override fun invalidate() {
    }

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

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

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

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

        val size = warnings.size
        warningsButton.setText(resources.getQuantityString(R.plurals.warnings, size, size))
        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)
        )
    }

    private fun beginDelayedTransition() = TransitionManager.beginDelayedTransition(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 = Math.abs(animation.speed)

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

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

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