import { Injectable, Inject, BadRequestException } from "@nestjs/common";
import { Logger } from "nestjs-pino";
import { SubscriptionsOrchestrator } from "../../subscriptions-orchestrator.service.js";
import { extractErrorMessage } from "@bff/core/utils/error.util.js";
import type { SimValidationResult } from "../interfaces/sim-base.interface.js";
import {
  cleanSimAccount,
  extractSimAccountFromSubscription,
  isSimSubscription,
} from "@customer-portal/domain/sim";

@Injectable()
export class SimValidationService {
  constructor(
    private readonly subscriptionsService: SubscriptionsOrchestrator,
    @Inject(Logger) private readonly logger: Logger
  ) {}

  /**
   * Check if a subscription is a SIM service and extract account identifier
   *
   * Uses domain validation functions for business logic.
   */
  async validateSimSubscription(
    userId: string,
    subscriptionId: number
  ): Promise<SimValidationResult> {
    try {
      // Get subscription details to verify it's a SIM service
      const subscription = await this.subscriptionsService.getSubscriptionById(
        userId,
        subscriptionId
      );

      // Check if this is a SIM service (using domain function)
      if (!isSimSubscription(subscription)) {
        throw new BadRequestException("This subscription is not a SIM service");
      }

      // Extract SIM account identifier (using domain function)
      let account = extractSimAccountFromSubscription(subscription);

      // If no account found, log detailed info and throw error
      if (!account) {
        this.logger.error(`No SIM account identifier found for subscription ${subscriptionId}`, {
          userId,
          subscriptionId,
          productName: subscription.productName,
          domain: subscription.domain,
          customFieldKeys: subscription.customFields ? Object.keys(subscription.customFields) : [],
          customFieldValues: subscription.customFields,
          orderNumber: subscription.orderNumber,
          note: "Set the phone number in 'domain' field or a custom field named 'phone', 'msisdn', 'Phone Number', etc.",
        });

        throw new BadRequestException(
          `No SIM phone number found for this subscription. Please ensure the phone number is set in WHMCS (domain field or custom field named 'Phone Number', 'MSISDN', etc.)`
        );
      }

      // Clean up the account format (using domain function)
      account = cleanSimAccount(account);

      this.logger.log(`Using SIM account: ${account}`, {
        userId,
        subscriptionId,
        account,
      });

      return { account };
    } catch (error) {
      const sanitizedError = extractErrorMessage(error);
      this.logger.error(
        `Failed to validate SIM subscription ${subscriptionId} for user ${userId}`,
        {
          error: sanitizedError,
        }
      );
      throw error;
    }
  }

  /**
   * Debug method to check subscription data for SIM services
   */
  async debugSimSubscription(
    userId: string,
    subscriptionId: number
  ): Promise<Record<string, unknown>> {
    try {
      const subscription = await this.subscriptionsService.getSubscriptionById(
        userId,
        subscriptionId
      );

      // Try to extract account using the standard function
      const extractedAccount = extractSimAccountFromSubscription(subscription);

      return {
        subscriptionId,
        productName: subscription.productName,
        domain: subscription.domain,
        orderNumber: subscription.orderNumber,
        isSimService: isSimSubscription(subscription),
        groupName: subscription.groupName,
        status: subscription.status,
        // Account extraction result
        extractedAccount,
        accountSource: extractedAccount
          ? subscription.domain
            ? "domain field"
            : "custom field or order number"
          : "NOT FOUND - check fields below",
        // All custom fields for debugging
        customFieldKeys: Object.keys(subscription.customFields || {}),
        customFields: subscription.customFields,
        hint: extractedAccount
          ? undefined
          : "Set phone number in 'domain' field OR add custom field named: phone, msisdn, phonenumber, Phone Number, MSISDN, etc.",
      };
    } catch (error) {
      const sanitizedError = extractErrorMessage(error);
      this.logger.error(`Failed to debug subscription ${subscriptionId}`, {
        error: sanitizedError,
      });
      throw error;
    }
  }
}
