<?php

namespace Drupal\azure_ad\Form;

use Drupal\azure_ad\MoAzureUtilities;
use Drupal\Component\Serialization\Json;
use Drupal\Component\Utility\Xss;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Config\ImmutableConfig;
use Drupal\Core\Extension\ModuleExtensionList;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\GeneratedUrl;
use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\Render\Markup;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\Core\Theme\ThemeManagerInterface;
use Drupal\Core\Url;
use Drupal\azure_ad\Helper\moAzureADHelper;
use Drupal\user_provisioning\moUserProvisioningConstants;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Response;

/**
 * Provides the Azure AD overview form.
 */
class MoAzureOverview extends FormBase {
  /**
   * Base URL.
   *
   * @var string|GeneratedUrl
   */
  private string|GeneratedUrl $baseUrl;

  /**
   * Configuration object for Azure AD settings.
   *
   * @var \Drupal\Core\Config\ImmutableConfig
   */
  private ImmutableConfig $config;

  /**
   * Current user service.
   *
   * @var \Drupal\Core\Session\AccountProxyInterface
   */
  private AccountProxyInterface $currentUser;

  /**
   * Drupal to Azure sync form service.
   *
   * @var \Drupal\azure_ad\Form\MoDrupalToAzureSync
   */
  private MoDrupalToAzureSync $drupalToAzureSyncForm;

  /**
   * Theme name.
   *
   * @var string
   */
  private string $themeName;

  /**
   * URL path.
   *
   * @var string
   */
  private string $urlPath;

  /**
   * Constructs a new MoAzureOverview object.
   */
  public function __construct(
    ConfigFactoryInterface $config_factory,
    MessengerInterface $messenger,
    ThemeManagerInterface $theme_manager,
    ModuleExtensionList $module_extension_list,
    AccountProxyInterface $current_user,
    MoDrupalToAzureSync $drupal_to_azure_sync_form,
  ) {
    $this->setConfigFactory($config_factory);
    $this->baseUrl = Url::fromRoute('<front>', [], ['absolute' => TRUE])->toString();
    $this->config = $config_factory->get('azure_ad.settings');
    $this->setMessenger($messenger);
    $this->themeName = $theme_manager->getActiveTheme()->getName();
    $this->urlPath = $this->baseUrl . '/' . $module_extension_list->getPath('azure_ad') . '/includes';
    $this->currentUser = $current_user;
    $this->drupalToAzureSyncForm = $drupal_to_azure_sync_form;
  }

  /**
   * {@inheritDoc}
   */
  public static function create(ContainerInterface $container): static {
    return new static(
      $container->get('config.factory'),
      $container->get('messenger'),
      $container->get('theme.manager'),
      $container->get('extension.list.module'),
      $container->get('current_user'),
      $container->get('azure_ad.form.mo_drupal_to_azure_sync')
    );
  }

  /**
   * Returns the form ID.
   *
   * @return string
   *   The form ID.
   */
  public function getFormId(): string {
    return "mo_azure_overview";
  }

  /**
   * Builds the form.
   *
   * @param array $form
   *   The form array.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The form state.
   *
   * @return array
   *   The form array.
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $form['mo_azure_ad_overview_add_css'] = [
      '#attached' => [
        'library' => [
          'azure_ad/azure_ad.admin',
          'core/drupal.dialog.ajax',
        ],
      ],
    ];

    $azure_ad_provisioning_step_no = $this->config->get('azure_ad_provisioning_step');

    if (empty($azure_ad_provisioning_step_no)) {
      $this->azureAdStep0($form, $form_state);
    }
    elseif ($azure_ad_provisioning_step_no == 'step1') {
      $this->azureAdStep1($form, $form_state);
    }
    elseif ($azure_ad_provisioning_step_no == 'step2') {
      $this->azureAdStep2($form, $form_state);
    }
    elseif ($azure_ad_provisioning_step_no == 'step3') {
      $this->azureAdStep3($form, $form_state);
    }
    else {
      $response = new RedirectResponse(Url::fromRoute('azure_ad.configure_azure')->toString());
      $response->send();
      return new Response();
    }

    $azure_ad_helper = new moAzureADHelper();
    $azure_ad_helper->moAzureShowCustomerSupportIcon($form, $form_state);

    return $form;
  }

  /**
   * {@inheritDoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $this->configFactory()->getEditable('azure_ad.settings')->set('azure_ad_provisioning_step', 'step1')->save();
  }

  /**
   * Builds the step 0 form.
   *
   * @param array $form
   *   The form array.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The form state.
   */
  private function azureAdStep0(array &$form, FormStateInterface $form_state) {

    $form['overview_header_style'] = [
      '#markup' => $this->t('<div class="mo_azure_header_container">'),
    ];

    $current_logged_in_user = $this->currentUser->getDisplayName();
    $current_logged_in_user = !empty($current_logged_in_user) ? $current_logged_in_user : 'there';

    $form['overview_left_side_content'] = [
      '#markup' => '<div class="mo_azure_header_container_left">
                                <h2>' . $this->t("Let's Get Started!") . '</h2>
                                <p>' . $this->t('Hello&nbsp;') . Xss::filter($current_logged_in_user) . $this->t('&nbsp;thank you for installing&nbsp;') . '<strong>' . $this->t('User Sync For Azure AD/B2C') . '</strong>' . $this->t('&nbsp;module!&nbsp;') . '<br><br>' . $this->t('This module offers bidirectional user synchronization between your Azure AD/B2C and your Drupal site using Microsoft Graph APIs. Make sure to check out the list of supported features and integrations to increase the functionality of your Drupal site.') .
        '<br><br>' . $this->t('Feel free to contact us at&nbsp;') . '<a href="mailto:' . moUserProvisioningConstants::SUPPORT_EMAIL . '">' . moUserProvisioningConstants::SUPPORT_EMAIL . '</a> ' . $this->t('for further queries or questions.') . '</p>',
    ];

    $form['overview_left_side_guide_button'] = [
      '#type' => 'link',
      '#title' => $this->t('&#128366; &nbsp; Setup Guide'),
      '#url' => Url::fromUri('https://www.drupal.org/docs/contributed-modules/azure-drupal-sync'),
      '#attributes' => ['class' => ['button', 'button--primary'], 'target' => '_blank'],
      '#prefix' => '<div class="container-inline">',
    ];

    $form['overview_left_side_configure_button'] = [
      '#type' => 'submit',
      '#value' => $this->t("&#9881; &nbsp; Let's configure the module &nbsp; &#11166;"),
      '#button_type' => 'primary',
      '#suffix' => '</div>',
    ];

    $form['overview_left_side_content_end'] = [
      '#markup' => '</div>',
    ];

    $form['overview_right_side_content'] = [
      '#markup' => $this->t(
              '<div class="mo_azure_header_container_right">
      <a class="mo_azure_header_container_right_video" href="https://www.youtube.com/watch?v=7WW3971s1Bg" target="_blank">
        <img src=":url/drupal-azure-sync-video-thumbnail.png" alt="video thumbnail">
      </a>
    </div>',
              [
                ':url' => $this->urlPath,
              ]
          ),
    ];

    $form['overview_style_end'] = [
      '#markup' => $this->t('</div>'),
    ];
  }

  /**
   * Builds the step 2 form.
   *
   * @param array $form
   *   The form array.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The form state.
   */
  private function azureAdStep2(array &$form, FormStateInterface $form_state) {
    $form['azure_ad_step1_header_style'] = [
      '#markup' => $this->t('<div class="mo_azure_header_container_step1">'),
    ];

    $this->guideLinks($form);

    $form['azure_ad_step1_title'] = [
      '#markup' => '<h2><u>' . $this->t('STEP 2/3') . '</u></h2><br><div class="mo_azure_ad_text_center"><h3>' . $this->t('Please select how would you like to perform the sync with Azure AD') . '</h3></div><br>',
    ];

    $rows = [
      [
        Markup::create('<a href="configure_app/da"><div class="mo_azure_step_1_img mo_azure_ad_text_center"><img class="mo_azure_sync_gif" src="' . $this->urlPath . '/drupal_ad_sync.gif" alt="Drupal to Azure AD Sync"></div></a>'),
        Markup::create('<a class="js-form-submit form-submit use-ajax mo_top_bar_button" data-dialog-type="modal" href="requestTrialAzure"><div class="mo_azure_step_1_img mo_azure_ad_text_center"><img class="mo_azure_sync_gif" src="' . $this->urlPath . '/ad_drupal_sync.gif" alt="Azure AD to Drupal Sync"></div></a>'),
      ],
    ];

    $form['azure_ad_step1_how_to_sync'] = [
      '#type' => 'table',
      '#responsive' => TRUE,
      '#rows' => $rows,
      '#attributes' => ['style' => 'border-collapse: separate;', 'class' => ['how_to_perform_sync']],
    ];

    $form['mo_azure_ad_step2Backbutton'] = [
      '#type' => 'submit',
      '#value' => $this->t('&#11164; Back'),
      '#button_type' => 'danger',
      '#submit' => ['::azureAdStep2BackButton'],
    ];

    $form['azure_ad_step1_header_end'] = [
      '#markup' => $this->t('</div>'),
    ];
  }

  /**
   * Builds the step 1 form.
   *
   * @param array $form
   *   The form array.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The form state.
   */
  private function azureAdStep1(array &$form, FormStateInterface $form_state) {
    $form['azure_ad_step2_header_style'] = [
      '#markup' => $this->t('<div class="mo_azure_header_container_step1">'),
    ];

    $this->guideLinks($form);

    $form['mo_configure_azure_note'] = [
      '#markup' => '<h2><u>' . $this->t('STEP 1/3') . '</u></h2><br><h3>' . $this->t('Azure App Configuration') . '</h3><hr><br><div class="mo_azure_highlight_background"><p>' . $this->t('Configure the following settings to register your Azure AD/B2C application in Drupal.') . '</p></div>',
    ];

    $this->azureAdConfigurationTable($form, $form_state);

    $form['configure_azure_step2_back_button'] = [
      '#type' => 'submit',
      '#value' => $this->t('&#11164; Back'),
      '#button_type' => 'danger',
      '#limit_validation_errors' => [],
      '#prefix' => '<div class="container-inline">',
      '#submit' => ['::moAzureStep1BackButton'],
    ];

    $form['configure_azure_save_button'] = [
      '#type' => 'submit',
      '#value' => $this->t('Save and Test Configuration'),
      '#button_type' => 'primary',
      '#submit' => ['::moAzureStep1SaveButton'],
    ];

    $azure_test_data = !empty($this->config->get('mo_azure_attr_list_from_server')) ? Json::decode($this->config->get('mo_azure_attr_list_from_server')) : '';
    if (!empty($this->config->get('mo_azure_application_id')) && !empty($this->config->get('mo_azure_application_secret')) && !empty($this->config->get('mo_azure_tenant_id')) && !empty($this->config->get('mo_azure_tenant_name'))) {

      $form['configure_azure_step2_next_button'] = [
        '#type' => 'submit',
        '#value' => $this->t('Next &#11166;'),
        '#button_type' => 'primary',
        '#attributes' => ['style' => 'float:right;'],
        '#disabled' => isset($azure_test_data['error_code']),
        '#submit' => ['::moAzureStep1NextButton'],
      ];

      if (!isset($azure_test_data['error_code'])) {
        $form['manual_user_provisioning'] = [
          '#markup' => '<a class="button button--primary js-form-submit mo_top_bar_button form-submit use-ajax formbutton" data-dialog-type="modal" data-dialog-options="{&quot;width&quot;:&quot;70%&quot;}" href="manualuserSync">' . $this->t('Test User Sync') . '</a>',
        ];
      }

      $form['contianer_close'] = [
        '#markup' => '</div>',
      ];

      $this->moAzureTestResult($form, $form_state);
    }

    $form['azure_ad_step2_header_end'] = [
      '#markup' => $this->t('</div>'),
    ];
  }

  /**
   * Builds the step 3 form.
   *
   * @param array $form
   *   The form array.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The form state.
   */
  private function azureAdStep3(array &$form, FormStateInterface $form_state) {
    $form['azure_ad_step3_header_style'] = [
      '#markup' => $this->t('<div class="mo_azure_header_container_step1">'),
    ];

    $this->guideLinks($form);
    $form['mo_configure_azure_note'] = [
      '#markup' => '<h2><u>STEP 3/3</u></h2><br><h3>' . $this->t('Types of Provisioning') . '</h3><hr><div class = "mo_azure_header_container_step2"><br><br>',
    ];

    if ($this->themeName != 'claro') {
      $form['configure_azure_step3_break'] = [
        '#markup' => '<br>',
      ];
    }

    $form['azure_ad_step3_provisioning_types'] = [
      '#type' => 'table',
      '#responsive' => TRUE,
      '#attributes' => ['class' => ['mo_azure_provisioning_types']],
    ];

    $data = ['description'];
    foreach ($data as $data_shown) {
      $row = $this->moAzureAdProvisioningTypes($data_shown);
      $form['azure_ad_step3_provisioning_types'][$data_shown] = $row;
    }

    if ($this->themeName != 'claro') {
      $form['configure_azure_step3_break2'] = [
        '#markup' => '<br>',
      ];
    }

    $form['azure_ad_Step3NextButton'] = [
      '#type' => 'submit',
      '#button_type' => 'primary',
      '#value' => $this->t('Next &#11166;'),
      '#attributes' => ['style' => 'float:right;'],
      '#submit' => ['::moAzureStep3NextButton'],
      '#prefix' => '<span>',
    ];

    $form['azure_ad_Step3BackButton'] = [
      '#type' => 'submit',
      '#button_type' => 'danger',
      '#value' => $this->t('&nbsp;&#11164; Back'),
      '#attributes' => ['style' => 'float:left;'],
      '#submit' => ['::moAzureStep3BackButton'],
      '#suffix' => '</span>',
    ];

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

    $form['azure_ad_step3_header_end'] = [
      '#markup' => $this->t('</div></div>'),
    ];
  }

  /**
   * Builds the Azure AD configuration table.
   *
   * @param array $form
   *   The form array.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The form state.
   * @param string $status
   *   The status of the form.
   */
  public function azureAdConfigurationTable(array &$form, FormStateInterface $form_state, $status = '') {
    if ($status == 'summary') {
      $form['azure_ad_summary_details']['mo_configure_azure_configuration'] = [
        '#type' => 'table',
        '#responsive' => TRUE,
        '#attributes' => ['style' => 'border-collapse: separate;', 'class' => 'mo_configure_azure_configuration'],
      ];
    }
    else {
      $form['mo_configure_azure_configuration'] = [
        '#type' => 'table',
        '#responsive' => TRUE,
        '#attributes' => ['style' => 'border-collapse: separate;', 'class' => 'mo_configure_azure_configuration'],
      ];
    }

    $data = $this->moDataConfigurations();

    $description_field = $this->moDataConfigurationNotes();

    foreach ($data as $key => $value) {
      $row = $this->moTableData($key, $value, $description_field);
      if ($status == 'summary') {
        $form['azure_ad_summary_details']['mo_configure_azure_configuration'][$key] = $row;
      }
      else {
        $form['mo_configure_azure_configuration'][$key] = $row;
      }
    }
  }

  /**
   * Builds the Azure AD test configuration data.
   *
   * @param string $key
   *   The key of the data.
   * @param string $value
   *   The value of the data.
   *
   * @return array
   *   The form array.
   */
  public function azureAdTestConfigurationData($key, $value) {

    $row[$key] = [
      '#type' => 'item',
      '#plain_text' => $key,
    ];

    $row[$value] = [
      '#type' => 'item',
      '#plain_text' => $value,
    ];

    return $row;
  }

  /**
   * Builds the Azure AD test result.
   *
   * @param array $form
   *   The form array.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The form state.
   */
  public function moAzureTestResult(array &$form, FormStateInterface $form_state) {
    $azure_test_data = Json::decode($this->config->get('mo_azure_attr_list_from_server'));

    $form['azure_step2_test_data'] = [
      '#type' => 'details',
      '#title' => $this->t('Test Configuration Result'),
      '#prefix' => '<div id="test_config_result">',
      '#suffix' => '</div>',
      '#open' => isset($azure_test_data["error_code"]),
    ];

    $form['azure_step2_test_data']['header_message'] = [
      '#markup' => isset($azure_test_data["error_code"]) ?
        $this->t('<div style="font-family:Calibri;padding:0 3%;">
                <div style="color: #a94442;background-color: #f2dede;padding: 15px;margin-bottom: 20px;text-align:center;border:1px solid #E6B3B2;font-size:18pt;">
                    ERROR
                </div></div>') :
        $this->t('<div class="success-container"><div class="mo-success-message">SUCCESS</div></div>'),
    ];

    if (isset($azure_test_data['Profile Picture'])) {
      $form['azure_step2_test_data']['profile_picture'] = [
        '#markup' => $this->t(
                '<div style="text-align: center;">
      <img width="100px" height="100px" style="max-height: 200px; display: inline-block;" src=":image" alt="profile image">
    </div><br>',
                [
                  ':image' => 'data:image/jpeg;base64,' . $azure_test_data['Profile Picture'],
                ]
            ),
      ];
    }

    $form['azure_step2_test_data']['azure_ad_step2_show_test_data'] = [
      '#type' => 'table',
      '#responsive' => TRUE,
      '#attributes' => ['style' => 'border-collapse: separate;', 'class' => ['mo_azure_test_data']],
    ];

    foreach ($azure_test_data as $key => $value) {
      if ($key != 'Profile Picture') {
        $row = $this->azureAdTestConfigurationData($key, $value);
        $form['azure_step2_test_data']['azure_ad_step2_show_test_data'][$key] = $row;
      }
    }
  }

  /**
   * Builds the table data.
   *
   * @param string $key
   *   The key of the data.
   * @param string $value
   *   The value of the data.
   * @param array $description_field
   *   The description field.
   */
  private function moTableData($key, $value, $description_field) {
    $row[$key . $key] = [
      '#markup' => '<div class="container-inline"><strong>' . $key . '</strong>',
    ];

    if ($key == 'Redirect URI: <span class="mo_redirect_uri">(Optional)</span> ') {
      $row[$value] = [
        '#type' => 'item',
        '#plain_text' => $value,
      ];
    }
    else {
      $row[$value] = [
        '#type' => 'textfield',
        '#default_value' => $this->config->get($value),
        '#required' => TRUE,
        '#maxlength' => 1048,
        '#description' => $description_field[$key],
      ];
    }
    return $row;
  }

  /**
   * Builds the data configurations.
   *
   * @return array
   *   The data configurations.
   */
  public function moDataConfigurations() {
    $callbackUrl = MoAzureUtilities::createCallbackUrl();
    $callbackUrl = rtrim($callbackUrl, '/');
    $this->configFactory()->getEditable('azure_ad.settings')->set('miniorange_auth_client_callback_uri', $callbackUrl)->save();

    return [
      'Tenant ID: ' => 'mo_azure_tenant_id',
      'Application (Client) ID: ' => 'mo_azure_application_id',
      'Client Secret: ' => 'mo_azure_application_secret',
      'Tenant Name/Primary Domain: ' => 'mo_azure_tenant_name',
      'Redirect URI: <span class="mo_redirect_uri">(Optional)</span> ' => $callbackUrl,
      'Test UPN/ID: ' => 'mo_azure_test_upn',
    ];
  }

  /**
   * Builds the data configuration notes.
   *
   * @return array
   *   The data configuration notes.
   */
  private function moDataConfigurationNotes() {
    return [
      'Tenant ID: ' => $this->t('You can find the&nbsp;') . '<strong>' . $this->t('Tenant ID') . '</strong>' . $this->t('&nbsp;in the&nbsp;') . '<strong>' . $this->t('Overview') . '</strong>' . $this->t('&nbsp;tab of your Azure application.'),
      'Application (Client) ID: ' => $this->t('You can find the&nbsp;') . '<strong>' . $this->t('Application ID') . '</strong>' . $this->t('&nbsp;in the&nbsp;') . '<strong>' . $this->t('Overview') . '</strong>' . $this->t('&nbsp;tab of your Azure application.'),
      'Client Secret: ' => $this->t('You can find the&nbsp;') . '<strong>' . $this->t('Client Secret') . '</strong>' . $this->t('&nbsp;value in the&nbsp;') . '<strong>' . $this->t('Certificates & Secrets') . '</strong>' . $this->t('&nbsp;tab of your Azure application.'),
      'Tenant Name/Primary Domain: ' => $this->t('You can find the&nbsp;') . '<strong>' . $this->t('Tenant Name') . '</strong>' . $this->t('&nbsp;under primary domain in the&nbsp;') . '<strong>' . $this->t('Overview') . '</strong>' . $this->t('&nbsp;tab of your Azure application. e.g. xxxxxx.onmicrosoft.com'),
      'Redirect URI: <span class="mo_redirect_uri">(Optional)</span> ' => $this->t('This is your Drupal site URL'),
      'Test UPN/ID: ' => $this->t('Please note that to test the configuration of your application you will need&nbsp;') . '<strong>' . $this->t('UserPrincipalName/ID') . '</strong>' . $this->t('&nbsp;of User. The&nbsp;') . '<strong>' . $this->t('User Principle Name / Object ID') . '</strong>' . $this->t('&nbsp;is present in the&nbsp;') . '<strong>' . $this->t('Users') . '</strong>' . $this->t('&nbsp;tab of your Azure Portal.'),
    ];
  }

  /**
   * Builds the manual sync.
   *
   * @param array $form
   *   The form array.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The form state.
   */
  public function moAzureManualSync(array &$form, FormStateInterface $form_state) {
    $this->drupalToAzureSyncForm->moAzureManualSync($form, $form_state);
  }

  /**
   * Builds the step 1 save button.
   *
   * @param array $form
   *   The form array.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The form state.
   */
  public function moAzureStep1SaveButton(array &$form, FormStateInterface $form_state) {
    $form_values = ($form_state->getValues())['mo_configure_azure_configuration'];
    $data = $this->moDataConfigurations();

    foreach ($data as $key => $value) {
      $this->configFactory()->getEditable('azure_ad.settings')->set($value, trim($form_values[$key][$value]))->save();
    }

    $this->configFactory()->getEditable('user_provisioning.settings')->set('mo_user_provisioning_configured_application', 'azure_ad')->save();

    $azure_ad_helper = new MoAzureADHelper();
    $azure_ad_helper->fetchAttributes();

    $azure_test_data = Json::decode($this->config->get('mo_azure_attr_list_from_server'));
    $this->configFactory()->getEditable('azure_ad.settings')->set('test_azure_config_result', isset($azure_test_data["error_code"]))->save();
    if (isset($azure_test_data["error_code"])) {
      $this->messenger->addError($this->t('An error occurred while performing test configuration. Please refer to <a href="#test_config_result">Test Configuration Result</a> for more information.'));
    }
    else {
      if ($this->config->get('azure_ad_provisioning_step') == 'azure_ad_user_provisioning') {
        $this->messenger->addStatus($this->t('Test Configuration successful. You can check the complete list of attributes received from Azure AD by clicking on the link <a href="#test_config_result">HERE</a>. Now, you can perform user provisioning'));
      }
      else {
        $this->messenger->addStatus($this->t('Test Configuration successful. You can check the complete list of attributes received from Azure AD by clicking on the link <a href="#test_config_result">HERE</a>. Now, click on the <strong>Next</strong> button.'));
      }
    }
  }

  /**
   * Builds the step 1 next button.
   *
   * @param array $form
   *   The form array.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The form state.
   */
  public function moAzureStep1NextButton(array &$form, FormStateInterface $form_state) {
    $this->configFactory()
      ->getEditable('azure_ad.settings')
      ->set('azure_ad_provisioning_step', 'step2')
      ->save();
  }

  /**
   * Builds the step 1 back button.
   *
   * @param array $form
   *   The form array.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The form state.
   */
  public function moAzureStep1BackButton(array &$form, FormStateInterface $form_state) {
    $this->configFactory()
      ->getEditable('azure_ad.settings')
      ->set('azure_ad_provisioning_step', '')
      ->save();
  }

  /**
   * Builds the step 3 back button.
   *
   * @param array $form
   *   The form array.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The form state.
   */
  public function moAzureStep3BackButton(array &$form, FormStateInterface $form_state) {
    $this->configFactory()
      ->getEditable('azure_ad.settings')
      ->set('azure_ad_provisioning_step', 'step2')
      ->save();
  }

  /**
   * Builds the step 3 next button.
   *
   * @param array $form
   *   The form array.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The form state.
   */
  public function moAzureStep3NextButton(array &$form, FormStateInterface $form_state) {
    $this->configFactory()->getEditable('azure_ad.settings')->set('azure_ad_provisioning_step', 'azure_ad_user_provisioning')->save();
  }

  /**
   * Builds the step 2 back button.
   *
   * @param array $form
   *   The form array.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The form state.
   */
  public function azureAdStep2BackButton(array &$form, FormStateInterface $form_state) {
    $this->configFactory()
      ->getEditable('azure_ad.settings')
      ->set('azure_ad_provisioning_step', 'step1')
      ->save();
  }

  /**
   * Builds the Azure AD provisioning types.
   *
   * @param array $data
   *   The data.
   *
   * @return array
   *   The form array.
   */
  private function moAzureAdProvisioningTypes($data) {

    $row['azure_ad_manual_provisioning_button'] = [
      '#prefix' => '<div class="mo_azure_ad_text_center"><h4>' . $this->t('Manual/On-Demand Provisioning') . '</h4><hr></div>' . $this->t('This will allow you to manually perform CRUD operations for any Drupal user in Azure AD.') . '<br><br><div class="azure_ad_provisioning_button">',
      '#markup' => '<a class="button button--primary use-ajax" data-dialog-type="modal" data-dialog-options="{&quot;width&quot;:&quot;70%&quot;}" href="configuremanualprovisioning">&#9881; Configure</a>',
      '#suffix' => '</div>',
    ];

    $row['azure_ad_automatic_provisioning_button'] = [
      '#prefix' => '<div class="mo_azure_ad_text_center"><h4>' . $this->t('Automatic Provisioning') . '</h4><hr></div>' . $this->t('This will allow you to automatically perform CRUD operations for any Drupal user in Azure AD when user registers/updates profile in your Drupal site.') . '<br><br><div class="azure_ad_provisioning_button">',
      '#markup' => '<a id = "auto_prov_modal_link" class="button button--primary use-ajax" data-dialog-type="modal" data-dialog-options="{&quot;width&quot;:&quot;70%&quot;}" href="configureautomaticprovisioning">&#9881; Configure</a>',
      '#suffix' => '</div>',
    ];

    $row['azure_ad_scheduler_provisioning_button'] = [
      '#type' => 'submit',
      '#value' => $this->t('&#9881; Configure'),
      '#disabled' => TRUE,
      '#prefix' => '<div class="mo_azure_ad_text_center"><h4>' . $this->t('Scheduler based Provisioning') . '<a href="azure_upgrade_plans"><img class="mo_oauth_pro_icon1" src="' . $this->urlPath . '/pro.png" alt="Premium"></a></h4><hr></div>' . $this->t('This will allow you to perform CRUD operations for any Drupal user in Azure AD on the CRON.') . '<br><br><div class="azure_ad_provisioning_button">',
      '#suffix' => '</div>',
    ];

    return $row;
  }

  /**
   * Builds the guide links.
   *
   * @param array $form
   *   The form array.
   */
  public function guideLinks(&$form) {
    $form['markup_setup_guide_start'] = [
      '#markup' => '<div class="container-inline">',
    ];

    $form['markup_video_guide'] = [
      '#markup' => '<a class="button button--primary mo-guides-floating" target="_blank" href="https://www.youtube.com/watch?v=7WW3971s1Bg">' . $this->t('&#x23E9; Video Guide') . '</a> ',
    ];

    $form['markup_setup_guide'] = [
      '#markup' => '<a class="button button--primary mo-guides-floating" target="_blank" href="https://www.drupal.org/docs/contributed-modules/azure-drupal-sync">' . $this->t('&#128366; Setup Guide') . '</a>',
    ];

    $form['markup_setup_guides_ends'] = [
      '#markup' => '</div>',
    ];
  }

}
