import APIClient
import AVFoundation
import ComponentLibrary
import ComposableArchitecture
import SwiftUI

struct EditClipPlayerProgressBar: View {
    let store: StoreOf<EditClipPlayer>
    var progress: Double
    var clip: Clip
    var highlightedPortionStart: Double
    var highlightedPortionEnd: Double
    let width: CGFloat
    let totalTime: Double
    let height: CGFloat = 4

    public init(store: StoreOf<EditClipPlayer>, clip: Clip, width: CGFloat) {
        self.store = store
        self.clip = clip
        self.totalTime = store.currentClipTotalTimeSeconds
        self.width = width
        self.highlightedPortionStart = clip.history?.rootClipContinueAt ?? totalTime
        self.highlightedPortionEnd = totalTime
        self.progress = min(store.rootClipItem.clip.duration + store.currentClipTotalTimeSeconds, max(0, store.elapsedTime.seconds))
    }

    var body: some View {
        ZStack(alignment: .leading) {
            Color.SemanticV1.textTertiary
                .frame(width: width)
                .frame(height: height)
            Color.SemanticV1.backgroundInvert
                .frame(width: progress / totalTime * width, height: height, alignment: .leading)
        }
        .frame(width: width)
        .animation(nil, value: store.isScrubbing)
        .scaleEffect(
            x: store.isScrubbing ? 1.01 : 1,
            y: store.isScrubbing ? 2 : 1
        )
        .animation(.default, value: store.isScrubbing)
        .contentShape(.rect)
        .gesture(drag)
    }

    private var drag: some Gesture {
        DragGesture(minimumDistance: 0)
            .onChanged { value in
                if !store.isScrubbing {
                    // Only trigger haptics when we start, not on every change
                    UIImpactFeedbackGenerator(style: .light).impactOccurred()
                }
                store.send(.binding(.set(\.scrub, .scrubbing(value.time(totalTime: totalTime, progressWidth: width)))))
            }
            .onEnded { value in
                UIImpactFeedbackGenerator(style: .light).impactOccurred()
                store.send(.binding(.set(\.scrub, .complete(value.time(totalTime: totalTime, progressWidth: width)))))
            }
    }
}

private extension DragGesture.Value {
    func time(totalTime: Double, progressWidth: CGFloat) -> CMTime {
        let percentage = location.x / progressWidth
        return CMTime(seconds: totalTime * percentage, preferredTimescale: CMTimeScale(1000))
    }
}
