import { useState, useRef, useEffect, useCallback, useMemo } from 'react';
import { Send, AlertCircle, Phone, PhoneOff, Mic, MicOff, MessageSquare, Square, Clock, Coins, X, Settings, ShieldCheck, Image, Video, FileText, Music, Calendar, Search, Code, Code2, Briefcase, BookOpen, Globe, ScanLine, Languages, FileSearch, Receipt, CreditCard, Box, Zap, Bot, FolderOpen, Download, Smile } from 'lucide-react';
import { Message } from '../types';
import { MessageBubble } from './MessageBubble';
import { AIAvatar } from './AIAvatar';
import { CrisisBanner } from './CrisisBanner';
import { DocumentScannerModal, DocumentType } from './DocumentScannerModal';
import { ScanHistoryModal } from './ScanHistoryModal';
import { CodeEditorModal } from './CodeEditorModal';
import { MemoryPromptToast } from './MemoryPromptToast';
import { BackgroundMusicPlayer } from './BackgroundMusicPlayer';
import { useRealtimeVoice } from '../hooks/useRealtimeVoice';
import { useSettings } from '../hooks/useSettings';
import { generateAIResponse, analyzeVideo, generateImage } from '../lib/openai';
import { getColorClasses } from '../utils/colors';
import { getThemeConfig, generateParticles } from '../utils/visualThemes';
import { getSystemInstructions } from '../lib/systemSettings';
import { RealtimeConfig } from '../lib/realtime';
import { audioManager } from '../utils/audioManager';
import { supabase } from '../lib/supabase';
import { memoryService } from '../lib/memoryService';
import { getGreeting } from '../utils/greetings';
import { splitTextIntoChunks, estimateSpeechDuration, formatDuration } from '../utils/ttsChunker';
import { extractVideoFrames } from '../utils/videoProcessor';
import { detectEmotion, EmotionType } from '../utils/emotionDetector';
import { detectCrisis, CrisisLevel } from '../utils/crisisDetector';
import {
  trackComponentInteraction,
  trackMessageSent,
  trackVoiceCallStart,
  trackVoiceCallEnd,
  trackQRCodeScanned,
  trackCrisisDetection
} from '../utils/analytics';
import {
  trackConversationMessage,
  trackSafetyEvent,
  trackPageview,
  trackUsageMetrics,
} from '../utils/databaseTracking';
import { getDocumentPrompt, formatExtractedDocument } from '../utils/documentPrompts';
import { enhanceDocumentImage } from '../utils/documentProcessor';
import {
  analyzeDocumentContent,
  extractReceiptData,
  extractBusinessCardData,
  generateSmartTags
} from '../utils/smartDocumentAnalysis';
import { AgentChatBubble, AgentTaskDetailModal, AgentTaskPanel } from './agent';
import { useAgentTasks } from '../hooks/useAgentTasks';
import { isAgenticRequest, detectTaskType } from '../lib/agentOrchestrator';
import type { AgentTask } from '../types/agent';
import { DocumentsManagerModal } from './DocumentsManagerModal';
import { ManusStudioModal } from './ManusStudioModal';
import { exportConversationAsPDF, exportConversationAsTXT } from '../utils/messageExport';
import { saveMessage, loadMessages, clearConversation } from '../utils/chatPersistence';
import { enrichWithImages, shouldEnrichWithImages } from '../utils/imageEnrichment';

interface ChatInterfaceProps {
  selectedImage: string | null;
  imageFile: File | null;
  qrCodeData: string | null;
  selectedVideo: string | null;
  videoFile: File | null;
  onClearImage: () => void;
  onClearVideo: () => void;
  onSettingsClick: () => void;
  onSafetyClick: () => void;
  fileInputRef: React.RefObject<HTMLInputElement>;
  videoInputRef: React.RefObject<HTMLInputElement>;
  onImageSelect: (event: React.ChangeEvent<HTMLInputElement>) => void;
  onVideoSelect: (event: React.ChangeEvent<HTMLInputElement>) => void;
  onNavigate?: (page: string) => void;
}

export const ChatInterface = ({
  selectedImage,
  qrCodeData,
  selectedVideo,
  videoFile,
  onClearImage,
  onClearVideo,
  onSettingsClick,
  onSafetyClick,
  fileInputRef,
  videoInputRef,
  onImageSelect,
  onVideoSelect,
  onNavigate
}: ChatInterfaceProps) => {
  const { settings, deductMinutes, getMinutesRemaining, updateSettings, isAuthenticated, userName, isLoading: isLoadingSettings } = useSettings();
  const colors = getColorClasses(settings.accentColor) || getColorClasses('blue');
  const [messages, setMessages] = useState<Message[]>([]);
  const [isLoadingMessages, setIsLoadingMessages] = useState(true);

  useEffect(() => {
    const initializeMessages = async () => {
      try {
        const savedMessages = await loadMessages(50);
        if (savedMessages.length > 0) {
          setMessages(savedMessages);
        }
      } catch (err) {
        console.error('Error loading messages:', err);
      } finally {
        setIsLoadingMessages(false);
      }
    };
    initializeMessages();
  }, []);

  const [inputText, setInputText] = useState('');
  const [error, setError] = useState<string | null>(null);
  const [isVoiceCallActive, setIsVoiceCallActive] = useState(false);

  useEffect(() => {
    if (selectedVideo && !inputText) {
      setInputText('Analyzuj tohle video a řekni mi co vidíš. Pokud je tam nějaký text, přelož ho.');
    } else if (!selectedVideo && inputText === 'Analyzuj tohle video a řekni mi co vidíš. Pokud je tam nějaký text, přelož ho.') {
      setInputText('');
    }
  }, [selectedVideo, inputText]);
  const [isConnecting, setIsConnecting] = useState(false);
  const [isProcessing, setIsProcessing] = useState(false);
  const [isOnline, setIsOnline] = useState(navigator.onLine);
  const [voiceCallDuration, setVoiceCallDuration] = useState(0);
  const [systemInstructions] = useState<string | null>(null);
  const [systemPromptConfig, setSystemPromptConfig] = useState<{ id: string; version?: string } | null>(null);
  const [userMemory, setUserMemory] = useState<any>(null);
  const messagesEndRef = useRef<HTMLDivElement>(null);
  const abortControllerRef = useRef<AbortController | null>(null);
  const voiceCallStartTimeRef = useRef<number | null>(null);
  const [isSpeaking, setIsSpeaking] = useState(false);
  const [currentEmotion, setCurrentEmotion] = useState<EmotionType>('neutral');
  const themeConfig = getThemeConfig(settings.visualTheme || 'default');
  const [backgroundParticles, setBackgroundParticles] = useState(() => themeConfig.particles ? generateParticles(25) : []);
  const [comingSoonNotification, setComingSoonNotification] = useState<string | null>(null);
  const [crisisDetection, setCrisisDetection] = useState<{ level: CrisisLevel; message: string } | null>(null);
  const [isDocumentScannerOpen, setIsDocumentScannerOpen] = useState(false);
  const [isScanHistoryOpen, setIsScanHistoryOpen] = useState(false);
  const [isCodeEditorOpen, setIsCodeEditorOpen] = useState(false);
  const [agentTaskDetailId, setAgentTaskDetailId] = useState<string | null>(null);
  const [agentTaskBubbles, setAgentTaskBubbles] = useState<Map<string, AgentTask>>(new Map());
  const agentTasks = useAgentTasks({ userId: settings.userId, autoRefresh: true });
  const [showMemoryPrompt, setShowMemoryPrompt] = useState(false);
  const [memoryPromptCount, setMemoryPromptCount] = useState(0);
  const [isMusicPlayerOpen, setIsMusicPlayerOpen] = useState(false);
  const [isDocumentsManagerOpen, setIsDocumentsManagerOpen] = useState(false);
  const [isManusStudioOpen, setIsManusStudioOpen] = useState(false);
  const [showConversationExport, setShowConversationExport] = useState(false);
  const [currentMusicQuery, setCurrentMusicQuery] = useState('');

  // Debug logging for music player state changes
  useEffect(() => {
    console.log('🎵 Music player state changed:', {
      isMusicPlayerOpen,
      currentMusicQuery,
      timestamp: new Date().toISOString()
    });
  }, [isMusicPlayerOpen, currentMusicQuery]);
  const [headerColorIndex, setHeaderColorIndex] = useState(() => {
    const saved = localStorage.getItem('headerColorIndex');
    return saved ? parseInt(saved, 10) : 1;
  });

  const headerColors = [
    { bg: 'bg-white', border: 'border-gray-200', text: 'text-gray-900', icon: 'text-gray-700', hover: 'hover:bg-gray-50' },
    { bg: 'bg-gray-900', border: 'border-gray-700', text: 'text-white', icon: 'text-gray-300', hover: 'hover:bg-gray-800' },
    { bg: 'bg-gradient-to-r from-blue-600 to-cyan-500', border: 'border-blue-400', text: 'text-white', icon: 'text-blue-100', hover: 'hover:bg-blue-700/30' },
    { bg: 'bg-gradient-to-r from-emerald-600 to-teal-500', border: 'border-emerald-400', text: 'text-white', icon: 'text-emerald-100', hover: 'hover:bg-emerald-700/30' },
    { bg: 'bg-gradient-to-r from-orange-500 to-amber-500', border: 'border-orange-400', text: 'text-white', icon: 'text-orange-100', hover: 'hover:bg-orange-600/30' },
    { bg: 'bg-gradient-to-r from-rose-600 to-pink-500', border: 'border-rose-400', text: 'text-white', icon: 'text-rose-100', hover: 'hover:bg-rose-700/30' },
    { bg: 'bg-gradient-to-r from-slate-700 to-slate-600', border: 'border-slate-500', text: 'text-white', icon: 'text-slate-300', hover: 'hover:bg-slate-600/30' },
  ];

  const currentHeaderColor = headerColors[headerColorIndex];

  const cycleHeaderColor = () => {
    const nextIndex = (headerColorIndex + 1) % headerColors.length;
    setHeaderColorIndex(nextIndex);
    localStorage.setItem('headerColorIndex', nextIndex.toString());
  };

  useEffect(() => {
    setBackgroundParticles(themeConfig.particles ? generateParticles(25) : []);
  }, [settings.visualTheme, themeConfig.particles]);

  useEffect(() => {
    const loadSystemConfig = async () => {
      const { getPromptConfig } = await import('../lib/apiKeyService');
      const promptConfig = await getPromptConfig();

      if (promptConfig) {
        setSystemPromptConfig(promptConfig);
      }

      const memory = await memoryService.getUserMemory();
      if (memory) {
        setUserMemory(memory);
      }
    };

    loadSystemConfig();
  }, []);

  const handleSmartAction = (text: string): boolean => {
    const lowerText = text.toLowerCase();
    const isMobile = /Mobile|Android|iPhone|iPad/i.test(navigator.userAgent);
    console.log('🎯 handleSmartAction called:', {
      text,
      lowerText,
      textLength: text.length,
      isMobile,
      isPWA: window.matchMedia('(display-mode: standalone)').matches,
      viewport: { width: window.innerWidth, height: window.innerHeight },
      timestamp: new Date().toISOString()
    });

    // Music playback patterns (order matters - specific patterns first!)
    const musicPatterns = [
      // Explicit commands with artist/song name - Czech/Slovak/English (flexible ending)
      /(?:pusť|pust|spusť|spust|přehraj|prehraj|zahraj|zahr[aá]j|pusti|spusti|hraj|hrajte)\s+(.+?)(?:\s+(?:hudba|hudbu|music|píseň|písnička|piesne|skladbu|song))?[.!]?$/i,
      /(?:pustite|spustite|přehrajte|prehrajte|zahrajte|zahrajte)\s+(.+?)(?:\s+(?:hudba|hudbu|music))?[.!]?$/i,

      // Want to hear/listen variations
      /(?:chci|chcem|chcel|chtěl|chtel|chtela)\s+(?:slyšet|slyset|počuť|počúvať|poslouchat|poslouchať|hear)\s+(.+)/i,
      /(?:chci|chcem|chcel|chtěl|chtel|chtela)\s+(?:bych|by|jsem)?\s*(?:slyšet|slyset|počuť|počúvať|poslouchat)?\s*(.+)/i,
      /(?:chtěl|chtel|chtela|chcel)\s+(?:bych|by|som)\s+(?:si\s+)?(?:poslechnout|poslouchat|počúvať|počuť)\s+(.+)/i,

      // Give me variations
      /(?:daj|dajte|dej|dejte|dajmi|dejmi)\s+(?:mi|mne)?\s*(.+)/i,

      // Open/start variations
      /(?:otevři|otvor|otevřete|otevre|otvorte)\s+(.+?)(?:\s+(?:hudba|hudbu))?$/i,
      /(?:spusti|spusť|spustite|start|začni|začněte|začnite)\s+(.+?)(?:\s+(?:hudba|hudbu|music))?$/i,

      // Switch/change variations
      /(?:přepni|prepni|přepnout|prepnout|zmenit|změň|změňte)\s+(?:na|do|to)?\s*(.+)/i,

      // Listen/hear variations
      /(?:poslouchat|počúvať|poslouchejme|počúvajme|listen|hearing)\s+(?:si|to)?\s*(.+)/i,
      /(?:slyšet|slyset|počuť|hear)\s+(.+)/i,

      // English play command
      /play\s+(.+?)(?:\s+(?:music|song))?$/i,

      // Find and play variations
      /(?:najdi|najdite|hledej|vyhledej|find|search)\s+(?:a|mi|and)?\s*(?:pusť|pust|spusť|přehraj|zahraj|hraj|play)?\s*(.+?)(?:\s+(?:hudba|hudbu|music))?$/i,
      /(?:vyhledej|vyhledat|najdi|najít)\s+(?:mi|a)?\s*(.+?)(?:\s+(?:a|and)\s+(?:pusť|přehraj|zahraj|hraj|play))?$/i,

      // Turn on/put on variations
      /(?:zapni|zapnite|zapněte|turn\s+on|put\s+on)\s+(.+?)(?:\s+(?:hudba|hudbu|music))?$/i,

      // Play for me / play me
      /(?:pusť|pust|spusť|přehraj|zahraj|hraj|play)\s+(?:mi|me|mne)\s+(.+)/i,

      // Would like to variations
      /(?:rád|rad|ráda|rada|like|would\s+like)\s+(?:bych|by)?\s*(?:poslouchat|poslechnout|počúvať|počuť|slyšet|hear|listen)\s+(.+)/i,

      // Artist/song name + "hudba/hudbu/music"
      /^(.+?)\s+(?:hudba|hudbu|music|píseň|piesne|skladbu|song)$/i,

      // Just "music" or "hudba" with artist
      /(?:music|hudba|hudbu|song|píseň)\s+(?:od|from|by)?\s*(.+)/i,

      // Let's listen/hear
      /(?:pojďme|pojdme|ďalej|poďme|let\'?s)\s+(?:poslouchat|počúvať|slyšet|počuť|listen|hear)\s+(.+)/i,
    ];

    // Music control patterns
    const stopMusicPatterns = [
      /zastav\s*(?:hudbu|music|přehrávač|prehravac)?|zastavit\s*hudbu|stop\s*(?:music|player)?/i,
      /vypni\s*(?:hudbu|music|přehrávač|prehravac)?|vypnout\s*hudbu|turn\s*off\s*(?:music|player)?/i,
      /zavři\s*(?:hudbu|music|přehrávač|prehravac)?|zavri\s*hudbu|zavřít\s*hudbu|close\s*(?:music|player)?/i,
      /konec\s*(?:hudby|hudbu|music)?|koniec\s*(?:hudby|hudbu)?|end\s*(?:music|player)?/i,
      /ukonči\s*(?:hudbu|přehrávání|prehravanie)?|ukončit\s*hudbu|quit\s*music/i,
      /přestaň\s*(?:hrát|přehrávat)?|prestan\s*(?:hrat|prehravat)?|stop\s*playing/i,
      /zhasni\s*(?:hudbu|music)?|vypnite\s*(?:hudbu|music)?|zastavte\s*(?:hudbu|music)?/i,
      /stačí\s*(?:hudby|music)?|dost\s*(?:hudby|music)?|enough\s*music/i
    ];

    // Document scanning patterns
    const scanPatterns = [
      /naskenuj|skenuj|sken|scan/i,
      /vytvor.*pdf|pdf.*z|generuj.*pdf/i,
      /analyzuj.*dokument|dokument.*analýza/i,
      /nasníma.*dokument|vyfoť.*dokument/i
    ];

    // Image upload patterns
    const imagePatterns = [
      /nahraj.*obrázek|upload.*obr|obrázek|fotk[ua]|pošl.*obr/i,
      /vyfoť|nafoť|vyfot.*se|selfie/i,
      /přida.*fotk|přilož.*fotk/i
    ];

    // Video upload patterns
    const videoPatterns = [
      /analyzuj.*video|video.*analýza/i,
      /nahraj.*video|upload.*video/i,
      /natočit.*video|pošl.*video/i
    ];

    // Check for music stop
    if (stopMusicPatterns.some(pattern => pattern.test(text))) {
      setIsMusicPlayerOpen(false);
      setCurrentMusicQuery('');

      const aiMessage: Message = {
        id: Date.now().toString(),
        content: 'Zastavuji hudbu.',
        role: 'assistant',
        timestamp: new Date(),
      };
      setMessages((prev) => [...prev, aiMessage]);

      trackComponentInteraction('chat-interface', 'stop_background_music');
      return true;
    }

    // Check for music playback
    console.log('🎵 Testing music patterns against text:', text);
    let patternIndex = 0;
    for (const pattern of musicPatterns) {
      const match = text.match(pattern);
      console.log(`🎵 Pattern ${patternIndex}: ${pattern.source} -> ${match ? 'MATCH' : 'no match'}`);
      patternIndex++;

      if (match) {
        console.log('🎵 Music pattern matched!', {
          pattern: pattern.source,
          match: match,
          fullText: text,
          matchGroups: match.slice(1)
        });

        // Extract artist/song name from various capture groups
        let query = '';
        for (let i = 1; i < match.length; i++) {
          if (match[i] && match[i].trim()) {
            query = match[i].trim();
            console.log(`🎵 Extracted query from group ${i}:`, query);
            break;
          }
        }

        // If no capture group matched, use the whole text
        if (!query) {
          query = text.replace(/hudba|hudbu|music/gi, '').trim();
          console.log('🎵 No capture group, extracted from full text:', query);
        }

        console.log('🎵 Starting music with final query:', {
          query,
          isMobile: /Mobile|Android|iPhone|iPad/i.test(navigator.userAgent),
          isPWA: window.matchMedia('(display-mode: standalone)').matches,
          currentState: { isMusicPlayerOpen, currentMusicQuery },
          viewport: { width: window.innerWidth, height: window.innerHeight }
        });

        setCurrentMusicQuery(query);
        setIsMusicPlayerOpen(true);
        console.log('✅ Music player state SET - isMusicPlayerOpen=true, currentMusicQuery=', query);

        const aiMessage: Message = {
          id: Date.now().toString(),
          content: `Spouštím ${query} na pozadí. Můžete pokračovat v konverzaci.`,
          role: 'assistant',
          timestamp: new Date(),
        };
        setMessages((prev) => [...prev, aiMessage]);

        trackComponentInteraction('chat-interface', 'start_background_music');
        console.log('✅ Returning TRUE from handleSmartAction - message will NOT be sent to AI');
        return true;
      }
    }

    console.log('❌ No music pattern matched, continuing to check other patterns...');

    // Check for document scanning
    if (scanPatterns.some(pattern => pattern.test(text))) {
      setIsDocumentScannerOpen(true);

      // Add AI message explaining what was opened
      const aiMessage: Message = {
        id: Date.now().toString(),
        content: 'Otevírám scanner dokumentů. Můžete naskenovat účtenku, vizitku, knihu nebo jakýkoliv dokument.',
        role: 'assistant',
        timestamp: new Date(),
      };
      setMessages((prev) => [...prev, aiMessage]);

      trackComponentInteraction('chat-interface', 'auto_open_scanner');
      return true;
    }

    // Check for image upload
    if (imagePatterns.some(pattern => pattern.test(text)) && !lowerText.includes('pdf')) {
      fileInputRef.current?.click();

      const aiMessage: Message = {
        id: Date.now().toString(),
        content: 'Otevírám výběr obrázků. Vyberte fotku, kterou chcete nahrát.',
        role: 'assistant',
        timestamp: new Date(),
      };
      setMessages((prev) => [...prev, aiMessage]);

      trackComponentInteraction('chat-interface', 'auto_open_image_picker');
      return true;
    }

    // Check for video upload
    if (videoPatterns.some(pattern => pattern.test(text))) {
      videoInputRef.current?.click();

      const aiMessage: Message = {
        id: Date.now().toString(),
        content: 'Otevírám výběr videí. Vyberte video, které chcete analyzovat.',
        role: 'assistant',
        timestamp: new Date(),
      };
      setMessages((prev) => [...prev, aiMessage]);

      trackComponentInteraction('chat-interface', 'auto_open_video_picker');
      return true;
    }

    return false;
  };

  const handleWebCommand = (text: string) => {

    const closePatterns = [
      /zavři prohlížeč/i,
      /zavri prehliadač/i,
      /zavři youtube/i,
      /zavri youtube/i,
      /zavři spotify/i,
      /zavri spotify/i,
      /zavři browser/i,
      /zavri browser/i,
      /uzavři prohlížeč/i,
      /uzavri prehliadač/i,
      /close browser/i,
      /close youtube/i,
      /close spotify/i
    ];

    const youtubePatterns = [
      /pusť (.+) na youtube/i,
      /přehraj (.+) na youtube/i,
      /pust (.+) na youtube/i,
      /najdi (.+) na youtube/i,
      /nájdi (.+) na youtube/i,
      /hledej (.+) na youtube/i,
      /otevři youtube/i,
      /otvor youtube/i,
      /youtube/i
    ];

    const spotifyPatterns = [
      /pusť (.+) na spotify/i,
      /přehraj (.+) na spotify/i,
      /pust (.+) na spotify/i,
      /spotify (.+)/i,
      /otevři spotify/i,
      /otvor spotify/i
    ];

    const mapPatterns = [
      /mapa (.+)/i,
      /mapy (.+)/i,
      /navigace (.+)/i,
      /naviguj (.+)/i,
      /cesta (.+)/i,
      /kde je (.+)/i,
      /kde sa nachádza (.+)/i,
      /ukáž mapu (.+)/i,
      /ukaž mapu (.+)/i,
      /map (.+)/i,
      /navigate to (.+)/i,
      /directions to (.+)/i,
      /where is (.+)/i
    ];

    const searchPatterns = [
      /vyhledej (.+)/i,
      /google (.+)/i,
      /najdi (.+)/i,
      /hledej (.+)/i,
      /vyhľadaj (.+)/i,
      /nájdi (.+)/i
    ];

    const urlPatterns = [
      /otevři (.+)/i,
      /jdi na (.+)/i,
      /zobraz (.+)/i,
      /otevřít (.+)/i,
      /otvor (.+)/i,
      /choď na (.+)/i,
      /prehliadač (.+)/i,
      /prohlížeč (.+)/i,
      /open (.+)/i,
      /spusť (.+)/i,
      /spusti (.+)/i,
      /načti (.+)/i,
      /nacti (.+)/i
    ];

    const openInBrowser = (url: string) => {
      const blockedInIframeDomains = [
        'youtube.com',
        'youtu.be',
        'spotify.com',
        'google.com',
        'google.cz',
        'google.sk',
        'maps.google.com',
        'facebook.com',
        'instagram.com',
        'twitter.com',
        'x.com',
        'linkedin.com',
        'github.com',
        'netflix.com',
        'amazon.com',
        'twitch.tv',
        'reddit.com',
        'tiktok.com',
        'pinterest.com',
      ];

      const shouldOpenExternal = blockedInIframeDomains.some(domain =>
        url.toLowerCase().includes(domain)
      );

      window.open(url, '_blank', 'noopener,noreferrer');
    };

    for (const pattern of closePatterns) {
      if (pattern.test(text)) {
        return true;
      }
    }

    for (const pattern of youtubePatterns) {
      const match = text.match(pattern);
      if (match) {
        let youtubeUrl;
        if (match[1]) {
          const query = match[1].trim();
          youtubeUrl = `https://www.youtube.com/results?search_query=${encodeURIComponent(query)}`;
        } else {
          youtubeUrl = 'https://www.youtube.com';
        }
        openInBrowser(youtubeUrl);
        return true;
      }
    }

    for (const pattern of spotifyPatterns) {
      const match = text.match(pattern);
      if (match) {
        let spotifyUrl;
        if (match[1]) {
          const query = match[1].trim();
          spotifyUrl = `https://open.spotify.com/search/${encodeURIComponent(query)}`;
        } else {
          spotifyUrl = 'https://open.spotify.com';
        }
        openInBrowser(spotifyUrl);
        return true;
      }
    }

    for (const pattern of mapPatterns) {
      const match = text.match(pattern);
      if (match) {
        const location = match[1].trim();
        const mapUrl = `https://www.google.com/maps/search/${encodeURIComponent(location)}`;
        openInBrowser(mapUrl);
        return true;
      }
    }

    for (const pattern of searchPatterns) {
      const match = text.match(pattern);
      if (match) {
        const query = match[1].trim();
        const searchUrl = `https://www.google.com/search?q=${encodeURIComponent(query)}`;
        openInBrowser(searchUrl);
        return true;
      }
    }

    for (const pattern of urlPatterns) {
      const match = text.match(pattern);
      if (match) {
        let url = match[1].trim();

        if (url.includes('%20') || url.includes('%') && !url.startsWith('http')) {
          console.log('❌ Skipping malformed URL with encoding:', url);
          return false;
        }

        const invalidPatterns = [
          /stranku/i,
          /stránku/i,
          /stranek/i,
          /stranka/i,
        ];

        if (invalidPatterns.some(p => p.test(url))) {
          console.log('❌ Skipping invalid URL pattern:', url);
          return false;
        }

        const commonSites: Record<string, string> = {
          'ryanair': 'https://www.ryanair.com',
          'wizz air': 'https://wizzair.com',
          'wizzair': 'https://wizzair.com',
          'easyjet': 'https://www.easyjet.com',
          'czech airlines': 'https://www.czechairlines.com',
          'emirates': 'https://www.emirates.com',
          'lufthansa': 'https://www.lufthansa.com',
          'klm': 'https://www.klm.com',
          'air france': 'https://www.airfrance.com',
          'booking': 'https://www.booking.com',
          'airbnb': 'https://www.airbnb.com',
          'hotels': 'https://www.hotels.com',
          'expedia': 'https://www.expedia.com',
          'facebook': 'https://www.facebook.com',
          'instagram': 'https://www.instagram.com',
          'twitter': 'https://www.twitter.com',
          'tiktok': 'https://www.tiktok.com',
          'linkedin': 'https://www.linkedin.com',
          'netflix': 'https://www.netflix.com',
          'amazon': 'https://www.amazon.com',
          'alza': 'https://www.alza.cz',
          'mall': 'https://www.mall.cz',
          'mapy': 'https://mapy.cz',
          'google': 'https://www.google.com'
        };

        const lowerUrl = url.toLowerCase();
        const commonSiteMatch = Object.keys(commonSites).find(key => lowerUrl.includes(key));

        if (commonSiteMatch) {
          url = commonSites[commonSiteMatch];
        } else if (!url.startsWith('http://') && !url.startsWith('https://')) {
          if (!url.includes('.')) {
            url = `https://www.google.com/search?q=${encodeURIComponent(url)}`;
          } else {
            const domainPattern = /^[a-zA-Z0-9-]+\.[a-zA-Z]{2,}$/;
            if (!domainPattern.test(url.split('/')[0])) {
              console.log('❌ Invalid domain format:', url);
              return false;
            }
            url = 'https://' + url;
          }
        }

        console.log('✅ Opening valid URL:', url);
        openInBrowser(url);
        return true;
      }
    }

    return false;
  };

  const apiKey = settings.openaiApiKey || import.meta.env.VITE_OPENAI_API_KEY;

  const mapRealtimeVoiceToTTS = (realtimeVoice: string): string => {
    const voiceMap: Record<string, string> = {
      'ash': 'alloy',
      'ballad': 'shimmer',
      'coral': 'nova',
      'sage': 'echo',
      'verse': 'onyx',
      'marin': 'fable',
      'cedar': 'echo',
      'alloy': 'alloy',
      'echo': 'echo',
      'shimmer': 'shimmer',
    };
    return voiceMap[realtimeVoice] || 'alloy';
  };

  const ttsVoice = mapRealtimeVoiceToTTS(settings.voicePreference || 'ash');

  const languageCode = settings.language?.split('-')[0] || 'sk';

  const voiceConfig = useMemo(() => {
    const config: RealtimeConfig = {
      model: 'gpt-realtime',
      voice: (settings.voicePreference as any) || 'ash',
      temperature: settings.temperature,
      language: languageCode,
    };

    return config;
  }, [settings.voiceModel, settings.voicePreference, settings.temperature, languageCode]);

  const realtimeVoice = useRealtimeVoice({
    ...voiceConfig,
    onTranscript: (text, isFinal) => {
      if (isFinal && text.trim()) {
        console.log('🎤 Final user transcript:', text);

        const crisisResult = detectCrisis(text);
        if (crisisResult.level !== 'none') {
          setCrisisDetection({
            level: crisisResult.level,
            message: crisisResult.message
          });

          console.log('🚨 Crisis detected in user voice input:', {
            level: crisisResult.level,
            phrases: crisisResult.detectedPhrases,
            timestamp: new Date().toISOString()
          });

          trackCrisisDetection(
            crisisResult.level as 'yellow' | 'red',
            crisisResult.detectedPhrases
          );
        }

        // Check for web commands first
        const wasWebHandled = handleWebCommand(text);
        if (wasWebHandled) {
          console.log('✅ Web command handled, skipping AI response');
          return;
        }

        // Check for smart actions (music, document scanning, etc.)
        const wasSmartActionHandled = handleSmartAction(text);
        if (wasSmartActionHandled) {
          console.log('✅ Smart action handled (music/scanner/etc)');
          return;
        }
      }
    },
    onResponse: (text) => {
      // CRITICAL: This is AI's response - NEVER call handleSmartAction or handleWebCommand here!
      // Music/scanner/etc commands should ONLY be detected in USER input (onTranscript), NOT in AI responses
      if (text.trim()) {
        const emotion = detectEmotion(text, false);
        setCurrentEmotion(emotion);

        setTimeout(() => {
          setCurrentEmotion('neutral');
        }, 5000);

        const assistantMessage: Message = {
          id: (Date.now() + 1).toString(),
          content: text,
          role: 'assistant',
          timestamp: new Date(),
        };
        setMessages((prev) => [...prev, assistantMessage]);

        saveMessage('assistant', text, {
          isVoice: true,
          model: 'gpt-realtime',
        });

        const voiceConversationId = localStorage.getItem('user_session_id') || 'default';
        trackConversationMessage(voiceConversationId, 'assistant', text, {
          isVoice: true,
          model: 'gpt-realtime',
        });

        if (settings.messageSound) {
          audioManager.playMessageSound();
        }

        const crisisResult = detectCrisis(text);
        if (crisisResult.level !== 'none') {
          setCrisisDetection({
            level: crisisResult.level,
            message: crisisResult.message
          });

          console.log('🚨 Crisis detected in voice response:', {
            level: crisisResult.level,
            phrases: crisisResult.detectedPhrases,
            timestamp: new Date().toISOString()
          });

          trackCrisisDetection(
            crisisResult.level as 'yellow' | 'red',
            crisisResult.detectedPhrases
          );
        }

        const lowerText = text.toLowerCase();

        const disconnectPhrases = [
          'odpojuji se',
          'odpojujem se',
          'odpojujem sa',
          'ukončuji hovor',
          'ukončujem hovor',
          'ukoncuji hovor',
          'ukoncujem hovor',
          'ukončím hovor',
          'ukoncim hovor',
          'končím hovor',
          'koncim hovor',
          'nashledanou',
          'na shledanou',
          'na shledanú',
          'měj se hezky',
          'mej se hezky',
          'maj sa pekne',
          'maj se hezky',
          'uvidíme se',
          'uvidime sa',
          'vidíme se příště',
          'vidime sa priste',
          'končím konverzaci',
          'koncim konverzaci',
          'ukončuji konverzaci',
          'ukoncuji konverzaci',
          'ukoncujem konverzaciu',
          'ukončujem konverzáciu',
          'pěkný den přeji',
          'pekný deň prajem',
          'hezký den přeji',
          'dobrou noc přeji',
          'dobrú noc prajem',
          'zatím ahoj',
          'čau čau',
          'cau cau',
          'ahoj ahoj',
          'pa pa',
          'bye bye',
          'dovídání',
          'dovidani',
          'do videnia',
          'sbohem',
          'zbohom',
          'to je všechno děkuji',
          'to je vsetko dakujem',
          'to stačí děkuji',
          'to staci dakujem',
          'hotovo děkuji',
          'hotovo dakujem',
          'díky moc nashledanou',
          'diky moc nashledanou',
          'ďakujem pekne nashledanou',
          'končíme tady',
          'koncime tady',
          'tak jo nashledanou',
          'tak dobře nashledanou',
          'tak dobre nashledanou',
          'někdy příště',
          'nekdy priste',
          'musím jít nashledanou',
          'musim jit nashledanou',
          'musím ísť nashledanou',
          'musim ist nashledanou',
          'odcházím nashledanou',
          'odchazim nashledanou',
          'odchádzam nashledanou',
          'už musím končit',
          'uz musim koncit',
          'už končím děkuji',
          'uz koncim dekuji',
          'přestaň mluvit',
          'prestan mluvit',
          'ukonči hovor',
          'ukonc hovor',
          'zavěs',
          'zaves',
          'odlož',
          'odloz'
        ];

        if (disconnectPhrases.some(phrase => lowerText.includes(phrase))) {
          const currentCallDuration = voiceCallStartTimeRef.current
            ? Math.floor((Date.now() - voiceCallStartTimeRef.current) / 1000)
            : 0;

          if (currentCallDuration >= 60) {
            console.log(`🔚 Disconnect phrase detected after ${currentCallDuration}s, ending call`);
            setTimeout(() => {
              stopVoiceCall();
            }, 1500);
            return;
          } else {
            console.log(`⏱️ Disconnect phrase detected but call only active for ${currentCallDuration}s (need 60s minimum)`);
          }
        }

        // Detect music player trigger phrases in AI response (realtime speech-to-speech)
        const musicPlayerTriggers = [
          // SLOVENSKY - "Rozumiem" varianty
          'rozumiem pustim',
          'rozumiem pust',
          'rozumiem pustím',
          'rozumím pustím',
          'rozumim pustim',
          'rozumiem spustam',
          'rozumiem spúšťam',
          'rozumiem prehram',
          'rozumiem prehrám',

          // SLOVENSKY - "Pustím ti" varianty
          'pustim ti',
          'pustím ti',
          'pust ti',
          'puštím ti',
          'prehram ti',
          'prehrám ti',
          'spustam ti',
          'spúšťam ti',

          // SLOVENSKY - "Nech sa páči" varianty
          'nech sa paci uz sa to spusta',
          'nech sa páči už sa to spúšťa',
          'nech sa paci to sa spusta',
          'nech sa páči to sa spúšťa',
          'nech sa paci uzi si hudbu',
          'nech sa páči uži si hudbu',
          'nech sa paci uz to ide',
          'nech sa páči už to ide',

          // CESKY - "Rozumím" varianty
          'rozumim pustim',
          'rozumím pustím',
          'rozumim spoustim',
          'rozumím spouštím',
          'rozumim prehrajem',
          'rozumím přehrajem',
          'rozumim prehraj',
          'rozumím přehraj',

          // CESKY - "Nech se páči" varianty
          'nech se paci uz se to spusti',
          'nech se páči už se to spustí',
          'nech se paci to se spusti',
          'nech se páči to se spustí',
          'nech se paci uzij si hudbu',
          'nech se páči užij si hudbu',
          'nech se paci uz to jede',
          'nech se páči už to jede',

          // CESKY - "Pustím ti" varianty
          'pustim ti',
          'pustím ti',
          'spoustim ti',
          'spouštím ti',
          'prehrajem ti',
          'přehrajem ti',
          'zahrajem ti',
          'zahraju ti',

          // ENGLISH - "I understand" variants
          'i understand let me play',
          'i understand ill play',
          "i understand i'll play",
          'i understand playing',
          'i understand starting',
          'i understand opening',

          // ENGLISH - "Here you go" variants
          'here you go',
          'here it is',
          'here we go',
          'there you go',
          'coming right up',

          // ENGLISH - "Playing" variants
          'playing for you',
          'playing now',
          'playing it now',
          'starting to play',
          'starting the music',
          'starting playback',
          'lets play',
          "let's play",
          'ill play',
          "i'll play",

          // ENGLISH - "Opening" variants
          'opening the player',
          'opening music player',
          'opening the music',
          'launching player',
          'launching music',

          // COMMON - "Už to" varianty
          'uz sa to spusta',
          'už sa to spúšťa',
          'uz se to spusti',
          'už se to spustí',
          'uz to ide',
          'už to ide',
          'uz to jede',
          'už to jede',
          'uz to bezi',
          'už to běží',

          // COMMON - "Spúšťam/Spouštím" varianty
          'spustam hudbu',
          'spúšťam hudbu',
          'spoustim hudbu',
          'spouštím hudbu',
          'spustam prehravac',
          'spúšťam prehrávač',
          'spoustim prehravac',
          'spouštím přehrávač',
          'spustam music',
          'spoustim music',

          // COMMON - "Otváram/Otevírám" varianty
          'otvaram prehravac',
          'otváram prehrávač',
          'oteviram prehravac',
          'otevírám přehrávač',
          'otvaram hudbu',
          'otváram hudbu',
          'oteviram hudbu',
          'otevírám hudbu',
          'otvaram player',
          'oteviram player',

          // COMMON - Kombinované varianty
          'hudba sa spusta',
          'hudba sa spúšťa',
          'hudba se spusti',
          'hudba se spustí',
          'music sa spusta',
          'music se spusti',
          'music is playing',
          'music is starting',

          // COMMON - "Je otvorený/otevřený"
          'prehravac je otvoreny',
          'prehrávač je otvorený',
          'prehravac je otevreny',
          'přehrávač je otevřený',
          'player je otvoreny',
          'player je otevreny',
          'player is open',
          'player is opening',

          // ADDITIONAL - Krátke potvrdenia s akciou
          'dobre pustim',
          'dobře pustím',
          'ok pustim',
          'ok pustím',
          'jasne pustim',
          'jasně pustím',
          'sure ill play',
          'sure playing',
          'okay playing',
          'alright playing',

          // ADDITIONAL - "Enjoy" varianty
          'uzi si',
          'uži si',
          'uzij si',
          'užij si',
          'uzivaj si',
          'užívaj si',
          'enjoy the music',
          'enjoy your music',
          'enjoy listening'
        ];

        if (musicPlayerTriggers.some(trigger => lowerText.includes(trigger))) {
          console.log('🎵 Music player trigger detected in AI response (realtime):', text);

          // Try to extract music query from AI response
          let query = 'hudba';

          // Look for artist/song patterns
          const queryPatterns = [
            /(?:s|se|so|s\s+)?([A-Z][a-zA-Z\s]+?)(?:\.|,|!|\?|$)/,  // Artist name (capitalized)
            /(?:od|from|by)\s+([^.,!?]+)/i,
            /(?:hudbu|music)\s+(?:od|from|by)\s+([^.,!?]+)/i,
            /(?:pesnicku|pesničku|skladbu|song)\s+([^.,!?]+)/i
          ];

          for (const pattern of queryPatterns) {
            const match = text.match(pattern);
            if (match && match[1] && match[1].trim().length > 2) {
              query = match[1].trim();
              console.log('🎵 Extracted music query from AI response:', query);
              break;
            }
          }

          console.log('🎵 Opening music player with query:', query);
          setCurrentMusicQuery(query);
          setIsMusicPlayerOpen(true);

          setTimeout(() => {
            scrollToBottom();
          }, 100);

          return;
        }

        if (lowerText.includes('otevírám youtube') ||
            lowerText.includes('oteviram youtube') ||
            lowerText.includes('otevírám spotify') ||
            lowerText.includes('oteviram spotify') ||
            lowerText.includes('vyhledávám') ||
            lowerText.includes('vyhledavam') ||
            lowerText.includes('otevírám') ||
            lowerText.includes('oteviram') ||
            lowerText.includes('spouštím navigaci') ||
            lowerText.includes('spoustim navigaci')) {

          const youtubeMatch = text.match(/youtube\s+s\s+(.+)/i) || text.match(/youtube\s+(.+)/i);
          if (youtubeMatch) {
            const query = youtubeMatch[1].trim().replace(/[.,!?]$/, '');
            const url = `https://www.youtube.com/results?search_query=${encodeURIComponent(query)}`;
            window.open(url, '_blank', 'noopener,noreferrer');
            return;
          }

          const spotifyMatch = text.match(/spotify\s+s\s+(.+)/i) || text.match(/spotify\s+(.+)/i);
          if (spotifyMatch) {
            const query = spotifyMatch[1].trim().replace(/[.,!?]$/, '');
            const url = `https://open.spotify.com/search/${encodeURIComponent(query)}`;
            window.open(url, '_blank', 'noopener,noreferrer');
            return;
          }

          const searchMatch = text.match(/vyhledávám\s+(.+)/i) || text.match(/vyhledavam\s+(.+)/i);
          if (searchMatch) {
            const query = searchMatch[1].trim().replace(/[.,!?]$/, '');
            const url = `https://www.google.com/search?q=${encodeURIComponent(query)}`;
            window.open(url, '_blank', 'noopener,noreferrer');
            return;
          }

          const navMatch = text.match(/navigaci\s+na\s+(.+)/i);
          if (navMatch) {
            const location = navMatch[1].trim().replace(/[.,!?]$/, '');
            const url = `https://www.google.com/maps/search/${encodeURIComponent(location)}`;
            window.open(url, '_blank', 'noopener,noreferrer');
            return;
          }
        }
      }
    },
    onError: (error) => {
      console.error('❌ Chyba realtime hlasu:', error);
      console.error('❌ Error message:', error.message);
      console.error('❌ Error stack:', error.stack);

      const msg = error.message || '';
      let friendlyMessage: string;
      if (msg.includes('quota') || msg.includes('billing') || msg.includes('exceeded')) {
        friendlyMessage = 'Jejda, momentalne je to nabite do stropu. Zkus to prosim za chvilku znovu!';
      } else if (msg.includes('401') || msg.includes('Unauthorized') || msg.includes('API key')) {
        friendlyMessage = 'Neco se pokazilo s pripojenim. Kontaktuj prosim spravce.';
      } else if (msg.includes('429') || msg.includes('rate limit')) {
        friendlyMessage = 'Prilis mnoho pozadavku najednou. Pockat chvilku a zkus to znovu!';
      } else if (msg.includes('502') || msg.includes('503') || msg.includes('unavailable')) {
        friendlyMessage = 'Sluzba je momentalne nedostupna. Zkus to prosim za par minut.';
      } else {
        friendlyMessage = 'Neco se nepovedlo. Zkus to prosim znovu!';
      }
      setError(friendlyMessage);
    },
  });

  const scrollToBottom = () => {
    messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
  };

  useEffect(() => {
    scrollToBottom();
  }, [messages]);

  const stopVoiceCall = useCallback(async (reason?: string) => {
    realtimeVoice.disconnect();
    setIsVoiceCallActive(false);

    if (voiceCallStartTimeRef.current) {
      const finalDurationSeconds = Math.floor((Date.now() - voiceCallStartTimeRef.current) / 1000);
      const finalDurationMinutes = Math.ceil(finalDurationSeconds / 60);

      console.log(`⏱️ Voice call ended: ${finalDurationSeconds}s (${finalDurationMinutes} minute${finalDurationMinutes !== 1 ? 's' : ''})`);

      if (finalDurationMinutes > 0) {
        const success = await deductMinutes(finalDurationMinutes);
        if (success) {
          console.log(`✅ Deducted ${finalDurationMinutes} minute${finalDurationMinutes !== 1 ? 's' : ''} from account`);
        } else {
          console.error(`❌ Failed to deduct minutes`);
        }
      }

      trackVoiceCallEnd(finalDurationSeconds, 0);
    }

    voiceCallStartTimeRef.current = null;
    setVoiceCallDuration(0);

    if (reason) {
      setError(reason);
    }
  }, [realtimeVoice, deductMinutes]);

  useEffect(() => {
    const handleOnline = () => {
      setIsOnline(true);
      setError(null);
    };
    const handleOffline = () => {
      setIsOnline(false);
      if (isVoiceCallActive) {
        stopVoiceCall('Spojení ztraceno - hlasový hovor ukončen');
      }
    };

    window.addEventListener('online', handleOnline);
    window.addEventListener('offline', handleOffline);

    return () => {
      window.removeEventListener('online', handleOnline);
      window.removeEventListener('offline', handleOffline);
    };
  }, [isVoiceCallActive, stopVoiceCall]);


  const playMessageSound = () => {
    if (settings.messageSound) {
      audioManager.playMessageSound();
    }
  };

  const speakText = async (text: string) => {
    console.log('🔊 speakText called with:', {
      textLength: text.length,
      autoPlayVoice: settings.autoPlayVoice,
      isVoiceCallActive,
      hasUserApiKey: !!settings.openaiApiKey,
    });

    if (isVoiceCallActive) {
      console.log('⏭️ TTS skipped - voice call is active');
      return;
    }

    if (!settings.autoPlayVoice) {
      console.log('⏭️ TTS skipped - autoPlayVoice is disabled');
      return;
    }

    try {
      const supabaseUrl = import.meta.env.VITE_SUPABASE_URL;
      const supabaseAnonKey = import.meta.env.VITE_SUPABASE_ANON_KEY;
      if (!supabaseUrl || !supabaseAnonKey) {
        return;
      }

      const chunks = splitTextIntoChunks(text);
      const estimatedDuration = estimateSpeechDuration(text);

      if (chunks.length > 1) {
        formatDuration(estimatedDuration);
      }

      const audioBlobs: Blob[] = [];

      for (const chunk of chunks) {
        const response = await fetch(`${supabaseUrl}/functions/v1/text-to-speech`, {
          method: 'POST',
          headers: {
            'Authorization': `Bearer ${supabaseAnonKey}`,
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({
            text: chunk.text,
            model: 'tts-1-hd',
            voice: ttsVoice,
            speed: settings.voiceSpeed,
          }),
        });

        if (!response.ok) {
          let detail = '';
          try { const j = await response.clone().json(); detail = j.detail || j.error || ''; } catch {}
          console.error('TTS response error:', response.status, detail);
          if (response.status === 429) {
            throw new Error('Příliš mnoho požadavků. Zkuste to prosím za chvíli.');
          } else {
            throw new Error(`Služba je dočasně nedostupná (${response.status}). ${detail}`);
          }
        }

        const audioBlob = await response.blob();
        audioBlobs.push(audioBlob);
      }

      setIsSpeaking(true);

      if (audioBlobs.length === 1) {
        await audioManager.playTTS(audioBlobs[0]);
      } else {
        await audioManager.playTTSChunks(audioBlobs);
      }

      console.log('✅ TTS playback complete');
      setIsSpeaking(false);
    } catch (error) {
      console.error('❌ Chyba při přehrávání TTS:', error);
      const errorMessage = error instanceof Error ? error.message : 'Neznámá chyba';

      if (errorMessage.includes('interakce') || errorMessage.includes('NotAllowedError')) {
        setError('Pro automatické přehrávání audio je nutná interakce s aplikací. Tip: Klikněte kamkoliv na stránku nebo na tlačítko mikrofonu a zkuste znovu.');
      } else {
        setError(`Chyba TTS: ${errorMessage}`);
      }

      setIsSpeaking(false);
    }
  };

  const stopSpeaking = () => {
    audioManager.stopCurrentAudio();
    setIsSpeaking(false);
  };

  const getConversationHistory = (): Array<{ role: 'user' | 'assistant'; content: string }> => {
    return messages.slice(-10).map(msg => ({
      role: msg.role as 'user' | 'assistant',
      content: msg.content
    }));
  };

  const showComingSoonNotification = (featureName: string) => {
    if (featureName === 'Překlad') {
      window.open('https://traiend.com/', '_blank', 'noopener,noreferrer');
      return;
    }
    setComingSoonNotification(`${featureName} - Tato funkce bude brzy dostupná`);
    setTimeout(() => {
      setComingSoonNotification(null);
    }, 3500);
  };

  const handleAvatarGreeting = async () => {
    if (isProcessing || isVoiceCallActive) return;

    const isInitialLoad = messages.length <= 1;
    const visitCount = settings.visitCount ?? 0;
    const lastGreetingIndex = settings.lastGreetingIndex ?? 0;

    trackComponentInteraction('ai-avatar', 'click', {
      isInitialLoad,
      visitCount
    });

    const { message: greetingContent, newIndex } = getGreeting(visitCount, lastGreetingIndex, isInitialLoad);

    const greetingMessage: Message = {
      id: Date.now().toString(),
      content: greetingContent,
      role: 'assistant',
      timestamp: new Date(),
    };

    setMessages(prev => [...prev, greetingMessage]);

    // Welcome bonus message for first-time visitors
    if (isInitialLoad && visitCount === 0 && !settings.welcomeBonusClaimed) {
      setTimeout(() => {
        const bonusMessage: Message = {
          id: Date.now().toString() + '-bonus',
          content: '🎁 Vítej! Dostal jsi 30 bonus minut navíc na první návštěvu. Celkem máš 90 minut voice chatu denně! Užívej si AI Pokec. 💚',
          role: 'assistant',
          timestamp: new Date(),
        };
        setMessages(prev => [...prev, bonusMessage]);
      }, 1500);
    }

    if (isInitialLoad) {
      console.log('📊 Incrementing visit count:', visitCount + 1);
      await updateSettings({
        visitCount: visitCount + 1,
        lastGreetingIndex: newIndex,
        lastVisitAt: new Date(),
      });
    }

    try {
      const greetingSupabaseUrl = import.meta.env.VITE_SUPABASE_URL;
      const greetingAnonKey = import.meta.env.VITE_SUPABASE_ANON_KEY;
      if (!greetingSupabaseUrl || !greetingAnonKey) {
        return;
      }

      const response = await fetch(`${greetingSupabaseUrl}/functions/v1/text-to-speech`, {
        method: 'POST',
        headers: {
          'Authorization': `Bearer ${greetingAnonKey}`,
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          text: greetingMessage.content,
          model: 'tts-1',
          voice: ttsVoice,
        }),
      });

      if (!response.ok) {
        throw new Error('Služba nedostupná');
      }
      const audioBlob = await response.blob();
      setIsSpeaking(true);

      await audioManager.playTTS(audioBlob);
      console.log('✅ Greeting TTS playback complete');
      setIsSpeaking(false);
    } catch (error) {
      console.error('Chyba při přehrávání pozdravu:', error);
      setIsSpeaking(false);
    }
  };

  const handleSendMessage = async (text: string) => {
    const messageText = text.trim();
    if ((!messageText && !selectedImage) || isProcessing || isVoiceCallActive) return;

    if (handleWebCommand(messageText)) {
      setInputText('');
      return;
    }

    // Check for smart actions (document scanning, uploads, etc.)
    if (handleSmartAction(messageText)) {
      setInputText('');
      return;
    }

    if (isAgenticRequest(messageText)) {
      setInputText('');
      const userMsg: Message = {
        id: `user-${Date.now()}`,
        content: messageText,
        role: 'user',
        timestamp: new Date(),
      };
      setMessages(prev => [...prev, userMsg]);

      const agentMsg: Message = {
        id: `agent-${Date.now()}`,
        content: `AI Agent pracuje na: "${messageText}"...`,
        role: 'assistant',
        timestamp: new Date(),
      };
      setMessages(prev => [...prev, agentMsg]);

      const taskType = detectTaskType(messageText);
      const result = await agentTasks.executeTask(messageText, taskType);

      if (result?.task) {
        const mappedTask: AgentTask = {
          id: result.task.id,
          userId: result.task.user_id,
          goal: result.task.goal,
          type: result.task.type,
          status: result.task.status,
          priority: result.task.priority || 0,
          subtasks: result.task.subtasks || [],
          context: result.task.context || {},
          progress: result.task.progress || 0,
          result: result.task.result,
          errorMessage: result.task.error_message,
          createdAt: result.task.created_at,
          updatedAt: result.task.updated_at,
        };
        setAgentTaskBubbles(prev => new Map(prev).set(agentMsg.id, mappedTask));
      }
      return;
    }

    setError(null);

    let finalMessageText = messageText || (selectedVideo ? 'Co je na tomto videu?' : 'Co je na tomto obrázku?');
    if (qrCodeData && !messageText) {
      finalMessageText = `Našel jsem QR kód na obrázku. Prosím přečti a vysvětli obsah QR kódu:\n\n${qrCodeData}`;
    } else if (qrCodeData && messageText) {
      finalMessageText = `${messageText}\n\n[Nalezen QR kód s obsahem: ${qrCodeData}]`;
    }

    const userMessage: Message = {
      id: Date.now().toString(),
      content: finalMessageText,
      role: 'user',
      timestamp: new Date(),
      imageUrl: selectedImage || undefined,
      imageData: selectedImage || undefined,
    };

    setMessages((prev) => [...prev, userMessage]);
    setInputText('');
    setIsProcessing(true);

    saveMessage('user', finalMessageText, {
      hasImage: !!selectedImage,
      hasVideo: !!selectedVideo,
      hasQrCode: !!qrCodeData,
    });

    const conversationId = localStorage.getItem('user_session_id') || 'default';
    trackConversationMessage(conversationId, 'user', finalMessageText, {
      hasImage: !!selectedImage,
      hasVideo: !!selectedVideo,
      hasQrCode: !!qrCodeData,
    });

    trackMessageSent(finalMessageText.length, false);
    if (selectedImage) {
      trackComponentInteraction('chat-interface', 'message_with_image');
    }
    if (selectedVideo) {
      trackComponentInteraction('chat-interface', 'message_with_video');
    }
    if (qrCodeData) {
      trackQRCodeScanned();
    }

    abortControllerRef.current = new AbortController();

    try {
      if (!isOnline) {
        throw new Error('Spojeni ztraceno. Zkontrolujte pripojeni k internetu.');
      }

      const messageApiKey = settings.openaiApiKey || import.meta.env.VITE_OPENAI_API_KEY;
      const supabaseUrl = import.meta.env.VITE_SUPABASE_URL;
      const supabaseAnonKey = import.meta.env.VITE_SUPABASE_ANON_KEY;

      if (!messageApiKey && (!supabaseUrl || !supabaseAnonKey)) {
        throw new Error('Sluzba neni docasne dostupna. Zkuste to prosim pozdeji.');
      }

      let aiResponse: string;
      let generatedImageUrl: string | undefined;

      const imageGenerationPatterns = [
        /(?:vygeneruj|generuj|vytvor|nakresli|namaluj|create|generate|draw|make)\s+(?:mi\s+)?(?:obrazek|obr[aá]zek|obrázok|picture|image|photo|fotku|fotku|ilustraci|ilustr[aá]ciu)/i,
        /(?:obrazek|obr[aá]zek|obrázok|picture|image|photo|fotku|ilustraci|ilustr[aá]ciu)\s+(?:s|z|of|with|kde|na)\s+/i,
        /(?:chci|chcem|chtěl|chtel|chcel|want|need)\s+(?:bych\s+)?(?:obrazek|obr[aá]zek|obrázok|picture|image|photo)/i,
        /(?:udelej|udělej|urob|make|do)\s+(?:mi\s+)?(?:obrazek|obr[aá]zek|obrázok|picture|image)/i,
        /(?:dall-?e|dalle|ai\s+art|ai\s+image)/i,
        /^(?:nakresli|namaluj|vykresli|draw|paint|sketch)\s+/i,
      ];

      const isImageGenerationRequest = imageGenerationPatterns.some(pattern => pattern.test(finalMessageText));

      if (isImageGenerationRequest && !selectedVideo && !selectedImage) {
        console.log('🎨 Image generation request detected:', finalMessageText);

        try {
          const result = await generateImage(
            finalMessageText,
            abortControllerRef.current.signal
          );

          generatedImageUrl = result.imageUrl;
          aiResponse = result.revisedPrompt
            ? `Vygeneroval jsem obrazek podle tveho popisu. DALL-E upravil prompt na: "${result.revisedPrompt}"`
            : 'Obrazek byl uspesne vygenerovan podle tveho popisu.';

          console.log('🎨 Image generated successfully:', generatedImageUrl);
        } catch (error) {
          console.error('🎨 Image generation failed:', error);
          aiResponse = 'Nepodarilo se vygenerovat obrazek. Zkuste to prosim znovu.';
        }
      } else if (selectedVideo && videoFile) {
        const effectiveVideoKey = messageApiKey;
        if (!effectiveVideoKey) {
          throw new Error('Pre analýzu videa je potrebný vlastný OpenAI kľúč v nastaveniach.');
        }
        const frames = await extractVideoFrames(videoFile, 5);
        const frameDataUrls = frames.map(f => f.dataUrl);
        const languageCode = settings.language?.split('-')[0] || 'cs';

        aiResponse = await analyzeVideo(
          finalMessageText,
          effectiveVideoKey,
          frameDataUrls,
          settings.textModel || 'gpt-4o',
          settings.temperature,
          abortControllerRef.current.signal,
          systemInstructions || undefined,
          languageCode
        );

        onClearVideo();
      } else {
        const conversationHistory = getConversationHistory();
        const memoryContext = memoryService.formatMemoryForPrompt(userMemory);

        if (messageApiKey) {
          const systemPrompt = systemInstructions ?
            (memoryContext ? `${systemInstructions}\n\n${memoryContext}` : systemInstructions)
            : memoryContext || undefined;

          aiResponse = await generateAIResponse(
            finalMessageText,
            messageApiKey,
            settings.textModel || 'gpt-4o',
            settings.temperature,
            conversationHistory,
            abortControllerRef.current.signal,
            systemPrompt,
            selectedImage || undefined
          );
        } else {
          const chatResponse = await fetch(`${supabaseUrl}/functions/v1/chat`, {
            method: 'POST',
            headers: {
              'Authorization': `Bearer ${supabaseAnonKey}`,
              'Content-Type': 'application/json',
            },
            body: JSON.stringify({
              message: finalMessageText,
              conversationHistory: conversationHistory.map(m => ({ role: m.role, content: m.content })),
              model: settings.textModel || 'gpt-4o',
              temperature: settings.temperature,
            }),
            signal: abortControllerRef.current.signal,
          });

          if (!chatResponse.ok) {
            const errData = await chatResponse.json().catch(() => ({}));
            throw new Error(errData.message || errData.error || 'Sluzba neni dostupna. Zkuste to prosim pozdeji.');
          }

          const chatData = await chatResponse.json();
          aiResponse = chatData.message;
        }

        onClearImage();
      }

      const assistantMessage: Message = {
        id: (Date.now() + 1).toString(),
        content: aiResponse,
        role: 'assistant',
        timestamp: new Date(),
        generatedImageUrl: generatedImageUrl,
      };

      setMessages((prev) => [...prev, assistantMessage]);
      playMessageSound();

      if (!generatedImageUrl && shouldEnrichWithImages(aiResponse)) {
        const supabaseUrl = import.meta.env.VITE_SUPABASE_URL;
        const supabaseAnonKey = import.meta.env.VITE_SUPABASE_ANON_KEY;
        if (supabaseUrl && supabaseAnonKey) {
          enrichWithImages(aiResponse, supabaseUrl, supabaseAnonKey).then((images) => {
            if (images.length > 0) {
              setMessages((prev) =>
                prev.map((m) =>
                  m.id === assistantMessage.id ? { ...m, suggestedImages: images } : m
                )
              );
            }
          }).catch(console.error);
        }
      }

      saveMessage('assistant', aiResponse, {
        hasGeneratedImage: !!generatedImageUrl,
        model: settings.textModel || 'gpt-4o',
      });

      trackConversationMessage(conversationId, 'assistant', aiResponse, {
        hasGeneratedImage: !!generatedImageUrl,
        model: settings.textModel || 'gpt-4o',
      });

      if (!generatedImageUrl) {
        speakText(aiResponse);
      }

      // Detect music player opening commands in AI response (with and without diacritics)
      const musicOpenPatterns = [
        /otev[ií]r[aá]m\s+(?:hudebn[iyíý]\s+)?p[řr]ehr[aá]va[čc]/i,
        /spou[šs]t[ií]m\s+(?:hudebn[iyíý]\s+)?p[řr]ehr[aá]va[čc]/i,
        /p[řr]ehr[aá]va[čc]\s+(?:je\s+)?otev[řr]en/i,
        /otev[ií]r[aá]m\s+(?:music|hudba|hudbu)/i,
        /spou[šs]t[ií]m\s+(?:music|hudba|hudbu)/i,
        /opening\s+(?:music|player)/i,
        /starting\s+(?:music|player)/i,
        /pusť.*na pozad[ií]/i,
        /p[řr]ehr[aá]v[aá]m.*na pozad[ií]/i,
        /p[řr]ehr[aá]va[cč]\s+.*na\s+pozad[íi]/i,
      ];

      const aiResponseLower = aiResponse.toLowerCase();
      let musicPlayerOpened = false;

      console.log('🎵 Checking AI response for music player triggers:', aiResponse.substring(0, 150));

      let aiPatternIndex = 0;
      for (const pattern of musicOpenPatterns) {
        const matches = pattern.test(aiResponse);
        console.log(`🎵 AI Pattern ${aiPatternIndex}: ${pattern.source} -> ${matches ? 'MATCH' : 'no match'}`);
        aiPatternIndex++;

        if (matches) {
          console.log('🎵 AI response MATCHED - triggering music player!', {
            pattern: pattern.source,
            aiResponse: aiResponse.substring(0, 200),
            userMessage: finalMessageText,
            isMobile: /Mobile|Android|iPhone|iPad/i.test(navigator.userAgent),
            viewport: { width: window.innerWidth, height: window.innerHeight }
          });

          // Try to extract music query from various sources
          let query = 'hudba';

          // 1. Look for artist/song in AI response (e.g., "s AC/DC", "pro Pink Floyd")
          const aiQueryMatch = aiResponse.match(/(?:s|se|pro|for|with|na)\s+["']?([^"'.!?]+?)(?:["'.!?]|\.|$)/i);
          if (aiQueryMatch && aiQueryMatch[1] && aiQueryMatch[1].trim().length > 2) {
            query = aiQueryMatch[1].trim();
            console.log('🎵 Extracted query from AI response:', query);
          } else {
            // 2. Fall back to user's original message
            const userQueryMatch = finalMessageText.match(/(?:hraj|pusť|pust|přehraj|zahraj|play)\s+(.+)/i);
            if (userQueryMatch && userQueryMatch[1]) {
              query = userQueryMatch[1].trim();
              console.log('🎵 Extracted query from user message:', query);
            }
          }

          console.log('🎵 Opening music player with query:', query);
          setCurrentMusicQuery(query);
          setIsMusicPlayerOpen(true);
          musicPlayerOpened = true;

          console.log('🎵 Music player state updated:', {
            isMusicPlayerOpen: true,
            currentMusicQuery: query,
            timestamp: new Date().toISOString()
          });

          // Force re-render and scroll to bottom to show the player
          setTimeout(() => {
            scrollToBottom();
          }, 100);

          break;
        }
      }

      if (!musicPlayerOpened) {
        console.log('🎵 No music player pattern matched in AI response:', aiResponse.substring(0, 100));
      }

      setTimeout(async () => {
        if (memoryService.shouldExtractMemories(messages.concat([userMessage, assistantMessage]))) {
          const extracted = await memoryService.extractMemoriesFromConversation(
            messages.concat([userMessage, assistantMessage]).map(m => ({
              role: m.role as 'user' | 'assistant',
              content: m.content
            })),
            settings.sessionId
          );

          if (extracted) {
            const { data: { session } } = await supabase.auth.getSession();
            if (!session) {
              const hasShownPrompt = localStorage.getItem('memory_prompt_shown');
              if (!hasShownPrompt) {
                const count = memoryService.getSessionMemoryCount();
                if (count > 0) {
                  setMemoryPromptCount(count);
                  setShowMemoryPrompt(true);
                  localStorage.setItem('memory_prompt_shown', 'true');
                }
              }
            }
          }
        }
      }, 1000);

      const combinedText = aiResponse + ' ' + inputText;
      const crisisResult = detectCrisis(combinedText);

      if (crisisResult.level !== 'none') {
        setCrisisDetection({
          level: crisisResult.level,
          message: crisisResult.message
        });

        console.log('🚨 Crisis detected:', {
          level: crisisResult.level,
          phrases: crisisResult.detectedPhrases,
          timestamp: new Date().toISOString()
        });

        trackCrisisDetection(
          crisisResult.level as 'yellow' | 'red',
          crisisResult.detectedPhrases
        );
      }
    } catch (error) {
      console.error('❌ Chyba při generování odpovědi:', error);
      console.error('❌ Error details:', {
        name: error instanceof Error ? error.name : 'unknown',
        message: error instanceof Error ? error.message : String(error),
        stack: error instanceof Error ? error.stack : 'no stack'
      });
      const errorMessage = error instanceof Error ? error.message : 'Došlo k neočekávané chybě.';

      if (errorMessage !== 'CONVERSATION_STOPPED') {
        setError(errorMessage);

        const errorResponseMessage: Message = {
          id: (Date.now() + 1).toString(),
          content: `Chyba: ${errorMessage}`,
          role: 'assistant',
          timestamp: new Date(),
        };
        setMessages((prev) => [...prev, errorResponseMessage]);
      }
    } finally {
      setIsProcessing(false);
      abortControllerRef.current = null;
    }
  };

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    if ((!inputText.trim() && !selectedImage && !selectedVideo) || isVoiceCallActive || isProcessing) return;
    handleSendMessage(inputText);
  };


  const handleStopConversation = () => {
    if (abortControllerRef.current) {
      abortControllerRef.current.abort();
      abortControllerRef.current = null;
    }
    setIsProcessing(false);
  };

  const handleDocumentScan = async (imageData: string, documentType: DocumentType) => {
    try {
      setIsProcessing(true);

      const enhancedImage = await enhanceDocumentImage(imageData);

      const prompt = getDocumentPrompt(documentType, settings.language || 'cs', systemInstructions || undefined);

      const userPrompt = documentType === 'book'
        ? 'Analyzuj tento sken stránky z knihy. Jedná se o úryvek pro vzdělávací účely (studium jazyka, pochopení textu). Extrahuj a přelož text podle instrukcí. Překlad je pro osobní a profesionalní použití.'
        : documentType === 'general'
        ? 'Analyzuj tento dokument, detekuj jeho typ a extrahuj všechen text. Pokud jde o stránku z knihy, jedná se o dluhy úryvek pro osobní vzdělávací účely. Překlad slouží pouze pro osobní pochopení obsahu.'
        : 'Analyzuj tento dokument a extrahuj všechen text podle instrukcí.';

      const response = await generateAIResponse(
        userPrompt,
        settings.openaiApiKey || import.meta.env.VITE_OPENAI_API_KEY,
        settings.textChatModel || 'gpt-4o',
        0.3,
        [],
        undefined,
        prompt,
        enhancedImage
      );

      const analysis = analyzeDocumentContent(response);
      const smartTags = generateSmartTags(response, analysis.detectedType);

      let structuredData: any = null;
      let expenseCategory: string | undefined = undefined;

      if (analysis.detectedType === 'receipt' || documentType === 'receipt') {
        structuredData = extractReceiptData(response);
        if (structuredData) {
          expenseCategory = structuredData.category;
        }
      } else if (analysis.detectedType === 'business-card' || documentType === 'business-card') {
        structuredData = extractBusinessCardData(response);
      }

      const allTags = [...new Set([...smartTags, ...(structuredData?.suggestedTags || [])])];

      const userMessage: Message = {
        id: Date.now().toString(),
        content: `📄 Naskenovaný dokument (${analysis.detectedType})`,
        role: 'user',
        timestamp: new Date(),
        image: enhancedImage,
      };

      const enhancedResponse = `${response}\n\n---\n\n**🤖 Chytrá analýza:**\n• Typ: ${analysis.detectedType}\n• Důvěra: ${Math.round(analysis.confidence * 100)}%\n• Shrnutí: ${analysis.summary}\n${expenseCategory ? `• Kategorie: ${expenseCategory}` : ''}\n${allTags.length > 0 ? `• Štítky: ${allTags.map(t => `#${t}`).join(' ')}` : ''}`;

      const assistantMessage: Message = {
        id: (Date.now() + 1).toString(),
        content: enhancedResponse,
        role: 'assistant',
        timestamp: new Date(),
      };

      setMessages((prev) => [...prev, userMessage, assistantMessage]);

      const { data: { user } } = await supabase.auth.getUser();
      if (!user) {
        throw new Error('Skenování dokumentů vyžaduje přihlášení');
      }

      await supabase.from('scanned_documents').insert({
        user_id: user.id,
        document_type: analysis.detectedType,
        original_image_url: imageData,
        processed_image_url: enhancedImage,
        extracted_text: response,
        translated_text: response,
        source_language: 'auto',
        target_language: settings.language || 'cs',
        tags: allTags,
        structured_data: structuredData,
        ai_summary: analysis.summary,
        expense_category: expenseCategory,
        metadata: {
          model: settings.textChatModel || 'gpt-4o',
          scanned_at: new Date().toISOString(),
          confidence: analysis.confidence,
          detected_type: analysis.detectedType,
        },
      });

      const estimatedMinutes = 0.5;
      await deductMinutes(estimatedMinutes, 'document_scan');

    } catch (error) {
      console.error('Error processing document:', error);
      setError('Nepodařilo se zpracovat dokument. Zkuste to prosím znovu.');
    } finally {
      setIsProcessing(false);
    }
  };


  useEffect(() => {
    if (error && error.includes('Nemáte dostatek minut') && getMinutesRemaining() >= 1) {
      console.log('✅ Minutes restored, clearing error');
      setError(null);
    }
    if (error && error.includes('Uživatel není přihlášen') && settings.userId) {
      console.log('✅ User logged in, clearing error');
      setError(null);
    }
  }, [settings.minutesIncluded, settings.minutesUsedThisMonth, settings.userId, error, getMinutesRemaining]);

  const toggleVoiceCall = async () => {
    const newState = !isVoiceCallActive;

    if (newState) {
      setError(null);
      voiceCallStartTimeRef.current = null;
      setVoiceCallDuration(0);
      setIsConnecting(true);

      try {
        if (realtimeVoice.isConnected) {
          realtimeVoice.disconnect();
          await new Promise(resolve => setTimeout(resolve, 200));
        }

        await realtimeVoice.connect();
        await realtimeVoice.startStreaming();

        voiceCallStartTimeRef.current = Date.now();
        setIsConnecting(false);
        setIsVoiceCallActive(true);

        trackVoiceCallStart();
      } catch (err) {
        console.error('Nepodařilo se zahájit hlasový hovor:', err);
        const errorMessage = err instanceof Error ? err.message : 'Nepodařilo se zahájit hlasový hovor';
        setError(errorMessage);
        setIsConnecting(false);
        setIsVoiceCallActive(false);
        voiceCallStartTimeRef.current = null;
        return;
      }
    } else {
      await stopVoiceCall();
    }
  };


  const comingSoonFeatures = [
    { name: 'Dokumenty', icon: FileText },
    { name: 'Kalendář', icon: Calendar },
    { name: 'Vyhledávání', icon: Search },
    { name: 'Práce', icon: Briefcase },
    { name: 'Učení', icon: BookOpen },
  ];

  const activeFeatures: Array<{ name: string; icon: any }> = [
    { name: 'Opus Studio', icon: Smile },
  ];

  return (
    <div className="flex flex-col h-full bg-white">
      {comingSoonNotification && (
        <div className="absolute top-0 left-0 right-0 z-[100] animate-slide-down">
          <div className="bg-gradient-to-r from-indigo-600 via-blue-600 to-cyan-600 text-white px-6 py-4 shadow-2xl border-b-4 border-white/20">
            <div className="max-w-2xl mx-auto flex items-center justify-center gap-3">
              <div className="flex-shrink-0 w-10 h-10 bg-white/20 backdrop-blur-sm rounded-full flex items-center justify-center">
                <svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
                </svg>
              </div>
              <p className="text-center font-semibold text-base tracking-wide">
                {comingSoonNotification}
              </p>
            </div>
          </div>
        </div>
      )}

      <div
          className={`relative flex-shrink-0 ${currentHeaderColor.bg} border-b ${currentHeaderColor.border} pt-12 sm:pt-3 cursor-pointer transition-all duration-300`}
          onClick={cycleHeaderColor}
          title="Klikni pro změnu barvy"
        >
        <div className="px-3 pb-2">
          <div className="flex items-center justify-center mb-2">
            <div className="flex items-center gap-2">
              <MessageSquare className={`w-5 h-5 ${headerColorIndex === 0 ? 'text-blue-600' : currentHeaderColor.icon}`} />
              <h1 className={`text-base font-semibold ${currentHeaderColor.text}`}>AI Pokec</h1>
            </div>
          </div>

          {isVoiceCallActive && realtimeVoice.isStreaming && (
            <div className="flex justify-center mb-2" onClick={(e) => e.stopPropagation()}>
              <span className={`flex items-center gap-1.5 px-2.5 py-1 rounded-full ${headerColorIndex === 0 ? 'bg-green-50' : 'bg-white/20 backdrop-blur-sm'}`}>
                <span className="w-1.5 h-1.5 bg-green-500 rounded-full animate-pulse" />
                <span className={`text-[10px] font-medium ${headerColorIndex === 0 ? 'text-green-700' : 'text-white'}`}>Live</span>
              </span>
            </div>
          )}

          <div className="flex items-center justify-between gap-2">
            <div className="flex items-center gap-0.5">
              {activeFeatures.map((feature) => {
                const Icon = feature.icon;
                const handleClick = () => {
                  if (feature.name === 'Hudba') {
                    onNavigate && onNavigate('music');
                  } else if (feature.name === 'Developer Studio') {
                    onNavigate && onNavigate('agent');
                  } else if (feature.name === 'Code Editor') {
                    setIsCodeEditorOpen(true);
                  } else if (feature.name === 'AI Agent') {
                    setAgentTaskDetailId('__panel__');
                  } else if (feature.name === 'Opus Studio') {
                    setIsManusStudioOpen(true);
                  } else {
                    showComingSoonNotification(feature.name);
                  }
                };
                return (
                  <button
                    key={feature.name}
                    onClick={(e) => { e.stopPropagation(); handleClick(); }}
                    className={`p-2 ${currentHeaderColor.hover} rounded-lg transition-colors`}
                    title={feature.name}
                  >
                    <Icon className={`w-5 h-5 ${currentHeaderColor.icon}`} />
                  </button>
                );
              })}
            </div>

            <div className="flex items-center gap-0.5">
              <input
                type="file"
                ref={fileInputRef}
                onChange={onImageSelect}
                accept="image/*"
                className="hidden"
              />

              <input
                type="file"
                ref={videoInputRef}
                onChange={onVideoSelect}
                accept="video/*"
                className="hidden"
              />

              <div className="relative">
                <button
                  onClick={(e) => { e.stopPropagation(); setShowConversationExport(!showConversationExport); }}
                  className={`p-2 ${currentHeaderColor.hover} rounded-lg transition-colors`}
                  title="Export konverzacie"
                >
                  <Download className={`w-5 h-5 ${currentHeaderColor.icon}`} />
                </button>
                {showConversationExport && (
                  <>
                    <div className="fixed inset-0 z-[100]" onClick={() => setShowConversationExport(false)} />
                    <div className="absolute right-0 top-full mt-1 z-[101] bg-white rounded-xl shadow-xl border border-gray-200 overflow-hidden min-w-[160px]">
                      <button
                        onClick={(e) => {
                          e.stopPropagation();
                          exportConversationAsPDF(messages.map(m => ({ content: m.content, role: m.role, timestamp: m.timestamp })));
                          setShowConversationExport(false);
                        }}
                        className="w-full flex items-center gap-2.5 px-3 py-2.5 hover:bg-gray-50 active:bg-gray-100 transition-all text-left"
                      >
                        <FileText className="w-4 h-4 text-red-500" />
                        <span className="text-xs font-semibold text-gray-700">Export PDF</span>
                      </button>
                      <div className="border-t border-gray-100" />
                      <button
                        onClick={(e) => {
                          e.stopPropagation();
                          exportConversationAsTXT(messages.map(m => ({ content: m.content, role: m.role, timestamp: m.timestamp })));
                          setShowConversationExport(false);
                        }}
                        className="w-full flex items-center gap-2.5 px-3 py-2.5 hover:bg-gray-50 active:bg-gray-100 transition-all text-left"
                      >
                        <FileText className="w-4 h-4 text-blue-500" />
                        <span className="text-xs font-semibold text-gray-700">Export TXT</span>
                      </button>
                    </div>
                  </>
                )}
              </div>

              <button
                onClick={(e) => { e.stopPropagation(); onSafetyClick(); }}
                className={`p-2 ${currentHeaderColor.hover} rounded-lg transition-colors`}
                title="Safety Center"
              >
                <ShieldCheck className={`w-5 h-5 ${currentHeaderColor.icon}`} />
              </button>

              <button
                onClick={(e) => { e.stopPropagation(); onSettingsClick(); }}
                className={`p-2 ${currentHeaderColor.hover} rounded-lg transition-colors`}
              >
                <Settings className={`w-5 h-5 ${currentHeaderColor.icon}`} />
              </button>
            </div>
          </div>
        </div>
      </div>

      <div
        className="flex-1 overflow-y-auto px-3 py-3 space-y-2 scrollbar-thin scrollbar-thumb-gray-300 scrollbar-track-transparent"
        style={{
          backgroundColor: '#ECE5DD',
          backgroundImage: `url("data:image/svg+xml,%3Csvg width='60' height='60' viewBox='0 0 60 60' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cg fill='%23d4ccc4' fill-opacity='0.4'%3E%3Cpath d='M36 34v-4h-2v4h-4v2h4v4h2v-4h4v-2h-4zm0-30V0h-2v4h-4v2h4v4h2V6h4V4h-4zM6 34v-4H4v4H0v2h4v4h2v-4h4v-2H6zM6 4V0H4v4H0v2h4v4h2V6h4V4H6z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E")`,
        }}
      >
        {messages.map((message) => {
          const agentTask = agentTaskBubbles.get(message.id);
          if (agentTask) {
            return (
              <AgentChatBubble
                key={message.id}
                task={agentTask}
                onViewDetail={(id) => setAgentTaskDetailId(id)}
              />
            );
          }
          return <MessageBubble key={message.id} message={message} />;
        })}

        {isProcessing && (
          <div className="flex justify-start mb-3">
            <div className="max-w-[85%]">
              <div className="px-4 py-3 bg-white rounded-3xl rounded-bl-md border border-gray-200 shadow-sm">
                <div className="flex space-x-2 items-center">
                  <div className="w-2 h-2 bg-blue-500 rounded-full animate-bounce" style={{ animationDelay: '0ms' }} />
                  <div className="w-2 h-2 bg-cyan-500 rounded-full animate-bounce" style={{ animationDelay: '150ms' }} />
                  <div className="w-2 h-2 bg-teal-500 rounded-full animate-bounce" style={{ animationDelay: '300ms' }} />
                </div>
              </div>
            </div>
          </div>
        )}

        {isMusicPlayerOpen && (
          <div className="flex justify-start mb-3 animate-bubble-appear" style={{ minHeight: '150px' }}>
            <div className="max-w-[95%] w-full md:max-w-[400px]">
              <BackgroundMusicPlayer
                isOpen={isMusicPlayerOpen}
                searchQuery={currentMusicQuery}
                onClose={() => {
                  console.log('🎵 Closing music player via onClose callback');
                  setIsMusicPlayerOpen(false);
                  setCurrentMusicQuery('');
                }}
              />
            </div>
          </div>
        )}

        <div ref={messagesEndRef} />
      </div>

      <div className="flex-shrink-0 bg-white border-t-2 border-gray-100 shadow-lg safe-area-inset-bottom">
        <div className="px-3 pb-3 pt-3">
        {error && (
          <div className="mb-3 p-3 bg-red-50 border border-red-200 rounded-2xl flex items-center space-x-2">
            <AlertCircle className="w-4 h-4 text-red-600 flex-shrink-0" />
            <p className="text-xs text-red-800 font-medium">{error}</p>
          </div>
        )}

        {isConnecting && (
          <div className="mb-3 bg-gradient-to-br from-blue-50 to-cyan-50 rounded-2xl p-3 border-2 border-blue-200">
            <div className="flex items-center justify-center gap-2">
              <div className="w-4 h-4 border-2 border-blue-600 border-t-transparent rounded-full animate-spin" />
              <span className="text-sm font-semibold text-blue-900">Připojování...</span>
            </div>
          </div>
        )}

        {isVoiceCallActive && realtimeVoice.assistantTranscript && (
          <div className="mb-3 space-y-2 max-h-32 overflow-y-auto">
            {realtimeVoice.assistantTranscript && (
              <div className="p-2 bg-green-50 border border-green-200 rounded-xl">
                <p className="text-xs text-green-600 font-semibold mb-1">AI:</p>
                <p className="text-xs text-gray-800 font-medium">{realtimeVoice.assistantTranscript}</p>
              </div>
            )}
          </div>
        )}

        {isVoiceCallActive ? (
          <div className="space-y-3">
            <div className="flex items-center justify-center gap-2 text-xs text-gray-600 font-medium">
              <Clock className="w-3.5 h-3.5 text-blue-500" />
              <span>
                {Math.floor(voiceCallDuration / 60)}:{(voiceCallDuration % 60).toString().padStart(2, '0')}
              </span>
              <span className="mx-1">•</span>
              <Coins className="w-3.5 h-3.5 text-green-600" />
              <span>{getMinutesRemaining()} min</span>
            </div>
            <div className="flex items-center justify-center gap-4">
              <button
                onClick={() => {
                  if (realtimeVoice.isStreaming) {
                    realtimeVoice.stopStreaming();
                  } else {
                    realtimeVoice.startStreaming();
                  }
                }}
                className={`flex-shrink-0 w-14 h-14 rounded-full ${realtimeVoice.isStreaming ? 'bg-gradient-to-br from-gray-500 to-gray-600' : 'bg-gradient-to-br from-blue-500 to-blue-600'} text-white flex items-center justify-center hover:scale-105 active:scale-95 transition-all shadow-lg`}
                title={realtimeVoice.isStreaming ? 'Ztlumit mikrofon' : 'Zapnout mikrofon'}
              >
                {realtimeVoice.isStreaming ? <MicOff className="w-6 h-6" /> : <Mic className="w-6 h-6" />}
              </button>
              <div className="text-center flex-1">
                <p className="text-sm text-gray-600 font-medium flex items-center justify-center gap-2">
                  {realtimeVoice.isStreaming ? (
                    <>
                      <Mic className="w-4 h-4 text-blue-500" />
                      <span>Hlasový hovor aktivní</span>
                    </>
                  ) : (
                    'Mikrofon ztlumen'
                  )}
                </p>
              </div>
              <button
                onClick={toggleVoiceCall}
                className="flex-shrink-0 w-16 h-16 rounded-full bg-gradient-to-br from-red-500 to-red-600 text-white flex items-center justify-center hover:scale-105 active:scale-95 transition-all shadow-xl"
                title="Ukončit hovor"
              >
                <PhoneOff className="w-8 h-8" />
              </button>
            </div>
          </div>
        ) : (
          <form onSubmit={handleSubmit}>
            {selectedImage && (
              <div className="mb-3 relative inline-block">
                <img
                  src={selectedImage}
                  alt="Preview"
                  className="max-h-32 rounded-xl border-2 border-gray-200"
                />
                {qrCodeData && (
                  <div className="absolute bottom-0 left-0 right-0 bg-green-500 text-white text-xs px-2 py-1 rounded-b-xl flex items-center gap-1">
                    <svg className="w-3 h-3" fill="currentColor" viewBox="0 0 20 20">
                      <path fillRule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clipRule="evenodd" />
                    </svg>
                    QR kód detekován
                  </div>
                )}
                <button
                  type="button"
                  onClick={onClearImage}
                  className="absolute -top-2 -right-2 w-6 h-6 bg-red-500 text-white rounded-full flex items-center justify-center hover:bg-red-600 shadow-lg"
                >
                  <X className="w-4 h-4" />
                </button>
              </div>
            )}
            {selectedVideo && (
              <div className="mb-3 relative inline-block">
                <video
                  src={selectedVideo}
                  controls
                  className="max-h-32 rounded-xl border-2 border-blue-300"
                />
                <div className="absolute bottom-0 left-0 right-0 bg-blue-500 text-white text-xs px-2 py-1 rounded-b-xl flex items-center gap-1">
                  <svg className="w-3 h-3" fill="currentColor" viewBox="0 0 20 20">
                    <path d="M2 6a2 2 0 012-2h6a2 2 0 012 2v8a2 2 0 01-2 2H4a2 2 0 01-2-2V6zM14.553 7.106A1 1 0 0014 8v4a1 1 0 00.553.894l2 1A1 1 0 0018 13V7a1 1 0 00-1.447-.894l-2 1z" />
                  </svg>
                  Video připraveno k analýze
                </div>
                <button
                  type="button"
                  onClick={onClearVideo}
                  className="absolute -top-2 -right-2 w-6 h-6 bg-red-500 text-white rounded-full flex items-center justify-center hover:bg-red-600 shadow-lg"
                >
                  <X className="w-4 h-4" />
                </button>
              </div>
            )}

            {crisisDetection && (
              <div className="mb-3">
                <CrisisBanner
                  level={crisisDetection.level}
                  message={crisisDetection.message}
                  onDismiss={(isFalsePositive) => {
                    if (isFalsePositive) {
                      console.log('✅ False positive dismissed');
                      trackCrisisDetection(
                        crisisDetection.level as 'yellow' | 'red',
                        [],
                        true
                      );
                    } else {
                      console.log('❌ Crisis banner closed');
                    }
                    setCrisisDetection(null);
                  }}
                />
              </div>
            )}

            <div className="flex items-center gap-2">
              <button
                type="button"
                onClick={toggleVoiceCall}
                disabled={isConnecting}
                className={`flex-shrink-0 w-14 h-14 rounded-full bg-gradient-to-br from-green-500 to-green-600 text-white flex items-center justify-center hover:scale-105 active:scale-95 transition-all shadow-lg ${isConnecting ? 'opacity-50 cursor-not-allowed' : ''}`}
              >
                {isConnecting ? (
                  <div className="w-6 h-6 border-2 border-white border-t-transparent rounded-full animate-spin" />
                ) : (
                  <Phone className="w-6 h-6" />
                )}
              </button>

              <input
                id="chat-message-input"
                name="message"
                type="text"
                value={inputText}
                onChange={(e) => setInputText(e.target.value)}
                placeholder="Zpráva"
                disabled={isProcessing}
                autoComplete="off"
                className={`flex-1 px-4 py-3.5 rounded-full bg-gray-100 border-2 border-gray-200 focus:${colors.border} focus:bg-white focus:outline-none transition-all disabled:opacity-50 text-base min-w-0`}
              />

              {isSpeaking && (
                <button
                  type="button"
                  onClick={stopSpeaking}
                  className="flex-shrink-0 w-14 h-14 rounded-full bg-gradient-to-br from-orange-500 to-orange-600 text-white flex items-center justify-center hover:scale-105 active:scale-95 transition-all shadow-lg"
                  title="Zastavit řeč"
                >
                  <Square className="w-6 h-6 fill-current" />
                </button>
              )}
              {isProcessing ? (
                <button
                  type="button"
                  onClick={handleStopConversation}
                  className="flex-shrink-0 w-14 h-14 rounded-full bg-gradient-to-br from-red-500 to-red-600 text-white flex items-center justify-center hover:scale-105 active:scale-95 transition-all shadow-lg"
                >
                  <Square className="w-6 h-6 fill-current" />
                </button>
              ) : (
                <button
                  type="submit"
                  disabled={!inputText.trim() && !selectedImage && !selectedVideo}
                  className={`flex-shrink-0 w-14 h-14 rounded-full bg-gradient-to-br ${colors.gradient} text-white flex items-center justify-center hover:scale-105 active:scale-95 transition-all shadow-lg disabled:opacity-50 disabled:cursor-not-allowed`}
                >
                  <Send className="w-6 h-6" />
                </button>
              )}
            </div>
          </form>
        )}
        </div>
      </div>

      <DocumentScannerModal
        isOpen={isDocumentScannerOpen}
        onClose={() => setIsDocumentScannerOpen(false)}
        onScanComplete={handleDocumentScan}
        onOpenHistory={() => setIsScanHistoryOpen(true)}
      />

      <ScanHistoryModal
        isOpen={isScanHistoryOpen}
        onClose={() => setIsScanHistoryOpen(false)}
        onDocumentSelect={(doc) => {
          setIsScanHistoryOpen(false);
          if (doc.translated_text) {
            setMessages((prev) => [...prev, {
              id: Date.now().toString(),
              content: doc.translated_text!,
              role: 'assistant',
              timestamp: new Date(),
              image: doc.processed_image_url || doc.original_image_url,
            }]);
          }
        }}
      />

      <CodeEditorModal
        isOpen={isCodeEditorOpen}
        onClose={() => setIsCodeEditorOpen(false)}
      />

      <DocumentsManagerModal
        isOpen={isDocumentsManagerOpen}
        onClose={() => setIsDocumentsManagerOpen(false)}
      />

      <ManusStudioModal
        isOpen={isManusStudioOpen}
        onClose={() => setIsManusStudioOpen(false)}
      />

      {showMemoryPrompt && (
        <MemoryPromptToast
          memoryCount={memoryPromptCount}
          onSignIn={() => {
            setShowMemoryPrompt(false);
            onSettingsClick();
          }}
          onClose={() => {
            setShowMemoryPrompt(false);
          }}
        />
      )}

      {agentTaskDetailId === '__panel__' && (
        <div className="fixed inset-0 z-50 flex items-end sm:items-center justify-center">
          <div className="absolute inset-0 bg-black/70 backdrop-blur-sm" onClick={() => setAgentTaskDetailId(null)} />
          <div className="relative w-full sm:max-w-lg sm:mx-4 max-h-[85vh] bg-slate-900 sm:rounded-3xl rounded-t-3xl shadow-2xl overflow-hidden flex flex-col">
            <AgentTaskPanel
              tasks={agentTasks.tasks}
              activeTasks={agentTasks.activeTasks}
              completedTasks={agentTasks.completedTasks}
              pendingConfirmations={agentTasks.pendingConfirmations}
              isLoading={agentTasks.isLoading}
              onViewDetail={(id) => setAgentTaskDetailId(id)}
              onCancelTask={agentTasks.handleCancelTask}
              onConfirmation={agentTasks.handleConfirmation}
              onRefresh={agentTasks.refreshTasks}
            />
          </div>
        </div>
      )}

      {agentTaskDetailId && agentTaskDetailId !== '__panel__' && (
        <AgentTaskDetailModal
          isOpen={true}
          onClose={() => setAgentTaskDetailId(null)}
          taskId={agentTaskDetailId}
          userId={settings.userId || ''}
          onConfirmation={agentTasks.handleConfirmation}
          onCancel={agentTasks.handleCancelTask}
          getTaskDetail={agentTasks.getTaskDetail}
        />
      )}
    </div>
  );
};
