<script setup lang="ts">
import { ref, onMounted, onUnmounted, watch } from 'vue'
import { RouterView, useRoute, useRouter } from 'vue-router'
import StatusBar from './components/StatusBar.vue'
import Toolbar from './components/Toolbar.vue'
import ComponentsDropdown from './components/ComponentsDropdown.vue'
import ToolsDropdown from './components/ToolsDropdown.vue'
// ConnectionDropdown removed - replaced with debug console
import FloatingTerminal from './components/FloatingTerminal.vue'
import FloatingResponse from './components/FloatingResponse.vue'
import FloatingVoice from './components/FloatingVoice.vue'
import PwaInstallBanner from './components/PwaInstallBanner.vue'
import { initWebMCP, getWebMCP, startTokenPolling, stopTokenPolling, connectWithToken } from './services/webmcp'
import { endpoints } from './config/endpoints'
import { initToolRegistry, activatePageTools, initToolsOnRefresh } from './services/toolRegistry'
import { setTerminalControls } from './services/tools/handlers/terminalHandlers'
import { setResponseControls } from './services/tools/handlers/responseHandlers'
import { useCanvasStore } from './stores/canvas'

const route = useRoute()
const router = useRouter()
const showTerminal = ref(false)
const showVoice = ref(false)
const showDebugConsole = ref(false)
const debugLogs = ref<Array<{ type: string; message: string; time: string }>>([])

// Intercept console.log for debug panel
const originalConsoleLog = console.log
const originalConsoleWarn = console.warn
const originalConsoleError = console.error

function addDebugLog(type: string, args: any[]) {
  const message = args.map(a => typeof a === 'object' ? JSON.stringify(a) : String(a)).join(' ')
  const time = new Date().toLocaleTimeString()
  debugLogs.value.push({ type, message, time })
  // Keep only last 100 logs
  if (debugLogs.value.length > 100) {
    debugLogs.value.shift()
  }
}

console.log = (...args) => {
  originalConsoleLog.apply(console, args)
  addDebugLog('log', args)
}
console.warn = (...args) => {
  originalConsoleWarn.apply(console, args)
  addDebugLog('warn', args)
}
console.error = (...args) => {
  originalConsoleError.apply(console, args)
  addDebugLog('error', args)
}

function copyDebugLogs() {
  const text = debugLogs.value.map(l => `[${l.time}] [${l.type}] ${l.message}`).join('\n')
  navigator.clipboard.writeText(text)
  canvasStore.showNotification('Logs copied!', 'success')
}

function clearDebugLogs() {
  debugLogs.value = []
}
const terminalRef = ref<InstanceType<typeof FloatingTerminal> | null>(null)
const responseRef = ref<InstanceType<typeof FloatingResponse> | null>(null)
const voiceRef = ref<InstanceType<typeof FloatingVoice> | null>(null)
const canvasStore = useCanvasStore()

// Voice FAB push-to-talk state
const voicePTTActive = ref(false)
let voiceTouchStarted = false
let voicePTTTimeout: number | null = null

// Claude status state (for FAB animations)
type ClaudeStatus = 'idle' | 'processing' | 'toolUse' | 'toolDone' | 'reading' | 'writing' | 'sessionStart' | 'subagentStart' | 'subagentStop' | 'notification' | 'permissionRequest' | 'thinking'

const claudeStatus = ref<ClaudeStatus>('idle')
const claudeTool = ref<string | null>(null)
const isProcessing = ref(false)       // Main processing state (UserPromptSubmit → Stop)
const isReading = ref(false)          // Reading files
const isWriting = ref(false)          // Writing files
const hasSubagent = ref(false)        // Subagent active
const awaitingPermission = ref(false) // Waiting for user permission (highest priority)
const showSessionStart = ref(false)   // Session start animation (3s)
const showNotification = ref(false)   // Notification pulse (2s)
const showToolFlash = ref(false)      // Tool use flash (500ms)

let statusWs: WebSocket | null = null
let statusReconnectTimeout: number | null = null
let processingTimeout: number | null = null
let sessionStartTimeout: number | null = null
let notificationTimeout: number | null = null
let toolFlashTimeout: number | null = null

function hardRefresh() {
  location.reload()
}

// Voice FAB push-to-talk handlers
function handleVoiceFabClick() {
  // If touch just ended, ignore click
  if (voiceTouchStarted) {
    voiceTouchStarted = false
    return
  }
  // Normal click: toggle panel
  showVoice.value = !showVoice.value
}

function handleVoiceFabTouchStart(e: TouchEvent) {
  e.preventDefault()
  voiceTouchStarted = true
  voicePTTActive.value = true

  // Open panel and start recording
  showVoice.value = true

  // Wait a moment for panel to open, then start recording
  setTimeout(() => {
    voiceRef.value?.startRecording()
  }, 100)
}

function handleVoiceFabTouchEnd(e: TouchEvent) {
  e.preventDefault()

  if (!voicePTTActive.value) return

  // Add buffer before stopping
  voicePTTTimeout = window.setTimeout(() => {
    voiceRef.value?.stopRecordingAndSend()
    voicePTTActive.value = false
  }, 1000)

  setTimeout(() => { voiceTouchStarted = false }, 100)
}

function connectStatusWs() {
  if (statusWs?.readyState === WebSocket.OPEN) return

  statusWs = new WebSocket(endpoints.claudeStatus)

  statusWs.onopen = () => {
    console.log('[App] Status WebSocket connected')
  }

  statusWs.onmessage = (event) => {
    try {
      const msg = JSON.parse(event.data)
      if (msg.type === 'claude-status') {
        const status = msg.status as ClaudeStatus
        console.log('[App] Claude status:', status, msg.tool)
        claudeStatus.value = status
        claudeTool.value = msg.tool || null

        // Handle different status types
        switch (status) {
          case 'processing':
          case 'thinking':
            isProcessing.value = true
            // Auto-reset after 2 minutes (safety)
            if (processingTimeout) clearTimeout(processingTimeout)
            processingTimeout = window.setTimeout(() => {
              isProcessing.value = false
            }, 120000)
            break

          case 'idle':
            isProcessing.value = false
            isReading.value = false
            isWriting.value = false
            awaitingPermission.value = false
            if (processingTimeout) clearTimeout(processingTimeout)
            break

          case 'permissionRequest':
            awaitingPermission.value = true
            break

          case 'reading':
            isReading.value = true
            triggerToolFlash()
            break

          case 'writing':
            isWriting.value = true
            triggerToolFlash()
            break

          case 'toolUse':
            triggerToolFlash()
            break

          case 'toolDone':
            isReading.value = false
            isWriting.value = false
            awaitingPermission.value = false
            break

          case 'sessionStart':
            showSessionStart.value = true
            if (sessionStartTimeout) clearTimeout(sessionStartTimeout)
            sessionStartTimeout = window.setTimeout(() => {
              showSessionStart.value = false
            }, 3000)
            break

          case 'subagentStart':
            hasSubagent.value = true
            break

          case 'subagentStop':
            hasSubagent.value = false
            break

          case 'notification':
            showNotification.value = true
            if (notificationTimeout) clearTimeout(notificationTimeout)
            notificationTimeout = window.setTimeout(() => {
              showNotification.value = false
            }, 2000)
            break
        }
      }
    } catch { /* ignore non-JSON messages */ }
  }

  statusWs.onclose = () => {
    isProcessing.value = false
    statusReconnectTimeout = window.setTimeout(connectStatusWs, 2000)
  }
}

function triggerToolFlash() {
  showToolFlash.value = true
  if (toolFlashTimeout) clearTimeout(toolFlashTimeout)
  toolFlashTimeout = window.setTimeout(() => {
    showToolFlash.value = false
  }, 500)
}

type PageName = 'home' | 'canvas' | 'components' | 'themes' | 'projects' | 'project-canvas' | 'database' | 'source' | 'terminal' | 'tools'

onMounted(async () => {
  // Connect to WebSocket for Claude status updates
  connectStatusWs()

  // Initialize WebMCP connection
  await initWebMCP()

  // Initialize tool registry with router
  initToolRegistry(router)

  // Initialize tools for current page (handles refresh)
  const currentPage = (route.name as string) || 'canvas'
  initToolsOnRefresh(currentPage as PageName)

  // Setup terminal controls for MCP tools
  setTerminalControls({
    open: (x?: number, y?: number) => {
      if (terminalRef.value) {
        terminalRef.value.open(x, y)
      } else {
        showTerminal.value = true
      }
    },
    close: () => {
      if (terminalRef.value) {
        terminalRef.value.close()
      } else {
        showTerminal.value = false
      }
    },
    toggle: () => {
      if (terminalRef.value) {
        terminalRef.value.toggle()
      } else {
        showTerminal.value = !showTerminal.value
      }
    },
    move: (x: number, y: number) => {
      terminalRef.value?.move(x, y)
    },
    resize: (w: number, h: number) => {
      terminalRef.value?.resize(w, h)
    },
    getState: () => {
      if (terminalRef.value) {
        return terminalRef.value.getState()
      }
      return { isOpen: showTerminal.value, position: { x: 0, y: 0 }, size: { w: 580, h: 360 } }
    }
  })

  // Setup response controls for MCP tools
  setResponseControls({
    addMessage: (message: string, type?: 'info' | 'success' | 'warning' | 'error') => {
      if (responseRef.value) {
        return responseRef.value.addMessage(message, type)
      }
      return ''
    },
    removeMessage: (id: string) => {
      responseRef.value?.removeMessage(id)
    },
    clearAll: () => {
      responseRef.value?.clearAll()
    },
    getMessages: () => {
      return responseRef.value?.getMessages() || []
    },
    move: (x: number, y: number) => {
      responseRef.value?.move(x, y)
    }
  })

  // Start polling for token if not connected
  const webmcp = getWebMCP()
  if (!webmcp?.isConnected) {
    startTokenPolling(async (token) => {
      console.log('[App] Token received, connecting...')
      const success = await connectWithToken(token)
      if (success) {
        canvasStore.showNotification('WebMCP connected!', 'success')
      }
    })
  }
})

onUnmounted(() => {
  stopTokenPolling()
  if (statusReconnectTimeout) clearTimeout(statusReconnectTimeout)
  if (processingTimeout) clearTimeout(processingTimeout)
  if (sessionStartTimeout) clearTimeout(sessionStartTimeout)
  if (notificationTimeout) clearTimeout(notificationTimeout)
  if (toolFlashTimeout) clearTimeout(toolFlashTimeout)
  statusWs?.close()
})

// Watch for route changes and update tools
watch(() => route.name, (newPage) => {
  if (newPage) {
    activatePageTools(newPage as PageName)
  }
})
</script>

<template>
  <div class="app-container">
    <header class="app-header">
      <div class="header-left">
        <h1 class="logo">Agent UI</h1>
        <button class="debug-btn" :class="{ active: showDebugConsole }" @click="showDebugConsole = !showDebugConsole" title="Debug Console">
          <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
            <path d="M12 20h9"/><path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z"/>
          </svg>
          <span v-if="debugLogs.length" class="log-count">{{ debugLogs.length }}</span>
        </button>
        <ComponentsDropdown />
        <ToolsDropdown />
        <PwaInstallBanner />
      </div>
      <button class="refresh-btn" @click="hardRefresh" title="Hard refresh (Ctrl+F5)">
        <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
          <path d="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8"/>
          <path d="M21 3v5h-5"/>
        </svg>
      </button>
      <StatusBar />
    </header>
    <main class="app-main">
      <Toolbar />
      <RouterView v-slot="{ Component }">
        <Transition name="page" mode="out-in">
          <component :is="Component" />
        </Transition>
      </RouterView>
    </main>

    <!-- Floating Terminal Toggle Button (Claude Life FAB) -->
    <button
      class="terminal-fab"
      :class="{
        active: showTerminal,
        processing: isProcessing,
        reading: isReading,
        writing: isWriting,
        subagent: hasSubagent,
        permission: awaitingPermission,
        'session-start': showSessionStart,
        notification: showNotification,
        'tool-flash': showToolFlash,
        'sheet-open': showTerminal || showVoice
      }"
      @click="showTerminal = !showTerminal"
      :title="awaitingPermission ? `Permiso requerido: ${claudeTool || 'herramienta'}` : isProcessing ? `Claude: ${claudeTool || 'processing'}` : 'Toggle Terminal'"
    >
      <!-- Subagent orbital ring -->
      <svg v-if="hasSubagent" class="orbital-ring" viewBox="0 0 100 100">
        <circle cx="50" cy="50" r="45" fill="none" stroke="currentColor" stroke-width="2" stroke-dasharray="20 10" />
      </svg>

      <!-- Session start ripples -->
      <div v-if="showSessionStart" class="session-ripples">
        <span></span>
        <span></span>
        <span></span>
      </div>

      <!-- Permission request icon (alert/hand) - highest priority -->
      <svg v-if="awaitingPermission" class="permission-icon" xmlns="http://www.w3.org/2000/svg" width="26" height="26" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
        <path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/>
        <line x1="12" y1="9" x2="12" y2="13"/>
        <line x1="12" y1="17" x2="12.01" y2="17"/>
      </svg>

      <!-- Processing animation (three dots) -->
      <div v-else-if="isProcessing && !isReading && !isWriting" class="thinking-dots">
        <span></span>
        <span></span>
        <span></span>
      </div>

      <!-- Reading icon (eye) -->
      <svg v-else-if="isReading" class="status-icon" xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
        <path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/>
        <circle cx="12" cy="12" r="3"/>
      </svg>

      <!-- Writing icon (pencil) -->
      <svg v-else-if="isWriting" class="status-icon" xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
        <path d="M12 19l7-7 3 3-7 7-3-3z"/>
        <path d="M18 13l-1.5-7.5L2 2l3.5 14.5L13 18l5-5z"/>
        <path d="M2 2l7.586 7.586"/>
        <circle cx="11" cy="11" r="2"/>
      </svg>

      <!-- Normal icons -->
      <template v-else>
        <!-- Terminal closed: Nucleo atom icon -->
        <svg v-if="!showTerminal" class="nucleo-icon" width="28" height="28" viewBox="0 0 24 24" fill="none">
          <!-- Core nucleus -->
          <circle cx="12" cy="12" r="3.5" fill="white" opacity="0.95"/>
          <!-- Orbital rings -->
          <ellipse cx="12" cy="12" rx="8" ry="3.5" stroke="white" stroke-width="1.3" fill="none" opacity="0.7" transform="rotate(-30 12 12)"/>
          <ellipse cx="12" cy="12" rx="8" ry="3.5" stroke="white" stroke-width="1.3" fill="none" opacity="0.5" transform="rotate(30 12 12)"/>
          <ellipse cx="12" cy="12" rx="8" ry="3.5" stroke="white" stroke-width="1.3" fill="none" opacity="0.6" transform="rotate(90 12 12)"/>
          <!-- Electrons -->
          <circle cx="12" cy="4" r="1.8" fill="white" opacity="0.9"/>
          <circle cx="19" cy="14" r="1.8" fill="white" opacity="0.7"/>
          <circle cx="5" cy="14" r="1.8" fill="white" opacity="0.8"/>
        </svg>
        <!-- Terminal open: Minimize chevron with connection indicator -->
        <template v-else>
          <span class="connection-dot"></span>
          <svg class="minimize-icon" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
            <polyline points="6 9 12 15 18 9"></polyline>
          </svg>
        </template>
      </template>
    </button>

    <!-- Voice FAB Button -->
    <button
      class="voice-fab"
      :class="{ active: showVoice, 'sheet-open': showTerminal || showVoice, 'ptt-active': voicePTTActive }"
      @click="handleVoiceFabClick"
      @touchstart="handleVoiceFabTouchStart"
      @touchend="handleVoiceFabTouchEnd"
      @touchcancel="handleVoiceFabTouchEnd"
      title="Voice Input (mantén presionado para PTT)"
    >
      <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
        <path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z"/>
        <path d="M19 10v2a7 7 0 0 1-14 0v-2"/>
        <line x1="12" y1="19" x2="12" y2="23"/>
        <line x1="8" y1="23" x2="16" y2="23"/>
      </svg>
    </button>

    <!-- Floating Terminal -->
    <FloatingTerminal ref="terminalRef" v-model="showTerminal" />

    <!-- Floating Response (Agent UI messages) -->
    <FloatingResponse ref="responseRef" />

    <!-- Floating Voice Input -->
    <FloatingVoice ref="voiceRef" v-model="showVoice" />

    <!-- Debug Console Panel -->
    <Teleport to="body">
      <Transition name="debug-slide">
        <div v-if="showDebugConsole" class="debug-console">
          <div class="debug-header">
            <span>Debug Console ({{ debugLogs.length }})</span>
            <div class="debug-actions">
              <button @click="copyDebugLogs" title="Copy all">Copy</button>
              <button @click="clearDebugLogs" title="Clear">Clear</button>
              <button @click="showDebugConsole = false" title="Close">×</button>
            </div>
          </div>
          <div class="debug-logs">
            <div
              v-for="(log, i) in debugLogs"
              :key="i"
              class="debug-log"
              :class="log.type"
              @click="navigator.clipboard.writeText(log.message)"
            >
              <span class="log-time">{{ log.time }}</span>
              <span class="log-type">{{ log.type }}</span>
              <span class="log-msg">{{ log.message }}</span>
            </div>
            <div v-if="!debugLogs.length" class="debug-empty">No logs yet</div>
          </div>
        </div>
      </Transition>
    </Teleport>
  </div>
</template>

<style scoped>
.app-container {
  display: flex;
  flex-direction: column;
  height: 100vh;
  height: 100dvh;
  background: var(--bg-primary);
}

.app-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.75rem 1.5rem;
  padding-top: calc(0.75rem + env(safe-area-inset-top, 0px));
  padding-left: calc(1.5rem + env(safe-area-inset-left, 0px));
  padding-right: calc(1.5rem + env(safe-area-inset-right, 0px));
  background: var(--bg-secondary);
  border-bottom: 1px solid var(--border-color);
  flex-shrink: 0;
}

.header-left {
  display: flex;
  align-items: center;
  gap: 1.5rem;
}

.logo {
  font-size: 1.25rem;
  font-weight: 600;
  color: var(--text-primary);
  margin: 0;
}

.refresh-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 0;
  background: transparent;
  border: 1px solid var(--border-color);
  border-radius: 6px;
  color: var(--text-secondary);
  cursor: pointer;
  transition: all 0.15s ease;
}

.refresh-btn:hover {
  background: var(--bg-hover);
  color: var(--accent);
  border-color: var(--accent);
}

.refresh-btn:active {
  transform: rotate(180deg);
}

.app-main {
  display: flex;
  flex: 1;
  overflow: hidden;
}

/* Page transitions */
.page-enter-active,
.page-leave-active {
  transition: opacity 0.2s ease, transform 0.2s ease;
}

.page-enter-from {
  opacity: 0;
  transform: translateX(20px);
}

.page-leave-to {
  opacity: 0;
  transform: translateX(-20px);
}

/* Terminal FAB - Claude Life */
.terminal-fab {
  position: fixed;
  bottom: 20px;
  right: 20px;
  width: 58px;
  height: 58px;
  border-radius: 18px;
  background: linear-gradient(145deg, #7c3aed 0%, #6366f1 50%, #8b5cf6 100%);
  color: white;
  border: 2px solid rgba(255, 255, 255, 0.15);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow:
    0 4px 15px rgba(124, 58, 237, 0.4),
    0 8px 30px rgba(99, 102, 241, 0.3),
    inset 0 1px 0 rgba(255, 255, 255, 0.2);
  transition: all 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
  z-index: 9998;
  overflow: visible;
  backdrop-filter: blur(10px);
}

.terminal-fab::before {
  content: '';
  position: absolute;
  inset: -3px;
  border-radius: 21px;
  background: linear-gradient(145deg, rgba(139, 92, 246, 0.5), rgba(99, 102, 241, 0.2));
  z-index: -1;
  opacity: 0;
  transition: opacity 0.3s ease;
}

.terminal-fab:hover {
  transform: translateY(-3px) scale(1.05);
  box-shadow:
    0 8px 25px rgba(124, 58, 237, 0.5),
    0 15px 40px rgba(99, 102, 241, 0.35),
    inset 0 1px 0 rgba(255, 255, 255, 0.25);
}

.terminal-fab:hover::before {
  opacity: 1;
}

/* Nucleo atom icon animation */
.nucleo-icon {
  animation: nucleo-orbit 8s linear infinite;
  filter: drop-shadow(0 0 6px rgba(255, 255, 255, 0.6));
}

.nucleo-icon ellipse {
  transform-origin: center;
}

/* Terminal active - Connected state */
.terminal-fab.active {
  background: linear-gradient(145deg, #6366f1 0%, #4f46e5 50%, #7c3aed 100%);
  border-color: rgba(16, 185, 129, 0.5);
  box-shadow:
    0 4px 15px rgba(99, 102, 241, 0.4),
    0 8px 30px rgba(79, 70, 229, 0.3),
    0 0 20px rgba(16, 185, 129, 0.2),
    inset 0 1px 0 rgba(255, 255, 255, 0.2);
  transform: none;
}

.terminal-fab.active:hover {
  transform: translateY(-2px);
  box-shadow:
    0 6px 20px rgba(99, 102, 241, 0.5),
    0 12px 35px rgba(79, 70, 229, 0.35),
    0 0 25px rgba(16, 185, 129, 0.3),
    inset 0 1px 0 rgba(255, 255, 255, 0.25);
}

/* Connection indicator dot */
.connection-dot {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 10px;
  height: 10px;
  background: #10b981;
  border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, 0.9);
  box-shadow: 0 0 8px rgba(16, 185, 129, 0.8);
  animation: connection-pulse 2s ease-in-out infinite;
}

/* Minimize icon */
.minimize-icon {
  opacity: 0.9;
  transition: transform 0.2s ease;
}

.terminal-fab.active:hover .minimize-icon {
  transform: translateY(2px);
}

/* Processing state (UserPromptSubmit → Stop) - Orange pulsing */
.terminal-fab.processing {
  background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%) !important;
  box-shadow: 0 8px 24px rgba(245, 158, 11, 0.4) !important;
  animation: processing-pulse 2s ease-in-out infinite !important;
  transform: rotate(0deg) !important;
}

.terminal-fab.processing:hover {
  box-shadow: 0 12px 32px rgba(245, 158, 11, 0.5) !important;
  transform: scale(1.05) !important;
}

/* Reading state - Cyan scanning */
.terminal-fab.reading {
  background: linear-gradient(135deg, #06b6d4 0%, #0891b2 100%) !important;
  box-shadow: 0 8px 24px rgba(6, 182, 212, 0.4) !important;
  animation: reading-scan 1.5s ease-in-out infinite !important;
}

/* Writing state - Green pulse */
.terminal-fab.writing {
  background: linear-gradient(135deg, #10b981 0%, #059669 100%) !important;
  box-shadow: 0 8px 24px rgba(16, 185, 129, 0.4) !important;
  animation: writing-pulse 0.8s ease-in-out infinite !important;
}

/* Subagent active - Purple with orbital ring */
.terminal-fab.subagent {
  box-shadow: 0 8px 24px rgba(139, 92, 246, 0.5) !important;
}

/* Session start - Green wake-up effect */
.terminal-fab.session-start {
  animation: session-wake 3s ease-out forwards !important;
}

/* Notification - Yellow bounce */
.terminal-fab.notification {
  animation: notification-bounce 0.5s ease-in-out 4 !important;
}

/* Permission Request - HIGHEST PRIORITY - Red pulsing alert */
.terminal-fab.permission {
  background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%) !important;
  box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.7) !important;
  animation: permission-pulse 1s ease-in-out infinite !important;
  transform: rotate(0deg) scale(1.1) !important;
  z-index: 10000 !important;
}

.terminal-fab.permission:hover {
  transform: scale(1.15) !important;
}

/* Permission icon animation */
.permission-icon {
  animation: permission-shake 0.5s ease-in-out infinite;
  filter: drop-shadow(0 0 8px rgba(255, 255, 255, 0.8));
}

/* Tool flash - Quick white flash */
.terminal-fab.tool-flash::after {
  content: '';
  position: absolute;
  inset: -4px;
  border-radius: 20px;
  background: rgba(255, 255, 255, 0.4);
  animation: tool-flash 0.5s ease-out forwards;
  pointer-events: none;
}

/* Thinking dots animation */
.thinking-dots {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
}

.thinking-dots span {
  width: 6px;
  height: 6px;
  background: white;
  border-radius: 50%;
  animation: thinking-dot 1.4s ease-in-out infinite;
}

.thinking-dots span:nth-child(1) { animation-delay: 0s; }
.thinking-dots span:nth-child(2) { animation-delay: 0.2s; }
.thinking-dots span:nth-child(3) { animation-delay: 0.4s; }

/* Status icons */
.status-icon {
  animation: icon-breathe 1s ease-in-out infinite;
}

/* Orbital ring for subagent */
.orbital-ring {
  position: absolute;
  width: 80px;
  height: 80px;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  animation: orbit-spin 3s linear infinite;
  color: rgba(139, 92, 246, 0.8);
  pointer-events: none;
}

/* Session start ripples */
.session-ripples {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.session-ripples span {
  position: absolute;
  inset: -10px;
  border: 2px solid rgba(16, 185, 129, 0.6);
  border-radius: 20px;
  animation: ripple-expand 3s ease-out forwards;
}

.session-ripples span:nth-child(1) { animation-delay: 0s; }
.session-ripples span:nth-child(2) { animation-delay: 0.5s; }
.session-ripples span:nth-child(3) { animation-delay: 1s; }

/* Keyframes */
@keyframes thinking-dot {
  0%, 80%, 100% { transform: scale(0.6); opacity: 0.5; }
  40% { transform: scale(1); opacity: 1; }
}

@keyframes processing-pulse {
  0%, 100% { box-shadow: 0 8px 24px rgba(245, 158, 11, 0.4); }
  50% { box-shadow: 0 8px 40px rgba(245, 158, 11, 0.7); }
}

@keyframes reading-scan {
  0%, 100% {
    box-shadow: 0 8px 24px rgba(6, 182, 212, 0.4);
    transform: rotate(0deg);
  }
  25% { transform: rotate(-2deg); }
  75% { transform: rotate(2deg); }
  50% {
    box-shadow: 0 8px 40px rgba(6, 182, 212, 0.7);
  }
}

@keyframes writing-pulse {
  0%, 100% {
    transform: scale(1);
    box-shadow: 0 8px 24px rgba(16, 185, 129, 0.4);
  }
  50% {
    transform: scale(1.05);
    box-shadow: 0 8px 32px rgba(16, 185, 129, 0.6);
  }
}

@keyframes session-wake {
  0% {
    transform: scale(0.8);
    opacity: 0.5;
    box-shadow: 0 0 0 rgba(16, 185, 129, 0);
  }
  30% {
    transform: scale(1.15);
    box-shadow: 0 0 60px rgba(16, 185, 129, 0.6);
  }
  60% { transform: scale(0.95); }
  100% {
    transform: scale(1);
    opacity: 1;
    box-shadow: 0 8px 24px rgba(99, 102, 241, 0.4);
  }
}

@keyframes notification-bounce {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-8px); }
}

@keyframes tool-flash {
  0% { opacity: 1; transform: scale(1); }
  100% { opacity: 0; transform: scale(1.3); }
}

@keyframes icon-breathe {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.7; }
}

@keyframes orbit-spin {
  from { transform: translate(-50%, -50%) rotate(0deg); }
  to { transform: translate(-50%, -50%) rotate(360deg); }
}

@keyframes ripple-expand {
  0% {
    transform: scale(1);
    opacity: 1;
  }
  100% {
    transform: scale(2);
    opacity: 0;
  }
}

@keyframes permission-pulse {
  0%, 100% {
    box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.7), 0 8px 24px rgba(239, 68, 68, 0.5);
    transform: scale(1.1);
  }
  50% {
    box-shadow: 0 0 0 15px rgba(239, 68, 68, 0), 0 8px 40px rgba(239, 68, 68, 0.8);
    transform: scale(1.15);
  }
}

@keyframes permission-shake {
  0%, 100% { transform: rotate(0deg); }
  25% { transform: rotate(-5deg); }
  75% { transform: rotate(5deg); }
}

@keyframes nucleo-orbit {
  0% {
    transform: rotate(0deg);
    filter: drop-shadow(0 0 6px rgba(255, 255, 255, 0.6));
  }
  50% {
    filter: drop-shadow(0 0 10px rgba(255, 255, 255, 0.9));
  }
  100% {
    transform: rotate(360deg);
    filter: drop-shadow(0 0 6px rgba(255, 255, 255, 0.6));
  }
}

@keyframes connection-pulse {
  0%, 100% {
    box-shadow: 0 0 8px rgba(16, 185, 129, 0.8);
    transform: scale(1);
  }
  50% {
    box-shadow: 0 0 12px rgba(16, 185, 129, 1), 0 0 20px rgba(16, 185, 129, 0.4);
    transform: scale(1.1);
  }
}

/* Voice FAB */
.voice-fab {
  position: fixed;
  bottom: 20px;
  left: 20px;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: linear-gradient(135deg, #10b981 0%, #059669 100%);
  color: white;
  border: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 6px 20px rgba(16, 185, 129, 0.4);
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  z-index: 9998;
}

.voice-fab:hover {
  transform: scale(1.08);
  box-shadow: 0 8px 24px rgba(16, 185, 129, 0.5);
}

.voice-fab.active {
  background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);
  box-shadow: 0 6px 20px rgba(239, 68, 68, 0.4);
}

.voice-fab.active:hover {
  box-shadow: 0 8px 24px rgba(239, 68, 68, 0.5);
}

/* Voice FAB PTT active - recording in progress */
.voice-fab.ptt-active {
  background: linear-gradient(135deg, #f97316 0%, #ea580c 100%);
  box-shadow: 0 0 30px rgba(249, 115, 22, 0.7);
  transform: scale(1.15);
  animation: ptt-pulse 0.5s ease-in-out infinite;
}

@keyframes ptt-pulse {
  0%, 100% { box-shadow: 0 0 30px rgba(249, 115, 22, 0.7); }
  50% { box-shadow: 0 0 50px rgba(249, 115, 22, 0.9); }
}

@media (max-width: 768px) {
  .terminal-fab {
    bottom: 16px;
    right: 16px;
    width: 54px;
    height: 54px;
    border-radius: 16px;
  }

  .terminal-fab::before {
    border-radius: 19px;
  }

  .connection-dot {
    width: 8px;
    height: 8px;
    top: 6px;
    right: 6px;
  }

  .orbital-ring {
    width: 70px;
    height: 70px;
  }

  .voice-fab {
    bottom: 16px;
    left: 16px;
    width: 44px;
    height: 44px;
  }
}

/* Mobile: FABs above bottom sheets */
@media (max-width: 1024px) and (pointer: coarse) {
  .terminal-fab,
  .voice-fab {
    z-index: 10001;
    transition: bottom 0.25s cubic-bezier(0.4, 0, 0.2, 1), transform 0.3s ease;
  }

  .terminal-fab.sheet-open,
  .voice-fab.sheet-open {
    bottom: calc(10vh + 16px);
  }
}

/* Debug Console Button */
.debug-btn {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 4px 8px;
  background: rgba(100, 100, 100, 0.2);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 6px;
  color: #888;
  font-size: 11px;
  cursor: pointer;
  transition: all 0.2s;
}

.debug-btn:hover {
  background: rgba(100, 100, 100, 0.3);
  color: #aaa;
}

.debug-btn.active {
  background: rgba(59, 130, 246, 0.3);
  border-color: rgba(59, 130, 246, 0.5);
  color: #60a5fa;
}

.log-count {
  background: #ef4444;
  color: white;
  font-size: 9px;
  padding: 1px 5px;
  border-radius: 10px;
  min-width: 16px;
  text-align: center;
}

/* Debug Console Panel */
.debug-console {
  position: fixed;
  top: 50px;
  left: 10px;
  right: 10px;
  bottom: 80px;
  background: rgba(20, 20, 25, 0.98);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 12px;
  z-index: 10002;
  display: flex;
  flex-direction: column;
  backdrop-filter: blur(10px);
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.5);
}

.debug-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 14px;
  background: rgba(255, 255, 255, 0.05);
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 12px 12px 0 0;
  color: #ddd;
  font-size: 12px;
  font-weight: 600;
}

.debug-actions {
  display: flex;
  gap: 8px;
}

.debug-actions button {
  padding: 4px 10px;
  background: rgba(255, 255, 255, 0.1);
  border: none;
  border-radius: 4px;
  color: #aaa;
  font-size: 11px;
  cursor: pointer;
}

.debug-actions button:hover {
  background: rgba(255, 255, 255, 0.2);
  color: #fff;
}

.debug-logs {
  flex: 1;
  overflow-y: auto;
  padding: 8px;
  font-family: 'Consolas', 'Monaco', monospace;
  font-size: 11px;
}

.debug-log {
  display: flex;
  gap: 8px;
  padding: 6px 8px;
  border-radius: 4px;
  cursor: pointer;
  border-bottom: 1px solid rgba(255, 255, 255, 0.03);
}

.debug-log:hover {
  background: rgba(255, 255, 255, 0.05);
}

.debug-log:active {
  background: rgba(59, 130, 246, 0.2);
}

.log-time {
  color: #666;
  flex-shrink: 0;
}

.log-type {
  width: 40px;
  flex-shrink: 0;
  font-weight: 600;
}

.debug-log.log .log-type { color: #888; }
.debug-log.warn .log-type { color: #f59e0b; }
.debug-log.error .log-type { color: #ef4444; }

.log-msg {
  color: #ccc;
  word-break: break-all;
}

.debug-log.warn .log-msg { color: #fcd34d; }
.debug-log.error .log-msg { color: #fca5a5; }

.debug-empty {
  color: #666;
  text-align: center;
  padding: 40px;
}

/* Debug slide animation */
.debug-slide-enter-active,
.debug-slide-leave-active {
  transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}

.debug-slide-enter-from,
.debug-slide-leave-to {
  opacity: 0;
  transform: translateY(-20px);
}
</style>
