import { derived } from 'svelte/store'
import { messages, type ToolCallResult } from './chat'
import { planSteps, currentTask } from './workspace'

export { type ToolCallResult }

export interface ActivityEntry {
  id: string
  type: 'goal' | 'plan' | 'step_running' | 'step_done' | 'step_failed' |
        'tool_running' | 'tool_done' | 'tool_error' |
        'knowledge' | 'complete' | 'question' | 'error' |
        'approval'
  description: string
  detail?: string
  timestamp: number
  toolName?: string
  stepSeq?: number
  indent?: boolean
  status: 'running' | 'done' | 'failed'
}

export const activityLog = derived([messages, planSteps, currentTask], ([$msgs, $steps, $task]) => {
  const entries: ActivityEntry[] = []
  const now = Date.now()

  // Goal
  if ($task?.goal) {
    entries.push({ id: 'goal', type: 'goal', description: $task.goal, timestamp: 0, status: 'done' })
  }

  // Plan steps
  for (const s of $steps) {
    if (s.status === 'pending') continue
    const stepLabel = s.title || `Step ${s.seq}`
    entries.push({
      id: s.id,
      type: s.status === 'running' ? 'step_running' : s.status === 'done' ? 'step_done' : 'step_failed',
      description: `Step ${s.seq}: ${stepLabel}`,
      detail: s.detail || undefined,
      timestamp: s.started_at ? new Date(s.started_at).getTime() : now,
      status: s.status === 'running' ? 'running' : s.status === 'done' ? 'done' : 'failed'
    })
  }

  // Tool calls (from messages). Tag each tool with the plan step that's
  // currently running when it fires.
  let currentStepSeq = 0
  let entryIdx = 0
  for (let mi = 0; mi < $msgs.length; mi++) {
    for (const t of $msgs[mi].tools) {
      // Track current step from update_plan_step calls
      if (t.type === 'tool_use' && t.name === 'update_plan_step') {
        const s = (t.args as any)?.seq as number | undefined
        const status = (t.args as any)?.status as string | undefined
        if (s && status === 'running') currentStepSeq = s
      } else if (t.name === 'set_goal' || t.name === 'propose_plan' || t.name === 'complete_task') {
        currentStepSeq = 0
      }

      const label = toolActivityLabel(t)
      const stepTag = currentStepSeq > 0 ? currentStepSeq : undefined
      if (t.type === 'tool_use') {
        entries.push({
          id: t.id ?? `tool_${mi}_${entryIdx++}`,
          type: 'tool_running',
          description: label,
          timestamp: now - ($msgs.length - mi) * 1000,
          toolName: t.name,
          stepSeq: stepTag,
          indent: stepTag != null,
          status: 'running'
        })
      } else if (t.type === 'tool_result') {
        const running = entries.find((e) =>
          e.type === 'tool_running' && e.id === t.id && e.status === 'running'
        )
        if (running && t.error) {
          running.type = 'tool_error'
          running.status = 'failed'
          running.description = `${t.name}: ${t.error.slice(0, 80)}`
        } else if (running) {
          running.type = 'tool_done'
          running.status = 'done'
          running.detail = typeof t.result === 'string'
            ? t.result.slice(0, 200)
            : JSON.stringify(t.result ?? '').slice(0, 200)
        } else {
          entries.push({
            id: t.id ?? `tool_${mi}_${entryIdx++}`,
            type: t.error ? 'tool_error' : 'tool_done',
            description: t.error ? `${t.name}: ${t.error.slice(0, 80)}` : t.name,
            detail: !t.error ? (typeof t.result === 'string' ? t.result.slice(0, 200) : '') : undefined,
            timestamp: now - ($msgs.length - mi) * 1000,
            toolName: t.name,
            stepSeq: stepTag,
            indent: stepTag != null,
            status: t.error ? 'failed' : 'done'
          })
        }
      }
    }
  }

  // Knowledge recorded — detect from upsert_knowledge tool results
  for (let mi = 0; mi < $msgs.length; mi++) {
    for (const t of $msgs[mi].tools) {
      if (t.type === 'tool_result' && t.name === 'upsert_knowledge' && !t.error) {
        const title = t.args?.title ?? ''
        entries.push({
          id: `knowledge_${mi}`,
          type: 'knowledge',
          description: title ? `Recorded: ${title.slice(0, 60)}` : 'Recorded knowledge',
          timestamp: now - ($msgs.length - mi) * 1000,
          status: 'done'
        })
      }
    }
  }

  // Task completion
  if ($task?.outcome) {
    entries.push({
      id: 'complete',
      type: 'complete',
      description: $task.summary || `Task ${$task.outcome}`,
      timestamp: now,
      status: $task.outcome === 'failure' ? 'failed' : 'done'
    })
  }

  // Approvals — detect from tool results containing 'requires approval'
  for (let mi = 0; mi < $msgs.length; mi++) {
    for (const t of $msgs[mi].tools) {
      if (t.type !== 'tool_result') continue
      const text = typeof t.result === 'string' ? t.result : JSON.stringify(t.result ?? '')
      if (text.includes('requires approval')) {
        const m = text.match(/execution\s+([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/i)
        const execId = m ? m[1] : ''
        const target = (t.args as any)?.target ?? ''
        const purpose = (t.args as any)?.purpose ?? ''
        entries.push({
          id: execId || `approval_${mi}`,
          type: 'approval',
          description: purpose ? `Approval: ${purpose.slice(0, 60)}` : `Approval required${target ? ` for ${target}` : ''}`,
          timestamp: now - ($msgs.length - mi) * 1000,
          status: 'running'
        })
      }
    }
  }

  // Sort oldest first
  entries.sort((a, b) => a.timestamp - b.timestamp)

  return entries
})

function toolActivityLabel(t: ToolCallResult): string {
  const args = t.args ?? {}
  switch (t.name) {
    case 'set_goal': return 'Set goal'
    case 'propose_plan': return 'Proposed plan'
    case 'search_knowledge': return `Research: ${args.query || ''}`
    case 'get_entity': return `Lookup: ${args.slug_or_id || ''}`
    case 'get_entity_knowledge': return 'Check prior knowledge'
    case 'get_relations': return 'Check relationships'
    case 'list_lxcs': return 'List containers'
    case 'list_entities': return 'List entities'
    case 'get_health_summary': return 'Fleet health'
    case 'get_state_snapshot': return 'State snapshot'
    case 'run': {
      const purpose = args.purpose as string || ''
      const target = (args.target as string) || ''
      if (purpose) return purpose
      if (target) return `Run on ${target}`
      return 'Run command'
    }
    case 'get_execution_status': return 'Check execution'
    case 'update_plan_step': return 'Update plan'
    case 'upsert_knowledge': return 'Record knowledge'
    case 'complete_task': return 'Complete task'
    case 'ping_service': return 'Check service'
    case 'ask_operator': return 'Ask operator'
    default: return t.name
  }
}