import SwiftUI
import Combine

struct SongDescription: View {
    @Binding var description: String
    @State private var showLyrics: Bool = false
    @State private var isInstrumental: Bool = false
    @State private var keyboardHeight: CGFloat = 0
    @FocusState private var isTextFieldFocused: Bool
    @State private var currentPlaceholderIndex = 0
    @State private var placeholderOpacity: Double = 1.0
    
    let placeholder: String
    let autoFocus: Bool
    let height: CGFloat
    let onDescriptionChange: ((String) -> Void)?
    
    private let placeholderTexts = [
        "Make a song about getting ghosted at the airport before a trip.",
        "Make a song about catching feelings for my best friend.",
        "Make a song about a wild night my friends won’t forget.",
        "Make a song about a breakup where sunsets were our only bond.",
        "Make a song about skipping work to party on the beach."
    ]
    
    init(description: Binding<String>, placeholder: String = "type something", autoFocus: Bool = false, height: CGFloat = 180, onDescriptionChange: ((String) -> Void)? = nil) {
        self._description = description
        self.placeholder = placeholder
        self.autoFocus = autoFocus
        self.height = height
        self.onDescriptionChange = onDescriptionChange
    }
    
    var body: some View {
        VStack(spacing: 0) {
            // Background container
            VStack(spacing: 0) {
                // Header section
                VStack(spacing: 0) {
                    // Title and dice icon
                    HStack {
                        Text("Song description")
                            .font(Constants.Typography.smallTitle)
                            .foregroundColor(Constants.Colors.Foreground.primary)
                        
                        Spacer()
                        
                        Button(action: {
                            // Generate random description action
                            let randomPrompt = placeholderTexts.randomElement() ?? placeholderTexts[0]
                            description = randomPrompt
                            onDescriptionChange?(randomPrompt)
                        }) {
                            Image("Icon/dice")
                                .resizable()
                                .renderingMode(.template)
                                .foregroundColor(Constants.Colors.Foreground.primary)
                                .frame(width: 16, height: 16)
                        }
                        .frame(width: 40, height: 40)
                        .background(Constants.Colors.Background.Glass.thin)
                        .clipShape(Circle())
                    }
                    .padding(.horizontal, 16)
                    .padding(.top, 16)
                    .padding(.bottom, 8)
                    
                    // Text input area with dynamic height
                    HStack {
                        ZStack(alignment: .topLeading) {
                            if description.isEmpty {
                                Text(placeholderTexts[currentPlaceholderIndex])
                                    .font(Constants.Typography.mediumRegular)
                                    .foregroundColor(Constants.Colors.Background.Fog.dense)
                                    .allowsHitTesting(false)
                                    .frame(maxHeight: .infinity, alignment: .top)
                                    .opacity(placeholderOpacity)
                                    .animation(.easeInOut(duration: 0.5), value: placeholderOpacity)
                            }
                            
                            TextField("", text: $description, axis: .vertical)
                                .font(Constants.Typography.mediumRegular)
                                .foregroundColor(Constants.Colors.Foreground.primary)
                                .lineLimit(keyboardHeight > 0 ? 1...20 : 1...10)
                                .textFieldStyle(PlainTextFieldStyle())
                                .focused($isTextFieldFocused)
                                .keyboardType(.default)
                                .colorScheme(.dark)
                                .frame(maxHeight: .infinity, alignment: .top)
                        }
                        .frame(maxHeight: .infinity, alignment: .top)
                    }
                    .padding(.horizontal, 16)
                }
                

                // Bottom actions section
                HStack(alignment: .center) {
                    // Lyrics button
                    MediumButton(
                        title: "Lyrics",
                        iconAssetName: "Icon/plus",
                        action: {
                            showLyrics.toggle()
                        }
                    )
                    
                    Spacer()
                    
                    // Instrumental toggle
                    ToggleButton(title: "Instrumental", isOn: isInstrumental)
                }
                .frame(height: 40)
                .padding(16)
            }
            .background(Constants.Colors.Background.Fog.thin)
            .clipShape(RoundedRectangle(cornerRadius: 16))
            .frame(height: height)
        }
        .onReceive(Publishers.keyboardHeight) { height in
            keyboardHeight = height
        }
        .onAppear {
            if autoFocus {
                DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
                    isTextFieldFocused = true
                }
            }
            startPlaceholderCycling()
        }
        .onChange(of: description) { _, newValue in
            onDescriptionChange?(newValue)
        }
    }
    
    private func startPlaceholderCycling() {
        Timer.scheduledTimer(withTimeInterval: 3.0, repeats: true) { _ in
            // Only cycle if the description is empty (placeholder is visible)
            guard description.isEmpty else { return }
            
            // Fade out current placeholder
            withAnimation(.easeInOut(duration: 0.3)) {
                placeholderOpacity = 0.0
            }
            
            // After fade out, change text and fade in
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
                currentPlaceholderIndex = (currentPlaceholderIndex + 1) % placeholderTexts.count
                
                withAnimation(.easeInOut(duration: 0.3)) {
                    placeholderOpacity = 1.0
                }
            }
        }
    }
}

// MARK: - Keyboard Height Publisher
extension Publishers {
    static var keyboardHeight: AnyPublisher<CGFloat, Never> {
        let willShow = NotificationCenter.default.publisher(for: UIResponder.keyboardWillShowNotification)
            .map { notification in
                (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect)?.height ?? 0
            }
        
        let willHide = NotificationCenter.default.publisher(for: UIResponder.keyboardWillHideNotification)
            .map { _ in CGFloat(0) }
        
        return MergeMany(willShow, willHide)
            .eraseToAnyPublisher()
    }
}

// MARK: - Preview
#Preview {
    @Previewable @State var sampleDescription = ""
    
    VStack(spacing: 20) {
        SongDescription(description: $sampleDescription, placeholder: "a dreamy track about summer nights")
    }
    .padding()
    .background(Constants.Colors.Background.primary)
}
