/**
 * Kubernetes API Client
 * Handles communication with Kubernetes API for cluster management
 */

import axios, { AxiosInstance } from 'axios'

export interface KubernetesCluster {
  name: string
  server: string
  context: string
  namespace: string
  version?: string
  nodes?: {
    total: number
    ready: number
  }
}

export interface KubernetesResource {
  kind: string
  apiVersion: string
  metadata: {
    name: string
    namespace?: string
    uid: string
    creationTimestamp: string
    labels?: Record<string, string>
    annotations?: Record<string, string>
  }
  spec?: any
  status?: any
}

export interface KubernetesNamespace {
  metadata: {
    name: string
    uid: string
    creationTimestamp: string
    labels?: Record<string, string>
  }
  status: {
    phase: string
  }
}

class KubernetesClient {
  private client: AxiosInstance
  private baseURL: string

  constructor(accessToken?: string, clusterURL?: string) {
    this.baseURL = clusterURL || process.env.NEXT_PUBLIC_KUBERNETES_API || 'http://localhost:8001'
    
    this.client = axios.create({
      baseURL: this.baseURL,
      headers: {
        'Content-Type': 'application/json',
        ...(accessToken && { Authorization: `Bearer ${accessToken}` }),
      },
    })
  }

  /**
   * Get cluster information
   */
  async getClusterInfo(): Promise<KubernetesCluster> {
    try {
      const versionResponse = await this.client.get('/version')
      const nodesResponse = await this.client.get('/api/v1/nodes')
      
      const nodes = nodesResponse.data.items || []
      const readyNodes = nodes.filter((node: any) => {
        const conditions = node.status?.conditions || []
        return conditions.some((c: any) => c.type === 'Ready' && c.status === 'True')
      })

      return {
        name: 'default-cluster',
        server: this.baseURL,
        context: 'default',
        namespace: 'default',
        version: versionResponse.data.gitVersion,
        nodes: {
          total: nodes.length,
          ready: readyNodes.length,
        },
      }
    } catch (error: any) {
      console.error('Failed to fetch cluster info:', error)
      throw new Error(`Failed to fetch cluster info: ${error.message}`)
    }
  }

  /**
   * List namespaces
   */
  async listNamespaces(): Promise<KubernetesNamespace[]> {
    try {
      const response = await this.client.get('/api/v1/namespaces')
      return response.data.items || []
    } catch (error: any) {
      console.error('Failed to list namespaces:', error)
      throw new Error(`Failed to list namespaces: ${error.message}`)
    }
  }

  /**
   * List resources by kind
   */
  async listResources(
    kind: string,
    namespace?: string,
    apiVersion: string = 'v1'
  ): Promise<KubernetesResource[]> {
    try {
      const path = namespace
        ? `/api/${apiVersion}/namespaces/${namespace}/${kind.toLowerCase()}s`
        : `/api/${apiVersion}/${kind.toLowerCase()}s`
      
      const response = await this.client.get(path)
      return response.data.items || []
    } catch (error: any) {
      console.error(`Failed to list ${kind} resources:`, error)
      throw new Error(`Failed to list resources: ${error.message}`)
    }
  }

  /**
   * Get a specific resource
   */
  async getResource(
    kind: string,
    name: string,
    namespace?: string,
    apiVersion: string = 'v1'
  ): Promise<KubernetesResource> {
    try {
      const path = namespace
        ? `/api/${apiVersion}/namespaces/${namespace}/${kind.toLowerCase()}s/${name}`
        : `/api/${apiVersion}/${kind.toLowerCase()}s/${name}`
      
      const response = await this.client.get(path)
      return response.data
    } catch (error: any) {
      console.error(`Failed to get ${kind} ${name}:`, error)
      throw new Error(`Failed to get resource: ${error.message}`)
    }
  }

  /**
   * List pods
   */
  async listPods(namespace?: string): Promise<KubernetesResource[]> {
    return this.listResources('Pod', namespace)
  }

  /**
   * List deployments
   */
  async listDeployments(namespace?: string): Promise<KubernetesResource[]> {
    return this.listResources('Deployment', namespace, 'apps/v1')
  }

  /**
   * List services
   */
  async listServices(namespace?: string): Promise<KubernetesResource[]> {
    return this.listResources('Service', namespace)
  }
}

export function createKubernetesClient(accessToken?: string, clusterURL?: string): KubernetesClient {
  return new KubernetesClient(accessToken, clusterURL)
}

