// @lifecycle canonical - Aggregates gate evaluations across configured services.
import type {
  GateService,
  GateEnhancementResult,
  GateServiceConfig,
} from './gate-service-interface.js';
import type { Logger } from '../../../infra/logging/index.js';
import type { ConvertedPrompt } from '../../execution/types.js';
import type { GateContext } from '../core/gate-definitions.js';
import type { GateGuidanceRenderer } from '../guidance/GateGuidanceRenderer.js';

const DEFAULT_CONFIG: GateServiceConfig = {
  enabled: true,
};

/**
 * Compositional Gate Service - Template rendering only (no server-side validation)
 *
 * Simplified to use GateGuidanceRenderer directly, removing the unnecessary
 * GateInstructionInjector abstraction layer.
 */
export class CompositionalGateService implements GateService {
  readonly serviceType = 'compositional' as const;
  private readonly logger: Logger;
  private readonly gateGuidanceRenderer: GateGuidanceRenderer;
  private config: GateServiceConfig;

  constructor(
    logger: Logger,
    gateGuidanceRenderer: GateGuidanceRenderer,
    config?: Partial<GateServiceConfig>
  ) {
    this.logger = logger;
    this.gateGuidanceRenderer = gateGuidanceRenderer;
    this.config = { ...DEFAULT_CONFIG, ...config };
  }

  async enhancePrompt(
    prompt: ConvertedPrompt,
    gateIds: string[],
    context: GateContext
  ): Promise<GateEnhancementResult> {
    if (!this.config.enabled || gateIds.length === 0) {
      return {
        enhancedPrompt: prompt,
        gateInstructionsInjected: false,
        injectedGateIds: [],
      };
    }

    this.logger.debug('[CompositionalGateService] Rendering gate guidance', {
      promptId: prompt.id,
      gateCount: gateIds.length,
    });

    try {
      const guidanceContext: GateContext = {
        category: context.category ?? prompt.category,
        promptId: context.promptId ?? prompt.id,
      };

      if (context.framework) {
        guidanceContext.framework = context.framework;
      }
      if (context.explicitGateIds) {
        guidanceContext.explicitGateIds = context.explicitGateIds;
      }

      const guidance = await this.gateGuidanceRenderer.renderGuidance(gateIds, guidanceContext);

      if (!guidance || guidance.trim().length === 0) {
        this.logger.debug('[CompositionalGateService] No guidance produced', {
          promptId: prompt.id,
        });
        return {
          enhancedPrompt: prompt,
          gateInstructionsInjected: false,
          injectedGateIds: [],
        };
      }

      const template = prompt.userMessageTemplate ?? '';
      const enhancedTemplate = template.length > 0 ? `${template}\n\n${guidance}` : guidance;

      this.logger.debug('[CompositionalGateService] Gate guidance injected', {
        promptId: prompt.id,
        gateCount: gateIds.length,
        guidanceLength: guidance.length,
      });

      return {
        enhancedPrompt: {
          ...prompt,
          userMessageTemplate: enhancedTemplate,
        },
        gateInstructionsInjected: true,
        injectedGateIds: gateIds,
        instructionLength: guidance.length,
      };
    } catch (error) {
      this.logger.error('[CompositionalGateService] Failed to render gate guidance', {
        error,
        promptId: prompt.id,
        gateIds,
      });
      return {
        enhancedPrompt: prompt,
        gateInstructionsInjected: false,
        injectedGateIds: [],
      };
    }
  }

  supportsValidation(): boolean {
    return false;
  }

  updateConfig(config: Partial<GateServiceConfig>): void {
    this.config = { ...this.config, ...config };
  }
}
