import React, { useState, useCallback, useEffect } from 'react';
import { v4 as uuidv4 } from 'uuid';

import './index.css';
import { useLayerGeneration } from './hooks/useLayerGeneration';
import { useAudioEngine } from './hooks/useAudioEngine';
import { useUserProfile } from './hooks/useUserProfile';
import { InstrumentLayer, Composition } from './utils/types';
import LayerStack from './components/LayerStack';
import InvitationModal from './components/InvitationModal';
import ShareModal from './components/ShareModal';

interface AppProps {
  sessionId?: string | null;
}

function App({ sessionId }: AppProps) {
  const [isLoadingSession, setIsLoadingSession] = useState(false);
  const [shareUrl, setShareUrl] = useState<string | null>(null);
  
  // Invitation state management
  const [showInvitationModal, setShowInvitationModal] = useState(false);
  const [inviterName, setInviterName] = useState<string | null>(null);
  const [sessionTitle, setSessionTitle] = useState<string | null>(null);
  
  // Share modal state management
  const [showShareModal, setShowShareModal] = useState(false);
  
  // Composition state management
  const [composition, setComposition] = useState<Composition>({
    id: uuidv4(),
    layers: [],
    masterVolume: 1,
    tempo: 120,
    style: '',
    isPlaying: false,
    currentTime: 0,
    duration: 0
  });
  
  const [promptText, setPromptText] = useState<string>('');
  const [keySignature, setKeySignature] = useState<string>('C major');
  const [sessionBpm, setSessionBpm] = useState<number>(120);
  const [sessionKey, setSessionKey] = useState<string>('C major');
  
  // Audio engine for mixing layers (must be before handleLayerUpdate)
  const {
    isPlaying,
    currentTime,
    duration,
    isLoading: audioLoading,
    play,
    stop,
    pause,
    resume,
    seekTo,
    setMasterVolume,
    setLayerVolume,
    setLayerMute,
    removeLayer: removeAudioLayer,
    loadLayer
  } = useAudioEngine();
  
  const handleLayerUpdate = useCallback(async (updatedLayer: InstrumentLayer) => {
    console.log('[UPDATE] Updating layer:', { 
      id: updatedLayer.id, 
      title: updatedLayer.title, 
      status: updatedLayer.status,
      audioUrl: !!updatedLayer.audioUrl
    });
    setComposition(prev => {
      const updatedLayers = prev.layers.map(layer => 
        layer.id === updatedLayer.id ? updatedLayer : layer
      );
      console.log('[UPDATE] Layers after update:', updatedLayers.map(l => ({ 
        id: l.id, 
        title: l.title, 
        status: l.status,
        audioUrl: !!l.audioUrl
      })));
      return {
        ...prev,
        layers: updatedLayers
      };
    });
  }, []);
  
  // Separate effect to handle audio loading
  const handleAudioLoading = useCallback(async (updatedLayer: InstrumentLayer) => {
    if (updatedLayer.status === 'ready' && updatedLayer.audioUrl) {
      try {
        const layerWithWaveform = await loadLayer(updatedLayer);
        if (layerWithWaveform) {
          // Update the layer with waveform data
          setComposition(prev => ({
            ...prev,
            layers: prev.layers.map(layer => 
              layer.id === updatedLayer.id ? layerWithWaveform : layer
            )
          }));
        }
      } catch (error) {
        console.error('Failed to load layer into audio engine:', error);
      }
    }
  }, [loadLayer]);
  
  const combinedLayerUpdate = useCallback(async (updatedLayer: InstrumentLayer) => {
    handleLayerUpdate(updatedLayer);
    await handleAudioLoading(updatedLayer);
    
    // Update the database if we're in a session and the layer is ready
    if (sessionId && updatedLayer.status === 'ready') {
      try {
        await fetch(`/api/sessions/${sessionId}/layers`, {
          method: 'PATCH',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({
            clipId: updatedLayer.id, // Using clipId as primary identifier
            audioUrl: updatedLayer.audioUrl,
            status: updatedLayer.status
          })
        });
      } catch (error) {
        console.error('Failed to update layer in database:', error);
      }
    }
  }, [handleLayerUpdate, handleAudioLoading, sessionId]);

  // Save layer to database when generated
  const saveLayerToSession = useCallback(async (layer: InstrumentLayer, currentSessionId: string) => {
    try {
      const response = await fetch(`/api/sessions/${currentSessionId}/layers`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          title: layer.title,
          prompt: layer.metadata.prompt,
          audioUrl: layer.audioUrl,
          clipId: layer.id, // Using id (which is now clipId) as the identifier
          status: layer.status,
          volume: layer.volume,
          muted: layer.muted
        })
      });
      
      if (!response.ok) {
        throw new Error('Failed to save layer');
      }
      
      return await response.json();
    } catch (error) {
      console.error('Failed to save layer to session:', error);
    }
  }, []);
  
  const { generateLayer, pollForCompletion, isGenerating, error } = useLayerGeneration(combinedLayerUpdate);
  
  // Get user profile for personalized invite links
  const { displayName: userDisplayName, isLoading: profileLoading } = useUserProfile();
  
  const handleGenerateLayer = async () => {
    if (!promptText.trim()) return;
    
    // Stop playback if currently playing
    if (isPlaying) {
      stop();
    }
    
    try {
      // If this is the first layer and we're not in a session, create session and redirect
      if (!sessionId && composition.layers.length === 0) {
        const response = await fetch('/api/sessions', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({
            bpm: composition.tempo,
            keySignature: keySignature
          })
        });
        
        if (response.ok) {
          const { sessionId: newSessionId } = await response.json();
          
          // Redirect to session with generation parameters
          const params = new URLSearchParams({
            generateFirst: 'true',
            prompt: promptText,
            bpm: composition.tempo.toString(),
            key: keySignature
          });
          window.location.href = `/session/${newSessionId}?${params.toString()}`;
          return;
        } else {
          throw new Error('Failed to create session');
        }
      }
      
      // If we're already in a session, generate normally
      const layer = await generateLayer({
        prompt: promptText,
        bpm: sessionId ? sessionBpm : composition.tempo,
        key: sessionId ? sessionKey : keySignature,
        duration: 30
      });
      
      // Add layer to composition
      console.log('[GENERATION] Adding new layer to composition:', { 
        id: layer.id, 
        title: layer.title, 
        status: layer.status,
        clipId: layer.clipId
      });
      setComposition(prev => {
        console.log('[GENERATION] Current layers before adding new one:', prev.layers.map(l => ({ 
          id: l.id, 
          title: l.title, 
          status: l.status
        })));
        const newLayers = [...prev.layers, layer];
        console.log('[GENERATION] Layers after adding new one:', newLayers.map(l => ({ 
          id: l.id, 
          title: l.title, 
          status: l.status
        })));
        return {
          ...prev,
          layers: newLayers
        };
      });
      
      // Save the processing layer to the session
      if (sessionId) {
        await saveLayerToSession(layer, sessionId);
      }
      
      // Clear the prompt input
      setPromptText('');
      
    } catch (err) {
      console.error('Failed to generate layer:', err);
    }
  };
  
  
  const handleBpmChange = (newBpm: number) => {
    setComposition(prev => ({ ...prev, tempo: newBpm }));
  };
  
  const handleRemoveLayer = async (layerId: string) => {
    // Remove from audio engine
    removeAudioLayer(layerId);
    
    // Remove from composition
    setComposition(prev => ({
      ...prev,
      layers: prev.layers.filter(layer => layer.id !== layerId)
    }));
    
    // Remove from database if in a session
    if (sessionId) {
      try {
        await fetch(`/api/sessions/${sessionId}/layers?clipId=${layerId}`, {
          method: 'DELETE'
        });
      } catch (error) {
        console.error('Failed to delete layer from database:', error);
      }
    }
  };
  
  
  // Master control handlers
  const handlePlay = () => {
    play(composition.layers);
  };
  
  const handleStop = () => {
    stop();
  };
  
  const handlePause = () => {
    pause();
  };
  
  const handleResume = () => {
    resume(composition.layers);
  };
  

  const handleSeek = useCallback(async (time: number) => {
    await seekTo(time, composition.layers);
  }, [seekTo, composition.layers]);

  const togglePlayPause = () => {
    if (isPlaying) {
      handlePause();
    } else if (composition.layers.some(layer => layer.status === 'ready')) {
      if (currentTime > 0) {
        handleResume();
      } else {
        handlePlay();
      }
    }
  };

  // Check for invitation parameters and show invitation modal
  useEffect(() => {
    if (sessionId && typeof window !== 'undefined') {
      const urlParams = new URLSearchParams(window.location.search);
      const inviter = urlParams.get('inviter');
      const invited = urlParams.get('invited');
      
      if (invited === 'true' && inviter) {
        setInviterName(decodeURIComponent(inviter));
        setSessionTitle('SUNO music session');
        setShowInvitationModal(true);
        // Keep URL parameters so people can access the session multiple times
      }
    }
  }, [sessionId]);

  // Check for generateFirst parameter and start generation
  useEffect(() => {
    if (sessionId && typeof window !== 'undefined') {
      const urlParams = new URLSearchParams(window.location.search);
      const shouldGenerateFirst = urlParams.get('generateFirst');
      const prompt = urlParams.get('prompt');
      const bpm = urlParams.get('bpm');
      const key = urlParams.get('key');
      
      if (shouldGenerateFirst === 'true' && prompt && bpm && key) {
        // Set the form values
        setPromptText(prompt);
        setSessionBpm(parseInt(bpm));
        setSessionKey(key);
        setKeySignature(key);
        setComposition(prev => ({ ...prev, tempo: parseInt(bpm) }));
        
        // Start generation after session loads (small delay to ensure session is loaded)
        setTimeout(async () => {
          try {
            const layer = await generateLayer({
              prompt: prompt,
              bpm: parseInt(bpm),
              key: key,
              duration: 30
            });
            
            // Add layer to composition
            setComposition(prev => ({
              ...prev,
              layers: [...prev.layers, layer]
            }));
            
            // Save the processing layer to the session
            await saveLayerToSession(layer, sessionId);
            
            // Clear the prompt input after generation
            setPromptText('');
            
            // Clean up URL parameters
            const newUrl = window.location.pathname;
            window.history.replaceState({}, '', newUrl);
            
          } catch (error) {
            console.error('Failed to generate first layer:', error);
          }
        }, 1000);
      }
    }
  }, [sessionId, generateLayer, saveLayerToSession]);

  // Function to load session data from database
  const loadSessionData = useCallback(async (isInitialLoad = false) => {
    if (!sessionId) return;
    
    if (isInitialLoad) {
      setIsLoadingSession(true);
    }
    
    try {
      const response = await fetch(`/api/sessions?id=${sessionId}`);
      const session = await response.json();
      
      if (session.error) {
        console.error('Failed to load session:', session.error);
        return;
      }
      
      // Convert database layers to app format using clipId as primary ID
      const dbLayers = session.layers.map((dbLayer: any) => {
        return {
          id: dbLayer.clipId, // Use clipId as primary ID
          instrumentType: 'other' as const,
          title: dbLayer.title,
          audioUrl: dbLayer.audioUrl,
          status: dbLayer.status || (dbLayer.audioUrl ? 'ready' : 'processing') as 'processing' | 'ready' | 'error',
          volume: dbLayer.volume,
          muted: dbLayer.muted,
          clipId: dbLayer.clipId,
          metadata: {
            prompt: dbLayer.prompt,
            gpt_description_prompt: dbLayer.prompt,
            tags: '',
            duration: undefined
          }
        };
      });
      
      // Debug: Log layer information
      if (!isInitialLoad) {
        console.log('[POLLING] Database layers:', dbLayers.map((l: InstrumentLayer) => ({ 
          id: l.id, 
          title: l.title, 
          status: l.status,
          audioUrl: !!l.audioUrl,
          clipId: l.clipId
        })));
      }
      
      // Only update session-level settings on initial load
      if (isInitialLoad) {
        setSessionBpm(session.bpm || 120);
        setSessionKey(session.keySignature || 'C major');
        setKeySignature(session.keySignature || 'C major');
      }
      
      setComposition(prev => {
        // For polling updates, completely replace with database layers (database is source of truth)
        if (!isInitialLoad) {
          console.log('[POLLING] Current local layers:', prev.layers.map(l => ({ 
            id: l.id, 
            title: l.title, 
            status: l.status,
            audioUrl: !!l.audioUrl,
            clipId: l.clipId
          })));
          
          // Database is the single source of truth - completely replace layers
          // But preserve audio buffers and waveform data from existing layers where possible
          const finalLayers = dbLayers.map((dbLayer: InstrumentLayer) => {
            const existingLayer = prev.layers.find(l => l.id === dbLayer.id);
            if (existingLayer && existingLayer.audioBuffer && existingLayer.waveformData) {
              console.log(`[POLLING] Preserving audio data for layer ${dbLayer.id}`);
              // Preserve audio buffer and waveform data but use database values for everything else
              return {
                ...dbLayer,
                audioBuffer: existingLayer.audioBuffer,
                waveformData: existingLayer.waveformData
              };
            } else {
              console.log(`[POLLING] Using fresh DB layer ${dbLayer.id}`);
              return dbLayer;
            }
          });
          
          // Load audio for new ready layers that don't have audio data yet
          finalLayers.forEach(async (layer: InstrumentLayer) => {
            if (layer.status === 'ready' && layer.audioUrl && !layer.audioBuffer && !layer.waveformData) {
              console.log(`[POLLING] Loading audio for new ready layer: ${layer.id}`);
              try {
                const layerWithWaveform = await loadLayer(layer);
                if (layerWithWaveform) {
                  console.log(`[POLLING] Successfully loaded waveform for layer: ${layer.id}`);
                  setComposition(prevComp => ({
                    ...prevComp,
                    layers: prevComp.layers.map(l => 
                      l.id === layer.id ? layerWithWaveform : l
                    )
                  }));
                }
              } catch (error) {
                console.error(`[POLLING] Error loading layer ${layer.id}:`, error);
              }
            }
          });

          console.log('[POLLING] Final layers (database source of truth):', finalLayers.map((l: InstrumentLayer) => ({ 
            id: l.id, 
            title: l.title, 
            status: l.status,
            audioUrl: !!l.audioUrl
          })));

          return {
            ...prev,
            layers: finalLayers
          };
        }
        
        // Initial load - set everything fresh
        return {
          ...prev,
          id: session.id,
          layers: dbLayers,
          tempo: session.bpm || 120
        };
      });
      
      // Only load audio on initial load
      if (isInitialLoad) {
        dbLayers.forEach(async (layer: InstrumentLayer) => {
          if (layer.status === 'ready' && layer.audioUrl) {
            try {
              const layerWithWaveform = await loadLayer(layer);
              if (layerWithWaveform) {
                setComposition(prev => ({
                  ...prev,
                  layers: prev.layers.map(l => 
                    l.id === layer.id ? layerWithWaveform : l
                  )
                }));
              }
            } catch (error) {
              console.error(`Error loading layer ${layer.id}:`, error);
              setComposition(prev => ({
                ...prev,
                layers: prev.layers.map(l => 
                  l.id === layer.id ? { ...l, status: 'error' as const } : l
                )
              }));
            }
          } else if (layer.status === 'processing' && layer.clipId) {
            pollForCompletion(layer, combinedLayerUpdate);
          }
        });
      }
    } catch (error) {
      console.error('Failed to load session:', error);
    } finally {
      if (isInitialLoad) {
        setIsLoadingSession(false);
      }
    }
  }, [sessionId, loadLayer, pollForCompletion, combinedLayerUpdate]);

  // Load session from database if sessionId is provided (initial load)
  useEffect(() => {
    if (sessionId) {
      loadSessionData(true);
    }
  }, [sessionId, loadSessionData]);
  
  // Poll for session updates every 2 seconds for collaborative sessions
  useEffect(() => {
    if (!sessionId) return;
    
    const intervalId = setInterval(() => {
      loadSessionData(false);
    }, 2000);
    
    return () => clearInterval(intervalId);
  }, [sessionId, loadSessionData]);

  // Create new session and get shareable URL
  // Invitation handlers
  const handleAcceptInvitation = useCallback(() => {
    setShowInvitationModal(false);
    // Continue with normal session loading - the session will load automatically
    // User can now collaborate and add their own layers
  }, []);

  const handleViewOnlyInvitation = useCallback(() => {
    setShowInvitationModal(false);
    // Continue with normal session loading - the session will load automatically
    // User can view and play but typically won't add new layers
  }, []);

  const handleDeclineInvitation = useCallback(() => {
    setShowInvitationModal(false);
    // Redirect to home page
    window.location.href = '/';
  }, []);

  const handleShareSession = useCallback(async () => {
    try {
      let sessionIdToShare = sessionId;
      
      // If we're not in a session yet, create a new one
      if (!sessionId) {
        const response = await fetch('/api/sessions', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({
            bpm: composition.tempo,
            keySignature: keySignature
          })
        });
        
        if (!response.ok) {
          throw new Error('Failed to create session');
        }
        
        const { sessionId: newSessionId } = await response.json();
        sessionIdToShare = newSessionId;
        
        // Save all current layers to the new session
        for (let i = 0; i < composition.layers.length; i++) {
          const layer = composition.layers[i];
          await saveLayerToSession(layer, newSessionId);
        }
      }
      
      // Generate shareable URL for the session (existing or new)
      const isLocalhost = window.location.hostname === 'localhost' || window.location.hostname.includes('192.168') || window.location.hostname.includes('127.0.0.1');
      const baseUrl = isLocalhost 
        ? window.location.origin
        : 'https://layers.suno.run';
      const url = `${baseUrl}/session/${sessionIdToShare}?invited=true&inviter=${encodeURIComponent(userDisplayName)}`;
      setShareUrl(url);
      
      // Show the share modal instead of alerts
      setShowShareModal(true);
      
    } catch (error) {
      console.error('Failed to share session:', error);
      alert('Failed to create shareable link');
    }
  }, [sessionId, composition.layers, saveLayerToSession, keySignature, composition.tempo]);

  return (
    <div className="min-h-screen bg-background-primary">
      <div className="container mx-auto px-4 py-12 max-w-4xl">
        {/* Minimal Header */}
        <header className="flex items-center justify-between mb-6">
          {/* Logo and Title */}
          <div className="flex items-center space-x-4">
            <div className="flex items-center justify-center w-12 h-12 rounded-xl shadow-lg overflow-hidden">
              <img 
                src="/suno-logo.png" 
                alt="SUNO Logo" 
                className="w-full h-full object-cover"
              />
            </div>
            <div>
              <h1 className="text-2xl font-bold text-white tracking-tight">
                SUNO
              </h1>
              <p className="text-sm text-gray-300 font-medium">Layers</p>
            </div>
          </div>
          
          {/* Controls */}
          <div className="flex flex-col items-end space-y-2">
            {/* Invite Friends Button - Available for all sessions with layers */}
            {/* Session indicator */}
            {sessionId && (
              <div className="text-sm text-foreground-secondary bg-background-secondary px-3 py-2 rounded-lg">
                Collaborative Session
              </div>
            )}
            
            {composition.layers.length > 0 && (
              <button
                onClick={handleShareSession}
                className="inline-flex items-center px-3 py-2 bg-white hover:bg-gray-800 font-medium rounded-lg transition-colors text-black"
              >
                <svg className="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M8.684 13.342C8.886 12.938 9 12.482 9 12c0-.482-.114-.938-.316-1.342m0 2.684a3 3 0 110-2.684m0 2.684l6.632 3.316m-6.632-6l6.632-3.316m0 0a3 3 0 105.367-2.684 3 3 0 00-5.367 2.684zm0 9.316a3 3 0 105.367 2.684 3 3 0 00-5.367-2.684z" />
                </svg>
                {sessionId ? 'Invite More Friends' : 'Invite Friends'}
              </button>
            )}
          </div>
        </header>

        <main className="space-y-8">
          {/* Loading Session Indicator - only show if not auto-generating */}
          {isLoadingSession && !new URLSearchParams(window?.location?.search || '').get('generateFirst') && (
            <div className="bg-gradient-to-br from-background-secondary to-background-tertiary rounded-xl border border-border-primary p-8 text-center backdrop-blur-sm shadow-xl animate-pulse">
              <div className="inline-flex items-center space-x-4">
                <div className="w-8 h-8 border-3 border-accent-orange border-t-transparent rounded-full animate-spin shadow-lg" />
                <div>
                  <span className="text-foreground-primary font-semibold">Loading collaborative session...</span>
                  <p className="text-sm text-foreground-tertiary mt-1">Syncing with SUNO servers</p>
                </div>
              </div>
            </div>
          )}

          {/* Unified Music Panel */}
          <div className="bg-background-primary rounded-xl shadow-sm border border-border-primary">
            {/* Layer Stack */}
            <LayerStack 
              layers={composition.layers}
              currentTime={currentTime}
              isPlaying={isPlaying}
              onLayerUpdate={handleLayerUpdate}
              onRemoveLayer={handleRemoveLayer}
              onVolumeChange={setLayerVolume}
              onMuteChange={setLayerMute}
              onSeek={handleSeek}
              onPlayPause={togglePlayPause}
              audioLoading={audioLoading}
              sessionBpm={sessionId ? sessionBpm : undefined}
              sessionKey={sessionId ? sessionKey : undefined}
              isSession={!!sessionId}
              sessionId={sessionId || undefined}
              isGenerating={isGenerating}
            />

            {/* Layer Generation Controls */}
            <div className="p-8 border-t border-border-primary">
              <div className="mb-6">
                <h2 className="text-xl font-semibold text-foreground-primary mb-2">
                  Generate New Layer
                </h2>
              </div>
              
              <div className="space-y-6 mb-8">
                {/* Text Prompt */}
                <div>
                  <label className="block text-sm font-medium text-foreground-secondary mb-2">Prompt</label>
                  <input 
                    type="text" 
                    value={promptText}
                    onChange={(e) => setPromptText(e.target.value)}
                    onKeyDown={(e) => {
                      if (e.key === 'Enter' && !isGenerating && promptText.trim()) {
                        handleGenerateLayer();
                      }
                    }}
                    placeholder="e.g. jazz drums, electric bass, synthesizer pad"
                    className="w-full px-3 py-2 border border-border-primary rounded-lg focus:outline-none focus:ring-2 focus:ring-accent-blue focus:border-accent-blue bg-background-primary text-foreground-primary placeholder:text-foreground-tertiary"
                  />
                </div>

                {/* Key and BPM in same row - only show when not in session */}
                {!sessionId && (
                  <div className="grid grid-cols-2 gap-6">
                    {/* Key Input */}
                    <div>
                      <label className="block text-sm font-medium text-foreground-secondary mb-2">
                        Key
                      </label>
                      <select
                        value={keySignature}
                        onChange={(e) => setKeySignature(e.target.value)}
                        className="w-full px-3 py-2 border rounded-lg focus:outline-none transition-all h-10 border-border-primary bg-background-primary focus:ring-2 focus:ring-accent-blue focus:border-accent-blue text-foreground-primary"
                      >
                        <option value="C major">C major</option>
                        <option value="C minor">C minor</option>
                        <option value="D major">D major</option>
                        <option value="D minor">D minor</option>
                        <option value="E major">E major</option>
                        <option value="E minor">E minor</option>
                        <option value="F major">F major</option>
                        <option value="F minor">F minor</option>
                        <option value="G major">G major</option>
                        <option value="G minor">G minor</option>
                        <option value="A major">A major</option>
                        <option value="A minor">A minor</option>
                        <option value="B major">B major</option>
                        <option value="B minor">B minor</option>
                        <option value="F# major">F# major</option>
                        <option value="F# minor">F# minor</option>
                        <option value="Bb major">Bb major</option>
                        <option value="Bb minor">Bb minor</option>
                        <option value="Eb major">Eb major</option>
                        <option value="Eb minor">Eb minor</option>
                        <option value="Ab major">Ab major</option>
                        <option value="Ab minor">Ab minor</option>
                        <option value="Db major">Db major</option>
                        <option value="Db minor">Db minor</option>
                      </select>
                    </div>

                    {/* BPM Input */}
                    <div>
                      <label className="block text-sm font-medium text-foreground-secondary mb-2">
                        BPM
                      </label>
                      <input 
                        type="number" 
                        value={composition.tempo}
                        onChange={(e) => handleBpmChange(Number(e.target.value))}
                        min="60" 
                        max="200"
                        className="w-full px-3 py-2 border rounded-lg focus:outline-none transition-all h-10 border-border-primary bg-background-primary focus:ring-2 focus:ring-accent-blue focus:border-accent-blue text-foreground-primary"
                      />
                    </div>
                  </div>
                )}
              </div>

              {/* Generate Button */}
              <button
                onClick={handleGenerateLayer}
                disabled={isGenerating || !promptText.trim()}
                className="w-full px-6 py-3 rounded-lg font-semibold text-white transition-colors bg-accent-orange hover:bg-accent-orange/80 disabled:bg-foreground-inactive"
              >
                {isGenerating ? 'Generating...' : 'Generate Layer'}
              </button>

              {/* Error Display */}
              {error && (
                <div className="mt-4 p-4 bg-accent-error/10 border border-accent-error rounded-lg">
                  <p className="text-accent-error">{error}</p>
                  {error.includes('NEXT_PUBLIC_SUNO_API_TOKEN') && (
                    <p className="text-accent-error mt-2 text-sm">
                      Please add your Suno API token to the <code className="bg-accent-error/20 px-1 rounded">.env.local</code> file.
                    </p>
                  )}
                </div>
              )}
            </div>
          </div>
        </main>
        
        {/* Footer */}
        <footer className="mt-16 text-center">
          <div className="inline-flex items-center space-x-2 px-4 py-2 rounded-full bg-background-secondary/50 backdrop-blur-sm border border-border-primary">
            <span className="text-sm text-foreground-tertiary">Powered by</span>
            <div className="flex items-center space-x-1">
              <div className="w-4 h-4 bg-gradient-to-r from-accent-orange to-accent-pink rounded-full"></div>
              <span className="text-sm font-bold text-foreground-primary">SUNO</span>
            </div>
          </div>
        </footer>
      </div>

      {/* Invitation Modal */}
      <InvitationModal
        isOpen={showInvitationModal}
        inviterName={inviterName || undefined}
        sessionTitle={sessionTitle || undefined}
        onAccept={handleAcceptInvitation}
        onDecline={handleDeclineInvitation}
        onViewOnly={handleViewOnlyInvitation}
      />

      {/* Share Modal */}
      <ShareModal
        isOpen={showShareModal}
        shareUrl={shareUrl || ''}
        isExistingSession={!!sessionId}
        onClose={() => setShowShareModal(false)}
      />
    </div>
  );
}

export default App;
