import { Controller, Get } from '@nestjs/common';
import {
  HealthCheckService,
  HealthCheck,
  TypeOrmHealthIndicator,
  MemoryHealthIndicator,
  DiskHealthIndicator,
} from '@nestjs/terminus';
import { RedisHealthIndicator } from './indicators/redis.health';
import { MongoHealthIndicator } from './indicators/mongo.health';
import { MinioHealthIndicator } from './indicators/minio.health';
import { AzureHealthIndicator } from './indicators/azure.health';

/**
 * Health Check Controller
 *
 * Provides comprehensive health status endpoints for monitoring and orchestration
 *
 * Endpoints:
 * - GET /health: Overall health status
 * - GET /health/liveness: Kubernetes liveness probe
 * - GET /health/readiness: Kubernetes readiness probe
 */
@Controller('health')
export class HealthController {
  constructor(
    private health: HealthCheckService,
    private db: TypeOrmHealthIndicator,
    private memory: MemoryHealthIndicator,
    private disk: DiskHealthIndicator,
    private redis: RedisHealthIndicator,
    private mongo: MongoHealthIndicator,
    private minio: MinioHealthIndicator,
    private azure: AzureHealthIndicator,
  ) {}

  /**
   * Comprehensive health check
   * Checks all system dependencies
   */
  @Get()
  @HealthCheck()
  check() {
    return this.health.check([
      // Database
      () => this.db.pingCheck('database', { timeout: 5000 }),

      // Redis cache
      () => this.redis.isHealthy('redis'),

      // MongoDB (AI chat history)
      () => this.mongo.isHealthy('mongodb'),

      // MinIO / S3 storage
      () => this.minio.isHealthy('minio'),

      // Azure OpenAI services
      () => this.azure.isHealthy('azure-openai'),

      // Memory usage (warn at 80%, fail at 90%)
      () => this.memory.checkHeap('memory_heap', 300 * 1024 * 1024), // 300MB
      () => this.memory.checkRSS('memory_rss', 500 * 1024 * 1024), // 500MB

      // Disk storage (warn at 80%, fail at 90%)
      () =>
        this.disk.checkStorage('disk', {
          path: '/',
          thresholdPercent: 0.9,
        }),
    ]);
  }

  /**
   * Liveness probe for Kubernetes
   * Indicates if the application is running and should be restarted
   */
  @Get('liveness')
  @HealthCheck()
  liveness() {
    return this.health.check([
      // Basic checks only - just ensure the app is running
      () => this.memory.checkHeap('memory_heap', 400 * 1024 * 1024), // More lenient
      () => this.memory.checkRSS('memory_rss', 600 * 1024 * 1024),
    ]);
  }

  /**
   * Readiness probe for Kubernetes
   * Indicates if the application is ready to serve traffic
   */
  @Get('readiness')
  @HealthCheck()
  readiness() {
    return this.health.check([
      // All critical services must be ready
      () => this.db.pingCheck('database', { timeout: 3000 }),
      () => this.redis.isHealthy('redis'),
      () => this.azure.isHealthy('azure-openai'),
    ]);
  }

  /**
   * Startup probe for Kubernetes
   * Indicates if the application has started successfully
   */
  @Get('startup')
  @HealthCheck()
  startup() {
    return this.health.check([
      // Check if database is accessible
      () => this.db.pingCheck('database', { timeout: 10000 }), // Longer timeout for startup
      () => this.redis.isHealthy('redis'),
    ]);
  }
}
