// ── License Client ──────────────────────────────────────────
// Generic license key activation via platform-service.
// Flow: enter key → POST /api/licenses/activate → receive tokens.
// Product apps configure with BLPlatformConfig.

import Foundation

/// License information returned from platform-service.
public struct BLLicenseInfo: Codable, Sendable {
    public let key: String
    public let plan: String
    public let status: String
    public let devicesUsed: Int
    public let maxDevices: Int
    public let expiresAt: String?

    public init(key: String, plan: String, status: String, devicesUsed: Int, maxDevices: Int, expiresAt: String?) {
        self.key = key
        self.plan = plan
        self.status = status
        self.devicesUsed = devicesUsed
        self.maxDevices = maxDevices
        self.expiresAt = expiresAt
    }
}

/// Activation result containing tokens + license info.
public struct BLActivationResult: Sendable {
    public let accessToken: String
    public let refreshToken: String
    public let license: BLLicenseInfo
}

/// Generic license client for all ByteLyst iOS apps.
/// Handles license key activation and status checking via platform-service.
public final class BLLicenseClient {

    private let config: BLPlatformConfig
    private let client: BLPlatformClient

    public init(config: BLPlatformConfig, client: BLPlatformClient) {
        self.config = config
        self.client = client
    }

    // MARK: - Activate

    /// Activate a license key on this device.
    /// Returns activation result with tokens and license info.
    public func activate(key: String, deviceId: String, deviceName: String) async throws -> BLActivationResult {
        let body: [String: String] = [
            "key": key.uppercased().trimmingCharacters(in: .whitespaces),
            "deviceId": deviceId,
            "deviceName": deviceName,
            "platform": config.platform,
        ]

        let (data, _) = try await client.rawRequest(path: "/api/licenses/activate", method: "POST", body: body)

        struct ActivateResponse: Codable {
            let accessToken: String
            let refreshToken: String
            let license: LicenseDoc
        }
        struct LicenseDoc: Codable {
            let key: String
            let plan: String
            let status: String
            let deviceIds: [String]
            let maxDevices: Int
            let expiresAt: String?
            let userId: String
        }

        let result = try JSONDecoder().decode(ActivateResponse.self, from: data)

        let info = BLLicenseInfo(
            key: result.license.key,
            plan: result.license.plan,
            status: result.license.status,
            devicesUsed: result.license.deviceIds.count,
            maxDevices: result.license.maxDevices,
            expiresAt: result.license.expiresAt
        )

        return BLActivationResult(
            accessToken: result.accessToken,
            refreshToken: result.refreshToken,
            license: info
        )
    }

    // MARK: - Status

    /// Check license status without activating.
    public func checkStatus(key: String) async throws -> BLLicenseInfo {
        let trimmedKey = key.uppercased().trimmingCharacters(in: .whitespaces)
        let encodedKey = trimmedKey.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) ?? trimmedKey
        return try await client.request(
            path: "/api/licenses/status/\(encodedKey)",
            responseType: BLLicenseInfo.self
        )
    }
}
