<script setup lang="ts">
import { computed } from 'vue'
import type { ParsedUserMessage, SectionSummary } from '@/types/transcript-debug'
import MarkdownContent from './MarkdownContent.vue'

const props = defineProps<{
  message: ParsedUserMessage
  collapsed?: boolean
  sectionCount?: number
  sectionSummary?: SectionSummary
}>()

const emit = defineEmits<{
  toggleCollapse: []
}>()

const isOptimistic = computed(() => props.message.uuid.startsWith('optimistic-'))

// ── Command / special message detection ──
type CommandInfo =
  | { type: 'caveat'; text: string }
  | { type: 'command'; name: string; message: string; args: string }
  | { type: 'stdout'; text: string }
  | { type: 'interrupted' }
  | { type: 'meta-action'; text: string }
  | null

const commandInfo = computed<CommandInfo>(() => {
  const c = props.message.content
  if (!c) return null

  // [Request interrupted by user ...]
  if (c.includes('[Request interrupted by user')) {
    return { type: 'interrupted' }
  }

  // Meta messages: "Continue from where you left off", etc.
  if (props.message.isMeta) {
    return { type: 'meta-action', text: c.trim() }
  }

  // <local-command-caveat>...</local-command-caveat>
  const caveatMatch = c.match(/<local-command-caveat>([\s\S]*?)<\/local-command-caveat>/)
  if (caveatMatch) return { type: 'caveat', text: caveatMatch[1].trim() }

  // <command-name>...</command-name>
  const cmdNameMatch = c.match(/<command-name>([\s\S]*?)<\/command-name>/)
  if (cmdNameMatch) {
    const msgMatch = c.match(/<command-message>([\s\S]*?)<\/command-message>/)
    const argsMatch = c.match(/<command-args>([\s\S]*?)<\/command-args>/)
    return {
      type: 'command',
      name: cmdNameMatch[1].trim(),
      message: msgMatch?.[1]?.trim() || '',
      args: argsMatch?.[1]?.trim() || ''
    }
  }

  // <local-command-stdout>...</local-command-stdout>
  const stdoutMatch = c.match(/<local-command-stdout>([\s\S]*?)<\/local-command-stdout>/)
  if (stdoutMatch !== null && c.includes('<local-command-stdout>')) {
    return { type: 'stdout', text: stdoutMatch[1].trim() }
  }

  return null
})

const isCommand = computed(() => commandInfo.value !== null)

function formatTime(ts: string): string {
  if (!ts) return ''
  return new Date(ts).toLocaleTimeString()
}

function formatTokens(n: number): string {
  if (n >= 1_000_000) return (n / 1_000_000).toFixed(1) + 'M'
  if (n >= 1_000) return (n / 1_000).toFixed(1).replace(/\.0$/, '') + 'k'
  return String(n)
}

const totalTokens = computed(() => {
  if (!props.sectionSummary) return 0
  return props.sectionSummary.inputTokens + props.sectionSummary.outputTokens
})
</script>

<template>
  <!-- ═══════ COMMAND MESSAGE (compact) ═══════ -->
  <div v-if="isCommand" class="cmd-row">
    <!-- Caveat: system note about local commands -->
    <template v-if="commandInfo!.type === 'caveat'">
      <span class="cmd-icon cmd-icon-caveat">
        <svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
          <circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/>
        </svg>
      </span>
      <span class="cmd-label cmd-caveat-text">local command caveat</span>
    </template>

    <!-- Command invocation -->
    <template v-else-if="commandInfo!.type === 'command'">
      <span class="cmd-icon">
        <svg width="10" height="10" 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>
      </span>
      <code class="cmd-name">{{ (commandInfo as any).name }}</code>
      <span v-if="(commandInfo as any).args" class="cmd-args">{{ (commandInfo as any).args }}</span>
    </template>

    <!-- Stdout -->
    <template v-else-if="commandInfo!.type === 'stdout'">
      <span class="cmd-icon cmd-icon-out">
        <svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
          <polyline points="17 1 21 5 17 9"/><path d="M3 11V9a4 4 0 0 1 4-4h14"/>
        </svg>
      </span>
      <span v-if="(commandInfo as any).text" class="cmd-stdout">{{ (commandInfo as any).text }}</span>
      <span v-else class="cmd-empty">no output</span>
    </template>

    <!-- Interrupted -->
    <template v-else-if="commandInfo!.type === 'interrupted'">
      <span class="cmd-icon cmd-icon-interrupted">
        <svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
          <circle cx="12" cy="12" r="10"/><rect x="9" y="9" width="6" height="6" rx="0.5" fill="currentColor" stroke="none"/>
        </svg>
      </span>
      <span class="cmd-label cmd-interrupted-text">interrupted by user</span>
    </template>

    <!-- Meta action (continue, etc.) -->
    <template v-else-if="commandInfo!.type === 'meta-action'">
      <span class="cmd-icon cmd-icon-meta">
        <svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
          <polyline points="23 4 23 10 17 10"/><path d="M20.49 15a9 9 0 1 1-2.12-9.36L23 10"/>
        </svg>
      </span>
      <span class="cmd-label cmd-meta-text">{{ (commandInfo as any).text }}</span>
    </template>

    <span class="cmd-time">{{ formatTime(message.timestamp) }}</span>
  </div>

  <!-- ═══════ NORMAL USER MESSAGE ═══════ -->
  <div v-else :class="['user-divider', { meta: message.isMeta, optimistic: isOptimistic }]">
    <div class="divider-line" />
    <div class="divider-content">
      <div class="divider-header">
        <span class="role-badge">User</span>
        <span v-if="message.isMeta" class="meta-badge">meta</span>
        <span v-if="isOptimistic" class="sending-badge">
          <span class="sending-dot"></span>
          <span class="sending-dot"></span>
          <span class="sending-dot"></span>
          Sending
        </span>
        <button
          v-if="sectionCount && sectionCount > 0"
          :class="['collapse-btn', { collapsed }]"
          @click.stop="emit('toggleCollapse')"
          :title="collapsed ? 'Expand section' : 'Collapse section'"
        >
          <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
            <polyline :points="collapsed ? '9 18 15 12 9 6' : '6 9 12 15 18 9'" />
          </svg>
          <template v-if="collapsed && sectionSummary">
            <span class="collapse-count">{{ sectionSummary.total }}</span>
            <template v-if="sectionSummary.toolNames.length">
              <span class="badge-sep">|</span>
              <span v-for="t in sectionSummary.toolNames" :key="t" class="tool-chip">{{ t }}</span>
            </template>
            <template v-if="sectionSummary.hasErrors">
              <span class="badge-sep">|</span>
              <span class="error-chip">{{ sectionSummary.errorCount }} err</span>
            </template>
            <template v-if="totalTokens > 0">
              <span class="badge-sep">|</span>
              <span class="token-chip">{{ formatTokens(totalTokens) }} tok</span>
            </template>
          </template>
        </button>
        <span class="timestamp">{{ formatTime(message.timestamp) }}</span>
      </div>
      <div class="divider-text">
        <MarkdownContent :content="message.content" />
      </div>
    </div>
  </div>
</template>

<style scoped>
/* ══════════════════════════════════════
   Command row — compact inline display
   ══════════════════════════════════════ */
.cmd-row {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.15rem 0.5rem;
  margin: 0.1rem 0;
  font-size: 11px;
  color: var(--text-muted);
  opacity: 0.55;
  transition: opacity 0.15s;
}

.cmd-row:hover {
  opacity: 0.85;
}

.cmd-icon {
  display: flex;
  align-items: center;
  color: #64748b;
  flex-shrink: 0;
}

.cmd-icon-caveat { color: #f59e0b; }
.cmd-icon-out { color: #64748b; }

.cmd-label {
  font-size: 10px;
  color: var(--text-muted);
  font-style: italic;
}

.cmd-name {
  font-size: 11px;
  font-weight: 600;
  font-family: 'SF Mono', 'Fira Code', monospace;
  color: #818cf8;
  background: rgba(129, 140, 248, 0.08);
  padding: 0 0.3rem;
  border-radius: 3px;
}

.cmd-args {
  font-size: 10px;
  font-family: 'SF Mono', 'Fira Code', monospace;
  color: var(--text-muted);
}

.cmd-stdout {
  font-size: 10px;
  font-family: 'SF Mono', 'Fira Code', monospace;
  color: var(--text-secondary);
  white-space: pre-wrap;
  word-break: break-all;
  max-width: 300px;
  overflow: hidden;
  text-overflow: ellipsis;
}

.cmd-empty {
  font-size: 10px;
  color: var(--text-muted);
  font-style: italic;
  opacity: 0.6;
}

.cmd-caveat-text {
  max-width: 250px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.cmd-icon-interrupted { color: #ef4444; }
.cmd-interrupted-text {
  color: rgba(239, 68, 68, 0.7);
  font-weight: 500;
  font-style: normal;
}

.cmd-icon-meta { color: #f59e0b; }
.cmd-meta-text {
  color: rgba(251, 191, 36, 0.65);
  font-weight: 500;
  font-style: normal;
  max-width: 300px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.cmd-time {
  margin-left: auto;
  font-size: 9px;
  color: var(--text-muted);
  font-family: 'SF Mono', 'Fira Code', monospace;
  opacity: 0.7;
  flex-shrink: 0;
}

/* ══════════════════════════════════════
   Normal user message
   ══════════════════════════════════════ */
.user-divider {
  width: 100%;
  margin: 0.75rem 0 0.25rem;
}

.divider-line {
  display: none;
}

.divider-content {
  padding: 0.45rem 0.65rem;
  background: linear-gradient(170deg, rgba(148, 163, 184, 0.10) 0%, rgba(100, 116, 139, 0.15) 50%, rgba(71, 85, 105, 0.12) 100%);
  border-top: 1px solid rgba(255, 255, 255, 0.08);
  border-left: 1px solid rgba(255, 255, 255, 0.05);
  border-right: 1px solid rgba(0, 0, 0, 0.12);
  border-bottom: 1px solid rgba(0, 0, 0, 0.18);
  border-radius: 8px;
  box-shadow:
    0 2px 6px rgba(0, 0, 0, 0.12),
    0 1px 2px rgba(0, 0, 0, 0.08),
    inset 0 1px 0 rgba(255, 255, 255, 0.07),
    inset 0 -1px 0 rgba(0, 0, 0, 0.05);
}

.divider-header {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.25rem;
}

.role-badge {
  font-size: 10px;
  font-weight: 700;
  color: #818cf8;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

.meta-badge {
  font-size: 9px;
  padding: 0.05rem 0.3rem;
  border-radius: 3px;
  background: transparent;
  color: rgba(251, 191, 36, 0.7);
  font-weight: 600;
}

.timestamp {
  font-size: 10px;
  color: var(--text-muted);
  margin-left: auto;
  font-family: 'SF Mono', 'Fira Code', monospace;
}

.divider-text {
  font-size: 13px;
  line-height: 1.5;
  color: var(--text-primary);
  font-weight: 500;
  word-break: break-word;
}

.divider-text :deep(.md-content) {
  font-size: inherit;
  line-height: inherit;
  color: inherit;
}

/* Tighten markdown spacing inside user bubbles */
.divider-text :deep(.md-content p) {
  margin: 0.15em 0;
}

.divider-text :deep(.md-content pre) {
  margin: 0.4em 0;
  font-size: 11px;
}

.divider-text :deep(.md-content code) {
  font-size: 0.9em;
}

/* Meta messages: dimmed */
.user-divider.meta {
  opacity: 0.45;
}

/* Collapse button */
.collapse-btn {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  padding: 1px 4px;
  border: none;
  border-radius: 3px;
  background: transparent;
  cursor: pointer;
  color: var(--text-muted);
  transition: all 0.15s;
  flex-wrap: wrap;
}

.collapse-btn:hover {
  background: rgba(129, 140, 248, 0.1);
  color: #818cf8;
}

.collapse-btn svg {
  transition: transform 0.2s ease;
}

.collapse-count {
  font-size: 9px;
  font-weight: 600;
  color: var(--text-muted);
  font-family: 'SF Mono', 'Fira Code', monospace;
}

.collapse-btn:hover .collapse-count {
  color: #818cf8;
}

.badge-sep {
  font-size: 9px;
  color: var(--text-muted);
  opacity: 0.35;
  user-select: none;
}

.tool-chip {
  font-size: 8px;
  font-weight: 600;
  font-family: 'SF Mono', 'Fira Code', monospace;
  color: #818cf8;
  background: rgba(129, 140, 248, 0.1);
  padding: 0 3px;
  border-radius: 3px;
  line-height: 1.4;
}

.collapse-btn:hover .tool-chip {
  color: #a5b4fc;
  background: rgba(129, 140, 248, 0.18);
}

.error-chip {
  font-size: 8px;
  font-weight: 600;
  font-family: 'SF Mono', 'Fira Code', monospace;
  color: #f87171;
  background: rgba(239, 68, 68, 0.12);
  padding: 0 3px;
  border-radius: 3px;
  line-height: 1.4;
}

.collapse-btn:hover .error-chip {
  color: #fca5a5;
  background: rgba(239, 68, 68, 0.2);
}

.token-chip {
  font-size: 8px;
  font-weight: 600;
  font-family: 'SF Mono', 'Fira Code', monospace;
  color: var(--text-muted);
  line-height: 1.4;
}

.collapse-btn:hover .token-chip {
  color: #818cf8;
}

/* Optimistic / sending */
.user-divider.optimistic {
  opacity: 0.6;
}

.sending-badge {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  font-size: 9px;
  color: var(--accent, #6366f1);
  font-weight: 500;
}

.sending-dot {
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: var(--accent, #6366f1);
  animation: sending-pulse 1.2s ease-in-out infinite;
}

.sending-dot:nth-child(2) { animation-delay: 0.15s; }
.sending-dot:nth-child(3) { animation-delay: 0.3s; }

@keyframes sending-pulse {
  0%, 80%, 100% { opacity: 0.2; }
  40% { opacity: 1; }
}
</style>
