package dev.jasonpearson.automobile.ctrlproxy

import android.view.animation.AccelerateDecelerateInterpolator
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertTrue
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner

@RunWith(RobolectricTestRunner::class)
class HighlightAnimatorTest {

  @Test
  fun `startFadeOut configures duration and interpolator`() {
    val animator =
        HighlightAnimator(
            onAlphaUpdate = { _, _ -> },
            onDrawProgressUpdate = { _, _ -> },
            onAnimationComplete = {},
            onAnimationActiveChanged = {},
        )

    animator.startFadeOut("highlight")

    val valueAnimator = animator.getAnimatorForTest("highlight")
    assertNotNull(valueAnimator)
    val expectedDuration =
        HighlightAnimator.DEFAULT_FADE_IN_DURATION_MS +
            HighlightAnimator.DEFAULT_DISPLAY_DURATION_MS +
            HighlightAnimator.DEFAULT_FADE_OUT_DURATION_MS
    assertEquals(expectedDuration, valueAnimator!!.duration)
    assertTrue(valueAnimator.interpolator is AccelerateDecelerateInterpolator)
  }

  @Test
  fun `startFadeOut updates alpha and completes`() {
    val updates = mutableListOf<Float>()
    val completions = mutableListOf<String>()
    val activity = mutableListOf<Boolean>()
    val animator =
        HighlightAnimator(
            onAlphaUpdate = { _, alpha -> updates.add(alpha) },
            onDrawProgressUpdate = { _, _ -> },
            onAnimationComplete = { id -> completions.add(id) },
            onAnimationActiveChanged = { active -> activity.add(active) },
        )

    animator.startFadeOut("highlight")

    val valueAnimator = animator.getAnimatorForTest("highlight")
    assertNotNull(valueAnimator)
    val totalDuration =
        HighlightAnimator.DEFAULT_FADE_IN_DURATION_MS +
            HighlightAnimator.DEFAULT_DISPLAY_DURATION_MS +
            HighlightAnimator.DEFAULT_FADE_OUT_DURATION_MS
    valueAnimator!!.setCurrentPlayTime(totalDuration / 2)
    valueAnimator.setCurrentPlayTime(totalDuration)
    valueAnimator.end()

    assertTrue(updates.isNotEmpty())
    assertTrue(updates.last() <= 0.01f)
    assertEquals(listOf("highlight"), completions)
    assertTrue(activity.first())
    assertTrue(!activity.last())
  }

  @Test
  fun `cancel prevents completion`() {
    val completions = mutableListOf<String>()
    val activity = mutableListOf<Boolean>()
    val animator =
        HighlightAnimator(
            onAlphaUpdate = { _, _ -> },
            onDrawProgressUpdate = { _, _ -> },
            onAnimationComplete = { id -> completions.add(id) },
            onAnimationActiveChanged = { active -> activity.add(active) },
        )

    animator.startFadeOut("highlight")
    animator.cancel("highlight")

    assertTrue(completions.isEmpty())
    assertTrue(activity.isNotEmpty())
    assertTrue(!activity.last())
  }
}
