package com.tt.honeyDue.ui.haptics

import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner

/**
 * Unit tests for the cross-platform [Haptics] API on Android.
 *
 * Uses a pluggable [HapticBackend] to verify the contract without
 * depending on real hardware (no-op in JVM unit tests otherwise).
 *
 * Mirrors iOS haptic taxonomy:
 *   UIImpactFeedbackGenerator(.light)  -> light
 *   UIImpactFeedbackGenerator(.medium) -> medium
 *   UIImpactFeedbackGenerator(.heavy)  -> heavy
 *   UINotificationFeedbackGenerator(.success|.warning|.error)
 */
@RunWith(RobolectricTestRunner::class)
class HapticsAndroidTest {

    private lateinit var fake: RecordingHapticBackend

    @Before
    fun setUp() {
        fake = RecordingHapticBackend()
        Haptics.setBackend(fake)
    }

    @After
    fun tearDown() {
        Haptics.resetBackend()
    }

    @Test
    fun light_delegatesToBackend_withLightEvent() {
        Haptics.light()
        assertEquals(listOf(HapticEvent.LIGHT), fake.events)
    }

    @Test
    fun medium_delegatesToBackend_withMediumEvent() {
        Haptics.medium()
        assertEquals(listOf(HapticEvent.MEDIUM), fake.events)
    }

    @Test
    fun heavy_delegatesToBackend_withHeavyEvent() {
        Haptics.heavy()
        assertEquals(listOf(HapticEvent.HEAVY), fake.events)
    }

    @Test
    fun success_delegatesToBackend_withSuccessEvent() {
        Haptics.success()
        assertEquals(listOf(HapticEvent.SUCCESS), fake.events)
    }

    @Test
    fun warning_delegatesToBackend_withWarningEvent() {
        Haptics.warning()
        assertEquals(listOf(HapticEvent.WARNING), fake.events)
    }

    @Test
    fun error_delegatesToBackend_withErrorEvent() {
        Haptics.error()
        assertEquals(listOf(HapticEvent.ERROR), fake.events)
    }

    @Test
    fun multipleCalls_areRecordedInOrder() {
        Haptics.light()
        Haptics.success()
        Haptics.error()
        assertEquals(
            listOf(HapticEvent.LIGHT, HapticEvent.SUCCESS, HapticEvent.ERROR),
            fake.events
        )
    }

    @Test
    fun androidDefaultBackend_isResilientWithoutInstalledContext() {
        Haptics.resetBackend()
        // Default backend must not crash even when no context/view is installed.
        Haptics.light()
        Haptics.success()
        Haptics.error()
        assertTrue("platform default backend should be resilient", true)
    }
}

/** Test-only backend that records events for assertion. */
private class RecordingHapticBackend : HapticBackend {
    val events = mutableListOf<HapticEvent>()
    override fun perform(event: HapticEvent) {
        events += event
    }
}
