// ── Feature Flag Client ──────────────────────────────────────
// Generic feature flag polling from platform-service /api/flags/poll.
// Flags cached in memory, re-polled at configurable interval.
// Matches the platform-service flags module API.

import Foundation

/// Generic feature flag client for all ByteLyst iOS apps.
/// Polls platform-service and caches flag values in memory.
public final class BLFeatureFlagClient {

    private let config: BLPlatformConfig
    private let client: BLPlatformClient
    private let pollIntervalSec: TimeInterval

    private var flags: [String: Bool] = [:]
    private let flagsLock = NSLock()
    private var pollTimer: Timer?

    public init(
        config: BLPlatformConfig,
        client: BLPlatformClient,
        pollIntervalSec: TimeInterval = 5 * 60
    ) {
        self.config = config
        self.client = client
        self.pollIntervalSec = pollIntervalSec
    }

    // MARK: - Lifecycle

    /// Start polling for feature flags.
    public func start(userId: String? = nil) {
        Task { await fetchFlags(userId: userId) }
        pollTimer?.invalidate()
        pollTimer = Timer.scheduledTimer(withTimeInterval: pollIntervalSec, repeats: true) { [weak self] _ in
            guard let self else { return }
            Task { await self.fetchFlags(userId: userId) }
        }
    }

    /// Stop polling.
    public func stop() {
        pollTimer?.invalidate()
        pollTimer = nil
    }

    // MARK: - Query

    /// Check if a feature flag is enabled.
    public func isEnabled(_ key: String) -> Bool {
        flagsLock.lock()
        defer { flagsLock.unlock() }
        return flags[key] == true
    }

    /// Get all current flag values.
    public func allFlags() -> [String: Bool] {
        flagsLock.lock()
        defer { flagsLock.unlock() }
        return flags
    }

    // MARK: - Fetch

    private struct FlagsResponse: Codable {
        let flags: [String: Bool]
    }

    private func fetchFlags(userId: String? = nil) async {
        var path = "/api/flags/poll?platform=\(config.platform)"
        if let userId { path += "&userId=\(userId)" }

        do {
            let result = try await client.request(
                path: path,
                responseType: FlagsResponse.self
            )
            flagsLock.lock()
            flags = result.flags
            flagsLock.unlock()
        } catch {
            // Keep existing flags on error — silent failure
        }
    }
}
