import SwiftUI

/// PC-style dark waveform scrubber for study media chrome.
struct MediaWaveformView: View {
    let currentTime: Double
    let duration: Double
    let isPlaying: Bool
    var clipRange: (start: Double, end: Double)?
    var onSeek: (Double) -> Void
    var onTogglePlay: () -> Void

    private let barCount = 120
    private let bars: [CGFloat]

    init(
        currentTime: Double,
        duration: Double,
        isPlaying: Bool,
        clipRange: (start: Double, end: Double)? = nil,
        onSeek: @escaping (Double) -> Void,
        onTogglePlay: @escaping () -> Void
    ) {
        self.currentTime = currentTime
        self.duration = duration
        self.isPlaying = isPlaying
        self.clipRange = clipRange
        self.onSeek = onSeek
        self.onTogglePlay = onTogglePlay
        var seeded: [CGFloat] = []
        seeded.reserveCapacity(120)
        for i in 0..<120 {
            let wave = sin(Double(i) * 0.31) * 0.22 + sin(Double(i) * 0.07) * 0.18
            let noise = Double((i * 17 + 31) % 23) / 23.0 * 0.35
            seeded.append(CGFloat(min(1, max(0.12, 0.35 + wave + noise))))
        }
        self.bars = seeded
    }

    private var progress: Double {
        guard duration > 0 else { return 0 }
        return min(1, max(0, currentTime / duration))
    }

    var body: some View {
        HStack(spacing: 10) {
            Button(action: onTogglePlay) {
                Image(systemName: isPlaying ? "pause.fill" : "play.fill")
                    .font(.system(size: 14, weight: .semibold))
                    .frame(width: 36, height: 36)
                    .background(Color.white.opacity(0.08))
                    .overlay(
                        RoundedRectangle(cornerRadius: 8)
                            .stroke(Color.white.opacity(0.15), lineWidth: 1)
                    )
                    .clipShape(RoundedRectangle(cornerRadius: 8))
            }
            .buttonStyle(.plain)
            .foregroundStyle(Color(red: 0.89, green: 0.91, blue: 0.94))
            .accessibilityLabel(isPlaying ? "暂停" : "播放")

            VStack(alignment: .leading, spacing: 4) {
                GeometryReader { geo in
                    ZStack(alignment: .leading) {
                        RoundedRectangle(cornerRadius: 6)
                            .fill(Color.white.opacity(0.06))

                        HStack(alignment: .bottom, spacing: 1) {
                            ForEach(Array(bars.enumerated()), id: \.offset) { _, height in
                                RoundedRectangle(cornerRadius: 1)
                                    .fill(Color(red: 0.22, green: 0.74, blue: 0.97))
                                    .frame(maxWidth: .infinity)
                                    .frame(height: max(4, geo.size.height * 0.82 * height))
                            }
                        }
                        .padding(.vertical, 2)
                        .opacity(0.85)

                        if let clipRange, duration > 0 {
                            let left = clipRange.start / duration
                            let width = max(0, (clipRange.end - clipRange.start) / duration)
                            RoundedRectangle(cornerRadius: 4)
                                .fill(Color.yellow.opacity(0.28))
                                .overlay(
                                    RoundedRectangle(cornerRadius: 4)
                                        .stroke(Color.yellow.opacity(0.7), lineWidth: 1)
                                )
                                .frame(width: geo.size.width * width)
                                .offset(x: geo.size.width * left)
                        }

                        Rectangle()
                            .fill(Color(red: 0.22, green: 0.74, blue: 0.97).opacity(0.28))
                            .frame(width: geo.size.width * progress)
                    }
                    .clipShape(RoundedRectangle(cornerRadius: 6))
                    .contentShape(Rectangle())
                    .gesture(
                        DragGesture(minimumDistance: 0)
                            .onChanged { value in
                                seek(at: value.location.x, width: geo.size.width)
                            }
                    )
                    .onTapGesture { location in
                        seek(at: location.x, width: geo.size.width)
                    }
                }
                .frame(height: 28)

                Text("\(Self.formatTime(currentTime)) / \(Self.formatTime(duration))")
                    .font(.system(size: 11, weight: .regular, design: .monospaced))
                    .foregroundStyle(Color(red: 0.58, green: 0.64, blue: 0.72))
            }
        }
        .padding(.horizontal, 12)
        .padding(.vertical, 6)
        .background(Color(red: 0.06, green: 0.09, blue: 0.16))
    }

    private func seek(at x: CGFloat, width: CGFloat) {
        guard width > 0, duration > 0 else { return }
        let ratio = min(1, max(0, Double(x / width)))
        onSeek(ratio * duration)
    }

    private static func formatTime(_ t: Double) -> String {
        guard t.isFinite, t >= 0 else { return "00:00" }
        let m = Int(t) / 60
        let s = Int(t) % 60
        return String(format: "%02d:%02d", m, s)
    }
}
