import { Processor, WorkerHost } from "@nestjs/bullmq";
import { Injectable, Inject } from "@nestjs/common";
import { Logger } from "nestjs-pino";
import { OrderFulfillmentOrchestrator } from "../services/order-fulfillment-orchestrator.service";
import { SalesforceService } from "@bff/integrations/salesforce/salesforce.service";
import type { ProvisioningJobData } from "./provisioning.queue";
import { QUEUE_NAMES } from "@bff/infra/queue/queue.constants";

@Processor(QUEUE_NAMES.PROVISIONING)
@Injectable()
export class ProvisioningProcessor extends WorkerHost {
  constructor(
    private readonly orchestrator: OrderFulfillmentOrchestrator,
    private readonly salesforceService: SalesforceService,
    @Inject(Logger) private readonly logger: Logger
  ) {
    super();
  }

  async process(job: { data: ProvisioningJobData }): Promise<void> {
    const { sfOrderId, idempotencyKey } = job.data;
    this.logger.log("Processing provisioning job", {
      sfOrderId,
      idempotencyKey,
      correlationId: job.data.correlationId,
    });

    // Guard: Only process if Salesforce Order is currently 'Activating'

    const order = await this.salesforceService.getOrder(sfOrderId);
    const status = order?.Activation_Status__c ?? "";
    const lastErrorCode = order?.Activation_Error_Code__c ?? "";
    if (status !== "Activating") {
      this.logger.log("Skipping provisioning job: Order not in Activating state", {
        sfOrderId,
        currentStatus: status,
      });
      return; // Ack + no-op to safely handle duplicate/old events
    }

    // Guard: Avoid thrashing on known user-actionable failures
    if (lastErrorCode === "PAYMENT_METHOD_MISSING") {
      this.logger.log("Skipping provisioning job: Awaiting payment method addition", {
        sfOrderId,
        currentStatus: status,
        lastErrorCode,
      });
      return;
    }

    // Execute the same orchestration used by the webhook path, but without payload validation
    await this.orchestrator.executeFulfillment(sfOrderId, {}, idempotencyKey);
    this.logger.log("Provisioning job completed", { sfOrderId });
  }
}
