<?php

namespace Drupal\azure_ad\Helper;

use Drupal\Component\Serialization\Json;
use Drupal\Core\Config\Config;
use Drupal\Core\Config\ImmutableConfig;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\GeneratedUrl;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\Url;
use Drupal\user_provisioning\ProviderSpecific\APIHandler\UserAPIHandler\moUserAzureAPIHandler;

/**
 * Helper for Azure AD integration and attribute handling.
 */
class moAzureADHelper {
  use StringTranslationTrait;

  /**
   * Immutable Azure AD module configuration.
   *
   * @var \Drupal\Core\Config\ImmutableConfig
   */
  private ImmutableConfig $config;


  /**
   * Editable Azure AD module configuration.
   *
   * @var \Drupal\Core\Config\Config
   */
  private Config $configFactory;

  /**
   * Base URL for the site.
   *
   * @var string|\Drupal\Core\GeneratedUrl
   */
  private string|GeneratedUrl $baseUrl;

  /**
   * URL path for module includes (e.g. assets).
   *
   * @var string
   */
  private string $urlPath;

  /**
   * Constructor for moAzureADHelper.
   */
  public function __construct() {
    $this->baseUrl = Url::fromRoute('<front>', [], ['absolute' => TRUE])->toString();

    $this->config = \Drupal::config('azure_ad.settings');
    $this->configFactory = \Drupal::configFactory()->getEditable('azure_ad.settings');
    $this->urlPath = $this->baseUrl . '/' . \Drupal::service('extension.list.module')->getPath('azure_ad') . '/includes';
  }

  /**
   * Fetches Azure AD user attributes and stores them in configuration.
   */
  public function fetchAttributes() {
    $azure = new moUserAzureAPIHandler();
    $user_details = $azure->moAzureGetUserDetails();
    if (!empty($user_details["error|code"])) {
      $this->configFactory
        ->set('mo_azure_attr_list_from_server', Json::encode($user_details))
        ->save();
    }
    else {
      $user_details = $this->moAzureArrayFlattenAttributes($user_details);

      if (isset($user_details['id'])) {
        $profile_pic = $azure->moAzureGetProfilePic($user_details['id']);
        if (!empty($profile_pic)) {
          $user_details['Profile Picture'] = $profile_pic;
        }
      }

      $user_details_encoded = Json::encode($user_details);
      $this->configFactory
        ->set('mo_azure_attr_list_from_server', $user_details_encoded)
        ->save();
    }
  }

  /**
   * Flattens nested Azure AD user detail arrays into a single level.
   *
   * @param array $details
   *   Nested array of user details.
   *
   * @return array
   *   Flattened array of attributes.
   */
  private function moAzureArrayFlattenAttributes($details): array {
    $arr = [];
    foreach ($details as $key => $value) {
      if (empty($value)) {
        continue;
      }
      if (!is_array($value)) {
        $arr[$key] = filter_var($value);
      }
      else {
        $this->moAzureArrayFlattenAttributesLvl2($key, $value, $arr);
      }
    }
    return $arr;
  }

  /**
   * Recursively flattens nested arrays into the haystack with compound keys.
   *
   * @param string $index
   *   Current key prefix.
   * @param array $arr
   *   Array to flatten.
   * @param array &$haystack
   *   Output array (passed by reference).
   */
  private function moAzureArrayFlattenAttributesLvl2($index, $arr, &$haystack) {
    foreach ($arr as $key => $value) {
      if (empty($value)) {
        continue;
      }
      if (!is_array($value)) {
        if (!str_contains(strtolower($index), 'error')) {
          $haystack[$index . "|" . $key] = $value;
        }
      }
      else {
        $this->moAzureArrayFlattenAttributesLvl2($index . "|" . $key, $value, $haystack);
      }
    }
  }

  /**
   * Adds the customer support icon to the form.
   */
  public function moAzureShowCustomerSupportIcon(array &$form, FormStateInterface $form_state) {
    $form['mo_azure_customer_support_icon'] = [
      '#type' => 'link',
      '#url' => Url::fromRoute('azure_ad.azure_customer_support'),
      '#title' => [
        '#markup' => '<img src="' . $this->urlPath . '/mo-customer-support.png" alt="Support icon">',
        '#allowed_tags' => ['img'],
      ],
      '#options' => [
        'attributes' => [
          'class' => ['use-ajax', 'mo-bottom-corner'],
          'data-dialog-type' => 'modal',
          'data-dialog-options' => json_encode([
            'width' => '600',
            'title' => 'Customer Support',
          ]),
        ],
      ],
    ];

    $form['#attached']['library'][] = 'core/drupal.dialog.ajax';
  }

}
