import { Controller, Get, ServiceUnavailableException } from '@nestjs/common';
import { Public } from '../../shared/common/decorators';
import { PrismaService } from '../../shared/prisma/prisma.service';
import { RedisService } from '../../shared/redis/redis.service';

type CheckStatus = 'ok' | 'error';

@Controller('health')
export class HealthController {
  constructor(
    private readonly prisma: PrismaService,
    private readonly redis: RedisService,
  ) {}

  @Public()
  @Get('live')
  live() {
    return { status: 'ok' as const };
  }

  @Public()
  @Get('ready')
  async ready() {
    const checks: Record<'database' | 'redis', CheckStatus> = {
      database: 'ok',
      redis: 'ok',
    };

    const [databaseReady, redisReady] = await Promise.all([
      this.checkDatabase(),
      this.checkRedis(),
    ]);

    if (!databaseReady) checks.database = 'error';
    if (!redisReady) checks.redis = 'error';

    if (!databaseReady || !redisReady) {
      throw new ServiceUnavailableException({ status: 'error', checks });
    }

    return { status: 'ok' as const, checks };
  }

  private async checkDatabase(): Promise<boolean> {
    try {
      await this.prisma.$queryRaw`SELECT 1`;
      return true;
    } catch {
      return false;
    }
  }

  private async checkRedis(): Promise<boolean> {
    try {
      return (await this.redis.raw.ping()) === 'PONG';
    } catch {
      return false;
    }
  }
}
