package com.tt.honeyDue.ui.screens.subscription

import com.tt.honeyDue.analytics.AnalyticsEvents
import com.tt.honeyDue.models.FeatureBenefit
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFalse
import kotlin.test.assertTrue

/**
 * P2 Stream E — FeatureComparisonScreen tests.
 *
 * These tests exercise the state-logic backing the full-screen feature
 * comparison (replaces the old FeatureComparisonDialog). They use plain
 * kotlin.test rather than Compose UI testing for the same reasons cited
 * in ThemeSelectionScreenTest — the commonTest recomposer/Dispatchers
 * interplay is flaky on iosSimulator.
 *
 * Mirrors iOS `iosApp/iosApp/Subscription/FeatureComparisonView.swift`.
 */
class FeatureComparisonScreenTest {

    // 1. The default feature-row set matches iOS FeatureComparisonView.swift
    //    lines 99-105 (shown when DataManager.featureBenefits is empty).
    @Test
    fun defaultFeatureRowsMatchIOSOrderAndText() {
        val rows = FeatureComparisonScreenState.defaultFeatureRows()

        assertEquals(4, rows.size, "iOS default list has 4 rows")

        assertEquals("Properties", rows[0].featureName)
        assertEquals("1 property", rows[0].freeTierText)
        assertEquals("Unlimited", rows[0].proTierText)

        assertEquals("Tasks", rows[1].featureName)
        assertEquals("10 tasks", rows[1].freeTierText)
        assertEquals("Unlimited", rows[1].proTierText)

        assertEquals("Contractors", rows[2].featureName)
        assertEquals("Not available", rows[2].freeTierText)
        assertEquals("Unlimited", rows[2].proTierText)

        assertEquals("Documents", rows[3].featureName)
        assertEquals("Not available", rows[3].freeTierText)
        assertEquals("Unlimited", rows[3].proTierText)
    }

    // 2. freeHasFeature returns false for "Not available" rows (the iOS
    //    comparison renders the free column grey for those), true for
    //    rows with an actual limit text like "1 property".
    @Test
    fun freeHasFeatureFollowsIosPerRowBooleans() {
        val rows = FeatureComparisonScreenState.defaultFeatureRows()

        assertTrue(FeatureComparisonScreenState.freeHasFeature(rows[0]), "Properties: free has 1")
        assertTrue(FeatureComparisonScreenState.freeHasFeature(rows[1]), "Tasks: free has 10")
        assertFalse(FeatureComparisonScreenState.freeHasFeature(rows[2]), "Contractors: free has none")
        assertFalse(FeatureComparisonScreenState.freeHasFeature(rows[3]), "Documents: free has none")
    }

    // 3. premiumHasFeature is true for every row on iOS — Pro is unlimited
    //    across the default set and every server-driven benefit.
    @Test
    fun premiumHasFeatureAlwaysTrueForProTier() {
        val rows = FeatureComparisonScreenState.defaultFeatureRows()
        rows.forEach { row ->
            assertTrue(
                FeatureComparisonScreenState.premiumHasFeature(row),
                "Pro always has ${row.featureName}"
            )
        }

        // Server-driven benefits: Pro tier is true unless the text is
        // explicitly "Not available" (treated the same as the Free column).
        val benefit = FeatureBenefit(
            featureName = "Reports",
            freeTierText = "Not available",
            proTierText = "Not available"
        )
        assertFalse(FeatureComparisonScreenState.premiumHasFeature(benefit))
    }

    // 4. CTA invocation calls the expected navigation callback.
    @Test
    fun ctaInvokesUpgradeNavigationCallback() {
        var navigated = false
        FeatureComparisonScreenState.onUpgradeTap(
            onNavigateToUpgrade = { navigated = true },
            captureEvent = { _, _ -> /* ignore */ },
        )
        assertTrue(navigated, "Upgrade CTA must navigate to upgrade flow")
    }

    // 5. Upgrade CTA fires analytics event paywall_compare_cta.
    @Test
    fun ctaFiresPaywallCompareAnalyticsEvent() {
        val captured = mutableListOf<Pair<String, Map<String, Any>?>>()
        FeatureComparisonScreenState.onUpgradeTap(
            onNavigateToUpgrade = { },
            captureEvent = { event, props -> captured.add(event to props) },
        )
        assertEquals(1, captured.size, "Exactly one analytics event")
        assertEquals(AnalyticsEvents.PAYWALL_COMPARE_CTA, captured[0].first)
    }

    // 6. Close / back callback is invoked when the user dismisses the
    //    screen (matches iOS "Close" toolbar button).
    @Test
    fun onCloseInvokesBackCallback() {
        var closed = false
        FeatureComparisonScreenState.onClose(onBack = { closed = true })
        assertTrue(closed, "Close/Back must call the onBack callback")
    }

    // 7. When DataManager has server-driven benefits, the screen uses
    //    those in preference to the default list.
    @Test
    fun serverDrivenBenefitsOverrideDefaults() {
        val serverBenefits = listOf(
            FeatureBenefit("Custom Feature A", "Not available", "Unlimited"),
            FeatureBenefit("Custom Feature B", "5 items", "Unlimited"),
        )
        val effective = FeatureComparisonScreenState.resolveFeatureRows(serverBenefits)
        assertEquals(2, effective.size)
        assertEquals("Custom Feature A", effective[0].featureName)
        assertFalse(FeatureComparisonScreenState.freeHasFeature(effective[0]))
        assertTrue(FeatureComparisonScreenState.freeHasFeature(effective[1]))

        val empty = FeatureComparisonScreenState.resolveFeatureRows(emptyList())
        assertEquals(4, empty.size, "Empty benefits falls back to default iOS list")
    }
}
