import { Injectable, Inject } from "@nestjs/common";
import { ConfigService } from "@nestjs/config";
import { Logger } from "nestjs-pino";
import { SalesforceConnection } from "@bff/integrations/salesforce/services/salesforce-connection.service.js";
import {
  assertSalesforceId,
  assertSoqlFieldName,
} from "@bff/integrations/salesforce/utils/soql.util.js";
import {
  buildProductQuery,
  buildServicesQuery,
} from "@bff/integrations/salesforce/utils/services-query-builder.js";
import { extractErrorMessage } from "@bff/core/utils/error.util.js";
import type {
  SalesforcePricebookEntryRecord,
  SalesforceProduct2WithPricebookEntries,
} from "@customer-portal/domain/services/providers";
import { extractPricebookEntry as extractSalesforcePricebookEntry } from "@customer-portal/domain/services/providers";
import type { SalesforceResponse } from "@customer-portal/domain/common/providers";

@Injectable()
export class BaseServicesService {
  protected readonly portalPriceBookId: string;
  protected readonly portalCategoryField: string;

  constructor(
    protected readonly sf: SalesforceConnection,
    private readonly configService: ConfigService,
    @Inject(Logger) protected readonly logger: Logger
  ) {
    const portalPricebook = this.configService.get<string>("PORTAL_PRICEBOOK_ID")!;
    this.portalPriceBookId = assertSalesforceId(portalPricebook, "PORTAL_PRICEBOOK_ID");
    const portalCategory =
      this.configService.get<string>("PRODUCT_PORTAL_CATEGORY_FIELD") ?? "Product2Categories1__c";
    this.portalCategoryField = assertSoqlFieldName(portalCategory, "PRODUCT_PORTAL_CATEGORY_FIELD");
  }

  protected async executeQuery<TRecord extends SalesforceProduct2WithPricebookEntries>(
    soql: string,
    context: string
  ): Promise<TRecord[]> {
    try {
      const res = (await this.sf.query(soql, {
        label: `services:${context.replace(/\s+/g, "_").toLowerCase()}`,
      })) as SalesforceResponse<TRecord>;
      return res.records ?? [];
    } catch (error: unknown) {
      this.logger.error(`Query failed: ${context}`, {
        error: extractErrorMessage(error),
      });
      return [];
    }
  }

  protected extractPricebookEntry(
    record: SalesforceProduct2WithPricebookEntries
  ): SalesforcePricebookEntryRecord | undefined {
    const entry = extractSalesforcePricebookEntry(record);
    if (!entry) {
      const sku = record.StockKeepingUnit ?? undefined;
      this.logger.warn(
        `No pricebook entry found for product ${String(record.Name)} (SKU: ${String(sku ?? "")}). Pricebook ID: ${this.portalPriceBookId}.`
      );
      return undefined;
    }

    return entry;
  }

  protected buildProductQuery(
    category: string,
    itemClass: string,
    additionalFields: string[] = [],
    additionalConditions: string = ""
  ): string {
    return buildProductQuery(
      this.portalPriceBookId,
      this.portalCategoryField,
      category,
      itemClass,
      additionalFields,
      additionalConditions
    );
  }

  protected parseJsonField(field: unknown): string[] {
    if (!field) return [];
    if (Array.isArray(field)) return field as string[];
    if (typeof field === "string") {
      try {
        const parsed: unknown = JSON.parse(field);
        return Array.isArray(parsed) ? (parsed as string[]) : [];
      } catch {
        return [];
      }
    }
    return [];
  }

  protected buildServicesQuery(category: string, additionalFields: string[] = []): string {
    return buildServicesQuery(
      this.portalPriceBookId,
      this.portalCategoryField,
      category,
      additionalFields
    );
  }
}
