import Foundation
import Combine

enum FreemiumLimits {
    static let maxSources = 5
    static let maxHistoricalMonths = 12
}

class FreemiumValidator: ObservableObject {
    private let iapService: IAPService

    init(iapService: IAPService) {
        self.iapService = iapService
    }

    // MARK: - Source Limits

    var isPremium: Bool {
        iapService.isPremium
    }

    func canAddSource(currentCount: Int) -> Bool {
        if iapService.isPremium { return true }
        return currentCount < FreemiumLimits.maxSources
    }

    func remainingSources(currentCount: Int) -> Int {
        if iapService.isPremium { return Int.max }
        return max(0, FreemiumLimits.maxSources - currentCount)
    }

    var sourceLimit: Int {
        iapService.isPremium ? Int.max : FreemiumLimits.maxSources
    }

    var sourceLimitDescription: String {
        if iapService.isPremium {
            return "Unlimited"
        }
        return "\(FreemiumLimits.maxSources) sources"
    }

    // MARK: - Historical Data Limits

    func filterSnapshots(_ snapshots: [Snapshot]) -> [Snapshot] {
        if iapService.isPremium { return snapshots }

        let cutoffDate = Calendar.current.date(
            byAdding: .month,
            value: -FreemiumLimits.maxHistoricalMonths,
            to: Date()
        ) ?? Date()

        return snapshots.filter { $0.date >= cutoffDate }
    }

    /// Number of distinct months of data that exist BEYOND the free history window.
    /// Used to make the locked value concrete ("8 more months with Premium") instead
    /// of silently truncating — users can't want what they can't see.
    func hiddenHistoryMonths(in snapshots: [Snapshot]) -> Int {
        if iapService.isPremium { return 0 }

        let cutoffDate = Calendar.current.date(
            byAdding: .month,
            value: -FreemiumLimits.maxHistoricalMonths,
            to: Date()
        ) ?? Date()

        let calendar = Calendar.current
        let hiddenMonths = Set(
            snapshots
                .filter { $0.date < cutoffDate }
                .map { calendar.dateComponents([.year, .month], from: $0.date) }
        )
        return hiddenMonths.count
    }

    func isSnapshotAccessible(_ snapshot: Snapshot) -> Bool {
        if iapService.isPremium { return true }

        let cutoffDate = Calendar.current.date(
            byAdding: .month,
            value: -FreemiumLimits.maxHistoricalMonths,
            to: Date()
        ) ?? Date()

        return snapshot.date >= cutoffDate
    }

    var historicalLimit: Int {
        iapService.isPremium ? Int.max : FreemiumLimits.maxHistoricalMonths
    }

    var historicalLimitDescription: String {
        if iapService.isPremium {
            return "Full history"
        }
        return "Last \(FreemiumLimits.maxHistoricalMonths) months"
    }

    // MARK: - Feature Access

    func canExport() -> Bool {
        return iapService.isPremium
    }

    func canViewPredictions() -> Bool {
        return iapService.isPremium
    }

    func canViewAdvancedCharts() -> Bool {
        return iapService.isPremium
    }

    func canAccessFeature(_ feature: PremiumFeature) -> Bool {
        if iapService.isPremium { return true }

        switch feature {
        case .multipleAccounts:
            return false
        case .unlimitedSources:
            return false
        case .fullHistory:
            return false
        case .advancedCharts:
            return false
        case .predictions:
            return false
        case .export:
            return false
        case .noAds:
            return false
        }
    }

    // MARK: - Premium Features Enum

    enum PremiumFeature: String, CaseIterable, Identifiable {
        case multipleAccounts = "multiple_accounts"
        case unlimitedSources = "unlimited_sources"
        case fullHistory = "full_history"
        case advancedCharts = "advanced_charts"
        case predictions = "predictions"
        case export = "export"
        case noAds = "no_ads"

        var id: String { rawValue }

        var title: String {
            switch self {
            case .multipleAccounts: return "Multiple Accounts"
            case .unlimitedSources: return "Unlimited Sources"
            case .fullHistory: return "Full History"
            case .advancedCharts: return "Advanced Charts"
            case .predictions: return "Predictions"
            case .export: return "Export Data"
            case .noAds: return "No Ads"
            }
        }

        var icon: String {
            switch self {
            case .multipleAccounts: return "person.2"
            case .unlimitedSources: return "infinity"
            case .fullHistory: return "clock.arrow.circlepath"
            case .advancedCharts: return "chart.bar.xaxis"
            case .predictions: return "wand.and.stars"
            case .export: return "square.and.arrow.up"
            case .noAds: return "xmark.circle"
            }
        }

        var description: String {
            switch self {
            case .multipleAccounts:
                return "Track separate portfolios for family or business"
            case .unlimitedSources:
                return "Track as many investment sources as you want"
            case .fullHistory:
                return "Access your complete investment history"
            case .advancedCharts:
                return "5 types of detailed analytics charts"
            case .predictions:
                return "AI-powered 12-month forecasts"
            case .export:
                return "Export to CSV and JSON formats"
            case .noAds:
                return "Ad-free experience forever"
            }
        }
    }

    // MARK: - Paywall Triggers

    enum PaywallTrigger: String {
        case sourceLimit = "source_limit"
        case historyLimit = "history_limit"
        case advancedCharts = "advanced_charts"
        case predictions = "predictions"
        case export = "export"
        case settingsUpgrade = "settings_upgrade"
        case manualTap = "manual_tap"
    }

    func shouldShowPaywall(for trigger: PaywallTrigger) -> Bool {
        guard !iapService.isPremium else { return false }

        switch trigger {
        case .sourceLimit, .historyLimit, .advancedCharts, .predictions, .export:
            return true
        case .settingsUpgrade, .manualTap:
            return true
        }
    }
}
