import Cocoa

/// 5 个球形波动画，由实时音频 RMS 电平驱动
final class WaveformView: NSView {

    private let weights: [Float] = [0.5, 0.8, 1.0, 0.75, 0.55]
    private var dots: [NSView] = []
    private var smoothedLevels: [Float] = [0, 0, 0, 0, 0]
    private var decayTimer: Timer?
    private var rawLevel: Float = 0

    private let dotSize: CGFloat = 4
    private let maxExtra: CGFloat = 28
    private let spacing: CGFloat = 6
    private let silenceThreshold: Float = 0.02

    override init(frame: NSRect) {
        super.init(frame: frame)
        setupDots()
        wantsLayer = true
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    private func setupDots() {
        dots.forEach { $0.removeFromSuperview() }
        dots.removeAll()

        let totalWidth = CGFloat(weights.count) * dotSize + CGFloat(weights.count - 1) * spacing
        let startX = (bounds.width - totalWidth) / 2

        for (index, _) in weights.enumerated() {
            let x = startX + CGFloat(index) * (dotSize + spacing)
            let dot = NSView(frame: NSRect(x: x, y: 0, width: dotSize, height: dotSize))
            dot.wantsLayer = true
            dot.layer?.cornerRadius = dotSize / 2
            dot.layer?.backgroundColor = NSColor.white.withAlphaComponent(0.9).cgColor
            addSubview(dot)
            dots.append(dot)
        }

        decayTimer?.invalidate()
        decayTimer = Timer.scheduledTimer(withTimeInterval: 0.04, repeats: true) { [weak self] _ in
            self?.updateDecay()
        }
    }

    func updateLevel(_ level: Float) {
        rawLevel = level
        for i in 0..<weights.count {
            let target = level * weights[i]
            if target > smoothedLevels[i] {
                smoothedLevels[i] = smoothedLevels[i] * 0.55 + target * 0.45
            }
        }
        applyLevels()
    }

    private func updateDecay() {
        for i in 0..<weights.count {
            let target = rawLevel * weights[i]
            if target < smoothedLevels[i] {
                smoothedLevels[i] = smoothedLevels[i] * 0.82 + target * 0.18
            }
            if smoothedLevels[i] < silenceThreshold {
                smoothedLevels[i] = 0
            }
        }
        applyLevels()
    }

    private func applyLevels() {
        CATransaction.begin()
        CATransaction.setAnimationDuration(0.06)  // 快速平滑过渡
        CATransaction.setAnimationTimingFunction(CAMediaTimingFunction(name: .easeOut))

        for (i, dot) in dots.enumerated() {
            let level = smoothedLevels[i]
            let extra = CGFloat(level) * maxExtra
            let height = dotSize + extra
            let y = (bounds.height - height) / 2

            dot.frame = NSRect(x: dot.frame.origin.x, y: y, width: dotSize, height: height)
            dot.layer?.cornerRadius = min(dotSize, height) / 2
        }

        CATransaction.commit()
    }

    override func viewDidMoveToWindow() {
        super.viewDidMoveToWindow()
        setupDots()
    }

    deinit {
        decayTimer?.invalidate()
    }
}
