import SwiftUI
import FirebaseFunctions
import AVFoundation
import NukeUI

struct RemixSelectionView: View {
    @EnvironmentObject var appState: AppState
    @Environment(\.dismiss) private var dismiss

    @State private var prompt: String = ""
    @FocusState private var isTextFieldFocused: Bool
    @State private var isRecording: Bool = false
    @State private var audioLevels: [CGFloat] = [2, 2, 2, 2, 2]
    @State private var recordingTimer: Timer?
    
    let song: UploadedSong
    let onCoverSelected: () -> Void
    let onExtendSelected: () -> Void
    
    init(song: UploadedSong, onCoverSelected: @escaping () -> Void = {}, onExtendSelected: @escaping () -> Void = {}) {
        self.song = song
        self.onCoverSelected = onCoverSelected
        self.onExtendSelected = onExtendSelected
    }
    
    var body: some View {
        VStack(spacing: 0) {
            // Grabber - always at top
            Grabber()
            
            // Header
            Text("Remix")
                .font(Constants.Typography.largeTitle)
                .foregroundColor(Constants.Colors.Foreground.primary)
                .tracking(0.36)
                .padding(.top, 8)
                .padding(.bottom, 8)
            
            // Centered content area
            VStack {
                Spacer()
                
                // Header with artwork and title - centered in available space
                VStack(spacing: 16) {
                    LazyImage(url: song.imageURL == nil ? nil : URL(string: song.imageURL!)) { state in
                        if let image = state.image {
                            image.resizable()
                                .aspectRatio(contentMode: .fill)
                                .frame(width: 134, height: 134)
                        } else {
                            RoundedRectangle(cornerRadius: 20)
                                .foregroundStyle(.gray)
                        }
                    }
                    .clipShape(RoundedRectangle(cornerRadius: 20))
                    .frame(width: 134, height: 134)
                    
                    // Song and artist info
                    VStack(spacing: 4) {
                        Text(song.name)
                            .font(.system(size: 16, weight: .medium))
                            .foregroundColor(Constants.Colors.Foreground.primary)
                            .tracking(0.36)
                            .lineLimit(1)
                        
                        Text("by \(song.artistName)")
                            .font(.system(size: 14, weight: .regular))
                            .foregroundColor(.white.opacity(0.5))
                            .tracking(0.24)
                            .lineLimit(1)
                    }
                }
                
                Spacer()
            }
            .padding(.horizontal, 16)
            
            // Bottom section - fixed position above keyboard
            VStack(spacing: 16) {
                // Genre Pills Carousel
                genrePillsCarousel
                
                // Input Field with Inline Button
                VStack(spacing: 16) {
                    ZStack(alignment: .bottomTrailing) {
                        // Multiline Text Input Field
                        TextField("Describe your remix (i.e. make it hip hop)", text: $prompt, axis: .vertical)
                            .font(Constants.Typography.mediumRegular)
                            .foregroundColor(Constants.Colors.Foreground.primary)
                            .padding(16)
                            .padding(.trailing, 52) // Always pad for icon space
                            .background(Constants.Colors.Background.Fog.thin)
                            .clipShape(RoundedRectangle(cornerRadius: 28))
                            .overlay(
                                RoundedRectangle(cornerRadius: 28)
                                    .stroke(Constants.Colors.Border.primary, lineWidth: 1)
                            )
                            .lineLimit(1...4)
                            .focused($isTextFieldFocused)
                        
                        // Icons (microphone, waveform, or checkmark)
                        ZStack {
                            if isRecording {
                                // Audio waveform visualization during recording
                                HStack(spacing: 3) {
                                    ForEach(0..<audioLevels.count, id: \.self) { index in
                                        RoundedRectangle(cornerRadius: 2)
                                            .fill(Color.white)
                                            .frame(width: 3, height: audioLevels[index])
                                            .animation(.easeInOut(duration: 0.3), value: audioLevels[index])
                                    }
                                }
                                .padding(.trailing, 16)
                                .padding(.bottom, 16)
                                .transition(.scale(scale: 0.1).combined(with: .opacity))
                                .onTapGesture {
                                    stopRecording()
                                }
                            } else if prompt.isEmpty {
                                // Microphone icon when empty
                                Button(action: {
                                    startRecording()
                                }) {
                                    Image("Icon/microphone")
                                        .resizable()
                                        .aspectRatio(contentMode: .fit)
                                        .frame(width: 20, height: 20)
                                        .foregroundColor(Constants.Colors.Foreground.tertiary)
                                        .opacity(0.5)
                                }
                                .buttonStyle(PlainButtonStyle())
                                .padding(.trailing, 16)
                                .padding(.bottom, 16)
                                .transition(.scale(scale: 0.1).combined(with: .opacity))
                            } else {
                                // Circular Create Button when text is entered
                                Button(action: {
                                    generateRemix()
                                }) {
                                    ZStack {
                                        // Aura background image
                                        Image("aura")
                                            .resizable()
                                            .aspectRatio(contentMode: .fill)
                                            .frame(width: 36, height: 36)
                                             .clipped()
                                            .clipShape(Circle())
                                        
                                        // Check icon
                                        Image("Icon/check")
                                            .resizable()
                                            .aspectRatio(contentMode: .fit)
                                            .frame(width: 18, height: 18)
                                            .foregroundColor(.white)
                                    }
                                }
                                .buttonStyle(PlainButtonStyle())
                                .padding(.trailing, 8)
                                .padding(.bottom, 8)
                                .transition(.scale(scale: 0.1).combined(with: .opacity))
                            }
                        }
                    }
                    .animation(.easeInOut(duration: 0.15), value: prompt.isEmpty)
                }
            }
            .padding(.horizontal, 16)
            .padding(.bottom, 12) // 12px from keyboard
        }
        .animation(.none) // Disable all implicit animations
        .gesture(
            DragGesture()
                .onEnded { value in
                    // If user swipes down and keyboard is focused, dismiss the entire sheet
                    if value.translation.height > 50 && isTextFieldFocused {
                        dismiss()
                    }
                }
        )
        .onAppear {
            // Focus immediately for faster keyboard launch
            isTextFieldFocused = true
        }
        .task {
            // Additional immediate focus attempt
            isTextFieldFocused = true
        } .presentationDetents([.large])
            .presentationDragIndicator(.hidden)
            .presentationBackground(.ultraThinMaterial)
    }

    
    // MARK: - Genre Pills Carousel
    private var genrePillsCarousel: some View {
        ScrollView(.horizontal, showsIndicators: false) {
            HStack(spacing: 8) {
                ForEach(currentGenres, id: \.self) { genre in
                    GenrePill(genre: genre) {
                        addGenreToPrompt(genre)
                    }
                }
            }
            .padding(.horizontal, 16) // Match container padding for alignment
        }
        .padding(.horizontal, -16) // Break out to allow edge-to-edge scrolling
    }
    
    // Current genre suggestions that update based on selections
    @State private var currentGenres = [
        "Pop", "Rock", "Hip Hop", "Jazz", "Classical", "Electronic", 
        "Country", "R&B", "Reggae", "Folk", "Blues", "Funk"
    ]
    
    // Genre relationships for complementary suggestions
    private let genreRelationships: [String: [String]] = [
        "Pop": ["Dance", "Synth-pop", "Indie Pop", "Teen Pop", "Electropop", "Pop Rock"],
        "Rock": ["Alternative", "Indie Rock", "Pop Rock", "Blues Rock", "Hard Rock", "Classic Rock"],
        "Hip Hop": ["Trap", "Lo-fi", "Boom Bap", "Drill", "R&B", "Neo-Soul"],
        "Jazz": ["Smooth Jazz", "Bebop", "Fusion", "Swing", "Latin Jazz", "Contemporary"],
        "Classical": ["Orchestral", "Chamber", "Baroque", "Romantic", "Modern Classical", "Cinematic"],
        "Electronic": ["House", "Techno", "Ambient", "Synth-wave", "Trance", "Drum & Bass"],
        "Country": ["Folk", "Bluegrass", "Americana", "Country Rock", "Western", "Alt-Country"],
        "R&B": ["Neo-Soul", "Hip Hop", "Funk", "Contemporary R&B", "Smooth R&B", "Gospel"],
        "Reggae": ["Dancehall", "Dub", "Ska", "Reggaeton", "Island", "Afrobeat"],
        "Folk": ["Acoustic", "Indie Folk", "Country", "Americana", "Celtic", "World Music"],
        "Blues": ["Delta Blues", "Electric Blues", "Jazz Blues", "Soul", "Gospel", "Rock Blues"],
        "Funk": ["Disco", "R&B", "Soul", "Afrobeat", "Jazz Funk", "P-Funk"]
    ]
    
    // Add genre to prompt and update suggestions
    private func addGenreToPrompt(_ genre: String) {
        if prompt.isEmpty {
            prompt = genre.lowercased()
        } else {
            prompt += ", " + genre.lowercased()
        }
        
        // Update genre suggestions to show complementary genres
        updateGenreSuggestions(for: genre)
    }
    
    // Update genre suggestions based on selected genre
    private func updateGenreSuggestions(for selectedGenre: String) {
        withAnimation(.easeInOut(duration: 0.3)) {
            if let complementaryGenres = genreRelationships[selectedGenre] {
                currentGenres = complementaryGenres
            } else {
                // If no specific relationships, show a mix of popular complementary genres
                currentGenres = ["Chill", "Upbeat", "Acoustic", "Electronic", "Ambient", "Energetic"]
            }
        }
    }
    
    private func generateRemix() {
        guard !prompt.isEmpty else { return }

        // First dismiss the sheet with animation
        dismiss()

        // Wait for sheet dismiss animation to complete, then navigate
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
            appState.showOmniplayer = false
            appState.selectedTab = .library
        }

        let functions = Functions.functions()

        print("remixing songId=(\(song.id)) with prompt=(\(prompt))")
        // Call the generate_song cloud function with the actual song ID
        functions.httpsCallable("generate_song").call([
            "prompt": prompt,
            "remixOfId": song.id
        ]) { result, error in
            DispatchQueue.main.async {
                if let error = error as NSError? {
                    print("❌ Error generating remix for song \(song.id): \(error.localizedDescription)")
                    // Could show toast/alert for error handling
                    return
                }

                if let data = result?.data as? [String: Any],
                   let songIds = data["songIds"] as? [String] {
                    print("✅ Successfully generated remix with IDs: \(songIds) from song: \(song.id)")
                    // Songs will appear in library when they're ready
                } else {
                    print("❌ Failed to generate remix")
                    // Could show toast/alert for error handling
                }
            }
        }
    }
    
    // MARK: - Audio Recording Functions
    private func startRecording() {
        isRecording = true
        
        // Request microphone permission
        AVAudioApplication.requestRecordPermission { granted in
            DispatchQueue.main.async {
                if granted {
                    // Start waveform animation
                    startWaveformAnimation()
                } else {
                    // Handle permission denied
                    isRecording = false
                    print("Microphone permission denied")
                }
            }
        }
    }
    
    private func stopRecording() {
        isRecording = false
        recordingTimer?.invalidate()
        recordingTimer = nil
        
        // Reset waveform to flat
        audioLevels = [2, 2, 2, 2, 2]
        
        // Here you would process the recorded audio and convert to text
        // For now, just set some placeholder text
        prompt = "Recorded audio prompt"
    }
    
    private func startWaveformAnimation() {
        recordingTimer = Timer.scheduledTimer(withTimeInterval: 0.2, repeats: true) { _ in
            // Generate smoother, more realistic audio waveform animation
            withAnimation(.easeInOut(duration: 0.3)) {
                audioLevels = audioLevels.enumerated().map { index, currentLevel in
                    // Create smoother transitions by limiting height changes
                    let targetHeight = CGFloat.random(in: 6...16)
                    let maxChange: CGFloat = 4
                    let difference = targetHeight - currentLevel
                    let actualChange = max(-maxChange, min(maxChange, difference))
                    return max(4, min(18, currentLevel + actualChange))
                }
            }
        }
    }
}

// MARK: - Prompt Suggestion Pill Component
struct PromptSuggestionPill: View {
    let prompt: String
    let action: () -> Void
    
    var body: some View {
        Button(action: action) {
            Text(prompt)
                .font(Constants.Typography.small)
                .foregroundColor(Constants.Colors.Foreground.tertiary)
                .tracking(0.28)
                .multilineTextAlignment(.leading)
                .lineLimit(2)
                .padding(.leading, 12)
                .padding(.top, 16)
                .padding(.trailing, 12)
                .padding(.bottom, 16)
                .frame(width: 150, height: 74, alignment: .topLeading)
                .background(Constants.Colors.Background.Fog.thin)
                .overlay(
                    RoundedRectangle(cornerRadius: 20)
                        .stroke(Constants.Colors.Border.primary, lineWidth: 1)
                )
                .clipShape(RoundedRectangle(cornerRadius: 20))
        }
        .buttonStyle(PlainButtonStyle())
    }
}

// MARK: - Genre Pill Component
struct GenrePill: View {
    let genre: String
    let action: () -> Void
    
    var body: some View {
        Button(action: action) {
            HStack(spacing: 4) {
                Image("Icon/plus")
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                    .frame(width: 16, height: 16)
                    .foregroundColor(Constants.Colors.Foreground.primary)
                
                Text(genre.lowercased())
                    .font(Constants.Typography.small)
                    .foregroundColor(Constants.Colors.Foreground.primary)
                    .tracking(0.28)
            }
            .padding(.horizontal, 16)
            .padding(.vertical, 8)
            .background(Constants.Colors.Background.Fog.thin)
            .overlay(
                RoundedRectangle(cornerRadius: 100)
                    .stroke(Constants.Colors.Border.primary, lineWidth: 1)
            )
            .clipShape(RoundedRectangle(cornerRadius: 100))
        }
        .buttonStyle(PlainButtonStyle())
    }
}

struct RemixOption: View {
    let iconName: String
    let title: String
    let description: String
    let action: () -> Void
    let isLast: Bool
    
    init(iconName: String, title: String, description: String, action: @escaping () -> Void, isLast: Bool = false) {
        self.iconName = iconName
        self.title = title
        self.description = description
        self.action = action
        self.isLast = isLast
    }
    
    var body: some View {
        Button(action: action) {
            HStack(spacing: 10) {
                // Icon
                Image(iconName)
                    .resizable()
                    .frame(width: 24, height: 24)
                    .foregroundColor(Constants.Colors.Foreground.primary)
                
                // Title and Description
                VStack(alignment: .leading, spacing: 0) {
                    Text(title)
                        .font(Constants.Typography.mediumTitle)
                        .foregroundColor(Constants.Colors.Foreground.primary)
                        .tracking(0.32)
                        .frame(maxWidth: .infinity, alignment: .leading)
                    
                    Text(description)
                        .font(Constants.Typography.xSmallRegular)
                        .foregroundColor(Constants.Colors.Foreground.tertiary)
                        .tracking(0.24)
                        .frame(maxWidth: .infinity, alignment: .leading)
                }
                
                // Chevron
                Image("Icon/chevron-right")
                    .resizable()
                    .frame(width: 16, height: 16)
                    .foregroundColor(Constants.Colors.Foreground.tertiary)
            }
            .padding(16)
        }
        .buttonStyle(PlainButtonStyle())
        
        // Divider (except for last item)
        if !isLast {
            Rectangle()
                .fill(Constants.Colors.Background.Fog.thick)
                .frame(height: 1)
                .padding(.leading, 50) // Align with text content
        }
    }
}

#Preview {
    RemixSelectionView(song: 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"
    ))
}
