<script setup lang="ts">
import { ref, computed, watch, nextTick, onBeforeUnmount } from 'vue'
import type { AgentName } from '@/types/transcript-debug'
import type { EphemeralTerminal } from '@/composables/useEphemeralTerminal'
import TerminalNavButtons from '../TerminalNavButtons.vue'

const props = defineProps<{
  agent: AgentName
  sessionId: string
  terminal: EphemeralTerminal | null
}>()

const AGENT_CMD: Record<AgentName, string> = {
  ejecutor: 'ejecutor',
  nucleo000: 'nucleo000',
  claude: 'claude'
}

const isOpen = ref(false)

// Local ref for xterm container - syncs to composable's containerRef
const terminalContainer = ref<HTMLElement | null>(null)

// Nav buttons toggle
const showNavButtons = ref(false)

// Drag state
const isDragging = ref(false)
const position = ref({ x: 0, y: 0 })
const hasCustomPosition = ref(false)
const dragOffset = ref({ x: 0, y: 0 })

// Resize state
const isResizing = ref(false)
const size = ref({ w: 620, h: 400 })
const resizeStart = ref({ x: 0, y: 0, w: 0, h: 0 })

const windowRef = ref<HTMLElement | null>(null)

const statusDotClass = computed(() => {
  if (!props.terminal) return ''
  switch (props.terminal.state.value) {
    case 'running':
    case 'shell-ready': return 'on'
    case 'connecting': return 'wait'
    case 'exited': return 'error'
    default: return ''
  }
})

const terminalStyle = computed((): Record<string, string> => {
  if (!hasCustomPosition.value) {
    return {
      width: `${size.value.w}px`,
      height: `${size.value.h}px`,
      bottom: '80px',
      right: '16px'
    }
  }
  return {
    width: `${size.value.w}px`,
    height: `${size.value.h}px`,
    top: `${position.value.y}px`,
    left: `${position.value.x}px`,
    bottom: 'auto',
    right: 'auto'
  }
})

// ── Open / Close ──

async function open() {
  if (isOpen.value) {
    closeTerminal()
    return
  }

  if (!props.terminal) return

  isOpen.value = true

  await nextTick()

  // Sync container ref
  if (terminalContainer.value) {
    props.terminal.containerRef.value = terminalContainer.value
  }

  // Init renderer if needed
  if (!props.terminal.renderer.isReady.value) {
    props.terminal.renderer.init()
  }

  setTimeout(() => {
    props.terminal?.renderer.fit()
    props.terminal?.renderer.terminal.value?.refresh(0, (props.terminal.renderer.terminal.value?.rows ?? 1) - 1)
    if (window.innerWidth > 1024) {
      props.terminal?.renderer.focus()
    }
  }, 150)
}

function closeTerminal() {
  isOpen.value = false
  hasCustomPosition.value = false
  showNavButtons.value = false
}

// ── Nav button actions ──

function navRunClaude() {
  props.terminal?.sendInput(AGENT_CMD[props.agent])
}

function navRunClaudeContinue() {
  props.terminal?.sendInput(AGENT_CMD[props.agent] + ' --continue')
}

function navRunClaudeResume() {
  props.terminal?.sendInput(AGENT_CMD[props.agent] + ' --resume')
}

function navRefresh() {
  props.terminal?.renderer.fit()
}

function navClearBuffer() {
  props.terminal?.renderer.reset()
}

function navSendKey(key: string) {
  const keyMap: Record<string, string> = {
    'up': '\x1b[A', 'down': '\x1b[B', 'left': '\x1b[D', 'right': '\x1b[C',
    'alt-m': '\x1bm', 'ctrl-c': '\x03', 'tab': '\t', 'esc': '\x1b'
  }
  const data = keyMap[key]
  if (data) props.terminal?.renderer.terminal.value?.paste(data)
}

function navScroll(direction: 'up' | 'down' | 'end') {
  if (!props.terminal) return
  if (direction === 'up') props.terminal.renderer.scrollLines(-10)
  else if (direction === 'down') props.terminal.renderer.scrollLines(10)
  else props.terminal.renderer.scrollToBottom()
}

function toggleNavButtons() {
  showNavButtons.value = !showNavButtons.value
}

// ── Drag ──

function startDrag(e: MouseEvent | TouchEvent) {
  if ((e.target as HTMLElement).closest('.window-controls')) return
  if (e instanceof TouchEvent) e.preventDefault()
  isDragging.value = true

  const touch = e instanceof TouchEvent ? e.touches[0] : null
  const clientX = e instanceof MouseEvent ? e.clientX : (touch?.clientX ?? 0)
  const clientY = e instanceof MouseEvent ? e.clientY : (touch?.clientY ?? 0)

  const rect = windowRef.value?.getBoundingClientRect()
  if (rect) {
    if (!hasCustomPosition.value) {
      position.value = { x: rect.left, y: rect.top }
    }
    dragOffset.value = { x: clientX - rect.left, y: clientY - rect.top }
  }
  document.addEventListener('mousemove', onDrag)
  document.addEventListener('mouseup', stopDrag)
  document.addEventListener('touchmove', onDrag, { passive: false })
  document.addEventListener('touchend', stopDrag)
}

function onDrag(e: MouseEvent | TouchEvent) {
  if (!isDragging.value) return
  if (e instanceof TouchEvent) e.preventDefault()

  const touch = e instanceof TouchEvent ? e.touches[0] : null
  const clientX = e instanceof MouseEvent ? e.clientX : (touch?.clientX ?? 0)
  const clientY = e instanceof MouseEvent ? e.clientY : (touch?.clientY ?? 0)

  const w = windowRef.value?.offsetWidth || 620
  const h = windowRef.value?.offsetHeight || 400
  position.value = {
    x: Math.max(-w * 0.75, Math.min(clientX - dragOffset.value.x, window.innerWidth - w * 0.25)),
    y: Math.max(-h * 0.75, Math.min(clientY - dragOffset.value.y, window.innerHeight - h * 0.25))
  }
}

function stopDrag() {
  isDragging.value = false
  hasCustomPosition.value = true
  document.removeEventListener('mousemove', onDrag)
  document.removeEventListener('mouseup', stopDrag)
  document.removeEventListener('touchmove', onDrag)
  document.removeEventListener('touchend', stopDrag)
}

// ── Resize ──

function startResize(e: MouseEvent) {
  e.preventDefault()
  e.stopPropagation()
  isResizing.value = true
  resizeStart.value = { x: e.clientX, y: e.clientY, w: size.value.w, h: size.value.h }
  document.addEventListener('mousemove', onResize)
  document.addEventListener('mouseup', stopResize)
}

function onResize(e: MouseEvent) {
  if (!isResizing.value) return
  size.value = {
    w: Math.max(400, Math.min(resizeStart.value.w + e.clientX - resizeStart.value.x, window.innerWidth - 40)),
    h: Math.max(250, Math.min(resizeStart.value.h + e.clientY - resizeStart.value.y, window.innerHeight - 40))
  }
}

function stopResize() {
  isResizing.value = false
  document.removeEventListener('mousemove', onResize)
  document.removeEventListener('mouseup', stopResize)
  nextTick(() => props.terminal?.renderer.fit())
}

// Sync container ref when it mounts
watch(terminalContainer, (el) => {
  if (props.terminal && el) {
    props.terminal.containerRef.value = el
  }
})

onBeforeUnmount(() => {
  document.removeEventListener('mousemove', onDrag)
  document.removeEventListener('mouseup', stopDrag)
  document.removeEventListener('touchmove', onDrag)
  document.removeEventListener('touchend', stopDrag)
  document.removeEventListener('mousemove', onResize)
  document.removeEventListener('mouseup', stopResize)
})
</script>

<template>
  <!-- Inline button -->
  <button class="resume-terminal-btn" @click.stop="open" title="Open terminal (resume session)">
    <svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
      <polyline points="4 17 10 11 4 5"/>
      <line x1="12" y1="19" x2="20" y2="19"/>
    </svg>
  </button>

  <!-- Floating terminal modal -->
  <Teleport to="body">
    <Transition name="rt-slide">
      <div
        v-show="isOpen"
        ref="windowRef"
        class="resume-terminal"
        :class="{ dragging: isDragging, resizing: isResizing }"
        :style="terminalStyle"
      >
        <div class="rt-glass">
          <!-- Titlebar -->
          <div class="rt-titlebar" @mousedown="startDrag" @touchstart="startDrag">
            <div class="rt-left">
              <div class="rt-badge">
                <svg width="8" height="8" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
                  <polyline points="4 17 10 11 4 5"/>
                  <line x1="12" y1="19" x2="20" y2="19"/>
                </svg>
              </div>
              <span class="rt-name">{{ AGENT_CMD[agent] }}</span>
              <span class="rt-session">{{ sessionId.slice(0, 8) }}…</span>
              <i class="rt-dot" :class="statusDotClass"></i>
              <span v-if="terminal?.state.value === 'connecting'" class="rt-status-text">Connecting...</span>
              <span v-else-if="terminal?.state.value === 'shell-ready'" class="rt-status-text">Starting...</span>
              <span v-else-if="terminal?.state.value === 'exited'" class="rt-status-text exited">Exited</span>
            </div>
            <div class="window-controls">
              <button
                class="wc-btn nav-toggle"
                :class="{ active: showNavButtons }"
                title="Toggle navigation"
                @click.stop="toggleNavButtons"
              >
                <svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M4 6h16M4 12h16M4 18h16"/></svg>
              </button>
              <button class="wc-btn x" title="Close" @click.stop="closeTerminal">
                <svg width="8" height="8" viewBox="0 0 10 10"><line x1="0" y1="0" x2="10" y2="10" stroke="currentColor" stroke-width="1.5"/><line x1="10" y1="0" x2="0" y2="10" stroke="currentColor" stroke-width="1.5"/></svg>
              </button>
            </div>
          </div>

          <!-- Terminal content -->
          <div class="rt-content">
            <div ref="terminalContainer" class="rt-term"></div>

            <!-- Overlay: connecting -->
            <div v-if="terminal?.state.value === 'connecting'" class="rt-overlay connecting">
              <div class="rt-overlay-msg">
                <div class="rt-spinner"></div>
                <span>Connecting...</span>
              </div>
            </div>
          </div>

          <!-- Resize handle -->
          <div class="rt-resize" @mousedown="startResize"></div>
        </div>

        <!-- Nav buttons bar (outside glass, hangs from bottom) -->
        <TerminalNavButtons
          v-if="showNavButtons"
          class="rt-nav-popup"
          @request-token="terminal?.sendInput('genera token usando tu mcp')"
          @run-claude="navRunClaude"
          @run-claude-continue="navRunClaudeContinue"
          @run-claude-resume="navRunClaudeResume"
          @clear-buffer="navClearBuffer"
          @refresh="navRefresh"
          @send-key="navSendKey"
          @scroll="navScroll"
        />
      </div>
    </Transition>
  </Teleport>
</template>

<style scoped>
/* ── Inline button ── */
.resume-terminal-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  border: none;
  background: transparent;
  border-radius: 3px;
  cursor: pointer;
  color: var(--text-muted);
  flex-shrink: 0;
  transition: all 0.15s;
}

.resume-terminal-btn:hover {
  background: var(--bg-hover);
  color: var(--accent, #6366f1);
}

/* ── Floating terminal ── */
.resume-terminal {
  position: fixed;
  min-width: 400px;
  min-height: 250px;
  z-index: 10002;
}

.rt-glass {
  position: relative;
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  background: rgba(200, 215, 235, 0.35);
  backdrop-filter: blur(24px) saturate(1.6);
  -webkit-backdrop-filter: blur(24px) saturate(1.6);
  border-radius: 5px;
  border: 1px solid rgba(255, 255, 255, 0.6);
  box-shadow: 0 0 0 1px rgba(80, 120, 180, 0.25), 0 6px 24px rgba(0, 0, 0, 0.25), inset 0 1px 0 rgba(255, 255, 255, 0.6);
  overflow: hidden;
}

.rt-titlebar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 24px;
  padding: 0 4px 0 6px;
  background: rgba(255, 255, 255, 0.25);
  border-bottom: 1px solid rgba(255, 255, 255, 0.3);
  cursor: grab;
  user-select: none;
  touch-action: none;
}

.resume-terminal.dragging .rt-titlebar { cursor: grabbing; }

.rt-left {
  display: flex;
  align-items: center;
  gap: 6px;
  font: 500 10px/1 system-ui, sans-serif;
  color: #222;
  min-width: 0;
}

.rt-badge {
  width: 16px;
  height: 16px;
  border-radius: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  background: linear-gradient(135deg, #6366f1 0%, #818cf8 100%);
  flex-shrink: 0;
}

.rt-name {
  font-weight: 600;
  font-size: 11px;
  color: #333;
}

.rt-session {
  font-size: 9px;
  font-family: 'Courier New', monospace;
  color: #666;
  letter-spacing: 0.3px;
}

.rt-dot {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: #999;
  flex-shrink: 0;
}
.rt-dot.on { background: #0a0; box-shadow: 0 0 4px #0a0; }
.rt-dot.wait { background: #a80; animation: rt-pulse 0.8s infinite; }
.rt-dot.error { background: #e44; box-shadow: 0 0 4px #e44; }

.rt-status-text {
  font-size: 9px;
  color: #666;
}
.rt-status-text.exited { color: #c33; }

.window-controls { display: flex; gap: 1px; }
.wc-btn {
  width: 20px;
  height: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, 0.3);
  border: 1px solid rgba(0, 0, 0, 0.1);
  border-radius: 2px;
  color: #333;
  cursor: pointer;
}
.wc-btn:hover { background: rgba(255, 255, 255, 0.5); }
.wc-btn.x:hover { background: linear-gradient(180deg, #e66 0%, #c33 100%); border-color: #a22; color: #fff; }
.wc-btn.nav-toggle { width: 44px; }
.wc-btn.nav-toggle.active { background: rgba(99, 102, 241, 0.3); border-color: rgba(99, 102, 241, 0.4); color: #818cf8; }
.wc-btn.nav-toggle:hover { background: rgba(99, 102, 241, 0.2); color: #818cf8; }

.rt-content {
  flex: 1;
  margin: 2px;
  border-radius: 2px;
  overflow: hidden;
  position: relative;
  background: rgba(12, 12, 12, 0.95);
}

.rt-term { width: 100%; height: 100%; }
.rt-term :deep(.xterm) { height: 100%; padding: 2px; }
.rt-term :deep(.xterm-viewport) {
  overflow-y: auto !important;
  scrollbar-width: thin;
}
.rt-term :deep(.xterm-viewport::-webkit-scrollbar) { width: 8px; background: rgba(0, 0, 0, 0.2); }
.rt-term :deep(.xterm-viewport::-webkit-scrollbar-thumb) { background: rgba(255, 255, 255, 0.15); border-radius: 4px; }

.rt-overlay {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.85);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 10;
}
.rt-overlay.connecting { cursor: wait; }

.rt-overlay-msg {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  color: #fff;
  text-align: center;
}
.rt-overlay-msg span { font-size: 13px; font-weight: 500; }

.rt-spinner {
  width: 20px;
  height: 20px;
  border: 2px solid rgba(255, 255, 255, 0.2);
  border-top-color: #fff;
  border-radius: 50%;
  animation: rt-spin 0.8s linear infinite;
}

.rt-resize {
  position: absolute;
  right: 0;
  bottom: 0;
  width: 16px;
  height: 16px;
  cursor: nwse-resize;
  background: linear-gradient(135deg, transparent 50%, rgba(255, 255, 255, 0.3) 50%, rgba(255, 255, 255, 0.1) 100%);
  border-radius: 0 0 5px 0;
}
.rt-resize:hover { background: linear-gradient(135deg, transparent 50%, rgba(255, 255, 255, 0.5) 50%, rgba(255, 255, 255, 0.2) 100%); }

.resume-terminal.resizing { user-select: none; }
.resume-terminal.resizing .rt-term { pointer-events: none; }

/* Nav buttons popup */
.rt-nav-popup {
  position: absolute;
  left: 0;
  right: 0;
  top: 100%;
  border-radius: 0 0 6px 6px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-top: none;
  backdrop-filter: blur(14px) saturate(1.3);
  -webkit-backdrop-filter: blur(14px) saturate(1.3);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
  z-index: 1;
}

.rt-slide-enter-active, .rt-slide-leave-active { transition: all 0.15s ease; }
.rt-slide-enter-from, .rt-slide-leave-to { opacity: 0; transform: translateY(16px) scale(0.98); }

@keyframes rt-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.4; } }
@keyframes rt-spin { to { transform: rotate(360deg); } }
</style>
