/**
 * API Integration Tests
 * End-to-end tests for GraphQL API
 */

import { describe, it, expect, beforeAll, afterAll } from 'vitest'
import { ApolloServer } from '@apollo/server'
import { schema } from '../../schema'
import { getDb } from '../../db'
import { Context } from '../../types/context'

interface HealthResponse {
  health: {
    status: string
    timestamp: string
    version: string
  }
}

interface ResourcesResponse {
  resources: Array<{
    id: string
    name: string
    type: string
    status: string
  }>
}

interface AnomaliesResponse {
  detectAnomalies: Array<{
    id: string
    severity: string
    anomalyType: string
    value: number
  }>
}

interface PredictResponse {
  predictUsage: {
    id: string
    predictedValue: number
    confidence: number
    trend: string
  }
}

describe('GraphQL API Integration', () => {
  let server: ApolloServer
  let testContext: Context

  beforeAll(async () => {
    server = new ApolloServer({
      schema,
    })

    const db = getDb()
    testContext = {
      request: {} as never, // Mock request for tests
      db,
      user: {
        id: 'test-user',
        email: 'test@example.com',
        name: 'Test User',
        role: 'ADMIN' as const,
        createdAt: new Date(),
        updatedAt: new Date(),
      },
    }
  })

  afterAll(async () => {
    await server.stop()
  })

  describe('Health Check', () => {
    it('should return health status', async () => {
      const result = await server.executeOperation(
        {
          query: `
            query {
              health {
                status
                timestamp
                version
              }
            }
          `,
        },
        { contextValue: testContext }
      )

      expect(result.body.kind).toBe('single')
      if (result.body.kind === 'single') {
        const data = result.body.singleResult.data as HealthResponse | null | undefined
        expect(data?.health).toBeDefined()
        expect(data?.health.status).toBe('ok')
      }
    })
  })

  describe('Resource Queries', () => {
    it('should query resources', async () => {
      const result = await server.executeOperation(
        {
          query: `
            query {
              resources {
                id
                name
                type
                status
              }
            }
          `,
        },
        { contextValue: testContext }
      )

      expect(result.body.kind).toBe('single')
      if (result.body.kind === 'single') {
        const data = result.body.singleResult.data as ResourcesResponse | null | undefined
        expect(data?.resources).toBeDefined()
        expect(Array.isArray(data?.resources)).toBe(true)
      }
    })
  })

  describe('Anomaly Detection', () => {
    it('should detect anomalies', async () => {
      const result = await server.executeOperation(
        {
          query: `
            mutation {
              detectAnomalies(config: {
                resourceId: "resource-1"
                metricType: "CPU_USAGE"
                sensitivity: "MEDIUM"
              }) {
                id
                severity
                anomalyType
                value
              }
            }
          `,
        },
        { contextValue: testContext }
      )

      expect(result.body.kind).toBe('single')
      if (result.body.kind === 'single') {
        const data = result.body.singleResult.data as AnomaliesResponse | null | undefined
        expect(data?.detectAnomalies).toBeDefined()
      }
    })
  })

  describe('Predictive Analytics', () => {
    it('should predict usage', async () => {
      const result = await server.executeOperation(
        {
          query: `
            mutation {
              predictUsage(config: {
                resourceId: "resource-1"
                metricType: "CPU_USAGE"
                timeframe: "24H"
                predictionType: "USAGE"
              }) {
                id
                predictedValue
                confidence
                trend
              }
            }
          `,
        },
        { contextValue: testContext }
      )

      expect(result.body.kind).toBe('single')
      if (result.body.kind === 'single') {
        const data = result.body.singleResult.data as PredictResponse | null | undefined
        expect(data?.predictUsage).toBeDefined()
      }
    })
  })
})

