import SwiftUI
import AVFoundation
import ComposableArchitecture

public struct ExtendWaveformTrimmer: View {
    @Binding var selectionEnd: Double
    @State private var isDraggingEndHandle = false
    @State private var originalSelectionEnd: Double = 0
    @State private var isDraggingPlaybackIndicator = false
    @State private var hasSentPlaybackScrubStart = false
    @State private var originalPlaybackX: CGFloat = 0
    
    let onSelectionChanged: ((Double) -> Void)?
    let totalDuration: TimeInterval
    let elapsedTime: Double?
    let isScrubbing: Bool
    let extendTimestamp: Double?
    let onPlaybackScrubbing: ((CustomCreatePlayer.Action.ScrubbingAction) -> Void)?
    let onPlaybackReachedExtendTimestamp: (() -> Void)?
    let waveformData: [Float]
    
    private let placeholderWaveformData: [Double] = [
        0.28, 0.47, 0.22, 0.19, 0.67, 0.87, 0.38, 0.76, 0.09, 0.49, 0.18, 0.66, 0.99, 0.38, 0.46, 0.24,
        0.96, 0.27, 0.37, 0.52, 0.73, 0.93, 0.94, 0.32, 0.68, 0.93, 0.24, 0.01, 0.58, 0.75, 0.29, 0.33,
        0.72, 0.57, 0.43, 0.79, 0.02, 0.42, 0.52, 0.55, 0.72, 0.88, 0.59, 0.14, 0.57, 0.92, 0.58, 0.52,
        0.88, 0.53, 0.67, 0.47, 0.59, 0.09, 0.94, 0.80, 0.01, 0.79, 0.31, 0.97, 0.91, 0.46, 0.87, 0.03,
        0.04, 0.98, 0.29, 0.03, 0.58, 0.37, 0.83, 0.46, 0.82, 0.80, 0.53, 0.82, 0.14, 0.55, 0.75, 0.35,
        0.62, 0.03, 0.91, 0.52, 0.04, 0.55, 0.99, 0.54, 0.17, 0.99, 0.35, 0.54, 0.91, 0.54, 0.06, 0.70,
        0.33, 0.57, 0.27, 0.40, 0.47, 0.29, 0.85, 0.44, 0.20, 0.97, 0.57, 0.68, 0.20, 0.47, 0.01, 0.48,
        0.43, 0.59, 0.24, 0.73, 0.72, 0.32, 0.85, 0.47, 0.69, 0.73, 0.42, 0.63, 0.33, 0.39, 0.24, 0.98
    ]
    
    public init(
        selectionEnd: Binding<Double>,
        totalDuration: TimeInterval,
        elapsedTime: Double? = nil,
        isScrubbing: Bool = false,
        extendTimestamp: Double? = nil,
        waveformData: [Float] = [],
        onSelectionChanged: ((Double) -> Void)? = nil,
        onPlaybackScrubbing: ((CustomCreatePlayer.Action.ScrubbingAction) -> Void)? = nil,
        onPlaybackReachedExtendTimestamp: (() -> Void)? = nil
    ) {
        self._selectionEnd = selectionEnd
        self.totalDuration = totalDuration
        self.elapsedTime = elapsedTime
        self.isScrubbing = isScrubbing
        self.extendTimestamp = extendTimestamp
        self.waveformData = waveformData
        self.onSelectionChanged = onSelectionChanged
        self.onPlaybackScrubbing = onPlaybackScrubbing
        self.onPlaybackReachedExtendTimestamp = onPlaybackReachedExtendTimestamp
    }
    
    private func formatTime(_ seconds: TimeInterval) -> String {
        let minutes = Int(seconds) / 60
        let remainingSeconds = Int(seconds) % 60
        return String(format: "%d:%02d", minutes, remainingSeconds)
    }
    
    public var body: some View {
        GeometryReader { geometry in
            let cornerRadius: CGFloat = 12
            let padding: CGFloat = 12
            let maxWaveHeight: CGFloat = 48
            let minWaveHeight: CGFloat = 8
            let barWidth: CGFloat = 3
            let spacing: CGFloat = 3
            
            let availableWidth = geometry.size.width - (padding * 2)
            let totalBarAndSpacingWidth = barWidth + spacing
            let maxBars = max(0, Int(availableWidth / totalBarAndSpacingWidth))
            let visiblePlaceholderData = Array(placeholderWaveformData.prefix(maxBars))
            
            ZStack {
                RoundedRectangle(cornerRadius: cornerRadius)
                    .fill(Color.clear)
                    .overlay(
                        RoundedRectangle(cornerRadius: cornerRadius)
                            .stroke(Color.FigmaMCP.Semantic.borderPrimary, lineWidth: 1)
                    )
                
                if waveformData.isEmpty {
                    HStack(spacing: spacing) {
                        ForEach(Array(visiblePlaceholderData.enumerated()), id: \.offset) { index, amplitude in
                            let barPositionInWaveform = Double(index) / Double(visiblePlaceholderData.count)
                            let waveformStart = Double(padding) / Double(geometry.size.width)
                            let waveformEnd = Double(geometry.size.width - padding) / Double(geometry.size.width)
                            let waveformWidth = waveformEnd - waveformStart
                            let barPositionInContainer = waveformStart + (barPositionInWaveform * waveformWidth)
                            let isInSelection = barPositionInContainer <= selectionEnd
                            
                            RoundedRectangle(cornerRadius: 100)
                                .fill(isInSelection ? Color.white.opacity(0.2) : Color.white.opacity(0.1))
                                .frame(width: barWidth, height: max(minWaveHeight, amplitude * maxWaveHeight))
                        }
                    }
                    .padding(padding)
                } else {
                    SimpleWaveformShape(
                        waveformData: waveformData,
                        width: availableWidth,
                        height: maxWaveHeight,
                        selectionEnd: selectionEnd
                    )
                    .padding(padding)
                }
                
                playbackIndicator(geometry: geometry)
                
                selectionOverlay(geometry: geometry)
                
                tooltipOverlay(geometry: geometry)
            }
        }
        .frame(height: 80)
    }
    
    private func playbackIndicator(geometry: GeometryProxy) -> some View {
        let currentTime = elapsedTime ?? 0.0
        let totalWidth = geometry.size.width
        let playbackProgress = min(1.0, max(0.0, currentTime / totalDuration))
        let playbackX = playbackProgress * totalWidth
        let selectionWidth = selectionEnd * totalWidth
        
        if playbackX > selectionWidth {
            return AnyView(EmptyView())
        }
        
        return AnyView(playbackIndicatorContent(
            geometry: geometry,
            playbackX: playbackX,
            selectionWidth: selectionWidth,
            totalWidth: totalWidth
        ))
    }
    
    private func playbackIndicatorContent(
        geometry: GeometryProxy,
        playbackX: CGFloat,
        selectionWidth: CGFloat,
        totalWidth: CGFloat
    ) -> some View {
        let indicatorWidth: CGFloat = 2
        let indicatorHeight = geometry.size.height
        let centerY = geometry.size.height / 2
        
        return ZStack {
            RoundedRectangle(cornerRadius: 1)
                .fill(Color.white)
                .frame(width: indicatorWidth, height: indicatorHeight)
                .shadow(color: .black.opacity(0.3), radius: 1.5, x: 0, y: 0)
                .position(x: playbackX, y: centerY)
                .mask(
                    UnevenRoundedRectangle(
                        topLeadingRadius: 12,
                        bottomLeadingRadius: 12,
                        bottomTrailingRadius: 0,
                        topTrailingRadius: 0
                    )
                    .frame(width: selectionWidth, height: indicatorHeight)
                    .position(x: selectionWidth/2, y: centerY)
                )
                .gesture(
                    DragGesture(minimumDistance: 0)
                        .onChanged { value in
                            if !isDraggingPlaybackIndicator {
                                isDraggingPlaybackIndicator = true
                                hasSentPlaybackScrubStart = false
                                originalPlaybackX = playbackX
                            }
                            
                            let newX = originalPlaybackX + value.translation.width
                            let clampedX = min(max(0, newX), selectionWidth)
                            let seconds = totalDuration * Double(clampedX / totalWidth)
                            
                            if !hasSentPlaybackScrubStart {
                                hasSentPlaybackScrubStart = true
                                onPlaybackScrubbing?(.beginScrubbing(seconds))
                            }
                            onPlaybackScrubbing?(.updateScrubbing(seconds))
                        }
                        .onEnded { value in
                            let newX = originalPlaybackX + value.translation.width
                            let clampedX = min(max(0, newX), selectionWidth)
                            let seconds = totalDuration * Double(clampedX / totalWidth)
                            onPlaybackScrubbing?(.endScrubbing(seconds))
                            isDraggingPlaybackIndicator = false
                            hasSentPlaybackScrubStart = false
                            originalPlaybackX = 0
                        }
                )
        }
    }
    
    @ViewBuilder
    private func selectionOverlay(geometry: GeometryProxy) -> some View {
        let totalWidth = geometry.size.width
        let selectionWidth = selectionEnd * totalWidth
        let handleWidth: CGFloat = 12
        let padding: CGFloat = 12
        
        let selectionBackground = UnevenRoundedRectangle(
            topLeadingRadius: 12,
            bottomLeadingRadius: 12,
            bottomTrailingRadius: 0,
            topTrailingRadius: 0
        )
        .fill(Color.FigmaMCP.Semantic.accentBrand.opacity(0.1))
        .frame(width: selectionWidth, height: geometry.size.height)
        
        let handle = UnevenRoundedRectangle(
            topLeadingRadius: 0,
            bottomLeadingRadius: 0,
            bottomTrailingRadius: 4,
            topTrailingRadius: 4
        )
        .fill(Color.FigmaMCP.Semantic.accentBrand)
        .frame(width: handleWidth, height: geometry.size.height + 1)
        
        ZStack {
            selectionBackground
                .position(x: selectionWidth/2, y: geometry.size.height/2)
                .allowsHitTesting(false)
            
            handle
                .position(x: selectionWidth, y: geometry.size.height/2)
                .gesture(
                    DragGesture(minimumDistance: 0)
                        .onChanged { value in
                            if !isDraggingEndHandle {
                                isDraggingEndHandle = true
                                originalSelectionEnd = selectionEnd
                            }
                            
                            let translation = value.translation.width / totalWidth
                            let newEnd = min(1.0, max(0.05, originalSelectionEnd + translation))
                            
                            selectionEnd = newEnd
                            onSelectionChanged?(newEnd)
                        }
                        .onEnded { _ in
                            isDraggingEndHandle = false
                        }
                )

            UnevenRoundedRectangle(
                topLeadingRadius: 12,
                bottomLeadingRadius: 12,
                bottomTrailingRadius: 0,
                topTrailingRadius: 0
            )
            .stroke(Color.FigmaMCP.Semantic.accentBrand, lineWidth: 1)
            .frame(width: selectionWidth, height: geometry.size.height)
            .position(x: selectionWidth/2, y: geometry.size.height/2)
            .allowsHitTesting(false)
        }
    }
    
    
    @ViewBuilder
    private func tooltipOverlay(geometry: GeometryProxy) -> some View {
        if isDraggingEndHandle {
            let totalWidth = geometry.size.width
            let selectionWidth = selectionEnd * totalWidth
            let endTime = selectionEnd * totalDuration
            SimpleTooltipView(text: formatTime(endTime), style: .timestamp)
                .position(x: selectionWidth, y: -20)
        }
    }
}

