<?php

namespace Drupal\user_provisioning\ProviderSpecific\Parsers\UserParser;

use Drupal\Core\Config\Config;
use Drupal\Core\Config\ImmutableConfig;
use Drupal\Core\Entity\EntityInterface;
use Drupal\user_provisioning\Helpers\moProviderSpecificProvisioning;
use Drupal\user_provisioning\Helpers\moUserProvisioningLogger;
use Drupal\user_provisioning\ProviderSpecific\Parsers\moResourceParserInterface;

/**
 * Parses user resources for Okta provisioning requests.
 */
class moUserOktaParser implements moResourceParserInterface {

  /**
   * Editable Okta sync configuration.
   *
   * @var \Drupal\Core\Config\Config
   *   Editable configuration object.
   */
  private Config $configFactory;

  /**
   * Immutable user provisioning configuration.
   *
   * @var \Drupal\Core\Config\ImmutableConfig
   *   Read-only configuration object.
   */
  private ImmutableConfig $config;

  /**
   * Logger for parser diagnostics.
   *
   * @var \Drupal\user_provisioning\Helpers\moUserProvisioningLogger
   *   Logger instance.
   */
  private moUserProvisioningLogger $moLogger;

  /**
   * Constructs the Okta user parser.
   */
  public function __construct() {
    $this->moLogger = new moUserProvisioningLogger();
    $this->configFactory = \Drupal::configFactory()->getEditable('okta_user_sync.settings');
    $this->config = \Drupal::config('user_provisioning.settings');
  }

  /**
   * Builds the user search query for Okta.
   */
  public function search($resource_id): string {

    $this->moLogger->addLog("Creating search request parameter.", __LINE__, __FUNCTION__, __FILE__);
    return 'users?search=profile.email eq "' . $resource_id . '"';
  }

  /**
   * {@inheritDoc}
   */
  public function get($resource_id) {
    // @todo Implement get() method.
  }

  /**
   * Builds an Okta POST request body for a Drupal user entity.
   */
  public function post(EntityInterface $entity) {
    $enable_auto_provisioning_okta = $this->configFactory->get('okta_user_sync_create_user_auto_radio_button');
    $enable_manual_provisioning_okta = $this->configFactory->get('okta_user_sync_create_user_manual_radio_button');
    $isManualSyncRequest = $this->configFactory->get('okta_user_sync_request_to_manual_sync');
    // The bare minimum attributes.
    $post_request_body = '';

    $username_attr = $this->configFactory->get('okta_user_sync_basic_mail_mapping');
    $email_attr = $this->configFactory->get('okta_user_sync_basic_mail_mapping');

    $user_email = $entity->getEmail();
    $username = $entity->getEmail();

    if (isset($email_attr)) {
      if ($email_attr == 'uid') {
        $user_email = $entity->id();
      }
      else {
        $user_email = $entity->get($email_attr)->value;
      }
    }

    if (isset($username_attr)) {
      if ($username_attr == 'uid') {
        $username = $entity->id();
      }
      else {
        $username = $entity->get($username_attr)->value;
      }
    }

    if ($enable_auto_provisioning_okta == '0' ||($enable_manual_provisioning_okta == '0' && $isManualSyncRequest == TRUE)) {
      $post_request_body = [
        'profile' => [
          'login' => $username,
          'email' => $user_email,
          'firstName' => $entity->getDisplayName(),
          'lastName' => $entity->getDisplayName(),
        ],
      ];
      $this->moLogger->addLog('POST request body for non-auto provisioning (manual or disabled auto provisioning): ' . print_r($post_request_body, TRUE), __LINE__, __FUNCTION__, __FILE__);
      $this->moLogger->addFormattedLog($post_request_body, __LINE__, __FUNCTION__, __FILE__, 'POST request body for non-auto provisioning (manual or disabled auto provisioning):');
    }
    elseif ($enable_auto_provisioning_okta == '1') {

      $user_password = $this->getUserPassword($entity);
      $post_request_body = [
        'profile' => [
          'login' => $username,
          'email' => $user_email,
          'firstName' => $entity->getDisplayName(),
          'lastName' => $entity->getDisplayName(),
        ],
        'credentials' => [
          'password' => ['value' => $user_password],
        ],

      ];
      $this->moLogger->addLog('POST request body for auto provisioning with password: ' . print_r($post_request_body, TRUE), __LINE__, __FUNCTION__, __FILE__);
      $this->moLogger->addFormattedLog($post_request_body, __LINE__, __FUNCTION__, __FILE__, 'POST request body for auto provisioning with password:');
    }
    $this->configFactory->set('okta_user_sync_request_to_manual_sync', FALSE)->save();

    return $post_request_body;

  }

  /**
   * Returns the decrypted Okta password for auto provisioning.
   */
  private function getUserPassword(EntityInterface $entity) {
    $name = $entity->getAccountName();
    $enable_auto_pass = \Drupal::configFactory()->getEditable('okta_user_sync.settings')->get('mo_okta_' . $name . '_dependency');
    $prov_specific = new moProviderSpecificProvisioning();
    return $prov_specific->decrypt_data($enable_auto_pass, $name);
  }

  /**
   * {@inheritDoc}
   */
  public function put(array $resource) {
    // @todo Implement put() method.
  }

  /**
   * {@inheritDoc}
   */
  public function patch(array $resource) {
    // @todo Implement patch() method.
  }

  /**
   * {@inheritDoc}
   */
  public function delete(array $resource) {
    // @todo Implement delete() method.
  }

  /**
   * Returns the entity identifier for deactivation requests.
   */
  public function deactivate(EntityInterface $entity) {
    return $entity->getEmail();

  }

}
