import { test, expect } from '@playwright/test'
import { API_KEY_HEADER } from './helpers'

test.describe('Direct CLI Integration', () => {
  const createdConnectionIds: string[] = []
  const createdAgentIds: number[] = []

  test.afterEach(async ({ request }) => {
    // Clean up connections
    for (const connId of createdConnectionIds) {
      await request.delete('/api/connect', {
        headers: API_KEY_HEADER,
        data: { connection_id: connId },
      })
    }
    createdConnectionIds.length = 0

    // Clean up auto-created agents
    for (const agentId of createdAgentIds) {
      await request.delete(`/api/agents/${agentId}`, { headers: API_KEY_HEADER })
    }
    createdAgentIds.length = 0
  })

  test('POST /api/connect creates connection and auto-creates agent', async ({ request }) => {
    const agentName = `e2e-cli-${Date.now()}`
    const res = await request.post('/api/connect', {
      headers: API_KEY_HEADER,
      data: {
        tool_name: 'claude-code',
        tool_version: '1.0.0',
        agent_name: agentName,
        agent_role: 'developer',
      },
    })
    expect(res.status()).toBe(200)
    const body = await res.json()

    expect(body.connection_id).toBeDefined()
    expect(body.agent_id).toBeDefined()
    expect(body.agent_name).toBe(agentName)
    expect(body.status).toBe('connected')
    expect(body.sse_url).toBe('/api/events')
    expect(body.heartbeat_url).toContain('/api/agents/')
    expect(body.token_report_url).toBe('/api/tokens')

    createdConnectionIds.push(body.connection_id)
    createdAgentIds.push(body.agent_id)

    // Verify agent was created
    const agentRes = await request.get(`/api/agents/${body.agent_id}`, {
      headers: API_KEY_HEADER,
    })
    expect(agentRes.status()).toBe(200)
    const agentBody = await agentRes.json()
    expect(agentBody.agent.name).toBe(agentName)
    expect(agentBody.agent.status).toBe('online')
  })

  test('GET /api/connect lists connections', async ({ request }) => {
    const agentName = `e2e-cli-list-${Date.now()}`
    const postRes = await request.post('/api/connect', {
      headers: API_KEY_HEADER,
      data: {
        tool_name: 'codex',
        agent_name: agentName,
      },
    })
    const postBody = await postRes.json()
    createdConnectionIds.push(postBody.connection_id)
    createdAgentIds.push(postBody.agent_id)

    const res = await request.get('/api/connect', { headers: API_KEY_HEADER })
    expect(res.status()).toBe(200)
    const body = await res.json()
    expect(Array.isArray(body.connections)).toBe(true)
    const found = body.connections.find((c: any) => c.connection_id === postBody.connection_id)
    expect(found).toBeDefined()
    expect(found.agent_name).toBe(agentName)
    expect(found.tool_name).toBe('codex')
  })

  test('POST heartbeat with inline token_usage', async ({ request }) => {
    const agentName = `e2e-cli-hb-${Date.now()}`
    const postRes = await request.post('/api/connect', {
      headers: API_KEY_HEADER,
      data: {
        tool_name: 'claude-code',
        agent_name: agentName,
      },
    })
    const postBody = await postRes.json()
    createdConnectionIds.push(postBody.connection_id)
    createdAgentIds.push(postBody.agent_id)

    const hbRes = await request.post(`/api/agents/${postBody.agent_id}/heartbeat`, {
      headers: API_KEY_HEADER,
      data: {
        connection_id: postBody.connection_id,
        token_usage: {
          model: 'claude-sonnet-4',
          inputTokens: 1000,
          outputTokens: 500,
        },
      },
    })
    expect(hbRes.status()).toBe(200)
    const hbBody = await hbRes.json()
    expect(hbBody.token_recorded).toBe(true)
    expect(hbBody.agent).toBe(agentName)

    const costsRes = await request.get('/api/tokens?action=agent-costs&timeframe=hour', {
      headers: API_KEY_HEADER,
    })
    expect(costsRes.status()).toBe(200)
    const costsBody = await costsRes.json()
    expect(costsBody.agents).toHaveProperty(agentName)
    expect(costsBody.agents[agentName].stats.totalTokens).toBeGreaterThanOrEqual(1500)
  })

  test('DELETE /api/connect disconnects and sets agent offline', async ({ request }) => {
    const agentName = `e2e-cli-del-${Date.now()}`
    const postRes = await request.post('/api/connect', {
      headers: API_KEY_HEADER,
      data: {
        tool_name: 'claude-code',
        agent_name: agentName,
      },
    })
    const postBody = await postRes.json()
    createdAgentIds.push(postBody.agent_id)

    const delRes = await request.delete('/api/connect', {
      headers: API_KEY_HEADER,
      data: { connection_id: postBody.connection_id },
    })
    expect(delRes.status()).toBe(200)
    const delBody = await delRes.json()
    expect(delBody.status).toBe('disconnected')

    // Agent should be offline
    const agentRes = await request.get(`/api/agents/${postBody.agent_id}`, {
      headers: API_KEY_HEADER,
    })
    const agentBody = await agentRes.json()
    expect(agentBody.agent.status).toBe('offline')
  })

  test('POST /api/connect requires auth', async ({ request }) => {
    const res = await request.post('/api/connect', {
      data: {
        tool_name: 'claude-code',
        agent_name: 'unauthorized-agent',
      },
    })
    expect(res.status()).toBe(401)
  })
})
