import SwiftUI
import NukeUI

struct LibrarySongRow: View {
    let song: UploadedSong
    let playlist: [UploadedSong]
    let showRemixIcon: Bool
    
    @Environment(AudioManager.self) var audioManager

    var showOriginalArtist: Artist? = nil
    var onRemix: (UploadedSong) -> Void = { _ in }

    @State private var barHeights: [CGFloat] = [4, 4, 4]
    @State private var animationTimer: Timer?

    private var isPlaying: Bool {
        audioManager.currentlyPlayingSong?.id == song.id && audioManager.isCurrentlyPlaying
    }
    
    private var isCurrentSong: Bool {
        audioManager.currentlyPlayingSong?.id == song.id
    }

    var body: some View {
        Button(action: {
            // Play from playlist when the row is tapped
            if let songIndex = playlist.firstIndex(where: { $0.id == song.id }) {
                audioManager.playPlaylist(playlist, startingAt: songIndex)
            } else {
                // Fallback to single song if not found in playlist
                audioManager.playPlaylist([song], startingAt: 0)
            }
        }) {
            HStack(alignment: .center, spacing: 12) {
                // Album Artwork
                ZStack {
                    let status = song.status?.lowercased()
                    if status == "error" {
                        // Error state: show error icon
                        ZStack {
                            LinearGradient(
                                gradient: Gradient(colors: [
                                    Constants.Palette.Vermilion._600,
                                    Constants.Colors.Accent.error
                                ]),
                                startPoint: .topLeading,
                                endPoint: .bottomTrailing
                            )
                            Image(systemName: "exclamationmark.octagon.fill")
                                .font(.system(size: 24, weight: .bold))
                                .foregroundColor(Constants.Colors.Foreground.onError)
                        }
                    } else if status == "queued" || status == "generating" {
                        // Queued/Generating state: show loading spinner
                        ZStack {
                            LinearGradient(
                                gradient: Gradient(colors: [
                                    Constants.Palette.Dumbo._200,
                                    Constants.Palette.Dumbo._300
                                ]),
                                startPoint: .topLeading,
                                endPoint: .bottomTrailing
                            )
                            ProgressView()
                                .progressViewStyle(CircularProgressViewStyle(tint: Constants.Colors.Accent.brand))
                        }
                    } else if let imageURL = song.imageURL, !imageURL.isEmpty {
                        LazyImage(url: URL(string: imageURL)) { state in
                            if let image = state.image {
                                image
                                    .resizable()
                                    .aspectRatio(contentMode: .fill)
                            } else {
                                placeholderView
                            }
                        }
                        .processors([.resize(size: .init(width: 52, height: 52), unit: .points, contentMode: .aspectFill, crop: true, upscale: true)])
                        .frame(width: 52, height: 52)
                        .fixedSize()
                    } else {
                        placeholderView
                    }
                }
                .frame(width: 52, height: 52)
                .clipShape(RoundedRectangle(cornerRadius: 8))
                
                // Song Info
                VStack(alignment: .leading, spacing: song.promptForDisplay.isEmpty ? 0 : 4) {
                    HStack(spacing: 6) {
                        // Small sound waves animation when current song
                        if isCurrentSong {
                            HStack(spacing: 2) {
                                ForEach(0..<3, id: \.self) { index in
                                    RoundedRectangle(cornerRadius: 1)
                                        .fill(Constants.Colors.Accent.brand)
                                        .frame(width: 2)
                                        .frame(height: barHeights[index])
                                        .animation(.easeOut(duration: 0.15), value: barHeights[index])
                                }
                            }
                            .onAppear {
                                if isPlaying {
                                    startAudioVisualization()
                                }
                            }
                            .onChange(of: isPlaying) { _, newValue in
                                if newValue {
                                    startAudioVisualization()
                                } else {
                                    stopAudioVisualization()
                                }
                            }
                            .onDisappear {
                                stopAudioVisualization()
                            }
                        }
                        
                        Text(song.name)
                            .font(Constants.Typography.smallTitle)
                            .foregroundColor(
                                isCurrentSong
                                ? Constants.Colors.Accent.brand 
                                : Constants.Colors.Foreground.primary
                            )
                            .lineLimit(1)
                            .animation(.none, value: isCurrentSong)
                    }

                    if let showOriginalArtist {
                        HStack(spacing: 4) {
                            Text(showOriginalArtist.displayName)
                                .font(Constants.Typography.small)
                                .foregroundStyle(Constants.Colors.Foreground.secondary)
                                .lineLimit(1)
                            Image("Icon/remix")
                                .resizable()
                                .renderingMode(.template)
                                .foregroundColor(Constants.Colors.Foreground.tertiary)
                                .frame(width: 16, height: 16)
                                .opacity(0.8)
                            Text("\(song.artistName)")
                                .font(Constants.Typography.small)
                                .foregroundStyle(Constants.Colors.Foreground.secondary)
                                .lineLimit(1)
                        }
                    } else if !song.promptForDisplay.isEmpty {
                        Text(song.promptForDisplay)
                            .font(Constants.Typography.small)
                            .foregroundColor(Constants.Colors.Foreground.tertiary)
                            .lineLimit(1)
                    }
                }
                .frame(maxHeight: .infinity, alignment: .center)
                
                Spacer()
                
                if showRemixIcon {
                    Button {
                        onRemix(song)
                    } label: {
                        Image("Icon/remix")
                            .renderingMode(.template)
                            .foregroundColor(Constants.Colors.Foreground.tertiary)
                    }
                }
            }
            .padding(.horizontal, 16)
            .padding(.vertical, 8)
            .contentShape(Rectangle())
        }
        .buttonStyle(PlainButtonStyle())
        .disabled((song.status?.lowercased() == "error") || (song.status?.lowercased() == "queued"))
    }
    
    private func startAudioVisualization() {
        // Start with flat state
        barHeights = [4, 4, 4]
        
        // Create random, lifelike audio visualization
        animationTimer = Timer.scheduledTimer(withTimeInterval: 0.25, repeats: true) { _ in
            withAnimation(.easeOut(duration: 0.2)) {
                // Generate semi-random heights that feel like audio levels
                barHeights[0] = randomAudioHeight(baseHeight: 5, variation: 2)
                barHeights[1] = randomAudioHeight(baseHeight: 7, variation: 3) // Middle bar tends to be tallest
                barHeights[2] = randomAudioHeight(baseHeight: 6, variation: 2)
            }
            
            // Sometimes create a subtle "beat" effect where all bars spike slightly
            if Int.random(in: 1...40) == 1 {
                DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
                    withAnimation(.easeOut(duration: 0.15)) {
                        barHeights = [8, 10, 7]
                    }
                }
            }
        }
    }
    
    private func stopAudioVisualization() {
        animationTimer?.invalidate()
        animationTimer = nil
        
        // Animate to flat state
        withAnimation(.easeOut(duration: 0.3)) {
            barHeights = [4, 4, 4]
        }
    }
    
    private func randomAudioHeight(baseHeight: CGFloat, variation: CGFloat) -> CGFloat {
        let randomVariation = CGFloat.random(in: -variation...variation)
        return max(3, baseHeight + randomVariation) // Minimum height of 3
    }
    
    private var placeholderView: some View {
        ZStack {
            // Background gradient
            LinearGradient(
                gradient: Gradient(colors: [
                    Color(hex: "#FF006E"),
                    Color(hex: "#8338EC")
                ]),
                startPoint: .topLeading,
                endPoint: .bottomTrailing
            )
            
            // Music note icon
            Image(systemName: "music.note")
                .font(.system(size: 24, weight: .bold))
                .foregroundColor(.white.opacity(0.8))
        }
    }
}

#Preview {
    let previewSongs = [
        UploadedSong(
            id: "1",
            name: "Amazing Song Title That's Pretty Long",
            artistName: "Taylor Swift",
            artistId: "artist1",
            createdAt: .now,
            imageURL: nil,
            audioURL: "https://example.com/song.mp3",
            originalPrompt: "upbeat pop song about summer",
            rewrittenPrompt: nil
        ),
        UploadedSong(
            id: "2",
            name: "Another Great Song",
            artistName: "The Weeknd",
            artistId: "artist2",
            createdAt: .now,
            imageURL: nil,
            audioURL: nil,
            originalPrompt: "dark moody R&B track",
            rewrittenPrompt: "R&B, dark, moody, soulful vocals, catchy chorus"
        )
    ]
    
    VStack(spacing: 0) {
        LibrarySongRow(
            song: previewSongs[0],
            playlist: previewSongs,
            showRemixIcon: true
        )
        
        LibrarySongRow(
            song: previewSongs[1],
            playlist: previewSongs,
            showRemixIcon: true
        )
    }
    .background(Constants.Colors.Background.primary)
}

