<?php

namespace Drupal\user_provisioning;

use Drupal\user_provisioning\Helpers\moUserProvisioningLogger;
use GuzzleHttp\Exception\RequestException;

/**
 * Handles customer API requests for user provisioning.
 */
class moUserProvisioningCustomer {
  /**
   * Customer email address.
   *
   * @var string|null
   */
  public ?string $email;
  /**
   * Customer phone number.
   *
   * @var string|null
   */
  public ?string $phone;
  /**
   * Customer password.
   *
   * @var string|null
   */
  public ?string $password;
  /**
   * OTP token for customer verification.
   *
   * @var string|null
   */
  public ?string $otpToken;
  /**
   * Default customer key used for support APIs.
   *
   * @var string
   */
  private string $defaultCustomerId;
  /**
   * Default customer API key used for support APIs.
   *
   * @var string
   */
  private string $defaultCustomerApiKey;
  /**
   * Logger instance for request debugging.
   *
   * @var \Drupal\user_provisioning\Helpers\moUserProvisioningLogger
   */
  private moUserProvisioningLogger $moLogger;

  /**
   * Constructs a provisioning customer instance.
   *
   * @param string $email
   *   The customer email address.
   * @param string|null $phone
   *   The customer phone number.
   * @param string|null $password
   *   The customer password.
   * @param string|null $otp_token
   *   The customer OTP token.
   */
  public function __construct($email, $phone = NULL, $password = NULL, $otp_token = NULL) {
    $this->email = $email;
    $this->phone = $phone;
    $this->password = $password;
    $this->otpToken = $otp_token;
    $this->defaultCustomerId = "16555";
    $this->defaultCustomerApiKey = "fFd2XcvTGDemZvbw1bcUesNJWEqKbbUq";
    $this->moLogger = new moUserProvisioningLogger();
  }

  /**
   * Checks whether cURL extension is installed.
   *
   * @return bool
   *   TRUE when cURL is available, otherwise FALSE.
   */
  public function isCurlInstalled(): bool {
    return in_array('curl', get_loaded_extensions());
  }

  /**
   * Builds API request headers.
   *
   * @param bool $add_extended_header
   *   Whether to append timestamp and authorization headers.
   *
   * @return false[]|string[]
   *   The list of request headers.
   */
  public function getHeader($add_extended_header = FALSE): array {

    $header = [
      'Content-Type' => 'application/json',
      'charset' => 'UTF - 8',
      'Authorization' => 'Basic',
    ];

    if ($add_extended_header) {
      /* Current time in milliseconds since midnight, January 1, 1970 UTC. */
      $current_time_in_millis = moUserProvisioningSupport::getTimestamp();

      /* Creating the Hash using SHA-512 algorithm */
      $string_to_hash = $this->defaultCustomerId . $current_time_in_millis . $this->defaultCustomerApiKey;
      $hashValue = hash("sha512", $string_to_hash);
      $timestamp_header = number_format($current_time_in_millis, 0, '', '');
      $header = array_merge($header, [
        "Customer-Key" => $this->defaultCustomerId,
        "Timestamp" => $timestamp_header,
        "Authorization" => $hashValue,
      ]);
    }
    $this->moLogger->addLog('Returning final header: ' . print_r($header, TRUE), __LINE__, __FUNCTION__, __FILE__);
    return $header;
  }

  /**
   * Calls the provisioning endpoint with the given payload.
   *
   * @param string $url
   *   The API endpoint URL.
   * @param array|string $fields
   *   The request payload.
   * @param bool $add_extended_header
   *   Whether to include extended authentication headers.
   *
   * @return false|string|void
   *   The response body, an error JSON string, or void on exception.
   */
  public function callService($url, $fields, $add_extended_header = FALSE) {
    if (!$this->isCurlInstalled()) {
      $this->moLogger->addLog('cURL is not installed. Returning error response.', __LINE__, __FUNCTION__, __FILE__);
      return json_encode([
        "statusCode" => 'ERROR',
        "statusMessage" => 'cURL is not enabled on your site. Please enable the cURL module.',
      ]);
    }
    $fieldString = is_string($fields) ? $fields : json_encode($fields);

    $header = $this->getHeader($add_extended_header);

    try {
      $response = \Drupal::httpClient()
        ->post($url, [
          'body' => $fieldString,
          'allow_redirects' => TRUE,
          'http_errors' => FALSE,
          'decode_content' => TRUE,
          'headers' => $header,
        ]);
      $response_body = $response->getBody()->getContents();
      $this->moLogger->addLog('Response body: ' . $response_body, __LINE__, __FUNCTION__, __FILE__);
      return $response_body;
    }
    catch (RequestException $exception) {
      $error = [
        '%apiName' => explode("moas", $url)[1],
        '%error' => $exception->getResponse()->getBody()->getContents(),
      ];
      \Drupal::logger('user_provisioning')->notice('Error at %apiName of  %error', $error);
    }
  }

}
