/**
 * Agent Store – V2 Dashboard
 *
 * Fetches agents from /api/dashboard/agents and available models
 * from /api/dashboard/models. Enriches raw API data with catalog
 * metadata (color, icon, description, hero) and maps into
 * AgentNodeData (for FlowCanvas) and AgentDetail (for Modal).
 *
 * Auto-refresh: every 30 seconds.
 */
import { defineStore } from 'pinia'
import { apiFetch } from '../services/api'
import type { AgentNodeData } from '../composables/useFlowLayout'
import type { AgentActivityItem, AgentDetailData, ThinkingItem } from '../components/dashboard/v2/types'

/* ── API Response Shapes ──────────────────────────── */

interface DashboardAgentInfo {
  id: string
  name: string
  role: string
  model: string
  isActive: boolean
  currentTask: string | null
  description?: string
  tags?: string[]
  progress?: number
  workload?: number
  goal?: string | null
  roleBadge?: string
  statusLabel?: string
  elapsed?: string | null
  think?: string | null
  next?: string | null
}

interface ModelOption {
  id: string
  name: string
  provider: string
}

interface AgentActivityEntry {
  time: string
  text: string
}

/* ── Status Mapping ───────────────────────────────── */

function mapStatus(isActive: boolean, currentTask: string | null): AgentNodeData['status'] {
  if (!isActive) return 'idle'
  if (currentTask && currentTask !== 'Idle') return 'work'
  return 'think'
}

const STATUS_LABELS: Record<AgentNodeData['status'], string> = {
  work: 'Arbeitet',
  think: 'Plant',
  idle: 'Bereit',
  block: 'Blockiert',
}

function avatarFor(id: string, name: string): string {
  if (id === 'iris') return 'IR'
  if (id === 'programmer' || id === 'developer') return '</>'
  return name.slice(0, 2).toUpperCase()
}

/* ── Enrich API Agent → AgentNodeData ─────────────── */

function enrichAgent(api: DashboardAgentInfo): AgentNodeData {
  const status = mapStatus(api.isActive, api.currentTask)
  return {
    id: api.id,
    name: api.name,
    role: api.role,
    roleBadge: api.roleBadge ?? 'badge-slate',
    model: api.model,
    avatar: avatarFor(api.id, api.name),
    status,
    statusLabel: api.statusLabel ?? STATUS_LABELS[status],
    task: api.currentTask,
    goal: api.goal ?? null,
    progress: api.progress ?? 0,
    elapsed: api.elapsed ?? '--',
    next: api.next ?? 'Standby',
    tokens: '0',
    cost: '0.00',
    think: api.think ?? null,
  }
}

/* ── Build AgentDetail from AgentNodeData ─────────── */

function buildThinkingItems(data: AgentNodeData): ThinkingItem[] {
  if (!data.think) return []
  const now = new Date()
  const ts = (ago: number) => {
    const d = new Date(now.getTime() - ago * 1000)
    return d.toLocaleTimeString('de-DE', { hour: '2-digit', minute: '2-digit', second: '2-digit' })
  }
  const sentences = data.think.split(/[.…!?]+/).filter(s => s.trim().length > 5)
  const items: ThinkingItem[] = []
  if (sentences.length >= 2) {
    items.push({ type: 'thought', text: sentences[0].trim() + '.', ts: ts(30) })
    items.push({ type: 'action', text: sentences[1].trim() + '…', ts: ts(18) })
    if (sentences.length >= 3) {
      items.push({ type: 'result', text: sentences[sentences.length - 1].trim() + '.', ts: ts(3) })
    } else {
      items.push({ type: 'result', text: 'Verarbeitung abgeschlossen.', ts: ts(3) })
    }
  } else if (sentences.length === 1) {
    items.push({ type: 'thought', text: sentences[0].trim(), ts: ts(15) })
    items.push({ type: 'action', text: 'Analysiere Daten und erstelle nächsten Schritt…', ts: ts(6) })
  } else {
    items.push({ type: 'thought', text: data.think, ts: ts(10) })
  }
  return items
}

export function buildAgentDetail(data: AgentNodeData, models: { id: string; alias: string }[]): AgentDetailData {
  const tokenNum = parseFloat(data.tokens?.replace(/[^0-9.]/g, '') || '0')
  const tokenMultiplier = data.tokens?.includes('M') ? 1_000_000 : data.tokens?.includes('k') ? 1_000 : 1
  const tokensToday = Math.round(tokenNum * tokenMultiplier)
  const costNum = parseFloat(data.cost || '0')
  const progress = data.progress || 0

  // Map model ID to display name for the modal dropdown (which uses alias for comparison)
  const matchingModel = models.find(m => m.id === data.model || m.alias === data.model)
  const displayModel = matchingModel?.alias ?? data.model

  return {
    id: data.id,
    name: data.name,
    role: data.role,
    roleBadge: data.roleBadge || 'badge-slate',
    model: displayModel,
    status: data.status === 'block' ? 'idle' : data.status,
    statusLabel: data.statusLabel,
    task: data.task,
    goal: data.goal,
    progress,
    elapsed: data.elapsed || '—',
    next: data.next || '—',
    tokens: data.tokens || '0',
    cost: data.cost || '0.00',
    think: data.think,
    md: data.md,
    tokensToday,
    costToday: costNum,
    workload: progress,
    uptime: data.elapsed || '—',
    lastActive: data.elapsed !== '—' ? 'Vor ' + data.elapsed : 'Nicht aktiv',
    activeTaskCount: data.task ? 1 : 0,
    thinking: buildThinkingItems(data),
    activity: [],
    availableModels: models,
  }
}

export const useAgentStore = defineStore('agents', {
  state: () => ({
    agents: [] as AgentNodeData[],
    models: [] as { id: string; alias: string }[],
    loading: false,
    error: null as string | null,
    selectedAgentId: null as string | null,
    activityByAgentId: {} as Record<string, AgentActivityItem[]>,
    refreshInterval: null as ReturnType<typeof setInterval> | null,
    isConnected: false,
  }),

  getters: {
    /** AgentNodeData list for FlowCanvas */
    agentList: (state) => state.agents,

    /** Agent IDs in display order (Iris first) */
    agentOrder: (state) => {
      const ordered = state.agents.filter(a => a.id === 'iris')
      state.agents.forEach(a => { if (a.id !== 'iris') ordered.push(a) })
      return ordered.map(a => a.id)
    },

    /** Selected agent detail for modal */
    selectedAgent(state): AgentDetailData | null {
      if (!state.selectedAgentId) return null
      const data = state.agents.find(a => a.id === state.selectedAgentId)
      if (!data) return null
      return {
        ...buildAgentDetail(data, state.models),
        activity: state.activityByAgentId[data.id] ?? [],
      }
    },

    /** Is the modal open? */
    modalOpen: (state) => state.selectedAgentId !== null,

    /* ── AlertBar Metrics ────────────────────────── */
    activeCount: (state) => state.agents.filter(a => a.status === 'work').length,
    thinkCount: (state) => state.agents.filter(a => a.status === 'think').length,
    idleCount: (state) => state.agents.filter(a => a.status === 'idle').length,
    blockerCount: (state) => state.agents.filter(a => a.status === 'block').length,
    todayCost: (state) => {
      const total = state.agents.reduce((s, a) => s + parseFloat(a.cost || '0'), 0)
      return '$' + total.toFixed(2)
    },
    todayTokens: (state) => {
      const total = state.agents.reduce((s, a) => {
        const raw = a.tokens?.replace(/[^0-9.]/g, '') || '0'
        const v = parseFloat(raw)
        return Number.isFinite(v) ? s + v : s
      }, 0)
      return total >= 1000 ? Math.round(total / 1000) + 'k' : Math.round(total) + ''
    },
  },

  actions: {
    /* ── API: Fetch agents ──────────────────────── */
    async fetchAgents() {
      try {
        const res = await apiFetch('/api/dashboard/agents')
        if (!res.ok) { this.isConnected = false; return }
        const data: DashboardAgentInfo[] = await res.json()
        this.agents = data.map(enrichAgent)
        this.isConnected = true
      } catch (err) {
        this.isConnected = false
        console.warn('[AgentStore] fetchAgents failed', err)
      }
    },

    /* ── API: Fetch available models ────────────── */
    async fetchModels() {
      try {
        const res = await apiFetch('/api/dashboard/models')
        if (!res.ok) return
        const data: ModelOption[] = await res.json()
        this.models = data.map(m => ({ id: m.id, alias: m.name }))
      } catch (err) {
        console.warn('[AgentStore] fetchModels failed', err)
      }
    },

    /* ── API: Change agent model ────────────────── */
    async changeModel(agentId: string, modelId: string) {
      // Optimistic update
      const agent = this.agents.find(a => a.id === agentId)
      if (agent) agent.model = modelId

      try {
        await apiFetch(`/api/dashboard/agents/${encodeURIComponent(agentId)}/model`, {
          method: 'PUT',
          body: JSON.stringify({ model: modelId }),
        })
      } catch (err) {
        console.warn('[AgentStore] changeModel failed', err)
        // Refetch to revert on failure
        await this.fetchAgents()
      }
    },

    async fetchAgentActivity(agentId: string) {
      try {
        const res = await apiFetch(`/api/dashboard/agents/${encodeURIComponent(agentId)}/activity?limit=5`)
        if (!res.ok) return
        const data: AgentActivityEntry[] = await res.json()
        this.activityByAgentId[agentId] = data.map(entry => ({
          time: entry.time,
          text: entry.text,
        }))
      } catch (err) {
        console.warn('[AgentStore] fetchAgentActivity failed', err)
      }
    },

    /* ── Selection ───────────────────────────────── */
    selectAgent(id: string | null) {
      this.selectedAgentId = id
      if (id) void this.fetchAgentActivity(id)
    },

    /* ── Polling ─────────────────────────────────── */
    startPolling() {
      if (this.refreshInterval) return
      this.fetchAgents()
      this.fetchModels()
      this.refreshInterval = setInterval(() => {
        this.fetchAgents()
        this.fetchModels()
      }, 15000)
    },

    stopPolling() {
      if (this.refreshInterval) {
        clearInterval(this.refreshInterval)
        this.refreshInterval = null
      }
    },
  },
})
