import Foundation

/// MaterialMonitor SDK 全局配置
///
/// Swift 使用：
/// ```swift
/// let config = MaterialMonitorConfig.Builder()
///     .appId("your_app_id")
///     .appKey("your_app_key")
///     .build()
/// ```
///
/// ObjC 使用（Builder ObjC 类名为 `MMConfigBuilder`）：
/// ```objc
/// MMConfigBuilder *b = [[MMConfigBuilder alloc] init];
/// [b appId:@"your_app_id"];
/// [b appKey:@"your_app_key"];
/// MaterialMonitorConfig *config = [b build];
/// ```
@objcMembers
public final class MaterialMonitorConfig: NSObject {

    /// 上传接口根域名（如 `"https://api.example.com"`），SDK 自动拼接 `/v1/creative/upload`
    /// 未设置或为空时使用内置默认地址（对齐 Android `baseUploadUrl` 配置）
    public let baseUploadUrl: String
    /// TopOn 应用 ID，作为 multipart 独立字段上传
    public let appId: String
    /// HMAC-MD5 签名密钥（禁止打印、缓存、写入日志、上传明文）
    public let appKey: String
    /// 最大上传尝试次数（首发 + 重试），默认 3
    public let maxUploadAttempts: Int
    /// 各次重试等待时长（ms），默认 [5000, 15000]
    @nonobjc public let retryDelayMs: [Int]
    /// 沙盒 `material_monitor/` 目录总容量上限（MB），默认 100
    public let maxCacheSizeMb: Int
    /// 建立 TCP 连接的超时时间（ms），默认 15000
    public let connectTimeoutMs: Int
    /// 等待服务器响应的超时时间（ms），默认 30000
    public let readTimeoutMs: Int
    /// 开启详细 Debug 日志（对齐 Android `debugPerfLogging`）
    /// 生产环境请保持 `false`，避免性能损耗和敏感信息泄漏
    public let debugPerfLogging: Bool
    /// IDFA（由业务方在 ATT 授权后传入；SDK 直接透传，不过滤全 0 值）
    public let idfa: String?
    /// IDFV（由业务方传入；未传时 SDK 自动从 UIDevice 读取）
    public let idfv: String?
    /// 宿主 SDK 版本号（由业务方传入，写入 meta device_info.sdk_version）
    public let sdkVersion: String?
    /// CAID（业务方传入）
    public let caid: String?

    private init(builder: Builder) {
        self.baseUploadUrl     = builder._baseUploadUrl
        self.appId             = builder._appId
        self.appKey            = builder._appKey
        self.maxUploadAttempts = builder._maxUploadAttempts
        self.retryDelayMs      = builder._retryDelayMs
        self.maxCacheSizeMb    = builder._maxCacheSizeMb
        self.connectTimeoutMs  = builder._connectTimeoutMs
        self.readTimeoutMs     = builder._readTimeoutMs
        self.debugPerfLogging  = builder._debugPerfLogging
        self.idfa              = builder._idfa
        self.idfv              = builder._idfv
        self.sdkVersion        = builder._sdkVersion
        self.caid              = builder._caid
        super.init()
    }

    /// 验证上传配置是否完整（appId / appKey 均非空）
    var isUploadReady: Bool {
        !appId.isEmpty && !appKey.isEmpty
    }

    // MARK: - Builder

    /// ObjC 可见类名：`MMConfigBuilder`
    @objc(MMConfigBuilder)
    public final class Builder: NSObject {

        fileprivate var _baseUploadUrl: String     = ""
        fileprivate var _appId: String             = ""
        fileprivate var _appKey: String            = ""
        fileprivate var _maxUploadAttempts: Int    = 3
        fileprivate var _retryDelayMs: [Int]       = [5_000, 15_000]
        fileprivate var _maxCacheSizeMb: Int       = 100
        fileprivate var _connectTimeoutMs: Int     = 15_000
        fileprivate var _readTimeoutMs: Int        = 30_000
        fileprivate var _debugPerfLogging: Bool    = false
        fileprivate var _idfa: String?             = nil
        fileprivate var _idfv: String?             = nil
        fileprivate var _sdkVersion: String?       = nil
        fileprivate var _caid: String?             = nil

        public override init() { super.init() }

        /// 上传接口根域名（如 `"https://api.example.com"`），不含路径部分
        /// 未设置时 SDK 使用内置默认地址
        @objc @discardableResult
        public func baseUploadUrl(_ url: String) -> Builder {
            _baseUploadUrl = url.trimmingCharacters(in: .init(charactersIn: "/")); return self
        }

        /// TopOn 应用 ID
        @objc @discardableResult
        public func appId(_ appId: String) -> Builder {
            _appId = appId; return self
        }

        /// HMAC-MD5 签名密钥（禁止打印 / 缓存 / 上传明文）
        @objc @discardableResult
        public func appKey(_ appKey: String) -> Builder {
            _appKey = appKey; return self
        }

        /// 最大上传尝试次数，最小值 1
        @objc @discardableResult
        public func maxUploadAttempts(_ count: Int) -> Builder {
            _maxUploadAttempts = max(1, count); return self
        }

        /// 各次重试等待时长（ms）；Swift 专属（ObjC 使用默认值 [5000,15000]）
        @nonobjc @discardableResult
        public func retryDelayMs(_ delays: [Int]) -> Builder {
            _retryDelayMs = delays.isEmpty ? [5_000, 15_000] : delays; return self
        }

        /// 沙盒目录总容量上限（MB），最小值 10MB
        @objc @discardableResult
        func maxCacheSizeMb(_ mb: Int) -> Builder {
            _maxCacheSizeMb = max(10, mb); return self
        }

        /// 建立 TCP 连接的超时（ms），最小值 3000
        @objc @discardableResult
        public func connectTimeoutMs(_ ms: Int) -> Builder {
            _connectTimeoutMs = max(3_000, ms); return self
        }

        /// 等待服务器响应的超时（ms），最小值 3000
        @objc @discardableResult
        public func readTimeoutMs(_ ms: Int) -> Builder {
            _readTimeoutMs = max(3_000, ms); return self
        }

        /// 开启详细 Debug 日志（生产环境请保持 false）
        @objc @discardableResult
        public func debugPerfLogging(_ enabled: Bool) -> Builder {
            _debugPerfLogging = enabled; return self
        }

        /// IDFA（业务方 ATT 授权后传入，SDK 直接透传）
        @objc @discardableResult
        public func idfa(_ idfa: String?) -> Builder {
            _idfa = idfa; return self
        }

        /// IDFV（未传时 SDK 自动从 UIDevice.current.identifierForVendor 读取）
        @objc @discardableResult
        public func idfv(_ idfv: String?) -> Builder {
            _idfv = idfv; return self
        }

        /// 宿主 SDK 版本号（写入 meta device_info.sdk_version）
        @objc @discardableResult
        public func sdkVersion(_ version: String?) -> Builder {
            _sdkVersion = version; return self
        }

        /// CAID
        @objc @discardableResult
        public func caid(_ caid: String?) -> Builder {
            _caid = caid; return self
        }

        /// 构建 MaterialMonitorConfig
        @objc public func build() -> MaterialMonitorConfig {
            MaterialMonitorConfig(builder: self)
        }
    }
}
