import APIClient
import ComponentLibrary
import SwiftUI

struct VisualizerCompositeCard: View {
    let config: VisualizerAssetConfig
    let lyrics: LyricsDataV2
    let clipTitle: String
    let clipAuthorHandle: String
    let startTime: TimeInterval
    let endTime: TimeInterval
    let elapsedTime: TimeInterval
    let clipDuration: TimeInterval
    let isPlaying: Bool
    let currentTime: TimeInterval
    let isVisualInFocus: Bool
    let cardSize: CGSize
    let onTimeUpdate: (String, TimeInterval, TimeInterval) -> Void

    var body: some View {
        Color.clear
            .background {
                graphic
            }
            .overlay {
                stickerOverlay
                lyricsOverlay
            }
            .frame(width: cardSize.width, height: cardSize.height)
            .opacity(isVisualInFocus ? 1.0 : 0.5)
            .animation(.easeInOut(duration: 0.3), value: isVisualInFocus)
    }
}

private extension VisualizerCompositeCard {
    var graphic: some View {
        VisualizerGraphic(
            size: cardSize,
            isPlaying: isVisualInFocus,
            overrideTime: .zero,
            videoGravity: .resizeAspectFill,
            assetConfig: config
        )
    }

    @ViewBuilder
    var stickerOverlay: some View {
        VisualizerGalleryPreviewOverlay(
            clipTitle: clipTitle,
            clipAuthor: clipAuthorHandle,
            currentTime: currentTime,
            clipDuration: clipDuration,
            frameSize: .init(width: cardSize.width, height: cardSize.height),
            assetConfig: config
        )
    }

    @ViewBuilder
    var lyricsOverlay: some View {
        let lyricsStyle = config.shareAssetConfig.lyricsStyle
        var lyricsOverlayPreset: LyricsPreset {
            switch lyricsStyle {
            case .none:
                return .blankTimeUpdateOnly
            case .lyricsBox:
                return .block(maxLines: 3)
            case .lyricsTwoLine:
                return .twoLine
            case .lyricsThreeLine:
                return .threeLine
            }
        }
        var lyricsFontSize: CGFloat {
            switch lyricsStyle {
            case .none:
                return 0.0001
            case .lyricsBox:
                return cardSize.width * 0.06
            case .lyricsTwoLine, .lyricsThreeLine:
                return cardSize.width * 0.05
            }
        }

        /*
            Bit of a tricky setup, only one lyrics overlay should be playing at a time.
            Lyrics overlay delta via onTimeUpdate is what advances lyrics + selection cursor
         */
        LyricsOverlay(
            id: config.id,
            size: cardSize,
            lyricLines: lyrics.lines,
            startTime: startTime,
            endTime: endTime,
            elapsedTime: elapsedTime,
            preset: lyricsOverlayPreset,
            fontResource: .ppNeueMontrealBold,
            fontSize: lyricsFontSize,
            maxLineWidth: cardSize.width * 0.8,
            isPaused: !isVisualInFocus,
            onTimeUpdate: onTimeUpdate
        )
        .opacity(isVisualInFocus ? 1.0 : 0.0)
    }
}
