import { Injectable, Inject, BadRequestException } from "@nestjs/common";
import { Logger } from "nestjs-pino";
import { SalesforceAccountService } from "@bff/integrations/salesforce/services/salesforce-account.service.js";
import { SalesforceFacade } from "@bff/integrations/salesforce/facades/salesforce.facade.js";

export interface ResolveSalesforceAccountParams {
  email: string;
  firstName: string;
  lastName: string;
  phone?: string;
  customerNumber?: string;
  source: string;
  existingAccountId?: string;
  updateSourceIfExists?: boolean;
}

export interface ResolveSalesforceAccountResult {
  sfAccountId: string;
  customerNumber: string | undefined;
}

/**
 * Step: Resolve or create a Salesforce account.
 *
 * Finds an existing SF account by email (or verifies a known ID),
 * or creates a new one when no match is found.
 *
 * No rollback — SF accounts are reusable across retries.
 */
@Injectable()
export class ResolveSalesforceAccountStep {
  constructor(
    private readonly salesforceAccountService: SalesforceAccountService,
    private readonly salesforceFacade: SalesforceFacade,
    @Inject(Logger) private readonly logger: Logger
  ) {}

  async execute(params: ResolveSalesforceAccountParams): Promise<ResolveSalesforceAccountResult> {
    const { email, firstName, lastName, phone, source, existingAccountId, updateSourceIfExists } =
      params;

    // If an existing SF account ID is provided, verify it still exists
    if (existingAccountId) {
      const existing = await this.salesforceAccountService.findByEmail(email);
      if (!existing || existing.id !== existingAccountId) {
        throw new BadRequestException("Account verification failed. Please start over.");
      }
      return { sfAccountId: existing.id, customerNumber: existing.accountNumber };
    }

    // Check if SF account exists by email
    const existingSf = await this.salesforceAccountService.findByEmail(email);
    if (existingSf) {
      this.logger.log({ email, sfAccountId: existingSf.id }, "Using existing SF account");

      if (updateSourceIfExists) {
        await this.salesforceFacade.updateAccountPortalFields(existingSf.id, {
          source,
        });
      }

      return { sfAccountId: existingSf.id, customerNumber: existingSf.accountNumber };
    }

    // Create new SF Account
    if (!firstName || !lastName) {
      throw new BadRequestException("Name is required to create an account.");
    }

    const { accountId, accountNumber } = await this.salesforceAccountService.createAccount({
      firstName,
      lastName,
      email,
      phone: phone ?? "",
      portalSource: source,
    });

    this.logger.log({ email, sfAccountId: accountId }, "Created new SF account");
    return { sfAccountId: accountId, customerNumber: accountNumber };
  }
}
