<script setup lang="ts">
import { ref, computed } from 'vue'
import type { ParsedToolCall } from '@/types/transcript-debug'
import ToolResultBlock from '../ToolResultBlock.vue'
import CodeBlock from '../CodeBlock.vue'

const props = defineProps<{
  call: ParsedToolCall
}>()

const isError = computed(() => props.call.result?.isError ?? false)
const toolName = computed(() => props.call.name)

// Common fields
const taskId = computed(() => (props.call.input?.taskId as string) || '')
const subject = computed(() => (props.call.input?.subject as string) || '')
const description = computed(() => (props.call.input?.description as string) || '')
const activeForm = computed(() => (props.call.input?.activeForm as string) || '')
const status = computed(() => (props.call.input?.status as string) || '')
const prompt = computed(() => (props.call.input?.prompt as string) || '')
const subagentType = computed(() => (props.call.input?.subagent_type as string) || '')
const model = computed(() => (props.call.input?.model as string) || '')
const runInBackground = computed(() => props.call.input?.run_in_background as boolean | undefined)

const expanded = ref(false)

// ---- Extract main topics from result ----
interface TopicItem {
  label: string
  status?: string // for TaskList JSON items
  id?: string
}

const mainTopics = computed<TopicItem[]>(() => {
  if (!props.call.result?.content) return []
  const content = props.call.result.content.trim()

  // 1) Try JSON (TaskList array / TaskGet single object)
  try {
    const data = JSON.parse(content)
    if (Array.isArray(data)) {
      return data.map((t: any) => ({
        label: t.subject || t.description || JSON.stringify(t).slice(0, 60),
        status: t.status,
        id: t.id,
      }))
    }
    if (data && typeof data === 'object' && (data.subject || data.id)) {
      return [{
        label: data.subject || data.description || '',
        status: data.status,
        id: data.id,
      }]
    }
  } catch { /* not JSON, parse as text */ }

  // 2) Text result: extract headings, numbered/bullet lists, bold items
  const lines = content.split('\n')
  const topics: TopicItem[] = []
  const seen = new Set<string>()

  for (const raw of lines) {
    const line = raw.trim()
    if (!line) continue

    let label = ''
    // Markdown headings: ## Foo or ### Foo
    if (/^#{1,4}\s+/.test(line)) {
      label = line.replace(/^#+\s+/, '').replace(/\*\*/g, '').trim()
    }
    // Numbered list: 1. Foo, 2. Foo
    else if (/^\d+[\.\)]\s+/.test(line)) {
      label = line.replace(/^\d+[\.\)]\s+/, '').replace(/\*\*/g, '').trim()
    }
    // Bullet list: - Foo, * Foo
    else if (/^[-*]\s+/.test(line)) {
      label = line.replace(/^[-*]\s+/, '').replace(/\*\*/g, '').trim()
    }

    if (label && label.length > 2 && !seen.has(label)) {
      seen.add(label)
      topics.push({ label: label.length > 90 ? label.slice(0, 90) + '...' : label })
    }
    if (topics.length >= 12) break
  }
  return topics
})

const hasTopics = computed(() => mainTopics.value.length > 0)

// Status helpers
const statusColorFor = (s: string) => {
  switch (s) {
    case 'completed': return '#22c55e'
    case 'in_progress': return '#f59e0b'
    case 'pending': return '#64748b'
    case 'deleted': return '#ef4444'
    default: return 'var(--card-color)'
  }
}

const statusColor = computed(() => statusColorFor(status.value))
const statusIcon = computed(() => {
  switch (status.value) {
    case 'completed': return '\u2713'
    case 'in_progress': return '\u25CF'
    case 'pending': return '\u25CB'
    case 'deleted': return '\u2717'
    default: return '\u2022'
  }
})

// Card color
const cardColor = computed(() => {
  switch (toolName.value) {
    case 'Task': return '#0ea5e9'
    case 'TaskCreate': return '#22c55e'
    case 'TaskUpdate': return '#a855f7'
    case 'TaskGet': return '#06b6d4'
    case 'TaskList': return '#64748b'
    default: return '#64748b'
  }
})

const hasExpandable = computed(() =>
  description.value.length > 0 || prompt.value.length > 0 || !!props.call.result
)

// Brief for body (only when no topics to show)
const descBrief = computed(() => {
  if (!description.value) return ''
  const first = description.value.split('\n')[0]
  return first.length > 80 ? first.slice(0, 80) + '...' : first
})

const hasBody = computed(() =>
  subject.value || activeForm.value || (!hasTopics.value && descBrief.value)
)
</script>

<template>
  <div :class="['task-card', { error: isError }]" :style="{ '--card-color': cardColor }">
    <!-- HEADER -->
    <div class="card-header" @click.stop="expanded = !expanded">
      <span class="card-icon">
        <svg v-if="toolName === 'Task'" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
          <circle cx="12" cy="12" r="3"/><path d="M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42"/>
        </svg>
        <svg v-else-if="toolName === 'TaskCreate'" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
          <circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="16"/><line x1="8" y1="12" x2="16" y2="12"/>
        </svg>
        <svg v-else-if="toolName === 'TaskUpdate'" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
          <path d="M9 11l3 3L22 4"/><path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"/>
        </svg>
        <svg v-else-if="toolName === 'TaskGet'" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
          <circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/>
        </svg>
        <svg v-else width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
          <line x1="8" y1="6" x2="21" y2="6"/><line x1="8" y1="12" x2="21" y2="12"/><line x1="8" y1="18" x2="21" y2="18"/>
          <line x1="3" y1="6" x2="3.01" y2="6"/><line x1="3" y1="12" x2="3.01" y2="12"/><line x1="3" y1="18" x2="3.01" y2="18"/>
        </svg>
      </span>
      <span class="card-label">{{ toolName }}</span>
      <span v-if="taskId" class="id-badge">#{{ taskId }}</span>
      <span v-if="status" class="status-badge" :style="{ color: statusColor, borderColor: statusColor, background: statusColor + '15' }">
        <span class="status-icon">{{ statusIcon }}</span>{{ status }}
      </span>
      <span v-if="subagentType" class="agent-badge">{{ subagentType }}</span>
      <span v-if="model" class="model-badge">{{ model }}</span>
      <span v-if="runInBackground" class="bg-badge">bg</span>
      <span v-if="isError" class="error-badge">err</span>
    </div>

    <!-- BODY: subject / brief -->
    <div v-if="hasBody" class="card-body">
      <span v-if="subject" class="topic subject-topic">{{ subject }}</span>
      <span v-if="activeForm" class="topic active-topic">{{ activeForm }}</span>
      <span v-if="!subject && !hasTopics && descBrief" class="topic desc-topic">{{ descBrief }}</span>
    </div>

    <!-- MAIN TOPICS: always visible bullets -->
    <div v-if="hasTopics" class="topic-list">
      <div v-for="(t, i) in mainTopics" :key="i" class="topic-item">
        <span class="topic-dot" :style="t.status ? { color: statusColorFor(t.status) } : {}">&#9679;</span>
        <span v-if="t.id" class="topic-id">#{{ t.id }}</span>
        <span class="topic-label">{{ t.label }}</span>
      </div>
    </div>

    <!-- EXPANDED: all details -->
    <template v-if="expanded">
      <div v-if="description" class="expand-section">
        <CodeBlock :code="description" max-height="200px" />
      </div>
      <div v-if="prompt" class="expand-section">
        <CodeBlock :code="prompt" max-height="200px" />
      </div>
      <div v-if="call.result" class="expand-section result-section">
        <ToolResultBlock :result="call.result" />
      </div>
    </template>
  </div>
</template>

<style scoped>
.task-card {
  border: none;
  border-left: 2px solid color-mix(in srgb, var(--card-color) 25%, transparent);
  border-radius: 6px;
  overflow: hidden;
  margin: 0.35rem 0;
  background: color-mix(in srgb, var(--card-color) 2%, transparent);
}

.task-card.error { border-left-color: rgba(239, 68, 68, 0.4); }

/* Header */
.card-header {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.3rem 0.6rem;
  background: transparent;
  min-height: 28px;
  cursor: pointer;
}
.card-header:hover { background: color-mix(in srgb, var(--card-color) 4%, transparent); }

.card-icon { display: flex; align-items: center; color: color-mix(in srgb, var(--card-color) 60%, transparent); flex-shrink: 0; }
.task-card.error .card-icon { color: rgba(239, 68, 68, 0.6); }

.card-label {
  font-size: 10px; font-weight: 700; color: color-mix(in srgb, var(--card-color) 70%, transparent);
  text-transform: uppercase; letter-spacing: 0.5px; flex-shrink: 0;
}
.task-card.error .card-label { color: rgba(239, 68, 68, 0.7); }

.header-spacer { flex: 1; }

/* Badges */
.id-badge, .agent-badge, .model-badge, .bg-badge, .error-badge, .status-badge {
  font-size: 9px; padding: 0.05rem 0.3rem; border-radius: 3px;
  font-weight: 600; flex-shrink: 0; background: transparent;
  font-family: 'SF Mono', 'Fira Code', monospace;
}

.id-badge { color: color-mix(in srgb, var(--card-color) 60%, transparent); }
.agent-badge { color: rgba(129, 140, 248, 0.7); font-family: inherit; }
.model-badge { color: color-mix(in srgb, var(--card-color) 50%, transparent); }
.bg-badge { color: rgba(129, 140, 248, 0.6); font-family: inherit; }
.error-badge { color: rgba(239, 68, 68, 0.7); }

.status-badge {
  display: inline-flex; align-items: center; gap: 0.15rem;
  border: none;
}
.status-icon { font-size: 9px; }

/* Toggle buttons */
.toggle-btn {
  display: flex; align-items: center; justify-content: center;
  width: 20px; height: 20px; border: none; border-radius: 4px;
  background: transparent; color: var(--text-muted); cursor: pointer;
  flex-shrink: 0; opacity: 0.5; transition: all 0.15s;
}
.toggle-btn:hover { opacity: 0.8; }
.toggle-btn.active { opacity: 1; color: color-mix(in srgb, var(--card-color) 80%, transparent); }

/* Body */
.card-body {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: 0.3rem; padding: 0.15rem 0.6rem 0.25rem;
}

.topic {
  font-size: 11px; line-height: 1.3; max-width: 100%;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.subject-topic { font-weight: 600; color: var(--text-primary); }
.active-topic { font-style: italic; color: var(--text-secondary); font-size: 10px; }
.active-topic::before { content: '\2014 '; color: var(--text-muted); }
.desc-topic { color: var(--text-muted); }

/* Topic list (always visible bullets) */
.topic-list {
  padding: 0.15rem 0.6rem 0.25rem;
  display: flex;
  flex-direction: column;
  gap: 0.05rem;
}

.topic-item {
  display: flex;
  align-items: baseline;
  gap: 0.35rem;
  font-size: 11px;
  line-height: 1.35;
  min-height: 16px;
}

.topic-dot {
  font-size: 6px;
  color: color-mix(in srgb, var(--card-color) 50%, transparent);
  flex-shrink: 0;
  width: 10px;
  text-align: center;
  position: relative;
  top: -1px;
}

.topic-id {
  font-size: 10px;
  color: var(--text-muted);
  font-family: 'SF Mono', 'Fira Code', monospace;
  flex-shrink: 0;
}

.topic-label {
  color: var(--text-secondary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Expandable sections */
.expand-section { border-top: 1px solid rgba(255, 255, 255, 0.04); }


.result-section :deep(.tool-result) { border: none; border-radius: 0; margin-top: 0; }
</style>
