import UIKit
import Network
import CoreTelephony

// MARK: - DeviceInfo

struct DeviceInfo {
    let idfa: String
    let idfv: String
    let os: String
    let osVersion: String
    let deviceModel: String
    let packageName: String
    let appVersion: String
    let sdkVersion: String
    let networkType: String
    let screenResolution: String
}

// MARK: - DeviceInfoCollector

/// 设备信息采集器
///
/// - IDFA 由业务方通过 `MaterialMonitorConfig` 传入，SDK 直接透传，不过滤全 0 值
/// - IDFV 由 SDK 自动获取
/// - 网络类型：通过 `NWPathMonitor` + `CTTelephonyNetworkInfo` 检测 WiFi / 4G / 5G
final class DeviceInfoCollector {

    static let sdkVersion = "1.0.0"

    private var currentNetworkType: String = "Unknown"
    private let pathMonitor = NWPathMonitor()
    private let monitorQueue = DispatchQueue(
        label: "com.materialmonitor.network",
        qos: .utility
    )

    init() {
        pathMonitor.pathUpdateHandler = { [weak self] path in
            self?.currentNetworkType = DeviceInfoCollector.resolveNetworkType(path)
        }
        pathMonitor.start(queue: monitorQueue)
    }

    deinit {
        pathMonitor.cancel()
    }

    // MARK: - Public

    /// 采集当前设备信息
    ///
    /// - Parameters:
    ///   - idfa:       业务方传入的 IDFA（含全 0 值直接透传，不过滤）
    ///   - idfv:       业务方传入的 IDFV；为 nil 时自动从 UIDevice 读取
    ///   - sdkVersion: 宿主 SDK 版本号；为 nil 时使用 MaterialMonitor 内部版本号
    ///   - caid:       业务方传入的 CAID
    func collect(idfa: String?, idfv: String?, sdkVersion: String?, caid: String?) -> DeviceInfo {
        DeviceInfo(
            idfa:             idfa ?? "",
            idfv:             idfv ?? UIDevice.current.identifierForVendor?.uuidString ?? "",
            os:               "ios",
            osVersion:        UIDevice.current.systemVersion,
            deviceModel:      deviceModel(),
            packageName:      Bundle.main.bundleIdentifier ?? "",
            appVersion:       Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "",
            sdkVersion:       sdkVersion ?? DeviceInfoCollector.sdkVersion,
            networkType:      currentNetworkType,
            screenResolution: screenResolution()
        )
    }

    // MARK: - Private

    private static func resolveNetworkType(_ path: NWPath) -> String {
        guard path.status == .satisfied else { return "Unknown" }
        if path.usesInterfaceType(.wifi) { return "WiFi" }
        if path.usesInterfaceType(.cellular) {
            if #available(iOS 14.1, *) {
                let info = CTTelephonyNetworkInfo()
                if let tech = info.serviceCurrentRadioAccessTechnology?.values.first {
                    if tech == CTRadioAccessTechnologyNRNSA ||
                       tech == CTRadioAccessTechnologyNR {
                        return "5G"
                    }
                }
            }
            return "4G"
        }
        return "Unknown"
    }

    private func deviceModel() -> String {
        var systemInfo = utsname()
        uname(&systemInfo)
        // utsname.machine 是一个固定大小的 C 字符数组，通过 Mirror 逐字节读取
        let mirror = Mirror(reflecting: systemInfo.machine)
        let chars: [Character] = mirror.children.compactMap {
            guard let value = $0.value as? Int8, value != 0 else { return nil }
            return Character(UnicodeScalar(UInt8(bitPattern: value)))
        }
        return String(chars)
    }

    private func screenResolution() -> String {
        let screen = UIScreen.main
        let w = Int(screen.bounds.width  * screen.scale)
        let h = Int(screen.bounds.height * screen.scale)
        return "\(w)x\(h)"
    }
}
