import SwiftUI
import Metal

struct SongGenerationMessage: View {
    let message: String
    let lyrics: LyricsStructure?
    let songs: [Song]
    let suggestions: [String]
    let currentlyPlayingSongId: String?
    let currentlySelectedSongId: String?
    let isLastSongGeneration: Bool
    let onSuggestionTap: (String) -> Void
    let onPlayPause: (String) -> Void
    let onSongSelect: (String) -> Void
    let onExpand: (Int) -> Void
    let onLyricsExpand: () -> Void
    let onSeeMoreLyrics: () -> Void
    let onCreateMore: () -> Void
    let onAnimationComplete: (() -> Void)?
    
    let audioManager = AudioManager.shared
    @State var playbackProgress = AudioManager.shared.progress

    @State private var lyricsExpanded: Bool = false
    @State private var showMessage: Bool = false
    @State private var showLyrics: Bool = false
    @State private var showSongs: Bool = false
    @State private var typedMessage: String = ""
    @State private var hasAnimated: Bool = false
    
    var body: some View {
        VStack(alignment: .leading, spacing: message.isEmpty ? 0 : 16) {
            // Text Response with typing animation (only show if message has content)
            if !message.isEmpty && showMessage {
                IncomingMessage(message: typedMessage, shouldAnimate: false)
            }
            
            // Lyrics Section with fade in
            if let lyrics = lyrics, showLyrics {
                InlineLyrics(
                    lyrics: lyrics,
                    isExpanded: lyricsExpanded,
                    onExpandTap: onLyricsExpand,
                    onSeeMoreTap: {
                        withAnimation(.easeInOut(duration: 0.3)) {
                            lyricsExpanded.toggle()
                        }
                        onSeeMoreLyrics()
                    }
                )
                .opacity(showLyrics ? 1.0 : 0.0)
                .animation(.easeInOut(duration: 0.5), value: showLyrics)
            }
            
            // Songs Section with simple fade-in animation
            if !songs.isEmpty && showSongs {
                VStack(spacing: 16) {
                    HStack(spacing: 16) {
                        ForEach(Array(songs.enumerated()), id: \.offset) { index, song in
                            InlineChatPlayer(
                                songTitle: song.title,
                                genres: song.genres,
                                isPlaying: currentlyPlayingSongId == song.id && (audioManager.isCurrentlyPlaying ?? false),
                                isSelected: currentlySelectedSongId == song.id,
                                progress: (currentlyPlayingSongId == song.id) ? (playbackProgress.currentProgress ?? 0.0) : 0.0,
                                artworkGradient: createGradient(from: song.artwork),
                                onPlayPause: {
                                    onPlayPause(song.id)
                                },
                                onSelect: {
                                    onSongSelect(song.id)
                                },
                                onExpand: {
                                    onExpand(index)
                                },
                                onProgressChanged: { progress in
                                    // Handle scrubbing - seek to new position in audio
                                    if currentlyPlayingSongId == song.id {
                                        audioManager.seekToProgress(progress)
                                    }
                                    print("🎵 Scrubbing to position: \(progress)")
                                },
                                onScrubStart: {
                                    // Mute audio while scrubbing
                                    if currentlyPlayingSongId == song.id {
                                        audioManager.startScrubbing()
                                    }
                                },
                                onScrubEnd: {
                                    // Restore audio after scrubbing
                                    if currentlyPlayingSongId == song.id {
                                        audioManager.endScrubbing()
                                    }
                                },
                                onThumbsUp: {
                                    print("Thumbs up for song \(index)")
                                },
                                onThumbsDown: {
                                    print("Thumbs down for song \(index)")
                                },
                                onShare: {
                                    print("Share song \(index)")
                                },
                                onMore: {
                                    print("More options for song \(index)")
                                }
                            )
                            .transition(.opacity)
                        }
                    }
                    
                    // Create More Button (left-aligned) - only show on last song generation
                    if isLastSongGeneration {
                        HStack {
                            CreateMoreButton {
                                onCreateMore()
                            }
                            Spacer()
                        }
                    }
                }
                .opacity(showSongs ? 1.0 : 0.0)
                .animation(.easeInOut(duration: 0.5), value: showSongs)
            }
        }
        .onAppear {
            if !hasAnimated {
                hasAnimated = true
                startAnimationSequence()
            } else {
                // If already animated, show all content immediately
                showMessage = !message.isEmpty
                showLyrics = lyrics != nil
                showSongs = !songs.isEmpty
                typedMessage = message
            }
        }
    }
    
    private func startAnimationSequence() {
        // 1. Start typing animation immediately if there's a message
        if !message.isEmpty {
            showMessage = true
            startTypingAnimation()
        } else {
            // If no message, skip to lyrics
            startLyricsAnimation()
        }
    }
    
    private func startTypingAnimation() {
        let characters = Array(message)
        let totalDuration: Double = 0.8 // Fast typing - 0.8 seconds total
        let intervalPerCharacter = totalDuration / Double(characters.count)
        
        typedMessage = ""
        
        for (index, character) in characters.enumerated() {
            DispatchQueue.main.asyncAfter(deadline: .now() + intervalPerCharacter * Double(index)) {
                typedMessage += String(character)
                
                // When typing is complete, start lyrics animation
                if index == characters.count - 1 {
                    DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
                        startLyricsAnimation()
                    }
                }
            }
        }
    }
    
    private func startLyricsAnimation() {
        // 2. Fade in lyrics
        if lyrics != nil {
            withAnimation(.easeInOut(duration: 0.3)) {
                showLyrics = true
            }
            
            // 3. After lyrics fade in, fade in songs
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.6) {
                startSongsAnimation()
            }
        } else {
            // If no lyrics, skip to songs
            startSongsAnimation()
        }
    }
    
    private func startSongsAnimation() {
        // 3. Simple fade in animation for songs
        if !songs.isEmpty {
            withAnimation(.easeInOut(duration: 0.3)) {
                showSongs = true
            }
            
            // Trigger scroll after animation completes
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.4) {
                onAnimationComplete?()
            }
        } else {
            // If no songs, still trigger scroll after a short delay
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
                onAnimationComplete?()
            }
        }
    }
    
    private func createGradient(from artwork: String?) -> LinearGradient {
        guard let artwork = artwork else {
            // Default gradient
            return LinearGradient(
                colors: [
                    Color(red: 0.8, green: 0.4, blue: 0.9),
                    Color(red: 0.4, green: 0.6, blue: 1.0)
                ],
                startPoint: .topLeading,
                endPoint: .bottomTrailing
            )
        }
        
        // Create consistent gradient based on artwork string hash
        let hash = artwork.hashValue
        let seed1 = abs(hash % 1000)
        let seed2 = abs((hash / 1000) % 1000)
        
        return LinearGradient(
            colors: [
                Color(
                    red: 0.3 + (Double(seed1 % 600) / 1000.0),
                    green: 0.3 + (Double((seed1 + 200) % 600) / 1000.0),
                    blue: 0.3 + (Double((seed1 + 400) % 600) / 1000.0)
                ),
                Color(
                    red: 0.3 + (Double(seed2 % 600) / 1000.0),
                    green: 0.3 + (Double((seed2 + 200) % 600) / 1000.0),
                    blue: 0.3 + (Double((seed2 + 400) % 600) / 1000.0)
                )
            ],
            startPoint: .topLeading,
            endPoint: .bottomTrailing
        )
    }
}


#Preview {
    let sampleLyrics = LyricsStructure(sections: [
        LyricsSection(type: "Chorus", content: "My friend, my friend, a heart of gold\nA story whispered, never getting old\nThrough stormy weather, you're always there\nA bond unbreakable, beyond compare"),
        LyricsSection(type: "Verse 1", content: "In laughter and in tears we stand\nSide by side, hand in hand\nMemories we've made so true\nI'm grateful for a friend like you")
    ])
    
    let sampleSongs = [
        Song(title: "Best Friend Forever", genres: ["pop", "acoustic"], artwork: nil, audioURL: "song1"),
        Song(title: "Friendship Anthem", genres: ["rock", "upbeat"], artwork: nil, audioURL: "song2")
    ]
    
    let sampleSuggestions = ["Create more", "Extend", "Make it slower", "Add a bridge"]
    
    ScrollView {
        SongGenerationMessage(
            message: "I've created a beautiful song about friendship for you! Here are the lyrics and two different versions to choose from.",
            lyrics: sampleLyrics,
            songs: sampleSongs,
            suggestions: sampleSuggestions,
            currentlyPlayingSongId: nil,
            currentlySelectedSongId: sampleSongs.first?.id,
            isLastSongGeneration: true,
            onSuggestionTap: { suggestion in
                print("Suggestion tapped: \(suggestion)")
            },
            onPlayPause: { songId in
                print("Play/Pause song \(songId)")
            },
            onSongSelect: { songId in
                print("Select song \(songId)")
            },
            onExpand: { index in
                print("Expand song \(index)")
            },
            onLyricsExpand: {
                print("Expand lyrics")
            },
            onSeeMoreLyrics: {
                print("See more lyrics")
            },
            onCreateMore: {
                print("Create more tapped")
            },
            onAnimationComplete: {
                print("Animation complete")
            }
        )
        .padding()
    }
    .background(Constants.Colors.Background.primary)
}
