/**
 * Debug Screen - Voice Call Testing with Detailed Logs
 *
 * All-in-one screen for testing Julia AI voice:
 * - Start/End call buttons
 * - Speaker/Earpiece toggle with logging
 * - Real-time logs of all LiveKit events
 * - Copy logs button
 * - Works on both iOS and Android
 */

import React, { useState, useEffect, useRef, useCallback } from 'react';
import {
  View,
  Text,
  StyleSheet,
  FlatList,
  TouchableOpacity,
  Platform,
  Share,
  AppState,
  AppStateStatus,
  TextInput,
  KeyboardAvoidingView,
} from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import { Ionicons } from '@expo/vector-icons';
import * as Clipboard from 'expo-clipboard';
import { activateKeepAwakeAsync, deactivateKeepAwake } from 'expo-keep-awake';
import type { Room as RoomType } from 'livekit-client';
import { AppColors, BorderRadius, FontSizes, Spacing } from '@/constants/theme';
import { getToken, VOICE_NAME } from '@/services/livekitService';
import { api } from '@/services/api';
import { useBeneficiary } from '@/contexts/BeneficiaryContext';
import {
  configureAudioForVoiceCall,
  stopAudioSession,
} from '@/utils/audioSession';
import {
  startVoiceCallService,
  stopVoiceCallService,
  checkAndPromptBatteryOptimization,
  requestNotificationPermission,
} from '@/utils/androidVoiceService';
import Constants from 'expo-constants';

const APP_VERSION = Constants.expoConfig?.version ?? '?.?.?';

type LogEntry = {
  id: string;
  time: string;
  message: string;
  type: 'info' | 'success' | 'error' | 'event';
};

type CallState = 'idle' | 'connecting' | 'connected' | 'ending';

export default function DebugScreen() {
  const [logs, setLogs] = useState<LogEntry[]>([]);
  const [callState, setCallState] = useState<CallState>('idle');
  const [callDuration, setCallDuration] = useState(0);
  const [agentState, setAgentState] = useState<string>('—'); // listening/thinking/speaking
  const [lastUserText, setLastUserText] = useState<string>(''); // Последний распознанный текст пользователя
  const [lastAgentText, setLastAgentText] = useState<string>(''); // Последний ответ агента
  const [micLevel, setMicLevel] = useState<number>(0); // Уровень микрофона 0-100
  const [deploymentId, setDeploymentIdState] = useState<string>(''); // Custom deployment ID
  const [loadingBeneficiary, setLoadingBeneficiary] = useState(true);
  const [accumulateResponses, setAccumulateResponses] = useState(true); // Накапливать chunks до полного ответа
  const flatListRef = useRef<FlatList>(null);

  // Refs для накопления chunks
  const accumulatedUserTextRef = useRef<string>('');
  const accumulatedAgentTextRef = useRef<string>('');
  const lastUserSegmentIdRef = useRef<string | null>(null);
  const lastAgentSegmentIdRef = useRef<string | null>(null);
  const roomRef = useRef<RoomType | null>(null);
  const callStartTimeRef = useRef<number | null>(null);
  const appStateRef = useRef<AppStateStatus>(AppState.currentState);

  const { currentBeneficiary, setDebugDeploymentId } = useBeneficiary();

  // Sync deploymentId with context for voice-call.tsx to use
  const setDeploymentId = useCallback((id: string) => {
    setDeploymentIdState(id);
    // Update context so voice-call.tsx can access it
    setDebugDeploymentId(id.trim() || null);
  }, [setDebugDeploymentId]);

  // Load default deployment ID from first beneficiary
  useEffect(() => {
    const loadDefaultDeploymentId = async () => {
      try {
        // First check if currentBeneficiary is available
        if (currentBeneficiary?.id) {
          const id = currentBeneficiary.id.toString();
          setDeploymentIdState(id);
          setDebugDeploymentId(id); // Also set in context
          setLoadingBeneficiary(false);
          return;
        }

        // Otherwise load from API
        const response = await api.getAllBeneficiaries();
        if (response.ok && response.data && response.data.length > 0) {
          const firstBeneficiary = response.data[0];
          const id = firstBeneficiary.id.toString();
          setDeploymentIdState(id);
          setDebugDeploymentId(id); // Also set in context
        }
      } catch (error) {
        console.error('[Debug] Failed to load beneficiary:', error);
      } finally {
        setLoadingBeneficiary(false);
      }
    };

    loadDefaultDeploymentId();
  }, [currentBeneficiary, setDebugDeploymentId]);

  // Add log entry
  const log = useCallback((message: string, type: LogEntry['type'] = 'info') => {
    const time = new Date().toLocaleTimeString('en-US', { hour12: false, hour: '2-digit', minute: '2-digit', second: '2-digit' });
    const ms = String(new Date().getMilliseconds()).padStart(3, '0');
    setLogs(prev => [...prev, {
      id: `${Date.now()}-${Math.random()}`,
      time: `${time}.${ms}`,
      message,
      type,
    }]);
  }, []);

  // Clear logs
  const clearLogs = useCallback(() => {
    setLogs([]);
  }, []);

  // Copy logs to clipboard
  const copyLogs = useCallback(async () => {
    const text = logs.map(l => `[${l.time}] ${l.message}`).join('\n');
    await Clipboard.setStringAsync(text);
    log('Logs copied to clipboard!', 'success');
  }, [logs, log]);

  // Share logs
  const shareLogs = useCallback(async () => {
    const text = logs.map(l => `[${l.time}] ${l.message}`).join('\n');
    try {
      await Share.share({ message: text, title: 'Voice Debug Logs' });
    } catch (e) {
      log(`Share failed: ${e}`, 'error');
    }
  }, [logs, log]);

  // Auto-scroll to bottom
  useEffect(() => {
    if (logs.length > 0) {
      setTimeout(() => flatListRef.current?.scrollToEnd({ animated: true }), 100);
    }
  }, [logs]);

  // Call duration timer
  useEffect(() => {
    if (callState !== 'connected') return;
    const interval = setInterval(() => {
      if (callStartTimeRef.current) {
        setCallDuration(Math.floor((Date.now() - callStartTimeRef.current) / 1000));
      }
    }, 1000);
    return () => clearInterval(interval);
  }, [callState]);

  // Handle app background/foreground
  useEffect(() => {
    const subscription = AppState.addEventListener('change', (nextAppState) => {
      if (appStateRef.current.match(/inactive|background/) && nextAppState === 'active') {
        log('App returned to foreground', 'event');
      } else if (appStateRef.current === 'active' && nextAppState.match(/inactive|background/)) {
        log('App went to background - call continues', 'event');
      }
      appStateRef.current = nextAppState;
    });
    return () => subscription.remove();
  }, [log]);

  // Start call
  const startCall = useCallback(async () => {
    if (callState !== 'idle') return;

    clearLogs();
    setCallState('connecting');
    setCallDuration(0);
    callStartTimeRef.current = null;

    try {
      log('=== STARTING VOICE CALL ===', 'info');
      log(`Platform: ${Platform.OS} ${Platform.Version}`, 'info');

      // Android: Request notification permission and check battery optimization
      if (Platform.OS === 'android') {
        log('Android: Requesting notification permission...', 'info');
        const notifPermission = await requestNotificationPermission();
        log(`Notification permission: ${notifPermission ? 'granted' : 'denied'}`, notifPermission ? 'success' : 'info');

        log('Android: Checking battery optimization...', 'info');
        const canProceed = await checkAndPromptBatteryOptimization();
        if (!canProceed) {
          log('User went to battery settings - call postponed', 'info');
          setCallState('idle');
          return;
        }
        log('Battery optimization check passed', 'success');
      }

      // Keep screen awake
      await activateKeepAwakeAsync('voiceCall').catch(() => {});
      log('Screen keep-awake activated', 'info');

      // Step 1: Register WebRTC globals
      log('Step 1: Importing @livekit/react-native...', 'info');
      const { registerGlobals } = await import('@livekit/react-native');

      if (typeof global.RTCPeerConnection === 'undefined') {
        log('Registering WebRTC globals...', 'info');
        registerGlobals();
        log('WebRTC globals registered', 'success');
      } else {
        log('WebRTC globals already registered', 'info');
      }

      // Step 2: Import livekit-client
      log('Step 2: Importing livekit-client...', 'info');
      const { Room, RoomEvent, ConnectionState, Track } = await import('livekit-client');
      log('livekit-client imported', 'success');

      // Step 3: Configure AudioSession (iOS + Android)
      log(`Step 3: Configuring AudioSession for ${Platform.OS}...`, 'info');
      try {
        await configureAudioForVoiceCall();
        log(`AudioSession configured for ${Platform.OS}`, 'success');
      } catch (audioErr: any) {
        log(`AudioSession config error: ${audioErr?.message || audioErr}`, 'error');
        // Continue anyway - might still work
      }

      // Step 4: Get token from server
      log('Step 4: Requesting token from server...', 'info');
      log(`Token server: wellnuo.smartlaunchhub.com/julia/token`, 'info');

      // Передаём deployment ID если указан
      const beneficiaryData = deploymentId.trim() ? {
        deploymentId: deploymentId.trim(),
        beneficiaryNamesDict: {},
      } : undefined;

      if (beneficiaryData) {
        log(`📋 Using custom Deployment ID: ${deploymentId}`, 'success');
      } else {
        log(`📋 No Deployment ID specified (default mode)`, 'info');
      }

      const result = await getToken(`user-${Date.now()}`, beneficiaryData);

      if (!result.success || !result.data) {
        throw new Error(result.error || 'Failed to get token');
      }

      const { token, wsUrl, roomName } = result.data;
      log(`Token received`, 'success');
      log(`Room: ${roomName}`, 'info');
      log(`WebSocket URL: ${wsUrl}`, 'info');

      // Step 5: Create room and setup listeners
      log('Step 5: Creating Room instance...', 'info');
      const newRoom = new Room();
      roomRef.current = newRoom;
      log('Room instance created', 'success');

      // Setup ALL event listeners
      log('Step 6: Setting up event listeners...', 'info');

      newRoom.on(RoomEvent.ConnectionStateChanged, (state: any) => {
        log(`EVENT: ConnectionStateChanged → ${state}`, 'event');
        if (state === ConnectionState.Connected) {
          setCallState('connected');
          callStartTimeRef.current = Date.now();
        } else if (state === ConnectionState.Disconnected) {
          setCallState('idle');
        }
      });

      newRoom.on(RoomEvent.Connected, () => {
        log('EVENT: Connected to room', 'success');
      });

      newRoom.on(RoomEvent.Disconnected, (reason?: any) => {
        log(`EVENT: Disconnected. Reason: ${reason || 'unknown'}`, 'event');
      });

      newRoom.on(RoomEvent.Reconnecting, () => {
        log('EVENT: Reconnecting...', 'event');
      });

      newRoom.on(RoomEvent.Reconnected, () => {
        log('EVENT: Reconnected', 'success');
      });

      newRoom.on(RoomEvent.ParticipantConnected, (participant: any) => {
        log(`👋 PARTICIPANT CONNECTED: ${participant.identity}`, 'success');

        // Подписаться на события этого участника (для агента Julia)
        participant.on('isSpeakingChanged', (speaking: boolean) => {
          if (speaking) {
            log(`🔊 ${participant.identity} STARTED SPEAKING`, 'success');
            setAgentState('speaking');
          } else {
            log(`🔇 ${participant.identity} stopped speaking`, 'info');
          }
        });

        participant.on('trackMuted', (pub: any) => {
          log(`🔇 ${participant.identity} muted ${pub.kind}`, 'event');
        });

        participant.on('trackUnmuted', (pub: any) => {
          log(`🔊 ${participant.identity} unmuted ${pub.kind}`, 'event');
        });

        participant.on('attributesChanged', (attrs: any) => {
          log(`📋 ${participant.identity} ATTRIBUTES:`, 'event');
          Object.entries(attrs || {}).forEach(([k, v]) => {
            log(`  ${k}: ${v}`, 'info');
            if (k === 'lk.agent.state') {
              setAgentState(String(v));
            }
          });
        });

        participant.on('transcriptionReceived', (segments: any[]) => {
          log(`🤖 ${participant.identity} TRANSCRIPTION:`, 'success');
          segments.forEach((seg: any, i: number) => {
            const text = seg.text || seg.final || '';
            log(`  [${i}] "${text}"`, 'info');
            if (text) setLastAgentText(text);
          });
        });

        // Показать текущие атрибуты участника
        const attrs = participant.attributes || {};
        if (Object.keys(attrs).length > 0) {
          log(`  Initial attributes: ${JSON.stringify(attrs)}`, 'info');
        }
      });

      newRoom.on(RoomEvent.ParticipantDisconnected, (participant: any) => {
        log(`👋 PARTICIPANT DISCONNECTED: ${participant.identity}`, 'event');
      });

      newRoom.on(RoomEvent.TrackSubscribed, (track: any, publication: any, participant: any) => {
        log(`EVENT: Track subscribed: ${track.kind} from ${participant.identity}`, 'event');
        if (track.kind === Track.Kind.Audio) {
          log('Audio track from Julia AI - should hear voice now', 'success');
        }
      });

      newRoom.on(RoomEvent.TrackUnsubscribed, (track: any, publication: any, participant: any) => {
        log(`EVENT: Track unsubscribed: ${track.kind} from ${participant.identity}`, 'event');
      });

      newRoom.on(RoomEvent.TrackMuted, (publication: any, participant: any) => {
        log(`EVENT: Track muted by ${participant.identity}`, 'event');
      });

      newRoom.on(RoomEvent.TrackUnmuted, (publication: any, participant: any) => {
        log(`EVENT: Track unmuted by ${participant.identity}`, 'event');
      });

      newRoom.on(RoomEvent.ActiveSpeakersChanged, (speakers: any[]) => {
        if (speakers.length > 0) {
          log(`EVENT: Active speakers: ${speakers.map(s => s.identity).join(', ')}`, 'event');
        }
      });

      newRoom.on(RoomEvent.DataReceived, (payload: any, participant: any, kind: any, topic: any) => {
        log(`📩 DATA RECEIVED from ${participant?.identity || 'unknown'}`, 'event');
        log(`  kind: ${kind}, topic: ${topic || 'none'}`, 'info');
        try {
          const text = new TextDecoder().decode(payload);
          const data = JSON.parse(text);
          log(`  type: ${data.type || 'unknown'}`, 'info');

          // Подробное логирование разных типов сообщений
          if (data.type === 'transcript' || data.type === 'transcription') {
            log(`  🗣️ TRANSCRIPT: role=${data.role}`, 'success');
            const text = data.text || data.content || '';
            log(`  📝 TEXT: "${text}"`, 'success');
            // Обновить UI
            if (data.role === 'user') {
              setLastUserText(text);
            } else if (data.role === 'assistant' || data.role === 'agent') {
              setLastAgentText(text);
            }
          } else if (data.type === 'state' || data.type === 'agent_state') {
            const stateValue = data.state || JSON.stringify(data);
            log(`  🤖 AGENT STATE: ${stateValue}`, 'success');
            setAgentState(stateValue);
          } else if (data.type === 'function_call' || data.type === 'tool_call') {
            log(`  🔧 FUNCTION CALL: ${data.name || data.function || JSON.stringify(data)}`, 'event');
          } else if (data.type === 'function_result' || data.type === 'tool_result') {
            log(`  ✅ FUNCTION RESULT: ${JSON.stringify(data.result || data).substring(0, 200)}`, 'event');
          } else {
            // Показать полный JSON для неизвестных типов
            log(`  📦 FULL DATA: ${JSON.stringify(data)}`, 'info');
          }
        } catch (e) {
          // Попробовать показать как текст
          try {
            const text = new TextDecoder().decode(payload);
            log(`  📄 RAW TEXT: "${text.substring(0, 300)}"`, 'info');
          } catch {
            log(`  📎 BINARY DATA: ${payload.byteLength} bytes`, 'info');
          }
        }
      });

      newRoom.on(RoomEvent.AudioPlaybackStatusChanged, () => {
        log(`EVENT: AudioPlaybackStatusChanged - canPlay: ${newRoom.canPlaybackAudio}`, 'event');
      });

      newRoom.on(RoomEvent.MediaDevicesError, (error: any) => {
        log(`EVENT: MediaDevicesError: ${error?.message || error}`, 'error');
      });

      newRoom.on(RoomEvent.RoomMetadataChanged, (metadata: string) => {
        log(`EVENT: RoomMetadataChanged: ${metadata}`, 'event');
      });

      // ===========================================
      // TRANSCRIPTION - распознанный текст (STT)
      // ===========================================
      newRoom.on(RoomEvent.TranscriptionReceived, (segments: any[], participant: any) => {
        const isUser = participant?.identity === newRoom.localParticipant.identity;
        const who = isUser ? '👤 USER' : '🤖 AGENT';

        segments.forEach((segment: any, idx: number) => {
          const text = segment.text || segment.final || '';
          const segmentId = segment.id || `seg-${Date.now()}`;
          const isFinalFlag = segment.final !== undefined;

          if (accumulateResponses) {
            // === РЕЖИМ НАКОПЛЕНИЯ: Показываем только финальные полные ответы ===
            if (isUser) {
              // Новый сегмент или продолжение текущего
              if (lastUserSegmentIdRef.current !== segmentId) {
                // Если был предыдущий финальный - логируем его
                if (accumulatedUserTextRef.current && lastUserSegmentIdRef.current) {
                  log(`👤 USER FINAL: "${accumulatedUserTextRef.current}"`, 'success');
                }
                accumulatedUserTextRef.current = text;
                lastUserSegmentIdRef.current = segmentId;
              } else {
                // Обновляем текущий сегмент
                accumulatedUserTextRef.current = text;
              }

              // Если финальный - логируем сразу
              if (isFinalFlag && text) {
                log(`👤 USER: "${text}"`, 'success');
                setLastUserText(text);
                accumulatedUserTextRef.current = '';
                lastUserSegmentIdRef.current = null;
              }
            } else {
              // AGENT
              if (lastAgentSegmentIdRef.current !== segmentId) {
                if (accumulatedAgentTextRef.current && lastAgentSegmentIdRef.current) {
                  log(`🤖 AGENT FINAL: "${accumulatedAgentTextRef.current}"`, 'success');
                }
                accumulatedAgentTextRef.current = text;
                lastAgentSegmentIdRef.current = segmentId;
              } else {
                accumulatedAgentTextRef.current = text;
              }

              if (isFinalFlag && text) {
                log(`🤖 JULIA: "${text}"`, 'success');
                setLastAgentText(text);
                accumulatedAgentTextRef.current = '';
                lastAgentSegmentIdRef.current = null;
              }
            }
          } else {
            // === РЕЖИМ ПОЛНОГО ЛОГИРОВАНИЯ: Показываем каждый chunk ===
            const finalLabel = isFinalFlag ? '(FINAL)' : '(interim)';
            log(`🎤 TRANSCRIPTION from ${who} (${participant?.identity || 'unknown'})`, 'success');
            log(`  [${idx}] ${finalLabel}: "${text}"`, 'event');
            if (segment.id) log(`    segment.id: ${segment.id}`, 'info');
            if (segment.firstReceivedTime) log(`    firstReceivedTime: ${segment.firstReceivedTime}`, 'info');
            if (segment.lastReceivedTime) log(`    lastReceivedTime: ${segment.lastReceivedTime}`, 'info');

            // Обновить UI с последним текстом
            if (text && (isFinalFlag || !segment.final)) {
              if (isUser) {
                setLastUserText(text);
              } else {
                setLastAgentText(text);
              }
            }
          }
        });
      });

      // ===========================================
      // PARTICIPANT ATTRIBUTES - состояние агента
      // ===========================================
      newRoom.on(RoomEvent.ParticipantAttributesChanged, (changedAttributes: any, participant: any) => {
        log(`👤 ATTRIBUTES CHANGED for ${participant?.identity || 'unknown'}`, 'event');
        Object.entries(changedAttributes || {}).forEach(([key, value]) => {
          log(`  ${key}: ${value}`, 'info');
          // Особенно важно: lk.agent.state показывает listening/thinking/speaking
          if (key === 'lk.agent.state') {
            log(`  🤖 AGENT STATE: ${value}`, 'success');
            // Обновить UI
            setAgentState(String(value));
          }
        });
        // Показать все текущие атрибуты
        const attrs = participant?.attributes || {};
        if (Object.keys(attrs).length > 0) {
          log(`  All attributes: ${JSON.stringify(attrs)}`, 'info');
        }
      });

      // ===========================================
      // SIGNAL CONNECTED/RECONNECTING
      // ===========================================
      newRoom.on(RoomEvent.SignalConnected, () => {
        log('EVENT: SignalConnected - WebSocket подключен', 'success');
      });

      newRoom.on(RoomEvent.SignalReconnecting, () => {
        log('EVENT: SignalReconnecting - переподключение сигнала...', 'event');
      });

      // ===========================================
      // LOCAL TRACK UNPUBLISHED
      // ===========================================
      newRoom.on(RoomEvent.LocalTrackUnpublished, (publication: any, participant: any) => {
        log(`EVENT: LocalTrackUnpublished - ${publication.trackSid}`, 'event');
      });

      // ===========================================
      // ДОПОЛНИТЕЛЬНЫЕ СОБЫТИЯ ДЛЯ ПОЛНОГО ДЕБАГА
      // ===========================================

      // Качество соединения
      newRoom.on(RoomEvent.ConnectionQualityChanged, (quality: any, participant: any) => {
        const qualityEmoji = quality === 'excellent' ? '🟢' : quality === 'good' ? '🟡' : '🔴';
        log(`${qualityEmoji} CONNECTION QUALITY: ${participant?.identity || 'local'} → ${quality}`, 'event');
      });

      // Изменение устройств (микрофон/камера подключены/отключены)
      newRoom.on(RoomEvent.MediaDevicesChanged, () => {
        log(`🔌 MEDIA DEVICES CHANGED - устройства обновились`, 'event');
      });

      // Изменение активного устройства
      newRoom.on(RoomEvent.ActiveDeviceChanged, (kind: any, deviceId: any) => {
        log(`🎛️ ACTIVE DEVICE CHANGED: ${kind} → ${deviceId}`, 'event');
      });

      // Ошибка подписки на трек
      newRoom.on(RoomEvent.TrackSubscriptionFailed, (trackSid: any, participant: any, reason: any) => {
        log(`❌ TRACK SUBSCRIPTION FAILED: ${trackSid} from ${participant?.identity}`, 'error');
        log(`  Reason: ${reason}`, 'error');
      });

      // Публикация трека (когда агент начинает говорить)
      newRoom.on(RoomEvent.TrackPublished, (publication: any, participant: any) => {
        log(`📢 TRACK PUBLISHED by ${participant?.identity}: ${publication.kind} (${publication.source})`, 'event');
      });

      // Отмена публикации трека
      newRoom.on(RoomEvent.TrackUnpublished, (publication: any, participant: any) => {
        log(`📤 TRACK UNPUBLISHED by ${participant?.identity}: ${publication.kind}`, 'event');
      });

      // Изменение метаданных участника
      newRoom.on(RoomEvent.ParticipantMetadataChanged, (metadata: any, participant: any) => {
        log(`📋 PARTICIPANT METADATA: ${participant?.identity}`, 'event');
        try {
          const parsed = JSON.parse(metadata || '{}');
          log(`  ${JSON.stringify(parsed)}`, 'info');
        } catch {
          log(`  ${metadata}`, 'info');
        }
      });

      // Изменение имени участника
      newRoom.on(RoomEvent.ParticipantNameChanged, (name: any, participant: any) => {
        log(`👤 PARTICIPANT NAME: ${participant?.identity} → ${name}`, 'event');
      });

      // Статус записи (если комната записывается)
      newRoom.on(RoomEvent.RecordingStatusChanged, (recording: any) => {
        log(`⏺️ RECORDING STATUS: ${recording ? 'RECORDING' : 'NOT RECORDING'}`, recording ? 'success' : 'info');
      });

      // Изменение статуса потока трека
      newRoom.on(RoomEvent.TrackStreamStateChanged, (publication: any, streamState: any, participant: any) => {
        log(`📊 TRACK STREAM STATE: ${participant?.identity}/${publication.trackSid} → ${streamState}`, 'event');
      });

      // Разрешения на подписку трека
      newRoom.on(RoomEvent.TrackSubscriptionPermissionChanged, (publication: any, status: any, participant: any) => {
        log(`🔐 TRACK PERMISSION: ${participant?.identity}/${publication.trackSid} → ${status}`, 'event');
      });

      // Статус подписки на трек
      newRoom.on(RoomEvent.TrackSubscriptionStatusChanged, (publication: any, status: any, participant: any) => {
        log(`📶 TRACK SUBSCRIPTION: ${participant?.identity}/${publication.trackSid} → ${status}`, 'event');
      });

      // Разрешения участника изменились
      newRoom.on(RoomEvent.ParticipantPermissionsChanged, (prevPermissions: any, participant: any) => {
        log(`🔑 PARTICIPANT PERMISSIONS CHANGED: ${participant?.identity}`, 'event');
        log(`  New permissions: ${JSON.stringify(participant?.permissions || {})}`, 'info');
      });

      // ChatMessage - сообщения в чате комнаты
      newRoom.on(RoomEvent.ChatMessage, (message: any, participant: any) => {
        log(`💬 CHAT MESSAGE from ${participant?.identity || 'system'}:`, 'success');
        log(`  ${message.message || JSON.stringify(message)}`, 'info');
      });

      // SIP DTMF - телефонные сигналы
      newRoom.on(RoomEvent.SipDTMFReceived, (dtmf: any, participant: any) => {
        log(`📞 SIP DTMF: ${dtmf.code} from ${participant?.identity}`, 'event');
      });

      // Детекция тишины микрофона
      newRoom.on(RoomEvent.LocalAudioSilenceDetected, (publication: any) => {
        log(`🔇 LOCAL AUDIO SILENCE DETECTED - микрофон молчит`, 'event');
      });

      // Изменения буфера DataChannel
      newRoom.on(RoomEvent.DCBufferStatusChanged, (isLow: any, kind: any) => {
        log(`📦 DC BUFFER: ${kind} buffer is ${isLow ? 'LOW' : 'OK'}`, isLow ? 'event' : 'info');
      });

      // Метрики производительности
      newRoom.on(RoomEvent.MetricsReceived, (metrics: any) => {
        log(`📈 METRICS RECEIVED:`, 'info');
        if (metrics.audioStats) {
          log(`  Audio: bitrate=${metrics.audioStats.bitrate}, packetsLost=${metrics.audioStats.packetsLost}`, 'info');
        }
        if (metrics.videoStats) {
          log(`  Video: bitrate=${metrics.videoStats.bitrate}, fps=${metrics.videoStats.fps}`, 'info');
        }
      });

      // Статус воспроизведения видео (если есть)
      newRoom.on(RoomEvent.VideoPlaybackStatusChanged, () => {
        log(`🎬 VIDEO PLAYBACK STATUS CHANGED`, 'event');
      });

      // Ошибка шифрования
      newRoom.on(RoomEvent.EncryptionError, (error: any) => {
        log(`🔒 ENCRYPTION ERROR: ${error?.message || error}`, 'error');
      });

      // Статус шифрования участника
      newRoom.on(RoomEvent.ParticipantEncryptionStatusChanged, (encrypted: any, participant: any) => {
        log(`🔐 ENCRYPTION STATUS: ${participant?.identity} → ${encrypted ? 'encrypted' : 'not encrypted'}`, 'event');
      });

      // Комната перемещена (редко)
      newRoom.on(RoomEvent.Moved, (room: any) => {
        log(`🚀 ROOM MOVED to new server`, 'event');
      });

      // Участник стал активным
      newRoom.on(RoomEvent.ParticipantActive, (participant: any) => {
        log(`✅ PARTICIPANT ACTIVE: ${participant?.identity}`, 'success');

        // Проверяем, что это агент Julia (не локальный участник)
        const isAgent = participant?.identity?.startsWith('agent-') ||
                       (participant?.attributes?.['lk.agent_name'] === 'julia-ai');

        if (isAgent) {
          log(``, 'success');
          log(`🟢🟢🟢 AGENT READY 🟢🟢🟢`, 'success');
          log(`🔊 Julia will now speak greeting...`, 'success');
          log(``, 'success');
        }
      });

      log('Event listeners set up (FULL DEBUG MODE)', 'success');

      // Step 7: Connect to room
      log('Step 7: Connecting to LiveKit room...', 'info');
      await newRoom.connect(wsUrl, token, { autoSubscribe: true });
      log('Connected to room', 'success');

      // Step 7.5: Start audio playback (required for iOS)
      log('Step 7.5: Starting audio playback...', 'info');
      await newRoom.startAudio();
      log(`Audio playback started, canPlay: ${newRoom.canPlaybackAudio}`, 'success');

      // Step 8: Enable microphone
      log('Step 8: Enabling microphone...', 'info');
      await newRoom.localParticipant.setMicrophoneEnabled(true);
      log('Microphone enabled', 'success');

      // Step 9: Log local audio track info
      log('Step 9: Checking local audio track...', 'info');
      const localAudioTracks = newRoom.localParticipant.audioTrackPublications;
      log(`Local audio publications: ${localAudioTracks.size}`, 'info');

      localAudioTracks.forEach((pub: any) => {
        log(`Local audio track: ${pub.trackSid}, muted: ${pub.isMuted}, source: ${pub.source}`, 'info');
        if (pub.track) {
          log(`Track mediaStreamTrack: ${pub.track.mediaStreamTrack ? 'exists' : 'NULL'}`, 'info');
          log(`Track enabled: ${pub.track.mediaStreamTrack?.enabled}`, 'info');
        }
      });

      // ===========================================
      // LOCAL PARTICIPANT EVENTS - события моего микрофона
      // ===========================================
      newRoom.localParticipant.on('localTrackPublished', (pub: any) => {
        log(`🎤 MY TRACK PUBLISHED: ${pub.kind} sid=${pub.trackSid}`, 'success');
      });

      newRoom.localParticipant.on('localTrackUnpublished', (pub: any) => {
        log(`🎤 MY TRACK UNPUBLISHED: ${pub.kind} sid=${pub.trackSid}`, 'event');
      });

      // IsSpeakingChanged - когда я начинаю/перестаю говорить
      newRoom.localParticipant.on('isSpeakingChanged', (speaking: boolean) => {
        if (speaking) {
          log(`🗣️ >>> I STARTED SPEAKING <<<`, 'success');
        } else {
          log(`🤐 I stopped speaking`, 'info');
        }
      });

      // Мой трек замьютился/размьютился
      newRoom.localParticipant.on('trackMuted', (pub: any) => {
        log(`🔇 MY TRACK MUTED: ${pub.kind}`, 'event');
      });

      newRoom.localParticipant.on('trackUnmuted', (pub: any) => {
        log(`🔊 MY TRACK UNMUTED: ${pub.kind}`, 'success');
      });

      // Ошибка медиа устройства на моём участнике
      newRoom.localParticipant.on('mediaDevicesError', (error: any) => {
        log(`❌ MY MEDIA DEVICE ERROR: ${error?.message || error}`, 'error');
      });

      // Аудио поток захвачен
      newRoom.localParticipant.on('audioStreamAcquired', () => {
        log(`🎙️ AUDIO STREAM ACQUIRED - микрофон захвачен!`, 'success');
      });

      // Транскрипция на моём треке
      newRoom.localParticipant.on('transcriptionReceived', (segments: any[]) => {
        log(`🎤 MY TRANSCRIPTION (${segments.length} segments):`, 'success');
        segments.forEach((seg: any, i: number) => {
          log(`  [${i}] "${seg.text || seg.final}"`, 'info');
        });
      });

      // Listen when I become an active speaker (means mic is working)
      newRoom.on(RoomEvent.ActiveSpeakersChanged, (speakers: any[]) => {
        const iAmSpeaking = speakers.some(s => s.identity === newRoom.localParticipant.identity);
        if (iAmSpeaking) {
          log(`🎙️ *** I AM SPEAKING - MIC WORKS! ***`, 'success');
        }
      });

      log(`Local participant: ${newRoom.localParticipant.identity}`, 'info');

      // ===========================================
      // AUDIO LEVEL MONITORING - периодическая проверка уровня микрофона
      // ===========================================
      let audioLevelInterval: ReturnType<typeof setInterval> | null = null;
      let lastLoggedLevel = -1;

      const startAudioLevelMonitoring = () => {
        if (audioLevelInterval) return;

        audioLevelInterval = setInterval(() => {
          try {
            // Найти microphone track среди всех публикаций
            const audioTracks = newRoom.localParticipant.audioTrackPublications;
            let localAudioTrack: any = null;
            audioTracks.forEach((pub: any) => {
              if (pub.source === 'microphone' || pub.kind === 'audio') {
                localAudioTrack = pub;
              }
            });
            if (localAudioTrack?.track) {
              // Получаем audio level через LiveKit API
              const audioLevel = (localAudioTrack.track as any).audioLevel;
              if (audioLevel !== undefined) {
                const roundedLevel = Math.round(audioLevel * 100);
                // Обновить UI
                setMicLevel(roundedLevel);
                // Логируем только когда уровень существенно изменился
                if (Math.abs(roundedLevel - lastLoggedLevel) > 5) {
                  lastLoggedLevel = roundedLevel;
                  const bars = '▓'.repeat(Math.min(20, Math.round(audioLevel * 20))) + '░'.repeat(Math.max(0, 20 - Math.round(audioLevel * 20)));
                  log(`🎚️ MIC LEVEL: [${bars}] ${roundedLevel}%`, audioLevel > 0.1 ? 'success' : 'info');
                }
              }
            }
          } catch (e) {
            // Ignore errors
          }
        }, 200); // Проверять каждые 200мс для плавного UI
      };

      // Запустить мониторинг audio level после подключения
      newRoom.on(RoomEvent.Connected, () => {
        log('Starting audio level monitoring...', 'info');
        setTimeout(startAudioLevelMonitoring, 1000);
      });

      // Остановить при отключении
      newRoom.on(RoomEvent.Disconnected, () => {
        if (audioLevelInterval) {
          clearInterval(audioLevelInterval);
          audioLevelInterval = null;
        }
      });

      // Android: Start foreground service to keep call alive in background
      if (Platform.OS === 'android') {
        log('Android: Starting foreground service...', 'info');
        try {
          await startVoiceCallService();
          log('Foreground service started - call will continue in background', 'success');
        } catch (fgErr: any) {
          log(`Foreground service error: ${fgErr?.message || fgErr}`, 'error');
          // Continue anyway - call will still work, just may be killed in background
        }
      }

      log('=== CALL ACTIVE ===', 'success');

    } catch (err: any) {
      log(`ERROR: ${err?.message || err}`, 'error');
      log(`Stack: ${err?.stack?.substring(0, 200) || 'no stack'}`, 'error');
      setCallState('idle');
      deactivateKeepAwake('voiceCall');
    }
  }, [callState, log, clearLogs]);

  // End call
  const endCall = useCallback(async () => {
    if (callState === 'idle') return;

    log('=== ENDING CALL ===', 'info');
    setCallState('ending');

    try {
      if (roomRef.current) {
        log('Disconnecting from room...', 'info');
        await roomRef.current.disconnect();
        roomRef.current = null;
        log('Disconnected from room', 'success');
      }

      // Android: Stop foreground service
      if (Platform.OS === 'android') {
        log('Android: Stopping foreground service...', 'info');
        try {
          await stopVoiceCallService();
          log('Foreground service stopped', 'success');
        } catch (fgErr: any) {
          log(`Foreground service stop error: ${fgErr?.message || fgErr}`, 'error');
        }
      }

      // Stop AudioSession (iOS + Android)
      log(`Stopping AudioSession on ${Platform.OS}...`, 'info');
      try {
        await stopAudioSession();
        log('AudioSession stopped', 'success');
      } catch (audioErr: any) {
        log(`AudioSession stop error: ${audioErr?.message || audioErr}`, 'error');
      }

      deactivateKeepAwake('voiceCall');
      log('Screen keep-awake deactivated', 'info');

    } catch (err: any) {
      log(`Error during cleanup: ${err?.message || err}`, 'error');
    }

    setCallState('idle');
    log('=== CALL ENDED ===', 'info');
  }, [callState, log]);

  // Format duration
  const formatDuration = (seconds: number): string => {
    const mins = Math.floor(seconds / 60);
    const secs = seconds % 60;
    return `${mins}:${secs.toString().padStart(2, '0')}`;
  };

  // Get log color
  const getLogColor = (type: LogEntry['type']): string => {
    switch (type) {
      case 'success': return '#4ade80';
      case 'error': return '#f87171';
      case 'event': return '#60a5fa';
      default: return '#e5e5e5';
    }
  };

  return (
    <SafeAreaView style={styles.container} edges={['top']}>
      {/* Header */}
      <View style={styles.header}>
        <View style={styles.headerRow}>
          <Text style={styles.title}>Voice Debug</Text>
          <Text style={styles.versionBadge}>v{APP_VERSION}</Text>
        </View>
        <Text style={styles.subtitle}>{VOICE_NAME}</Text>
      </View>

      {/* Call Status */}
      <View style={styles.statusBar}>
        <View style={styles.statusLeft}>
          <View style={[
            styles.statusDot,
            { backgroundColor: callState === 'connected' ? '#4ade80' : callState === 'connecting' ? '#fbbf24' : '#6b7280' }
          ]} />
          <Text style={styles.statusText}>
            {callState === 'idle' && 'Ready'}
            {callState === 'connecting' && 'Connecting...'}
            {callState === 'connected' && `Connected ${formatDuration(callDuration)}`}
            {callState === 'ending' && 'Ending...'}
          </Text>
        </View>
        <Text style={styles.logCount}>{logs.length} logs</Text>
      </View>

      {/* Deployment ID Input */}
      {callState === 'idle' && (
        <View style={styles.deploymentIdContainer}>
          <Text style={styles.deploymentIdLabel}>Deployment ID (optional):</Text>
          <TextInput
            style={styles.deploymentIdInput}
            value={deploymentId}
            onChangeText={setDeploymentId}
            placeholder="Enter deployment ID..."
            placeholderTextColor="#6b7280"
            keyboardType="default"
            autoCapitalize="none"
            autoCorrect={false}
          />
          {deploymentId.trim() && (
            <TouchableOpacity
              style={styles.clearDeploymentId}
              onPress={() => setDeploymentId('')}
            >
              <Ionicons name="close-circle" size={20} color="#6b7280" />
            </TouchableOpacity>
          )}
        </View>
      )}

      {/* Log Mode Toggle */}
      <View style={styles.logModeContainer}>
        <Text style={styles.logModeLabel}>Log mode:</Text>
        <TouchableOpacity
          style={[styles.logModeButton, accumulateResponses && styles.logModeButtonActive]}
          onPress={() => setAccumulateResponses(true)}
        >
          <Text style={[styles.logModeButtonText, accumulateResponses && styles.logModeButtonTextActive]}>
            Clean (final only)
          </Text>
        </TouchableOpacity>
        <TouchableOpacity
          style={[styles.logModeButton, !accumulateResponses && styles.logModeButtonActive]}
          onPress={() => setAccumulateResponses(false)}
        >
          <Text style={[styles.logModeButtonText, !accumulateResponses && styles.logModeButtonTextActive]}>
            Verbose (all chunks)
          </Text>
        </TouchableOpacity>
      </View>

      {/* Control Buttons - Row 1: Call controls */}
      <View style={styles.controls}>
        {callState === 'idle' ? (
          <TouchableOpacity style={styles.startButton} onPress={startCall}>
            <Ionicons name="call" size={24} color="#fff" />
            <Text style={styles.buttonText}>Start Call</Text>
          </TouchableOpacity>
        ) : (
          <TouchableOpacity
            style={styles.endButton}
            onPress={endCall}
            disabled={callState === 'ending'}
          >
            <Ionicons name="call" size={24} color="#fff" style={{ transform: [{ rotate: '135deg' }] }} />
            <Text style={styles.buttonText}>End Call</Text>
          </TouchableOpacity>
        )}

      </View>

      {/* Control Buttons - Row 2: Log controls */}
      <View style={styles.controlsRow2}>
        <TouchableOpacity style={styles.copyButton} onPress={copyLogs}>
          <Ionicons name="copy" size={20} color="#fff" />
          <Text style={styles.smallButtonText}>Copy</Text>
        </TouchableOpacity>

        <TouchableOpacity style={styles.shareButton} onPress={shareLogs}>
          <Ionicons name="share" size={20} color="#fff" />
          <Text style={styles.smallButtonText}>Share</Text>
        </TouchableOpacity>

        <TouchableOpacity style={styles.clearButton} onPress={clearLogs}>
          <Ionicons name="trash" size={20} color="#fff" />
          <Text style={styles.smallButtonText}>Clear</Text>
        </TouchableOpacity>

        <View style={styles.platformBadge}>
          <Text style={styles.platformText}>{Platform.OS} {Platform.Version}</Text>
        </View>
      </View>

      {/* ========== LIVE STATUS PANEL ========== */}
      {callState === 'connected' && (
        <View style={styles.liveStatusPanel}>
          {/* Agent State */}
          <View style={styles.liveStatusRow}>
            <Text style={styles.liveStatusLabel}>🤖 Agent:</Text>
            <View style={[
              styles.agentStateBadge,
              agentState === 'speaking' && styles.agentStateSpeaking,
              agentState === 'thinking' && styles.agentStateThinking,
              agentState === 'listening' && styles.agentStateListening,
            ]}>
              <Text style={styles.agentStateText}>
                {agentState === 'speaking' ? '🔊 SPEAKING' :
                 agentState === 'thinking' ? '🧠 THINKING' :
                 agentState === 'listening' ? '👂 LISTENING' :
                 agentState}
              </Text>
            </View>
          </View>

          {/* Mic Level */}
          <View style={styles.liveStatusRow}>
            <Text style={styles.liveStatusLabel}>🎙️ Mic:</Text>
            <View style={styles.micLevelContainer}>
              <View style={[styles.micLevelBar, { width: `${Math.min(100, micLevel)}%` }]} />
            </View>
            <Text style={styles.micLevelText}>{micLevel}%</Text>
          </View>

          {/* Last User Text */}
          {lastUserText ? (
            <View style={styles.liveStatusRow}>
              <Text style={styles.liveStatusLabel}>👤 You:</Text>
              <Text style={styles.transcriptText} numberOfLines={2}>{lastUserText}</Text>
            </View>
          ) : null}

          {/* Last Agent Text */}
          {lastAgentText ? (
            <View style={styles.liveStatusRow}>
              <Text style={styles.liveStatusLabel}>🤖 Julia:</Text>
              <Text style={styles.transcriptText} numberOfLines={2}>{lastAgentText}</Text>
            </View>
          ) : null}
        </View>
      )}

      {/* Logs */}
      <FlatList
        ref={flatListRef}
        data={logs}
        keyExtractor={(item) => item.id}
        style={styles.logsList}
        contentContainerStyle={styles.logsContent}
        renderItem={({ item }) => (
          <Text style={[styles.logEntry, { color: getLogColor(item.type) }]}>
            <Text style={styles.logTime}>[{item.time}]</Text> {item.message}
          </Text>
        )}
        ListEmptyComponent={
          <View style={styles.emptyContainer}>
            <Ionicons name="terminal" size={48} color="#6b7280" />
            <Text style={styles.emptyText}>Press "Start Call" to begin</Text>
          </View>
        }
      />
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#0f0f0f',
  },
  header: {
    padding: Spacing.md,
    borderBottomWidth: 1,
    borderBottomColor: '#333',
  },
  headerRow: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
  },
  title: {
    fontSize: 24,
    fontWeight: '700',
    color: '#fff',
  },
  versionBadge: {
    fontSize: 14,
    fontWeight: '600',
    color: '#22c55e',
    backgroundColor: 'rgba(34, 197, 94, 0.15)',
    paddingHorizontal: 10,
    paddingVertical: 4,
    borderRadius: 8,
    overflow: 'hidden',
  },
  subtitle: {
    fontSize: 14,
    color: '#888',
    marginTop: 2,
  },
  statusBar: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
    paddingHorizontal: Spacing.md,
    paddingVertical: Spacing.sm,
    backgroundColor: '#1a1a1a',
  },
  statusLeft: {
    flexDirection: 'row',
    alignItems: 'center',
  },
  statusDot: {
    width: 10,
    height: 10,
    borderRadius: 5,
    marginRight: 8,
  },
  statusText: {
    color: '#fff',
    fontSize: 14,
    fontWeight: '500',
  },
  logCount: {
    color: '#888',
    fontSize: 12,
  },
  deploymentIdContainer: {
    flexDirection: 'row',
    alignItems: 'center',
    paddingHorizontal: Spacing.md,
    paddingVertical: Spacing.sm,
    backgroundColor: '#1f1f1f',
    borderBottomWidth: 1,
    borderBottomColor: '#333',
  },
  deploymentIdLabel: {
    color: '#9ca3af',
    fontSize: 12,
    marginRight: 8,
  },
  deploymentIdInput: {
    flex: 1,
    backgroundColor: '#2a2a2a',
    color: '#fff',
    fontSize: 14,
    paddingVertical: 8,
    paddingHorizontal: 12,
    borderRadius: 8,
    borderWidth: 1,
    borderColor: '#404040',
  },
  clearDeploymentId: {
    marginLeft: 8,
    padding: 4,
  },
  logModeContainer: {
    flexDirection: 'row',
    alignItems: 'center',
    paddingHorizontal: Spacing.md,
    paddingVertical: Spacing.xs,
    backgroundColor: '#1a1a1a',
    gap: 8,
  },
  logModeLabel: {
    color: '#9ca3af',
    fontSize: 12,
    marginRight: 4,
  },
  logModeButton: {
    paddingHorizontal: 10,
    paddingVertical: 5,
    borderRadius: 6,
    backgroundColor: '#333',
    borderWidth: 1,
    borderColor: '#404040',
  },
  logModeButtonActive: {
    backgroundColor: '#3b82f6',
    borderColor: '#3b82f6',
  },
  logModeButtonText: {
    color: '#888',
    fontSize: 11,
    fontWeight: '500',
  },
  logModeButtonTextActive: {
    color: '#fff',
  },
  controls: {
    flexDirection: 'row',
    padding: Spacing.md,
    paddingBottom: Spacing.sm,
    gap: 10,
  },
  controlsRow2: {
    flexDirection: 'row',
    paddingHorizontal: Spacing.md,
    paddingBottom: Spacing.md,
    gap: 10,
    borderBottomWidth: 1,
    borderBottomColor: '#333',
  },
  startButton: {
    flex: 1,
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'center',
    backgroundColor: '#22c55e',
    paddingVertical: 14,
    borderRadius: 12,
    gap: 8,
  },
  endButton: {
    flex: 1,
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'center',
    backgroundColor: '#ef4444',
    paddingVertical: 14,
    borderRadius: 12,
    gap: 8,
  },
  buttonText: {
    color: '#fff',
    fontSize: 16,
    fontWeight: '600',
  },
  copyButton: {
    alignItems: 'center',
    justifyContent: 'center',
    backgroundColor: '#3b82f6',
    paddingVertical: 10,
    paddingHorizontal: 12,
    borderRadius: 10,
  },
  shareButton: {
    alignItems: 'center',
    justifyContent: 'center',
    backgroundColor: '#8b5cf6',
    paddingVertical: 10,
    paddingHorizontal: 12,
    borderRadius: 10,
  },
  clearButton: {
    alignItems: 'center',
    justifyContent: 'center',
    backgroundColor: '#6b7280',
    paddingVertical: 10,
    paddingHorizontal: 12,
    borderRadius: 10,
  },
  platformBadge: {
    flex: 1,
    alignItems: 'flex-end',
    justifyContent: 'center',
  },
  platformText: {
    color: '#888',
    fontSize: 11,
    fontWeight: '500',
  },
  smallButtonText: {
    color: '#fff',
    fontSize: 10,
    fontWeight: '500',
    marginTop: 2,
  },
  logsList: {
    flex: 1,
  },
  logsContent: {
    padding: Spacing.sm,
    paddingBottom: 100,
  },
  logEntry: {
    fontSize: 12,
    fontFamily: Platform.OS === 'ios' ? 'Menlo' : 'monospace',
    lineHeight: 18,
    marginBottom: 2,
  },
  logTime: {
    color: '#888',
  },
  emptyContainer: {
    alignItems: 'center',
    justifyContent: 'center',
    paddingTop: 100,
  },
  emptyText: {
    color: '#6b7280',
    fontSize: 16,
    marginTop: 12,
  },
  // ========== LIVE STATUS PANEL STYLES ==========
  liveStatusPanel: {
    backgroundColor: '#1a1a1a',
    borderBottomWidth: 1,
    borderBottomColor: '#333',
    padding: Spacing.sm,
    gap: 6,
  },
  liveStatusRow: {
    flexDirection: 'row',
    alignItems: 'center',
    gap: 8,
  },
  liveStatusLabel: {
    color: '#888',
    fontSize: 11,
    fontWeight: '600',
    width: 55,
  },
  agentStateBadge: {
    paddingHorizontal: 8,
    paddingVertical: 3,
    borderRadius: 6,
    backgroundColor: '#333',
  },
  agentStateSpeaking: {
    backgroundColor: '#22c55e',
  },
  agentStateThinking: {
    backgroundColor: '#f59e0b',
  },
  agentStateListening: {
    backgroundColor: '#3b82f6',
  },
  agentStateText: {
    color: '#fff',
    fontSize: 11,
    fontWeight: '700',
  },
  micLevelContainer: {
    flex: 1,
    height: 8,
    backgroundColor: '#333',
    borderRadius: 4,
    overflow: 'hidden',
  },
  micLevelBar: {
    height: '100%',
    backgroundColor: '#22c55e',
    borderRadius: 4,
  },
  micLevelText: {
    color: '#888',
    fontSize: 11,
    fontWeight: '600',
    width: 35,
    textAlign: 'right',
  },
  transcriptText: {
    flex: 1,
    color: '#e5e5e5',
    fontSize: 11,
    fontStyle: 'italic',
  },
});
