import { Injectable, Optional } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { AgentEnginePort } from '../../domain/ports/outbound/agent-engine.port';
import { AgentEngineType } from '../../domain/value-objects/agent-engine-type.vo';
import { ClaudeCodeCliEngine } from './claude-code-cli/claude-code-engine';
import { ClaudeApiEngine } from './claude-api/claude-api-engine';
import { ClaudeAgentSdkEngine } from './claude-agent-sdk/claude-agent-sdk-engine';

@Injectable()
export class EngineRegistry {
  private engines = new Map<AgentEngineType, AgentEnginePort>();

  constructor(
    @Optional() private readonly cliEngine: ClaudeCodeCliEngine,
    @Optional() private readonly apiEngine: ClaudeApiEngine,
    @Optional() private readonly sdkEngine: ClaudeAgentSdkEngine,
    private readonly configService: ConfigService,
  ) {
    if (cliEngine) this.engines.set(AgentEngineType.CLAUDE_CODE_CLI, cliEngine);
    if (apiEngine) this.engines.set(AgentEngineType.CLAUDE_API, apiEngine);
    if (sdkEngine) this.engines.set(AgentEngineType.CLAUDE_AGENT_SDK, sdkEngine);
  }

  getActiveEngine(): AgentEnginePort {
    const type = this.configService.get<AgentEngineType>(
      'AGENT_ENGINE_TYPE',
      AgentEngineType.CLAUDE_CODE_CLI,
    );
    const engine = this.engines.get(type);
    if (!engine) throw new Error(`Engine ${type} not registered`);
    return engine;
  }

  switchEngine(type: AgentEngineType): AgentEnginePort {
    const engine = this.engines.get(type);
    if (!engine) throw new Error(`Engine ${type} not available`);
    return engine;
  }

  listAvailable(): AgentEngineType[] {
    return [...this.engines.keys()];
  }
}
