import { Injectable, Logger } from '@nestjs/common';
import { StandingOrderRepository } from '../../infrastructure/repositories/standing-order.repository';
import { StandingOrder } from '../../domain/entities/standing-order.entity';
import { RedisEventBus } from '@it0/events';
import { EventPatterns } from '@it0/common';
import * as crypto from 'crypto';

export interface CreateStandingOrderInput {
  tenantId: string;
  name: string;
  description?: string;
  definedInSessionId: string;
  trigger: StandingOrder['trigger'];
  targets: StandingOrder['targets'];
  agentPrompt: string;
  agentSkills?: string[];
  runbookId?: string;
  maxRiskLevel?: 0 | 1;
  maxTurns?: number;
  maxBudgetUsd?: number;
  decisionBoundary: StandingOrder['decisionBoundary'];
  escalationPolicyId?: string;
  validFrom?: Date;
  validUntil?: Date;
  createdBy: string;
}

@Injectable()
export class CreateStandingOrderUseCase {
  private readonly logger = new Logger(CreateStandingOrderUseCase.name);

  constructor(
    private readonly standingOrderRepository: StandingOrderRepository,
    private readonly eventBus: RedisEventBus,
  ) {}

  async execute(input: CreateStandingOrderInput): Promise<StandingOrder> {
    this.logger.log(`Creating standing order: ${input.name}`);

    const order = new StandingOrder();
    order.id = crypto.randomUUID().slice(0, 30);
    order.tenantId = input.tenantId;
    order.name = input.name;
    order.description = input.description;
    order.definedInSessionId = input.definedInSessionId;
    order.triggerType = input.trigger.type;
    order.trigger = input.trigger;
    order.targets = input.targets;
    order.agentPrompt = input.agentPrompt;
    order.agentSkills = input.agentSkills;
    order.runbookId = input.runbookId;
    order.maxRiskLevel = input.maxRiskLevel ?? 0;
    order.maxTurns = input.maxTurns ?? 20;
    order.maxBudgetUsd = input.maxBudgetUsd;
    order.decisionBoundary = input.decisionBoundary;
    order.escalationPolicyId = input.escalationPolicyId;
    order.status = 'active';
    order.validFrom = input.validFrom ?? new Date();
    order.validUntil = input.validUntil;
    order.createdBy = input.createdBy;
    order.createdAt = new Date();
    order.updatedAt = new Date();

    const saved = await this.standingOrderRepository.save(order);

    await this.eventBus.publish(EventPatterns.STANDING_ORDER_CREATED, {
      id: crypto.randomUUID(),
      tenantId: input.tenantId,
      timestamp: new Date(),
      source: 'ops-service',
      type: 'standing.order.created',
      payload: {
        orderId: saved.id,
        name: saved.name,
        triggerType: saved.triggerType,
      },
    });

    this.logger.log(`Standing order created: ${saved.id}`);
    return saved;
  }
}
