package com.airbnb.lottie.samples

import android.animation.ValueAnimator
import android.annotation.SuppressLint
import android.app.AlertDialog
import android.arch.lifecycle.Lifecycle
import android.arch.lifecycle.Observer
import android.arch.lifecycle.ViewModelProviders
import android.graphics.Color
import android.os.Bundle
import android.support.design.widget.BottomSheetBehavior
import android.support.design.widget.Snackbar
import android.support.transition.AutoTransition
import android.support.transition.TransitionManager
import android.support.v4.app.Fragment
import android.support.v4.content.ContextCompat
import android.support.v7.app.AppCompatActivity
import android.util.Log
import android.view.*
import android.widget.EditText
import androidx.view.children
import androidx.view.isVisible
import com.airbnb.lottie.L
import com.airbnb.lottie.LottieAnimationView
import com.airbnb.lottie.LottieComposition
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.lottie.utils.MiscUtils
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 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
import kotlin.properties.ObservableProperty
import kotlin.reflect.KProperty

private class UiState(private val callback: () -> Unit) {

    private inner class BooleanProperty(initialValue: Boolean) : ObservableProperty<Boolean>(initialValue) {
        override fun afterChange(property: KProperty<*>, oldValue: Boolean, newValue: Boolean) {
            callback()
        }
    }

    var controls by BooleanProperty(true)
    var controlBar by BooleanProperty(true)
    var renderGraph by BooleanProperty(false)
    var border by BooleanProperty(false)
    var backgroundColor by BooleanProperty(false)
    var scale by BooleanProperty(false)
    var speed by BooleanProperty(false)
    var trim by BooleanProperty(false)
}

class PlayerFragment : Fragment() {

    private val transition = AutoTransition().apply { duration = 175 }
    private val uiState = UiState { updateUiFromState() }
    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 var composition: LottieComposition? = null

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

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

    private val viewModel by lazy { ViewModelProviders.of(this).get(PlayerViewModel::class.java) }

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

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

        viewModel.composition.observe(this, Observer {
            loadingView.isVisible = false
            onCompositionLoaded(it)
        })
        viewModel.error.observe(this, Observer {
            Snackbar.make(coordinatorLayout, R.string.composition_load_error, Snackbar.LENGTH_LONG).show()
            Log.w(L.TAG, "Error loading composition.", viewModel.error.value);
        })
        viewModel.fetchAnimation(args)

        borderToggle.setOnClickListener { uiState.border++ }
        backgroundColorToggle.setOnClickListener { uiState.backgroundColor++ }
        scaleToggle.setOnClickListener { uiState.scale++ }
        speedToggle.setOnClickListener { uiState.speed++ }
        trimToggle.setOnClickListener { uiState.trim++ }
        renderGraphToggle.setOnClickListener { uiState.renderGraph++ }

        closeBackgroundColorButton.setOnClickListener { uiState.backgroundColor = false }
        closeScaleButton.setOnClickListener { uiState.scale = false }
        closeSpeedButton.setOnClickListener { uiState.speed = false }
        closeTrimButton.setOnClickListener { uiState.trim = false }

        hardwareAccelerationToggle.setOnClickListener {
            animationView.useHardwareAcceleration(!animationView.useHardwareAcceleration)
            updateUiFromState()
        }

        mergePathsToggle.setOnClickListener {
            animationView.enableMergePathsForKitKatAndAbove(!animationView.isMergePathsEnabledForKitKatAndAbove)
            updateUiFromState()
        }

        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.repeatCount = ValueAnimator.INFINITE

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

        loopButton.setOnClickListener {
            val repeatCount = if (animationView.repeatCount == ValueAnimator.INFINITE) 0 else ValueAnimator.INFINITE
            animationView.repeatCount = repeatCount
            updateUiFromState()
        }

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

        minFrame.setOnClickListener {
            val minFrameView = EditText(context)
            minFrameView.setText(animationView.minFrame.toInt().toString())
            AlertDialog.Builder(context)
                    .setTitle(R.string.min_frame_dialog)
                    .setView(minFrameView)
                    .setPositiveButton("Load") { _, _ ->
                        var frame = minFrameView.text.toString().toFloatOrNull() ?: 0f
                        frame = MiscUtils.clamp(frame, composition?.startFrame ?: frame, animationView.maxFrame)

                        animationView.setMinFrame(frame.toInt())
                        updateUiFromState()
                    }
                    .setNegativeButton("Cancel") { dialog, _ -> dialog.dismiss() }
                    .show()
        }

        maxFrame.setOnClickListener {
            val maxFrameView = EditText(context)
            maxFrameView.setText(animationView.maxFrame.toInt().toString())
            AlertDialog.Builder(context)
                    .setTitle(R.string.max_frame_dialog)
                    .setView(maxFrameView)
                    .setPositiveButton("Load") { _, _ ->
                        var frame = maxFrameView.text.toString().toFloatOrNull() ?: 0f
                        frame = MiscUtils.clamp(frame, animationView.minFrame, composition?.endFrame ?: frame)
                        animationView.setMaxFrame(frame.toInt())
                        updateUiFromState()
                    }
                    .setNegativeButton("Cancel") { dialog, _ -> dialog.dismiss() }
                    .show()
        }

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

        speedButtonsContainer.children.forEach {
            if (it is ControlBarItemToggleView) {
                it.setOnClickListener {
                    animationView.speed = (it as ControlBarItemToggleView)
                            .getText()
                            .replace("x", "")
                            .toFloat()
                    updateUiFromState()
                }
            }
        }

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

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

        warningsButton.setOnClickListener {
            updateWarnings()
            if (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

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

                }
            }
        }

        updateUiFromState()
    }

    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 -> {
                uiState.controls = !item.isChecked
                uiState.controlBar = !item.isChecked
                uiState.renderGraph = false
                uiState.border = false
                uiState.backgroundColor = false
                uiState.scale = false
                uiState.speed = false
                uiState.trim = false
                updateUiFromState()
                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
        this.composition = composition

        animationView.setComposition(composition)
        animationView.setMinAndMaxFrame(composition.startFrame.toInt(), composition.endFrame.toInt())
        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()
        }

        // Force warning to update
        warningsContainer.removeAllViews()
        updateWarnings()

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

        keyPathsRecyclerView.requestModelBuild()
    }

    private fun updateUiFromState() {
        beginDelayedTransition()

        controlsContainer.isVisible = uiState.controls
        controlBar.isVisible = uiState.controlBar

        renderGraphToggle.isActivated = uiState.renderGraph
        renderTimesGraphContainer.isVisible = uiState.renderGraph
        renderTimesPerLayerButton.isVisible = uiState.renderGraph
        lottieVersionView.isVisible = !uiState.renderGraph

        borderToggle.isActivated = uiState.border
        borderToggle.setImageResource(
                if (uiState.border) R.drawable.ic_border_on
                else R.drawable.ic_border_off
        )
        animationView.setBackgroundResource(if (borderToggle.isActivated) R.drawable.outline else 0)

        backgroundColorToggle.isActivated = uiState.backgroundColor
        backgroundColorContainer.isVisible = uiState.backgroundColor

        scaleToggle.isActivated = uiState.scale
        scaleContainer.isVisible = uiState.scale

        trimToggle.isActivated = uiState.trim
        trimContainer.isVisible = uiState.trim
        // I think this is a lint bug. It complains about int being <ErrorType>
        //noinspection StringFormatMatches
        minFrame.setText(resources.getString(R.string.min_frame, animationView.minFrame.toInt()))
        //noinspection StringFormatMatches
        maxFrame.setText(resources.getString(R.string.max_frame, animationView.maxFrame.toInt()))

        hardwareAccelerationToggle.isActivated = animationView.useHardwareAcceleration
        mergePathsToggle.isActivated = animationView.isMergePathsEnabledForKitKatAndAbove

        speedToggle.isActivated = uiState.speed
        speedContainer.isVisible = uiState.speed
        speedButtonsContainer.children.forEach {
            if (it is ControlBarItemToggleView) {
                it.isActivated = it.getText().replace("x", "").toFloat() == animationView.speed
            }
        }

        loopButton.isActivated = animationView.repeatCount == ValueAnimator.INFINITE
        playButton.isActivated = animationView.isAnimating
    }

    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() {
        val warnings = composition?.warnings ?: emptySet<String>()
        if (!warnings.isEmpty() && warnings.size == warningsContainer.childCount) return

        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.15f

    private fun maxScale(): Float {
        val screenWidth = resources.displayMetrics.widthPixels.toFloat()
        val screenHeight = resources.displayMetrics.heightPixels.toFloat()
        return min(
                screenWidth / (composition?.bounds?.width()?.toFloat() ?: screenWidth),
                screenHeight / (composition?.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"
    }
}