/**
 * Freebit Account Registration Service (PA02-01)
 *
 * Handles MVNO account registration via the Freebit PA02-01 API.
 * This is the first step in Physical SIM activation - registering
 * the phone number (account) in Freebit's system.
 *
 * @see docs/freebit-apis/PA02-01-account-registration.md
 */

import { Injectable, Inject, BadRequestException } from "@nestjs/common";
import { Logger } from "nestjs-pino";
import { extractErrorMessage } from "@bff/core/utils/error.util.js";
import { FreebitClientService } from "./freebit-client.service.js";

/**
 * PA02-01 Account Registration parameters
 */
export interface AccountRegistrationParams {
  /** MSISDN (phone number) - 11-14 digits */
  account: string;
  /** Freebit plan code (e.g., "PASI_5G") */
  planCode: string;
  /** Create type: "new" for new account, "add" for existing (use "add" after PA05-18) */
  createType?: "new" | "add";
  /** Global IP assignment: "10" = valid (deprecated), "20" = invalid */
  globalIp?: "10" | "20";
  /** Priority flag: "10" = valid, "20" = invalid (default) */
  priorityFlag?: "10" | "20";
}

/**
 * PA02-01 Request payload structure
 */
interface FreebitAccountRegistrationRequest {
  createType: "new" | "add";
  requestDatas: Array<{
    kind: "MVNO";
    account: string;
    planCode: string;
    globalIp?: string;
    priorityFlag?: string;
  }>;
}

/**
 * PA02-01 Response structure
 */
interface FreebitAccountRegistrationResponse {
  resultCode: string;
  status?: {
    message?: string;
    statusCode?: string | number;
  };
  responseDatas?: Array<{
    kind: string;
    account: string;
    ipv4?: string;
    ipv6?: string;
    resultCode: string;
  }>;
}

@Injectable()
export class FreebitAccountRegistrationService {
  constructor(
    private readonly client: FreebitClientService,
    @Inject(Logger) private readonly logger: Logger
  ) {}

  /**
   * Register a new MVNO account (PA02-01)
   *
   * This creates a new account in Freebit's system with the specified
   * phone number and plan. This must be called before PA05-05 voice options.
   *
   * Note: Account creation is asynchronous and may take up to 10 minutes.
   *
   * @param params - Account registration parameters
   * @throws BadRequestException if registration fails
   */
  async registerAccount(params: AccountRegistrationParams): Promise<void> {
    const { account, planCode, createType = "new", globalIp, priorityFlag } = params;

    // Validate required parameters
    if (!account || account.length < 11 || account.length > 14) {
      throw new BadRequestException(
        "Invalid phone number (account) for registration - must be 11-14 digits"
      );
    }

    if (!planCode) {
      throw new BadRequestException("Plan code is required for account registration");
    }

    this.logger.log("Starting MVNO account registration (PA02-01)", {
      account,
      accountLength: account.length,
      planCode,
      createType,
      hasGlobalIp: !!globalIp,
      hasPriorityFlag: !!priorityFlag,
    });

    try {
      // Build payload according to PA02-01 documentation
      // Note: authKey is added automatically by makeAuthenticatedRequest
      const payload: FreebitAccountRegistrationRequest = {
        createType,
        requestDatas: [
          {
            kind: "MVNO",
            account,
            planCode,
            ...(globalIp && { globalIp }),
            ...(priorityFlag && { priorityFlag }),
          },
        ],
      };

      // PA02-01 uses form-urlencoded format with json= parameter
      const response = await this.client.makeAuthenticatedRequest<
        FreebitAccountRegistrationResponse,
        FreebitAccountRegistrationRequest
      >("/master/addAcnt/", payload);

      // Check response for individual account results
      const accountResult = response.responseDatas?.[0];
      if (accountResult && accountResult.resultCode !== "100") {
        throw new BadRequestException(
          `Account registration failed for ${account}: result code ${accountResult.resultCode}`
        );
      }

      this.logger.log("MVNO account registration successful (PA02-01)", {
        account,
        planCode,
      });
    } catch (error: unknown) {
      const message = extractErrorMessage(error);
      this.logger.error("MVNO account registration failed (PA02-01)", {
        account,
        planCode,
        error: message,
      });
      throw new BadRequestException(`Account registration failed: ${message}`);
    }
  }
}
