import SwiftUI

public struct Waveform: View {
    private let isAnimating: Bool
    public let color: Color
    public let barHeight: CGFloat
    public let barWidth: CGFloat
    public let barSpacing: CGFloat
    public let barCount: Int

    public init(
        isAnimating: Bool,
        barCount: Int = 5,
        color: Color = Color.SemanticV1.textPrimary,
        barHeight: CGFloat = 16,
        barWidth: CGFloat = 2,
        barSpacing: CGFloat = 3
    ) {
        self.isAnimating = isAnimating
        self.barCount = barCount
        self.color = color
        self.barHeight = barHeight
        self.barWidth = barWidth
        self.barSpacing = barSpacing
    }

    private var animationForever: Animation { .linear(duration: 0.8).repeatForever() }

    public var body: some View {
        HStack(spacing: barSpacing) {
            ForEach(0 ..< barCount, id: \.self) { index in
                bar(low: barLowValue(for: index))
                    .animation(isAnimating ? animationForever.speed(animationSpeed(for: index)) : .linear, value: isAnimating)
            }
        }
    }

    private func barLowValue(for index: Int) -> CGFloat {
        let values: [CGFloat] = [0.3, 0.4, 0.5, 0.3, 0.3]
        return values[index % values.count]
    }

    private func animationSpeed(for index: Int) -> Double {
        let speeds: [Double] = [1.5, 1.2, 1.0, 1.7, 1.0]
        return speeds[index % speeds.count]
    }

    private func bar(low: CGFloat = 0.0, high: CGFloat = 1.0) -> some View {
        RoundedRectangle(cornerRadius: 2)
            .fill(color)
            .frame(height: (isAnimating ? high : low) * barHeight)
            .frame(width: barWidth, height: barHeight, alignment: .center)
    }
}

struct Waveform_Previews: PreviewProvider {
    static var previews: some View {
        WaveformSample()
    }
}

struct WaveformSample: View {
    var body: some View {
        Waveform(isAnimating: false)
            .frame(width: 16, height: 16)
            .padding()
    }
}
