import { beforeEach, describe, expect, it, vi } from 'vitest'
import { mount } from '@vue/test-utils'

const mocks = vi.hoisted(() => ({
  getHierarchyStats: vi.fn(),
  updateConfig: vi.fn(),
}))

vi.mock('@/api/agent', () => ({
  agentApi: {
    getHierarchyStats: mocks.getHierarchyStats,
    updateConfig: mocks.updateConfig,
  },
}))

import AgentsPage from './index.vue'

const hierarchyStats = {
  main_agents: [
    {
      agent_id: 'planner',
      call_count: 12,
      current_task: null,
      status: 'idle',
      sub_commanders: [
        { agent_id: 'planner_scope', call_count: 4, current_task: null, status: 'idle' },
        { agent_id: 'planner_steps', call_count: 9, current_task: '拆解执行步骤', status: 'active' },
      ],
    },
    {
      agent_id: 'executor',
      call_count: 8,
      current_task: null,
      status: 'idle',
      sub_commanders: [
        { agent_id: 'executor_tasks', call_count: 8, current_task: null, status: 'idle' },
        { agent_id: 'executor_forum', call_count: 4, current_task: null, status: 'idle' },
      ],
    },
    {
      agent_id: 'librarian',
      call_count: 5,
      current_task: null,
      status: 'idle',
      sub_commanders: [
        { agent_id: 'librarian_retrieval', call_count: 5, current_task: null, status: 'idle' },
        { agent_id: 'librarian_graph', call_count: 2, current_task: null, status: 'idle' },
      ],
    },
    {
      agent_id: 'analyst',
      call_count: 3,
      current_task: null,
      status: 'idle',
      sub_commanders: [
        { agent_id: 'analyst_progress', call_count: 2, current_task: null, status: 'idle' },
        { agent_id: 'analyst_insights', call_count: 3, current_task: null, status: 'idle' },
      ],
    },
  ],
}

describe('agents page pcb command center', () => {
  beforeEach(() => {
    vi.clearAllMocks()
    vi.useFakeTimers()
    vi.stubGlobal('ResizeObserver', class {
      observe() {}
      disconnect() {}
      unobserve() {}
    })
    Object.defineProperty(window, 'matchMedia', {
      writable: true,
      value: vi.fn().mockImplementation(() => ({
        matches: true,
        media: '(prefers-reduced-motion: no-preference)',
        onchange: null,
        addListener: vi.fn(),
        removeListener: vi.fn(),
        addEventListener: vi.fn(),
        removeEventListener: vi.fn(),
        dispatchEvent: vi.fn(),
      })),
    })
    mocks.getHierarchyStats.mockResolvedValue(hierarchyStats)
    mocks.updateConfig.mockResolvedValue({})
  })

  it('shows commander skills and active route telemetry for an active sub commander path', async () => {
    const wrapper = mount(AgentsPage)
    await Promise.resolve()
    await Promise.resolve()

    const skillsPanel = wrapper.get('[data-testid="commander-skills"]')
    expect(skillsPanel.text()).toContain('指挥官技能')
    expect(skillsPanel.text()).toContain('路径拆解')

    const activeSkill = wrapper.get('[data-testid="commander-skill-skill_planner"]')
    expect(activeSkill.classes()).toContain('active')

    const plannerBus = wrapper.get('[data-testid="bus-link-planner"]')
    expect(plannerBus.classes()).toContain('energized')

    const plannerStepsBranch = wrapper.get('[data-testid="sub-link-planner_steps"]')
    expect(plannerStepsBranch.classes()).toContain('energized')

    const routeTelemetry = wrapper.get('[data-testid="route-telemetry"]')
    expect(routeTelemetry.text()).toContain('ACTIVE ROUTE')
    expect(routeTelemetry.text()).toContain('PLANNER')
    expect(routeTelemetry.text()).toContain('STEPS')
  })

  it('renders child agents beneath the four main roles in the same hierarchy canvas', async () => {
    const wrapper = mount(AgentsPage)
    await Promise.resolve()
    await Promise.resolve()

    expect(wrapper.get('[data-testid="agent-chip-planner_scope"]').text()).toContain('SCOPE')
    expect(wrapper.get('[data-testid="agent-chip-planner_steps"]').text()).toContain('STEPS')
    expect(wrapper.get('[data-testid="agent-chip-executor_tasks"]').text()).toContain('TASK OPS')
    expect(wrapper.get('[data-testid="agent-chip-analyst_insights"]').text()).toContain('INSIGHTS')
  })

  it('keeps the configuration drawer available when selecting a main agent chip', async () => {
    const wrapper = mount(AgentsPage)
    await Promise.resolve()
    await Promise.resolve()

    await wrapper.get('[data-testid="agent-chip-planner"]').trigger('click')

    expect(wrapper.text()).toContain('AGENT CONFIGURATION')
    expect(wrapper.find('input').exists()).toBe(true)
  })

  it('cycles the energized demo path when hierarchy stats are offline', async () => {
    mocks.getHierarchyStats.mockRejectedValue(new Error('offline'))
    const wrapper = mount(AgentsPage)
    await Promise.resolve()
    await Promise.resolve()

    expect(wrapper.get('[data-testid="bus-link-planner"]').classes()).toContain('energized')
    expect(wrapper.get('[data-testid="sub-link-planner_scope"]').classes()).toContain('energized')

    await vi.advanceTimersByTimeAsync(1700)

    expect(wrapper.get('[data-testid="sub-link-planner_scope"]').classes()).not.toContain('energized')
    expect(wrapper.get('[data-testid="sub-link-planner_steps"]').classes()).toContain('energized')
  })
})

