import { Injectable, Logger } from '@nestjs/common';
import { HttpService } from '@nestjs/axios';
import { ConfigService } from '@nestjs/config';
import { firstValueFrom } from 'rxjs';
import { AgentClientPort, AgentTaskParams, AgentStreamEvent } from '../../domain/ports/outbound/agent-client.port';

@Injectable()
export class AgentClientService implements AgentClientPort {
  private readonly logger = new Logger(AgentClientService.name);
  private readonly baseUrl: string;

  constructor(
    private readonly httpService: HttpService,
    private readonly configService: ConfigService,
  ) {
    this.baseUrl = this.configService.get<string>(
      'AGENT_SERVICE_URL',
      'http://localhost:3001',
    );
  }

  async *executeTask(params: AgentTaskParams): AsyncGenerator<AgentStreamEvent> {
    this.logger.log(`Executing agent task for tenant ${params.tenantId}`);

    const response = await firstValueFrom(
      this.httpService.post(`${this.baseUrl}/api/v1/agent/tasks`, {
        tenantId: params.tenantId,
        instructions: params.instructions,
        skills: params.skills ?? [],
        runbookId: params.runbookId,
        maxRiskLevel: params.maxRiskLevel ?? 1,
        maxTurns: params.maxTurns ?? 20,
        maxBudgetUsd: params.maxBudgetUsd,
        targets: { serverIds: params.targetServerIds },
        triggerContext: params.triggerContext,
      }),
    );

    yield {
      type: 'result',
      data: {
        sessionId: response.data.sessionId,
        status: response.data.status,
        summary: response.data.summary,
        actionsTaken: response.data.actionsTaken ?? [],
      },
    };
  }

  async cancelTask(sessionId: string): Promise<void> {
    this.logger.log(`Cancelling agent task session: ${sessionId}`);

    await firstValueFrom(
      this.httpService.post(`${this.baseUrl}/api/v1/agent/sessions/${sessionId}/cancel`),
    );
  }

  async *continueSession(sessionId: string, message: string): AsyncGenerator<AgentStreamEvent> {
    this.logger.log(`Continuing agent session: ${sessionId}`);

    const response = await firstValueFrom(
      this.httpService.post(`${this.baseUrl}/api/v1/agent/sessions/${sessionId}/continue`, {
        message,
      }),
    );

    yield {
      type: 'result',
      data: {
        sessionId,
        status: response.data.status,
        summary: response.data.summary,
        actionsTaken: response.data.actionsTaken ?? [],
      },
    };
  }
}
