import UIKit

// MARK: - CALayer Filter Helpers (Private API — same approach as Telegram iOS)

extension CALayer {
    static func blurFilter() -> NSObject? {
        return makeFilter(name: "gaussianBlur")
    }

    static func colorMatrixFilter() -> NSObject? {
        return makeFilter(name: "colorMatrix")
    }

    static func variableBlurFilter() -> NSObject? {
        return makeFilter(name: "variableBlur")
    }

    private static func makeFilter(name: String) -> NSObject? {
        let className = ["CA", "Filter"].joined()
        guard let cls = NSClassFromString(className) as? NSObject.Type else { return nil }
        let sel = NSSelectorFromString("filterWithName:")
        guard cls.responds(to: sel) else { return nil }
        return cls.perform(sel, with: name)?.takeUnretainedValue() as? NSObject
    }
}

// MARK: - CABackdropLayer Helpers

enum BackdropLayerHelper {
    static func createBackdropLayer() -> CALayer? {
        let className = ["CA", "Backdrop", "Layer"].joined()
        guard let cls = NSClassFromString(className) as? CALayer.Type else { return nil }
        return cls.init()
    }

    static func setScale(_ layer: CALayer, scale: Double) {
        let sel = NSSelectorFromString("setScale:")
        guard layer.responds(to: sel) else { return }
        layer.perform(sel, with: NSNumber(value: scale))
    }
}

// MARK: - Device Capability

enum DeviceCapability {
    static let isGraphicallyCapable: Bool = {
        var length = MemoryLayout<UInt32>.size
        var cpuCount: UInt32 = 0
        sysctlbyname("hw.ncpu", &cpuCount, &length, nil, 0)
        return cpuCount >= 4
    }()
}

// MARK: - BackdropLayerDelegate (disables implicit animations)

final class BackdropLayerDelegate: NSObject, CALayerDelegate {
    static let shared = BackdropLayerDelegate()

    func action(for layer: CALayer, forKey event: String) -> CAAction? {
        return NSNull()
    }
}

// MARK: - UIColor Mixing (Telegram parity)

extension UIColor {
    func mixedWith(_ other: UIColor, alpha: CGFloat) -> UIColor {
        let alpha = min(1.0, max(0.0, alpha))
        let oneMinusAlpha = 1.0 - alpha

        var r1: CGFloat = 0.0
        var r2: CGFloat = 0.0
        var g1: CGFloat = 0.0
        var g2: CGFloat = 0.0
        var b1: CGFloat = 0.0
        var b2: CGFloat = 0.0
        var a1: CGFloat = 0.0
        var a2: CGFloat = 0.0
        if self.getRed(&r1, green: &g1, blue: &b1, alpha: &a1) &&
            other.getRed(&r2, green: &g2, blue: &b2, alpha: &a2)
        {
            let r = r1 * oneMinusAlpha + r2 * alpha
            let g = g1 * oneMinusAlpha + g2 * alpha
            let b = b1 * oneMinusAlpha + b2 * alpha
            let a = a1 * oneMinusAlpha + a2 * alpha
            return UIColor(red: r, green: g, blue: b, alpha: a)
        }
        return self
    }
}
