import { Injectable, Logger, OnModuleInit } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { HttpService } from '@nestjs/axios';
import { firstValueFrom } from 'rxjs';
import { RedisEventBus } from '@it0/events';
import { EventPatterns } from '@it0/common';
import { AlertRuleRepository } from '../../infrastructure/repositories/alert-rule.repository';

interface AlertFiredPayload {
  ruleId: string;
  serverId: string;
  severity: string;
  message: string;
  metricValue?: number;
}

@Injectable()
export class AlertRunbookBridgeService implements OnModuleInit {
  private readonly logger = new Logger(AlertRunbookBridgeService.name);
  private readonly opsServiceUrl: string;

  constructor(
    private readonly alertRuleRepo: AlertRuleRepository,
    private readonly eventBus: RedisEventBus,
    private readonly configService: ConfigService,
    private readonly httpService: HttpService,
  ) {
    this.opsServiceUrl = this.configService.get<string>(
      'OPS_SERVICE_URL',
      'http://localhost:3004',
    );
  }

  async onModuleInit(): Promise<void> {
    this.logger.log('Subscribing to ALERT_FIRED events for runbook bridging...');

    await this.eventBus.subscribe(
      EventPatterns.ALERT_FIRED,
      'monitor-runbook-bridge',
      `bridge-${crypto.randomUUID().slice(0, 8)}`,
      async (event) => {
        await this.handleAlert(event.payload ?? event);
      },
    );
  }

  async handleAlert(data: AlertFiredPayload): Promise<void> {
    if (!data?.ruleId) {
      this.logger.warn('Received ALERT_FIRED event without ruleId, skipping');
      return;
    }

    const rule = await this.alertRuleRepo.findById(data.ruleId);
    if (!rule) {
      this.logger.warn(`Alert rule ${data.ruleId} not found, skipping runbook bridge`);
      return;
    }

    if (!rule.runbookId) {
      this.logger.debug(`Alert rule ${data.ruleId} has no linked runbook, skipping`);
      return;
    }

    try {
      const response = await firstValueFrom(
        this.httpService.post(`${this.opsServiceUrl}/api/v1/ops/tasks`, {
          runbookId: rule.runbookId,
          triggeredBy: 'monitor-service:alert-runbook-bridge',
          context: {
            alertRuleId: rule.id,
            alertRuleName: rule.name,
            serverId: data.serverId,
            severity: data.severity,
            message: data.message,
            metricValue: data.metricValue,
            metricType: rule.metricType,
            threshold: rule.condition.threshold,
          },
        }),
      );

      this.logger.log(
        `Created OpsTask ${response.data?.id} from alert rule "${rule.name}" ` +
          `(runbook: ${rule.runbookId}) for server ${data.serverId}`,
      );
    } catch (error: any) {
      this.logger.error(
        `Failed to create OpsTask for alert rule "${rule.name}": ${error.message}`,
      );
    }
  }
}
