package com.tt.honeyDue

import android.content.Context
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.junit4.createAndroidComposeRule
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.performTextInput
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.tt.honeyDue.data.DataManager
import com.tt.honeyDue.data.PersistenceManager
import com.tt.honeyDue.storage.TaskCacheManager
import com.tt.honeyDue.storage.TaskCacheStorage
import com.tt.honeyDue.storage.ThemeStorageManager
import com.tt.honeyDue.storage.TokenManager
import com.tt.honeyDue.testing.AccessibilityIds
import org.junit.After
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith

/**
 * Android port of `iosApp/HoneyDueUITests/SimpleLoginTest.swift` — a smoke
 * test suite that verifies the app launches and surfaces a usable login
 * screen. Merged into one test (`testAppLaunchesAndShowsLoginScreen`) because
 * `createAndroidComposeRule<MainActivity>()` launches a fresh activity per
 * test anyway, and the two iOS tests exercise the exact same semantic
 * contract.
 */
@RunWith(AndroidJUnit4::class)
class SimpleLoginTest {

    @get:Rule
    val composeRule = createAndroidComposeRule<MainActivity>()

    @Before
    fun setUp() {
        val context = ApplicationProvider.getApplicationContext<Context>()
        if (!isDataManagerInitialized()) {
            DataManager.initialize(
                tokenMgr = TokenManager.getInstance(context),
                themeMgr = ThemeStorageManager.getInstance(context),
                persistenceMgr = PersistenceManager.getInstance(context),
            )
        }
        TaskCacheStorage.initialize(TaskCacheManager.getInstance(context))

        // CRITICAL: mirror iOS `ensureLoggedOut()` — UITestHelpers handles both
        // the already-logged-in and mid-onboarding cases.
        UITestHelpers.ensureOnLoginScreen(composeRule)
    }

    @After
    fun tearDown() {
        UITestHelpers.tearDown(composeRule)
    }

    /**
     * iOS: `testAppLaunchesAndShowsLoginScreen` + `testCanTypeInLoginFields`.
     *
     * Verifies the login screen elements exist AND that the username/password
     * fields accept text input (the minimum contract for SimpleLoginTest).
     */
    @Test
    fun testAppLaunchesAndShowsLoginScreen() {
        // App launches and username field is reachable.
        composeRule.onNodeWithTag(
            AccessibilityIds.Authentication.usernameField,
            useUnmergedTree = true,
        ).assertIsDisplayed()

        // Can type into username & password fields.
        composeRule.onNodeWithTag(
            AccessibilityIds.Authentication.usernameField,
            useUnmergedTree = true,
        ).performTextInput("testuser")

        composeRule.onNodeWithTag(
            AccessibilityIds.Authentication.passwordField,
            useUnmergedTree = true,
        ).performTextInput("testpass123")

        // Login button should be displayed (and, because both fields are
        // populated, also enabled — we don't tap it here to avoid a real API
        // call from a smoke test).
        composeRule.onNodeWithTag(
            AccessibilityIds.Authentication.loginButton,
            useUnmergedTree = true,
        ).assertIsDisplayed()
    }

    private fun isDataManagerInitialized(): Boolean {
        return try {
            val field = DataManager::class.java.getDeclaredField("_isInitialized")
            field.isAccessible = true
            @Suppress("UNCHECKED_CAST")
            val flow = field.get(DataManager) as kotlinx.coroutines.flow.MutableStateFlow<Boolean>
            flow.value
        } catch (t: Throwable) {
            false
        }
    }
}
