import { createServer, Server } from 'http';
import { Queue } from 'bullmq';
import { getServiceConfig, getWorkerConfig } from '@wcag-ada/config';
import { logger } from '../utils/logger';
import { prisma } from '../utils/prisma';
import { createRedisConnection } from '../utils/redis';

export class HealthService {
  private server: Server | null = null;
  private config = getServiceConfig('worker');
  private workerConfig = getWorkerConfig();

  async start(): Promise<void> {
    this.server = createServer(async (req, res) => {
      if (req.url === '/health' && req.method === 'GET') {
        const health = await this.getHealthStatus();
        res.writeHead(health.healthy ? 200 : 503, { 'Content-Type': 'application/json' });
        res.end(JSON.stringify(health));
      } else {
        res.writeHead(404);
        res.end();
      }
    });

    this.server.listen(this.config.port, () => {
      logger.info(`Health server listening on port ${this.config.port}`);
    });
  }

  private async getHealthStatus() {
    const checks = {
      server: 'ok',
      database: 'unknown',
      redis: 'unknown',
      queue: 'unknown',
    };

    // Check database
    try {
      await prisma.$queryRaw`SELECT 1`;
      checks.database = 'ok';
    } catch (error) {
      checks.database = 'error';
      logger.error('Database health check failed', error);
    }

    // Check Redis
    try {
      const redis = createRedisConnection();
      await redis.ping();
      await redis.quit();
      checks.redis = 'ok';
    } catch (error) {
      checks.redis = 'error';
      logger.error('Redis health check failed', error);
    }

    // Check queue
    try {
      const queue = new Queue(this.workerConfig.queueName, {
        connection: createRedisConnection(),
      });
      await queue.getJobCounts();
      await queue.close();
      checks.queue = 'ok';
    } catch (error) {
      checks.queue = 'error';
      logger.error('Queue health check failed', error);
    }

    const healthy = Object.values(checks).every(status => status === 'ok');

    return {
      healthy,
      checks,
      timestamp: new Date().toISOString(),
    };
  }

  async stop(): Promise<void> {
    if (this.server) {
      return new Promise((resolve) => {
        this.server!.close(() => {
          logger.info('Health server stopped');
          resolve();
        });
      });
    }
  }
}