package com.tt.honeyDue.utils

import com.tt.honeyDue.data.DataManager

/**
 * Canonical product IDs for in-app subscriptions.
 *
 * These must match the product IDs configured in:
 * - Apple App Store Connect (StoreKit configuration)
 * - Google Play Console (subscription products)
 *
 * All code referencing subscription product IDs should use these constants
 * instead of hardcoded strings to ensure consistency.
 */
object SubscriptionProducts {
    const val MONTHLY = "com.tt.honeyDue.pro.monthly"
    const val ANNUAL = "com.tt.honeyDue.pro.annual"

    /** All product IDs as a list, useful for querying store product details. */
    val all: List<String> = listOf(MONTHLY, ANNUAL)
}

/**
 * Helper for checking subscription limits and determining when to show upgrade prompts.
 *
 * Reads ALL subscription state from DataManager (single source of truth).
 * The current tier is derived from the backend subscription status:
 *   - If expiresAt is present and non-empty, user is "pro"
 *   - Otherwise, user is "free"
 *
 * RULES:
 * 1. Backend limitations OFF: Never show upgrade view, allow everything
 * 2. Backend limitations ON + limit=0: Show upgrade view, block access entirely (no add button)
 * 3. Backend limitations ON + limit>0: Allow access with add button, show upgrade when limit reached
 *
 * These rules apply to: residence, task, contractors, documents
 */
object SubscriptionHelper {
    /**
     * Result of a usage/access check
     * @param allowed Whether the action is allowed
     * @param triggerKey The upgrade trigger key to use if not allowed (null if allowed)
     */
    data class UsageCheck(val allowed: Boolean, val triggerKey: String?)

    /**
     * Derive the current subscription tier from DataManager.
     * "pro" if the backend subscription has an active trial or a non-empty expiresAt (active paid plan),
     * "free" otherwise.
     */
    val currentTier: String
        get() {
            val subscription = DataManager.subscription.value ?: return "free"
            if (subscription.trialActive) return "pro"
            val expiresAt = subscription.expiresAt
            return if (!expiresAt.isNullOrEmpty()) "pro" else "free"
        }

    /**
     * Whether the user has a premium (pro) subscription.
     * True when limitations are disabled (everyone gets full access)
     * OR when the user is on the pro tier.
     */
    val isPremium: Boolean
        get() {
            val subscription = DataManager.subscription.value ?: return false
            // If limitations are disabled, everyone effectively has premium access
            if (!subscription.limitationsEnabled) return true
            return currentTier == "pro"
        }

    /**
     * Check if the user can purchase a subscription on the given platform.
     * If the user already has an active Pro subscription from a different platform,
     * purchasing on this platform is not allowed.
     *
     * @param currentPlatform The platform attempting the purchase ("ios", "android", or "stripe")
     * @return UsageCheck with allowed=false if already subscribed on another platform
     */
    fun canPurchaseOnPlatform(currentPlatform: String): UsageCheck {
        val subscription = DataManager.subscription.value
            ?: return UsageCheck(allowed = true, triggerKey = null)
        if (currentTier != "pro") return UsageCheck(allowed = true, triggerKey = null)
        val source = subscription.subscriptionSource
        if (source != null && source != currentPlatform) {
            return UsageCheck(allowed = false, triggerKey = "already_subscribed_other_platform")
        }
        return UsageCheck(allowed = true, triggerKey = null)
    }

    // ===== PROPERTY (RESIDENCE) =====

    /**
     * Check if the user should see an upgrade view instead of the residences screen.
     * Returns true (blocked) only when limitations are ON and limit=0.
     */
    fun isResidencesBlocked(): UsageCheck {
        val subscription = DataManager.subscription.value
            ?: return UsageCheck(false, null)  // Allow access while loading

        if (!subscription.limitationsEnabled) {
            return UsageCheck(false, null)  // Limitations disabled, never block
        }

        val tier = currentTier
        if (tier == "pro") {
            return UsageCheck(false, null)  // Pro users never blocked
        }

        val limit = subscription.limits[tier]?.properties

        // If limit is 0, block access entirely
        if (limit == 0) {
            return UsageCheck(true, "add_second_property")
        }

        return UsageCheck(false, null)  // limit > 0 or unlimited, allow access
    }

    /**
     * Check if user can add a property (when trying to add, not for blocking the screen).
     * Used when limit > 0 and user has reached the limit.
     */
    fun canAddProperty(currentCount: Int = 0): UsageCheck {
        val subscription = DataManager.subscription.value
            ?: return UsageCheck(true, null)  // Allow if no subscription data

        if (!subscription.limitationsEnabled) {
            return UsageCheck(true, null)  // Limitations disabled, allow everything
        }

        val tier = currentTier
        if (tier == "pro") {
            return UsageCheck(true, null)  // Pro tier gets unlimited access
        }

        // Get limit for current tier (null = unlimited)
        val limit = subscription.limits[tier]?.properties

        // null means unlimited
        if (limit == null) {
            return UsageCheck(true, null)
        }

        // If limit is 0, they shouldn't even be here (screen should be blocked)
        // But if they somehow are, block the add
        if (limit == 0) {
            return UsageCheck(false, "add_second_property")
        }

        // limit > 0: check if they've reached it
        if (currentCount >= limit) {
            return UsageCheck(false, "add_second_property")
        }

        return UsageCheck(true, null)
    }

    // ===== TASKS =====

    /**
     * Check if the user should see an upgrade view instead of the tasks screen.
     * Returns true (blocked) only when limitations are ON and limit=0.
     */
    fun isTasksBlocked(): UsageCheck {
        val subscription = DataManager.subscription.value
            ?: return UsageCheck(false, null)  // Allow access while loading

        if (!subscription.limitationsEnabled) {
            return UsageCheck(false, null)
        }

        val tier = currentTier
        if (tier == "pro") {
            return UsageCheck(false, null)
        }

        val limit = subscription.limits[tier]?.tasks

        if (limit == 0) {
            return UsageCheck(true, "add_11th_task")
        }

        return UsageCheck(false, null)
    }

    /**
     * Check if user can add a task (when trying to add).
     */
    fun canAddTask(currentCount: Int = 0): UsageCheck {
        val subscription = DataManager.subscription.value
            ?: return UsageCheck(true, null)

        if (!subscription.limitationsEnabled) {
            return UsageCheck(true, null)
        }

        val tier = currentTier
        if (tier == "pro") {
            return UsageCheck(true, null)
        }

        val limit = subscription.limits[tier]?.tasks

        if (limit == null) {
            return UsageCheck(true, null)  // Unlimited
        }

        if (limit == 0) {
            return UsageCheck(false, "add_11th_task")
        }

        if (currentCount >= limit) {
            return UsageCheck(false, "add_11th_task")
        }

        return UsageCheck(true, null)
    }

    // ===== CONTRACTORS =====

    /**
     * Check if the user should see an upgrade view instead of the contractors screen.
     * Returns true (blocked) only when limitations are ON and limit=0.
     */
    fun isContractorsBlocked(): UsageCheck {
        val subscription = DataManager.subscription.value
            ?: return UsageCheck(false, null)  // Allow access while loading

        if (!subscription.limitationsEnabled) {
            return UsageCheck(false, null)
        }

        val tier = currentTier
        if (tier == "pro") {
            return UsageCheck(false, null)
        }

        val limit = subscription.limits[tier]?.contractors

        if (limit == 0) {
            return UsageCheck(true, "view_contractors")
        }

        return UsageCheck(false, null)
    }

    /**
     * Check if user can add a contractor (when trying to add).
     */
    fun canAddContractor(currentCount: Int = 0): UsageCheck {
        val subscription = DataManager.subscription.value
            ?: return UsageCheck(true, null)

        if (!subscription.limitationsEnabled) {
            return UsageCheck(true, null)
        }

        val tier = currentTier
        if (tier == "pro") {
            return UsageCheck(true, null)
        }

        val limit = subscription.limits[tier]?.contractors

        if (limit == null) {
            return UsageCheck(true, null)
        }

        if (limit == 0) {
            return UsageCheck(false, "view_contractors")
        }

        if (currentCount >= limit) {
            return UsageCheck(false, "view_contractors")
        }

        return UsageCheck(true, null)
    }

    // ===== DOCUMENTS =====

    /**
     * Check if the user should see an upgrade view instead of the documents screen.
     * Returns true (blocked) only when limitations are ON and limit=0.
     */
    fun isDocumentsBlocked(): UsageCheck {
        val subscription = DataManager.subscription.value
            ?: return UsageCheck(false, null)  // Allow access while loading

        if (!subscription.limitationsEnabled) {
            return UsageCheck(false, null)
        }

        val tier = currentTier
        if (tier == "pro") {
            return UsageCheck(false, null)
        }

        val limit = subscription.limits[tier]?.documents

        if (limit == 0) {
            return UsageCheck(true, "view_documents")
        }

        return UsageCheck(false, null)
    }

    /**
     * Check if user can add a document (when trying to add).
     */
    fun canAddDocument(currentCount: Int = 0): UsageCheck {
        val subscription = DataManager.subscription.value
            ?: return UsageCheck(true, null)

        if (!subscription.limitationsEnabled) {
            return UsageCheck(true, null)
        }

        val tier = currentTier
        if (tier == "pro") {
            return UsageCheck(true, null)
        }

        val limit = subscription.limits[tier]?.documents

        if (limit == null) {
            return UsageCheck(true, null)
        }

        if (limit == 0) {
            return UsageCheck(false, "view_documents")
        }

        if (currentCount >= limit) {
            return UsageCheck(false, "view_documents")
        }

        return UsageCheck(true, null)
    }

    // ===== RESIDENCE SHARING =====

    /**
     * Check if user can share a residence (Pro feature).
     * Returns true (blocked) when limitations are ON and user is not pro.
     */
    fun canShareResidence(): UsageCheck {
        val subscription = DataManager.subscription.value
            ?: return UsageCheck(true, null)  // Allow if no subscription data (fallback)

        if (!subscription.limitationsEnabled) {
            return UsageCheck(true, null)  // Limitations disabled, allow everything
        }

        if (currentTier == "pro") {
            return UsageCheck(true, null)  // Pro tier can share
        }

        // Free users cannot share residences
        return UsageCheck(false, "share_residence")
    }

    // ===== CONTRACTOR SHARING =====

    /**
     * Check if user can share a contractor (Pro feature).
     * Returns true (blocked) when limitations are ON and user is not pro.
     */
    fun canShareContractor(): UsageCheck {
        val subscription = DataManager.subscription.value
            ?: return UsageCheck(true, null)  // Allow if no subscription data (fallback)

        if (!subscription.limitationsEnabled) {
            return UsageCheck(true, null)  // Limitations disabled, allow everything
        }

        if (currentTier == "pro") {
            return UsageCheck(true, null)  // Pro tier can share
        }

        // Free users cannot share contractors
        return UsageCheck(false, "share_contractor")
    }

    // ===== DEPRECATED - Keep for backwards compatibility =====

    @Deprecated("Use isContractorsBlocked() instead", ReplaceWith("isContractorsBlocked()"))
    fun shouldShowUpgradePromptForContractors(): UsageCheck = isContractorsBlocked()

    @Deprecated("Use isDocumentsBlocked() instead", ReplaceWith("isDocumentsBlocked()"))
    fun shouldShowUpgradePromptForDocuments(): UsageCheck = isDocumentsBlocked()
}
