<?php

namespace Drupal\user_provisioning\Form;

use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\OpenModalDialogCommand;
use Drupal\Core\Ajax\ReplaceCommand;
use Drupal\Core\Ajax\InvokeCommand;
use Drupal\Core\Config\Config;
use Drupal\Core\Config\ImmutableConfig;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
use Drupal\user\Entity\Role;
use Drupal\user\Entity\User;
use Drupal\user_provisioning\Controller\user_provisioningController;
use Drupal\user_provisioning\Helpers\AjaxTables;
use Drupal\user_provisioning\Helpers\moSCIMClient;
use Drupal\user_provisioning\Helpers\moUserProvisioningLogger;
use Drupal\user_provisioning\moUserProvisioningConstants;
use Drupal\user_provisioning\moUserProvisioningUtilities;
use Drupal\user_provisioning\ProviderSpecific\EntityHandler\moUserProvisioningUserHandler;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Request;

/**
 *
 */
class MoUserProvisioning extends FormBase {
  private string $url_path;
  private string $base_url;
  private Config $config_factory;
  private ImmutableConfig $config;
  private Request $request;
  private LoggerInterface $logger;
  /**
   *
   */
  public function __construct() {
    $this->base_url = \Drupal::request()->getSchemeAndHttpHost() . \Drupal::request()->getBaseUrl();
    $this->url_path = $this->base_url . '/' . \Drupal::service('extension.list.module')->getPath('user_provisioning') . '/images';
    $this->config = \Drupal::config('user_provisioning.settings');
    $this->config_factory = \Drupal::configFactory()->getEditable('user_provisioning.settings');
    $this->request = \Drupal::request();
    $this->logger = \Drupal::logger('user_provisioning');
    $this->messenger = \Drupal::messenger();
  }

  /**
   * {@inheritDoc}
   */
  public function getFormId(): string
  {
    return 'mo_provisioning';
  }

  /**
   * {@inheritDoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state): array
  {
    $form['mo_user_prov_add_css'] = [
      '#attached' => [
        'library' => [
          'user_provisioning/user_provisioning.admin',
          'user_provisioning/user_provisioning.mo_search_field',
          'core/drupal.dialog.ajax',
        ],
      ],
    ];

    if ($this->request->get('summary')) {
      $this->moUserProvScimClientProvSummary($form, $form_state);
    }

    $application_name = $this->request->get('app_name');
    $application_selected = $this->config->get('mo_user_provisioning_app_name');

      if ((empty($application_name) && empty($application_selected))) {
          $this->moUserProvisioningMethod($form, $form_state);
      }
      elseif ($application_name == 'api_provisioning'){
          $this->moUserProvisioningApiDirectorySelection($form, $form_state);
      }
      else {
          if ($application_name == 'scim_provisioning') {
              $this->moUserProvisioningApplication($form, $form_state);
          } elseif (!empty($application_selected) || !empty($application_name)) {
              if ($application_name == 'scim_server') {
                  $this->moUserProvisioningServer($form, $form_state);
              } else {
                  $this->moUserProvisioningClient($form, $form_state);
              }
          }
      }

    moUserProvisioningUtilities::moProvShowCustomerSupportIcon($form, $form_state);
    return $form;
  }

  private function moUserProvisioningApiDirectorySelection(array &$form, FormStateInterface $form_state)
  {
      $module_handler = \Drupal::moduleHandler();
      $module_list = \Drupal::service('extension.list.module');
      $module_list->reset();

      // Check if modules are installed (enabled)
      $okta_installed = $module_handler->moduleExists('okta_user_sync');
      $azure_installed = $module_handler->moduleExists('azure_ad');
      $keycloak_installed = $module_handler->moduleExists('keycloak_user_provisioning');

      // Check if modules are downloaded (exist in file system but may not be enabled)
      // Using Drupal's extension discovery system - works regardless of folder structure
      $okta_downloaded = FALSE;
      $azure_downloaded = FALSE;
      $keycloak_downloaded = FALSE;

      try {
          $module_list->getPathname('okta_user_sync');
          $okta_downloaded = TRUE;
      } catch (\Exception $e) {
          // Module not found in filesystem
          $okta_downloaded = FALSE;
      }

      try {
          $module_list->getPathname('azure_ad');
          $azure_downloaded = TRUE;
      } catch (\Exception $e) {
          // Module not found in filesystem
          $azure_downloaded = FALSE;
      }

      try{
          $module_list->getPathname('keycloak_user_provisioning');
          $keycloak_downloaded = TRUE;
      } catch (\Exception $e) {
          // Module not found in filesystem
          $keycloak_downloaded = FALSE;
      }

      $selected_directory = $form_state->getValue('directory') ?? 'okta';

      $form['directory_wrapper']['directory'] = [
          '#type' => 'radios',
          '#title' => $this->t('Select Directory'),
          '#options' => [
              'okta' => $this->t('Okta'),
              'azure' => $this->t('Azure'),
              'keycloak' => $this->t('Keycloak'),
          ],
          '#default_value' => $selected_directory,
          '#attributes' => [
              'class' => ['container-inline', 'custom-radio-spacing'],
          ],
      ];

      // Message field that shows module installation status
      $form['directory_wrapper']['module_status_message'] = [
          '#type' => 'container',
          '#attributes' => ['class' => ['module-status-message']],
      ];

      // Okta message - not downloaded
      if (!$okta_downloaded) {
          $form['directory_wrapper']['module_status_message']['okta_message_not_downloaded'] = [
              '#type' => 'container',
              '#attributes' => [
                  'class' => ['messages', 'messages--warning'],
              ],
              '#markup' => $this->t('Okta User Sync module is not downloaded. Please download the module first. <a href="https://www.drupal.org/project/okta_user_sync" target="_blank">Download Okta User Sync module</a>'),
              '#states' => [
                  'visible' => [
                      ':input[name="directory"]' => ['value' => 'okta'],
                  ],
              ],
          ];
      }
      // Okta message - downloaded but not enabled
      elseif ($okta_downloaded && !$okta_installed) {
          $form['directory_wrapper']['module_status_message']['okta_message_not_enabled'] = [
              '#type' => 'container',
              '#attributes' => [
                  'class' => ['messages', 'messages--warning'],
              ],
              '#markup' => $this->t('Okta User Sync module is downloaded but not enabled. Please install/enable the module to continue. Go to <a href="/admin/modules">Extend</a> and enable "Okta User Sync" module.'),
              '#states' => [
                  'visible' => [
                      ':input[name="directory"]' => ['value' => 'okta'],
                  ],
              ],
          ];
      }

      // Azure message - not downloaded
      if (!$azure_downloaded) {
          $form['directory_wrapper']['module_status_message']['azure_message_not_downloaded'] = [
              '#type' => 'container',
              '#attributes' => [
                  'class' => ['messages', 'messages--warning'],
              ],
              '#markup' => $this->t('Azure AD module is not downloaded. Please download the module first. <a href="https://www.drupal.org/project/azure_ad" target="_blank">Download Azure AD module</a>'),
              '#states' => [
                  'visible' => [
                      ':input[name="directory"]' => ['value' => 'azure'],
                  ],
              ],
          ];
      }
      // Azure message - downloaded but not enabled
      elseif ($azure_downloaded && !$azure_installed) {
          $form['directory_wrapper']['module_status_message']['azure_message_not_enabled'] = [
              '#type' => 'container',
              '#attributes' => [
                  'class' => ['messages', 'messages--warning'],
              ],
              '#markup' => $this->t('Azure AD module is downloaded but not enabled. Please install/enable the module to continue. Go to <a href="/admin/modules">Extend</a> and enable "Azure AD" module.'),
              '#states' => [
                  'visible' => [
                      ':input[name="directory"]' => ['value' => 'azure'],
                  ],
              ],
          ];
      }

      // Keycloak message - not downloaded
      if(!$keycloak_downloaded) {
          $form['directory_wrapper']['module_status_message']['keycloak_message_not_downloaded'] = [
              '#type' => 'container',
              '#attributes' => [
                  'class' => ['messages', 'messages--warning'],
              ],
              '#markup' => $this->t('Keycloak User Provisioning module is not downloaded. Please download the module first. <a href="https://www.drupal.org/project/keycloak_user_provisioning" target="_blank">Download Keycloak User Provisioning module</a>'),
              '#states' => [
                  'visible' => [
                      ':input[name="directory"]' => ['value' => 'keycloak'],
                  ],
              ],
          ];
      } elseif($keycloak_downloaded && !$keycloak_installed) {
          $form['directory_wrapper']['module_status_message']['keycloak_user_provisioning_message_not_enabled'] = [
              '#type' => 'container',
              '#attributes' => [
                  'class' => ['messages', 'messages--warning'],
              ],
              '#markup' => $this->t('Keycloak User Provisioning module is downloaded but not enabled. Please install/enable the module to continue. Go to <a href="/admin/modules">Extend</a> and enable "Keycloak User Provisioning" module.'),
              '#states' => [
                  'visible' => [
                      ':input[name="directory"]' => ['value' => 'keycloak'],
                  ],
              ],
          ];
      }

      // Continue button - controlled purely by Drupal #states API
      $form['directory_wrapper']['continue_button'] = [
          '#type' => 'submit',
          '#value' => $this->t('Continue'),
          '#button_type' => 'primary',
          '#submit' => ['::continueToModuleConfiguration'],
      ];

      // Build #states conditions based on module installation status
      $disabled_conditions = [];

      if (!$okta_installed && !$azure_installed && !$keycloak_installed) {
          // None of the modules are installed - always disabled
          $form['directory_wrapper']['continue_button']['#disabled'] = TRUE;
      } else {
          // Add conditions for when button should be disabled
          if (!$okta_installed) {
              $disabled_conditions[] = [':input[name="directory"]' => ['value' => 'okta']];
          }
          if (!$azure_installed) {
              if (!empty($disabled_conditions)) {
                  $disabled_conditions[] = 'or';
              }
              $disabled_conditions[] = [':input[name="directory"]' => ['value' => 'azure']];
          }
          if(!$keycloak_installed) {
              if(!empty($disabled_conditions)) {
                  $disabled_conditions[] = 'or';
              }
              $disabled_conditions[] = [':input[name="directory"]' => ['value' => 'keycloak']];
          }

          // Apply #states only if there are conditions
          if (!empty($disabled_conditions)) {
              $form['directory_wrapper']['continue_button']['#states'] = [
                  'disabled' => $disabled_conditions,
              ];
          }
      }

      // Hidden fields to track module installation and download status
      $form['okta_module_installed'] = [
          '#type' => 'hidden',
          '#value' => $okta_installed ? '1' : '0',
      ];

      $form['azure_module_installed'] = [
          '#type' => 'hidden',
          '#value' => $azure_installed ? '1' : '0',
      ];

      $form['keycloak_module_installed'] = [
          '#type' => 'hidden',
          '#value' => $keycloak_installed ? '1' : '0',
      ];

      $form['okta_module_downloaded'] = [
          '#type' => 'hidden',
          '#value' => $okta_downloaded ? '1' : '0',
      ];

      $form['azure_module_downloaded'] = [
          '#type' => 'hidden',
          '#value' => $azure_downloaded ? '1' : '0',
      ];

      $form['keycloak_module_downloaded'] = [
          '#type' => 'hidden',
          '#value' => $keycloak_downloaded ? '1' : '0',
      ];

      return $form;
  }

    private function moUserProvisioningMethod(array &$form, FormStateInterface $form_state)
    {
        $form['#prefix'] = '<div class="user-provisioning-container">';
        $form['#suffix'] = '</div>';

        $form['title'] = [
            '#markup' => '<h2>' . $this->t('Configure Application') . '</h2>',
        ];

        $form['subtitle'] = [
            '#markup' => '<div class="provisioning-subtitle">' . $this->t('Choose Your Provisioning Method') . '</div>',
        ];

        $form['selected_provisioning'] = [
            '#type' => 'hidden',
            '#default_value' => 'api',
            '#attributes' => ['id' => 'selected-provisioning-method'],
        ];

        $cards = [
            [
                'id' => 'scim',
                'title' => $this->t('SCIM based Provisioning'),
                'description' => $this->t('Use the standard SCIM protocol to automate user provisioning between systems'),
                'url' => Url::fromRoute('user_provisioning.provisioning', ['app_name' => 'scim_provisioning'])->toString(),
                'selected' => false,
            ],
            [
                'id' => 'api',
                'title' => $this->t('API based Provisioning'),
                'description' => $this->t('Set up direct user provisioning through IdP API integration.'),
                'url' => Url::fromRoute('user_provisioning.provisioning', ['app_name' => 'api_provisioning'])->toString(),
                'selected' => true,
            ],
        ];

        $form['provisioning_options'] = [
            '#theme' => 'user-provisioning-cards',
            '#cards' => $cards,
        ];

        return $form;
    }

  /**
   * {@inheritDoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    // @todo Implement submitForm() method.
  }

  /**
   * Submit handler for Continue button - redirects to selected module.
   */
  public function continueToModuleConfiguration(array &$form, FormStateInterface $form_state) {
    $selected_directory = $form_state->getValue('directory');

    if ($selected_directory == 'okta') {
      // Redirect to Okta User Sync module configuration
      $form_state->setRedirect('okta_user_sync.overview');
    }
    elseif ($selected_directory == 'azure') {
      // Redirect to Azure AD module configuration
      $form_state->setRedirect('azure_ad.overview');
    }
    elseif ($selected_directory == 'keycloak') {
        // Redirect to Azure AD module configuration
        $form_state->setRedirect('keycloak_user_provisioning.overview');
    }
  }

  /**
   *
   */
  private function moUserProvisioningApplication(array &$form, FormStateInterface $form_state) {
    $form['mo_user_prov_header_style'] = [
      '#markup' => t('<h3>Configure Application <a class="button mo_top_guide_button" target="_blank" href="https://www.drupal.org/docs/contributed-modules/user-sync-provisioning-in-drupal">&#128366; Setup Guides</a></h3><hr><br>'),
    ];

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

    $data = ['title', 'description'];
    foreach ($data as $data_shown) {
      $row = $this->moUserProvisioningTypes($data_shown);
      $form['mo_user_prov_scim'][$data_shown] = $row;
    }
  }

  /**
   *
   */
  private function moUserProvisioningServer(array &$form, FormStateInterface $form_state) {
    $form['mo_user_prov_add_js'] = [
      '#attached' => [
        'library' => [
          'user_provisioning/user_provisioning.openPopup',
        ],
      ],
    ];

    $form['mo_user_provisioning_previous_page'] = [
      '#type' => 'link',
      '#title' => $this->t('&#11164; &nbsp;Back'),
      '#url' => Url::fromUri($this->base_url . moUserProvisioningConstants::USER_PROVISIONING_TAB),
      '#attributes' => ['class' => ['button', 'button--danger']],
    ];

    $form['mo_user_prov_header_style'] = [
      '#markup' => t('
            <h3>Changes from Provider to Drupal (Drupal as SCIM Server) <a href="upgrade_plans"><img class="scim_client_know_more" src="' . $this->url_path . '/pro.png" alt="Premium"><span class="scim_client_know_more_hidden">Available in the Premium version</span></a><a class="button mo_top_guide_button" target="_blank" href="https://www.drupal.org/docs/contributed-modules/user-sync-provisioning-in-drupal">&#128366; Setup Guides</a></h3><hr><br>'),
    ];

    $mo_table_content = [
      [
        'SCIM Base URL',
        $this->t('This feature is available in the <a href="' . $this->base_url . moUserProvisioningConstants::UPGRADE_PLANS . '">Premium</a> version of the module.'),
      ],
      [
        'SCIM Bearer Token',
        $this->t('This feature is available in the <a href="' . $this->base_url . moUserProvisioningConstants::UPGRADE_PLANS . '">Premium</a> version of the module.'),
      ],
    ];

    $form['mo_user_provisioning_scim_server_configuration'] = [
      '#type' => 'details',
      '#title' => t('Configure Drupal as SCIM Server'),
      '#open' => TRUE,
    ];

    $form['mo_user_provisioning_scim_server_configuration']['mo_user_provisioning_scim_server_metadata'] = [
      '#type' => 'table',
      '#header' => ['ATTRIBUTE', 'VALUE'],
      '#rows' => $mo_table_content,
      '#empty' => t('Something is not right. Please run the update script or contact us at <a href="mailto:drupalsupport@xecurify.com">drupalsupport@xecurify.com</a>'),
      '#responsive' => TRUE,
      '#sticky' => TRUE,
      '#size' => 2,
      '#attributes' => ['class' => ['mo_user_provisioning_table_server']],
    ];

    $form['mo_user_provisioning_scim_server_configuration']['mo_user_provisioning_scim_server_generate_new_token'] = [
      '#type' => 'submit',
      '#button_type' => 'primary',
      '#value' => t('Generate new Token'),
      '#disabled' => TRUE,
      '#prefix' => '<br/>',
      '#suffix' => '<br/>',
    ];

    $form['mo_user_provisioning_scim_server_configuration']['mo_user_provisioning_scim_server_description'] = [
      '#markup' => t('</br></br>
            <div class="mo_user_provisioning_tab_sub_heading">This tab is capable of doing following SCIM Operations</div><hr>
            <br><div class="mo_user_provisioning_background_note">
                <strong>Create:</strong>
                <ol>It will create users using usernames and other attributes of Provider.<br/>
                <strong>Note: </strong>If Username field is blank, it will copy email as a username, as Drupal does not accept blank Username.</ol>
                <strong>Update:</strong>
                <ol>It will update the user fields, all attributes/fields except email and username.</ol>
                <strong>Delete:</strong>
                <ol>Once a user is deleted from Provider, it would delete a user from Drupal User list as well.</ol>
                <strong>Deactivate:</strong>
                <ol>Once a user is deleted from Provider, it would deactivate a user from the Drupal user list.</ol>
            </div>
            '),
    ];

    $this->featureAdvertise($form);

    $this->attributeMappingAdvertise($form);

    $this->roleMappingAdvertise($form);

    $this->groupMappingAdvertise($form);

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

  }

  /**
   *
   */
  private function moUserProvisioningClient(array &$form, FormStateInterface $form_state) {
    $step = $this->config->get('mo_user_prov_scim_client_step');
    $configuration_edit = $this->request->get('summary');

    if ($step == 'step2') {

    $form['mo_user_prov_header_style'] = [
        '#markup' => t('<h3>Choose when to trigger User Sync & Provisioning <a class="button mo_top_guide_button" target="_blank" href="https://www.drupal.org/docs/contributed-modules/user-sync-provisioning-in-drupal">&#128366; Setup Guides</a></h3><hr><br>'),
    ];

      $this->moUserProvScimClientProvConf($form, $form_state);
    }
    elseif ($step == 'step3' && $configuration_edit == NULL) {
      $this->moUserProvSummaryTest($form, $form_state);
    }
    elseif ($step == 'step3' && $configuration_edit == 'configuration') {
      $this->moUserProvScimClientProvSummary($form, $form_state);
    }
    else {
      $form['mo_user_prov_header_style'] = [
          '#markup' => t('<h3>Configure Drupal as SCIM Client (Changes from Drupal to Provider) <a class="button mo_top_guide_button" target="_blank" href="https://www.drupal.org/docs/contributed-modules/user-sync-provisioning-in-drupal">&#128366; Setup Guides</a></h3><hr><br>'),
      ];

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

  /**
   *
   */
  private function moUserProvSummaryTest(array &$form, FormStateInterface $form_state) {
    $form['mo_user_prov_header_style'] = [
      '#markup' => t('<a class="button mo_user_provisioning_right_side" href="audits_and_logs">Audits and Logs</a><br><h3>Summary</h3><hr>'),

    ];

    $form['mo_user_prov_scim_client_summary_table'] = [
      '#type' => 'table',
      '#responsive' => TRUE,
      '#header' => [
        $this->t('Application Name'),
        $this->t('Edit Configurations'),
        $this->t('Mapping'),
        $this->t('Reset Configurations'),
        $this->t('Manual Provisioning'),
      ],
      '#attributes' => ['class' => ['mo_user_prov_summary_table']],
    ];

    $form['mo_user_prov_scim_client_summary_table']['data'] = $this->moUserProvSummaryTableData();

  }

  /**
   *
   */
  private function moUserProvSummaryTableData() {
    $app = ($this->config->get('mo_user_provisioning_app_name') == 'scim_client') ? 'Custom SCIM Server' : $this->config->get('mo_user_provisioning_app_name');

    $row['app_name'] = [
      '#markup' => $this->t('<strong>' . $app . '<strong>'),
    ];

    $row['edit_conf'] = [
      '#markup' => $this->t('<a href="provisioning?summary=configuration">Edit</a>'),
    ];

    $row['edit_mapping'] = [
      '#markup' => $this->t('<a id="edit-mo-user-prov-scim-client-mapping" href="provisioning?summary=configuration#edit-mo-user-prov-scim-client-mapping">Edit Mapping</a>'),
    ];

    $row['reset_conf'] = [
      '#markup' => $this->t('<a href="resetConfiguration">Reset</a>'),
    ];

    $row['perform_manual_sync'] = [
      '#markup' => $this->t('<a class="button button--primary button--small js-form-submit form-submit use-ajax" href="PerformManualSync">Perform Manual Sync</a>'),
    ];

    return $row;
  }

  /**
   *
   */
  private function moUserProvConf(array &$form, FormStateInterface $form_state, $summary = FALSE) {

    $form['mo_user_prov_scim_client'] = [
      '#type' => 'details',
      '#title' => t('Configure Drupal as SCIM Client'),
      '#open' => TRUE,
    ];

    $form['mo_user_prov_scim_client']['mo_user_prov_scim_client_enable_api_integration'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Enable SCIM Client API integration'),
      '#default_value' => $this->config->get('mo_user_prov_scim_client_enable_api_integration'),
      '#description' => '<strong>Note:-</strong> ' . $this->t('Enable this checkbox to update below configuration and activate the provisioning.'),
    ];

    $form['mo_user_prov_scim_client']['mo_user_prov_client_conf_table'] = [
      '#type' => 'table',
      '#responsive' => TRUE,
      '#attributes' => ['style' => 'border-collapse: separate;'],
    ];

    $data = $this->moUserProvScimClientData();

    foreach ($data as $key => $value) {
      $row = $this->moUserProvScimClientTable($key, $value);
      $form['mo_user_prov_scim_client']['mo_user_prov_client_conf_table'][$key] = $row;
    }

    $form['mo_user_prov_scim_client']['mo_user_provisioning_configuration_test'] = [
      '#type' => 'submit',
      '#button_type' => 'primary',
      '#value' => $this->t('Save and Test Credentials'),
      '#submit' => ['::testAPICredentials'],
      '#states' => [
        // Disable the button when the checkbox is unchecked
        'disabled' => [
            ':input[name="mo_user_prov_scim_client_enable_api_integration"]' => ['checked' => FALSE],
        ],
      ],
    ];

    $form['mo_user_prov_scim_client']['mo_user_provisioning_configuration_reset'] = [
      '#type' => 'submit',
      '#button_type' => 'danger',
      '#value' => $this->t('Reset Configuration'),
      '#limit_validation_errors' => [],
      '#submit' => ['::resetConfigurations'],
    ];

    $form['mo_user_prov_scim_client_mapping'] = [
      '#type' => 'details',
      '#title' => t('Attribute Mapping'),
      '#open' => TRUE,
    ];

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

    $form['mo_user_prov_scim_client_mapping']['mo_user_provisioning_add_more'] = [
      '#type' => 'submit',
      '#button_type' => 'primary',
      '#value' => $this->t('Add more'),
      '#ajax' => [
        'callback' => '::showPremiumFeatureModal',
        'event' => 'click',
        'progress' => 'none',
      ],
      '#limit_validation_errors' => [],
      '#submit' => [],
    ];

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

    if (!$summary) {
        $form['mo_user_provisioning_save_and_next_wrapper'] = [
            '#type' => 'container',
            '#attributes' => [
                'style' => 'text-align: center; margin-top: 20px;',
            ],
        ];

        $form['mo_user_provisioning_save_and_next_wrapper']['mo_user_provisioning_next'] = [
            '#type' => 'submit',
            '#button_type' => 'primary',
            '#value' => $this->t('Save & Next Step  &#11166;'),
            '#submit' => ['::saveAndNextScimMapping'],
            '#validate' => ['::validateScimMapping'],
            '#disabled' => $this->config->get('mo_user_prov_authorization_success') != TRUE,
        ];
    }
  }

  /**
   *
   */
  private function moUserProvScimClientProvConf(array &$form, FormStateInterface $form_state, $summary = FALSE) {

    $form['mo_user_prov_scim_client_prov_types'] = [
      '#type' => 'details',
      '#title' => t('Provisioning Types'),
      '#open' => TRUE,
    ];

    $form['mo_user_prov_scim_client_prov_types']['user_prov_manual_provisioning'] = [
        '#type' => 'checkbox',
        '#title' => $this->t('Manual/On-Demand Provisioning'),
        '#description' => $this->t('Manually perform CRUD operations for any Drupal user in your provider.'),
        '#default_value' => $this->config->get('manual_provisioning'),
        '#disabled' => false,
    ];

    $form['mo_user_prov_scim_client_prov_types']['user_prov_automatic_provisioning'] = [
        '#type' => 'checkbox',
        '#title' => $this->t('Automatic Provisioning'),
        '#description' => $this->t('Automatically perform CRUD operations for any Drupal user in your provider when user registers/updates profile in your Drupal site.'),
        '#default_value' => $this->config->get('event_based_provisioning'),
        '#disabled' => false,
    ];

    $form['mo_user_prov_scim_client_prov_types']['user_prov_scheduler_provisioning'] = [
        '#type' => 'checkbox',
        '#title' => $this->t('Scheduler based Provisioning'),
        '#description' => $this->t('Manually perform CRUD operations for any Drupal user in your provider.'),
        '#disabled' => true,
        '#attributes' => ['style' => 'cursor: not-allowed;'],
    ];

      $form['mo_user_prov_scim_client_prov_operations'] = [
      '#type' => 'details',
      '#title' => t('Provisioning Operations'),
      '#open' => TRUE,
      '#states' => [
        'visible' => [
            [':input[id = "edit-user-prov-manual-provisioning"]' => ['checked' => TRUE]], 'or',
            [':input[id = "edit-user-prov-automatic-provisioning"]' => ['checked' => TRUE]],
        ],
      ],
    ];

    $form['mo_user_prov_scim_client_prov_operations']['features'] = [
      '#markup' => '<div class="premium-upgrade-message">
        In the free version, only <strong>Read</strong> and <strong>Create User</strong> operations are available.
        Other features are part of the <strong>Premium Plan</strong>.
        Upgrade to unlock full access.
        <a href="' . $this->base_url . moUserProvisioningConstants::UPGRADE_PLANS . '" class="upgrade-now">Upgrade Now</a>
      </div>',
    ];

    $this->moProvisioningOperations($form ,'mo_user_prov_scim_client_prov_operations');

    $form['mo_user_prov_scim_client_prov_operations']['enable_role_filter'] = [
      '#type' => 'checkbox',
      '#description' => t('Users with any of the selected roles will be provisioned.'),
      '#title' => $this->t('Enable Role Filter'),
      '#disabled' => TRUE,
      '#default_value' => $this->config_factory->get('role_filter') ?? FALSE,
      '#prefix' => '<hr>',
    ];

    $drupal_roles = array_keys(Role::loadMultiple());
    $count = 0;

    $form['mo_user_prov_scim_client_prov_operations']['role_table'] = [
      '#markup' => '<div class="user_provisioning_checkboxes">',
    ];



    foreach (array_chunk($drupal_roles, 3) as $attributes) {
      foreach ($attributes as $attribute) {
        $form['mo_user_prov_scim_client_prov_operations']['role_table'][$count][$attribute] = [
          '#type' => 'checkbox',
          '#title' => $attribute,
          '#default_value' => FALSE,
          '#disabled' => TRUE,
        ];
      }
      $count++;
    }

    $form['mo_user_prov_scim_client_prov_operations']['role_table']['awa'] = [
      '#markup' => '</div><hr>',
    ];


    $form['mo_user_prov_scim_client_prov_operations']['group_provisioning'] = [
      '#type' => 'checkbox',
      '#title' => t('Enable Group Provisioning.'),
      '#description' => '<strong><span style="color: red">' .t('Note:'). '</span></strong>' . t('Enable this if you wish to provision the Drupal Roles of the Users to Roles/Groups of the connected application via SCIM Group APIs. Default roles will be omitted.'),
      '#default_value' => $this->config->get('group_provisioning') ?? FALSE,
    ];

    // Add Fetch Existing Groups button
    $form['mo_user_prov_scim_client_prov_operations']['fetch_all_groups'] = [
      '#type' => 'submit',
      '#value' => $this->t('Fetch Existing Groups'),
      '#button_type' => 'primary',
      '#ajax' => [
        'callback' => '::fetchExistingGroupModal',
        'event' => 'click',
        'progress' => 'none',
      ],
      '#states' => [
        'enabled' => [
          ':input[name="group_provisioning"]' => ['checked' => TRUE],
        ],
      ],
      '#limit_validation_errors' => [],
      '#submit' => [],
    ];

    if (!$summary) {
      $form['mo_user_prov_back_step1'] = [
        '#type' => 'submit',
        '#value' => t('&#11164; Back to configuration'),
        '#button_type' => 'danger',
        '#submit' => ['::moUserProvBackStep1'],
      ];

      $form['mo_user_prov_all_done_step1'] = [
        '#type' => 'submit',
        '#value' => t('All Done! &#11166; '),
        '#button_type' => 'primary',
        '#submit' => ['::moUserProvAllDone'],
        '#attributes' => ['style' => 'float: right;'],
        '#states' => [
          'visible' => [
            [
              ':input[id = "edit-user-prov-manual-provisioning"]' => ['checked' => TRUE],
              'and',
              ':input[name = "create_user"]' => ['checked' => TRUE],
            ],
            'or',
            [
              ':input[id = "edit-user-prov-automatic-provisioning"]' => ['checked' => TRUE],
              'and',
              ':input[name = "create_user"]' => ['checked' => TRUE],
            ],
          ],
        ],
      ];
    }
  }

  /**
   *
   */
  public function validateScimMapping(array &$form, FormStateInterface $form_state) {
    $form_values = $form_state->getValues();
    foreach ($form_values['mapping_table'] as $key => $attribute_row) {
      if (empty($attribute_row['drupal_attr'])) {
        $form_state->setErrorByName("mapping_table][$key][drupal_attr", $this->t("Please choose a valid attribute from the dropdown"));
      }
    }
  }

  /**
   *
   */
  public function saveAndNextScimMapping(array &$form, FormStateInterface $form_state) {
    $form_values = $form_state->getValues();

    $this->config_factory->set('mo_user_prov_mapping_conf', json_encode($form_values['mapping_table']))->save();
    $this->config_factory->set('mo_user_prov_scim_client_step', 'step2')->save();
    $this->messenger->addMessage($this->t('Attribute mapping saved successfully.'));

    $redirect_url = Url::fromRoute('user_provisioning.provisioning');
    $form_state->setRedirectUrl($redirect_url);
  }

  /**
   *
   */
  public function moUserProvBackStep1(array &$form, FormStateInterface $form_state) {
    $this->config_factory->set('mo_user_prov_scim_client_step', 'step1')->save();
  }

  /**
   *
   */
  private function moUserProvScimClientData() {
    return $data = [
      'SCIM 2.0 Base URL: ' => 'mo_user_provisioning_scim_server_base_url',
      'SCIM Bearer Token: ' => 'mo_user_provisioning_scim_server_bearer_token',
    ];
  }

  /**
   *
   */
  private function moUserProvScimClientTable($key, $value) {
    $row[$key . $key] = [
      '#markup' => '<div class="container-inline"><strong>' . $key . '</strong>',
    ];

    if ($key == 'SCIM 2.0 Base URL: ') {
      $row[$value] = [
        '#type' => 'url',
        '#required' => TRUE,
        '#default_value' => !empty($this->config->get($value)) ? $this->config->get($value) : '',
        '#attributes' => ['class' => ['mo_user_prov_client_conf_table']],
        '#states' => ['disabled' => [':input[name = "mo_user_prov_scim_client_enable_api_integration"]' => ['checked' => FALSE]]],
        '#suffix' => '</div>',
      ];
    }
    else {
      $row[$value] = [
        '#type' => 'textfield',
        '#required' => TRUE,
        '#default_value' => $this->config->get($value),
        '#maxlength' => 1048,
        '#attributes' => ['class' => ['mo_user_prov_client_conf_table']],
        '#states' => ['disabled' => [':input[name = "mo_user_prov_scim_client_enable_api_integration"]' => ['checked' => FALSE]]],
        '#suffix' => '</div>',
      ];
    }

    return $row;
  }

  /**
   *
   */
  public function moScimServerButton() {
    $this->redirect('user_provisioning.provisioning', ['app_name' => 'scim_server'])->send();
  }

  /**
   *
   */
  public function moScimClientButton() {
    $this->redirect('user_provisioning.provisioning', ['app_name' => 'scim_client'])->send();
  }

  /**
   *
   */
  private function moUserProvisioningTypes($data) {

    if ($data == 'title') {
      $row['azure_ad_manual_provisioning'] = [
        '#markup' => '<div class="mo_user_prov_text_center"><h4>Changes from Drupal to Provider (SCIM Client)</h4></div>',
      ];

      $row['azure_ad_automatic_provisioning'] = [
        '#markup' => '<div class="mo_user_prov_text_center"><h4>Changes from Provider to Drupal (SCIM Server)</h4></div>',
      ];
    }
    else {
      $row['azure_ad_manual_provisioning_button'] = [
        '#type' => 'submit',
        '#value' => t('&#9881; Configure '),
        '#button_type' => 'primary',
        '#submit' => ['::moScimClientButton'],
        '#prefix' => 'Drupal as a SCIM client allows for smooth and secure synchronization of changes made to user identities from Drupal to any SCIM-compatible provider.<br><br><div class="mo_user_prov_text_center">',
        '#suffix' => '</div>',
      ];

      $row['azure_ad_automatic_provisioning_button'] = [
        '#type' => 'submit',
        '#value' => t('&#9881; Configure'),
        '#button_type' => 'primary',
        '#submit' => ['::moScimServerButton'],
        '#prefix' => 'Drupal as a SCIM server allows for smooth and secure synchronization of changes made to user identities from any SCIM-compatible provider to Drupal.<br><br><div class="mo_user_prov_text_center">',
        '#suffix' => '</div>',
      ];
    }
    return $row;
  }

  /**
   *
   */
  private function roleMappingAdvertise(&$form) {

    $form['mo_user_provision_role_feature_advertise'] = [
      '#type' => 'details',
      '#title' => $this->t('Role Mapping '),
    ];

    $form['mo_user_provision_role_feature_advertise']['mo_user_provision_enable_role_mapping'] = [
      '#type'          => 'checkbox',
      '#title'         => '<b>' . t('Enable Role Mapping') . '</b>',
      '#description'   => t('<b style="color: red">Note :</b> Enable this first if you want to use default role mapping feature.'),
      '#disabled'      => TRUE,
    ];

    $form['mo_user_provision_role_feature_advertise']['mo_up_scim_role_mapping_enable'] = [
      '#type'        => 'checkbox',
      '#title'       => '<b>' . t('Update the users existing roles.') . '</b>',
      '#description' => t('<b>Note :</b> Enable this if you want to update/delete the existing user roles in the Drupal.'),
      '#disabled'    => TRUE,
    ];

    $form['mo_user_provision_role_feature_advertise']['mo_up_scim_basic_role_mapping'] = [
      '#type' => 'fieldset',
      '#title' => t('Basic Role Mapping'),
      '#attributes' => ['style' => 'padding:2% 2% 4%; margin-bottom:2%'],
    ];

    $roles = Role::loadMultiple();
    $role_label = [];

    foreach ($roles as $role){
      if($role->label() !== 'Anonymous user')
        $role_label[] = $role->label();
    }

    $form['mo_user_provision_role_feature_advertise']['mo_up_scim_basic_role_mapping']['mo_user_provision_default_role'] = [
      '#type'          => 'select',
      '#title'         => t('Select default group for new users'),
      '#description'   => t('<strong>Note: </strong>This role will be assigned to user at the time of user creation in Drupal site.'),
      '#attributes'    => ['style' => 'width:40%;height:29px;'],
      '#options'       => $role_label,
      '#disabled'      => TRUE,
    ];

    $form['mo_user_provision_role_feature_advertise']['mo_up_scim_custom_role_mapping'] = [
      '#type' => 'fieldset',
      '#title' => t('Custom Role Mapping'),
      '#attributes' => ['style' => 'padding:2% 2% 4%; margin-bottom:2%'],
      '#disabled'   => TRUE,
    ];

    $form['mo_user_provision_role_feature_advertise']['mo_up_scim_custom_role_mapping']['mo_up_scim_role_attribute'] = [
      '#type' => 'textfield',
      '#title' => t('Role Attribute'),
      '#id' => 'text_field',
      '#attributes' => ['placeholder' => 'Enter Role Attribute'],
      '#disbled' => TRUE,
    ];

    $form['mo_user_provision_role_feature_advertise']['mo_up_scim_custom_role_mapping']['mo_up_scim_roles'] = [
      '#type' => 'table',
      '#title' => $this->t('Role mapping'),
      '#prefix' => '<div id="mo_up_scim_roles_ajax">',
      '#suffix' => '</div>',
      '#header' => [
        $this->t('Drupal Roles'),
        $this->t('SCIM Client Attribute Value'),
        '',
      ],
    ];

    $form['mo_user_provision_role_feature_advertise']['mo_up_scim_custom_role_mapping']['mo_up_scim_roles']['row_1'] = [
      [
        '#title' => $this->t('Drupal Role Name'),
        '#title_display' => 'invisible',
        '#type' => 'select',
        '#disabled' => TRUE,
        '#options' => ['- Select Drupal Role -'],
      ],
      [
        '#title' => $this->t('SCIM Client Attribute Name'),
        '#title_display' => 'invisible',
        '#type' => 'select',
        '#disabled' => TRUE,
        '#options' => ['- Select Attribute Value -'],
      ],
      [
        '#type' => 'button',
        '#disabled' => TRUE,
        '#value' => 'Delete',
        '#attributes' => ['class' => ['mo_user_prov_text_center']],
      ],
    ];

    $form['mo_user_provision_role_feature_advertise']['mo_up_scim_custom_role_mapping']['add'] = [
      '#type' => 'submit',
      '#name' => 'add',
      '#value' => $this->t('Add More Roles'),
      '#disabled' => TRUE,
    ];

    $form['mo_user_provision_role_feature_advertise']['mo_user_provision_role_mapping_submit'] = [
      '#type'        => 'submit',
      '#button_type' => 'primary',
      '#value'       => t('Save Configuration'),
      '#disabled'    => TRUE,
    ];

  }

  /**
   *
   */
  private function attributeMappingAdvertise(&$form) {

    $form['mo_user_provisioning_scim_server_attribute_mapping'] = [
      '#type'       => 'details',
      '#title'      => t('Attribute Mapping'),
    ];

    $form['mo_user_provisioning_scim_server_attribute_mapping']['markup_cam'] = [
      '#markup' => t('
				<div class="mo_user_provisioning_background_note"><p> This feature allows you to map the user attributes from your provider to the user attributes in Drupal.				</div>'),
    ];

    $form['mo_user_provisioning_scim_server_attribute_mapping']['mo_up_scim_basic_attribute_mapping'] = [
      '#type' => 'fieldset',
      '#title' => t('Basic Attribute Mapping'),
      '#attributes' => ['style' => 'padding:2% 2% 4%; margin-bottom:2%'],
    ];

    $form['mo_user_provisioning_scim_server_attribute_mapping']['mo_up_scim_basic_attribute_mapping']['mo_up_scim_username_attribute'] = [
      '#type' => 'textfield',
      '#title' => t('Username Attribute'),
      '#default_value' => $this->config->get('mo_up_scim_username_attribute'),
      '#disabled' => TRUE,
    ];

    $form['mo_user_provisioning_scim_server_attribute_mapping']['mo_up_scim_basic_attribute_mapping']['mo_up_scim_email_attribute'] = [
      '#type' => 'textfield',
      '#title' => t('Email Attribute'),
      '#default_value' => $this->config->get('mo_up_scim_email_attribute'),
      '#disabled' => TRUE,
    ];

    $form['mo_user_provisioning_scim_server_attribute_mapping']['mo_up_scim_custom_attribute_mapping'] = [
      '#type' => 'fieldset',
      '#title' => t('Custom Attribute Mapping'),
      '#attributes' => ['style' => 'padding:2% 2% 4%; margin-bottom:2%'],

    ];

    $form['mo_user_provisioning_scim_server_attribute_mapping']['mo_up_scim_custom_attribute_mapping']['mo_user_provisioning_mapping']['mo_user_provisioning_attributes'] = [
      '#type' => 'table',
      '#title' => $this->t('Attribute mapping'),
      '#header' => [
        $this->t('SCIM Client Attribute Name'),
        $this->t('Drupal Attribute'),
        '',
      ],
    ];

    $form['mo_user_provisioning_scim_server_attribute_mapping']['mo_up_scim_custom_attribute_mapping']['mo_user_provisioning_mapping']['mo_user_provisioning_attributes']['row1'] = [
      [
        '#title' => $this->t('Attribute Name'),
        '#title_display' => 'invisible',
        '#type' => 'select',
        '#disabled' => TRUE,
        '#options' => ['- Select IDP Attribute -'],
      ],
      [
        '#title' => $this->t('User Attribute Machine Name'),
        '#title_display' => 'invisible',
        '#type' => 'select',
        '#disabled' => TRUE,
        '#options' => ['- Select Attribute Value -'],
      ],
      [
        '#type' => 'button',
        '#disabled' => TRUE,
        '#value' => 'Delete',
        '#attributes' => ['class' => ['mo_user_prov_text_center']],
      ],
    ];

    $form['mo_user_provisioning_scim_server_attribute_mapping']['mo_up_scim_custom_attribute_mapping']['mo_user_provisioning_attribute_mapping_add_more'] = [
      '#type'        => 'submit',
      '#button_type' => 'primary',
      '#value'       => t('Add More'),
      '#disabled'    => TRUE,
    ];

    $form['mo_user_provisioning_scim_server_attribute_mapping']['mo_user_provisioning_attribute_mapping_submit'] = [
      '#type'        => 'submit',
      '#button_type' => 'primary',
      '#value'       => t('Save Configuration'),
      '#disabled'    => TRUE,
    ];

  }

  /**
   *
   */
  private function groupMappingAdvertise(&$form) {

    $form['mo_user_provisioning_scim_server_group_mapping'] = [
      '#type'       => 'details',
      '#title'      => t('Group Mapping '),
    ];

    $form['mo_user_provisioning_scim_server_group_mapping']['mo_user_provisioning_group_mapping_description'] = [
      '#markup' => t('<br/><div class="mo_user_provisioning_background_note"><strong>' . $this->t('Note: ') . '</strong>'
        . $this->t('This section maps the groups created using the Group module. The mapping is done based on the user attribute value received from the SCIM Provider. The module will look for the group name based on the received value under the mapped field and assign that group to the user if that group exists.')
        . '</div>'),
    ];

    $form['mo_user_provisioning_scim_server_group_mapping']['mo_user_provisioning_enable_group_mapping'] = [
      '#type'          => 'checkbox',
      '#title'         => t('Check this option if you want to <b>Enable Group Mapping</b>'),
      '#description'   => t('<b style="color: red">Note :</b> Enable this first if you want to use group mapping feature below.'),
      '#disabled'      => TRUE,
      '#prefix'        => '<br>',
      '#suffix'        => '<br/>',
    ];

    $form['mo_user_provisioning_scim_server_group_mapping']['group_mapping_field_attribute_name'] = [
      '#type'          => 'textfield',
      '#title'         => $this->t('User attribute name for group mapping'),
      '#description'   => $this->t('Enter the attribute name under which you will be receiving the group name. E.g., name.givenName'),
      '#maxlength'     => 255,
      '#disabled'      => TRUE,
    ];

    $form['mo_user_provisioning_scim_server_group_mapping']['group_mapping_field_machine_name'] = [
      '#type'          => 'textfield',
      '#title'         => $this->t('Machine name of the field'),
      '#description'   => $this->t('Enter the machine name of the field with which you want to compare the received value to assign group.'),
      '#disabled'      => TRUE,
      '#states'        => ['disabled' => [':input[name = "mo_user_provisioning_enable_group_mapping"]' => ['checked' => FALSE]]],
      '#maxlength'     => 255,
    ];

    $form['mo_user_provisioning_scim_server_group_mapping']['mo_user_provisioning_group_mapping_submit'] = [
      '#type'        => 'submit',
      '#button_type' => 'primary',
      '#value'       => t('Save Configuration'),
      '#disabled'    => TRUE,
      '#prefix' => '<br>',

    ];

  }

  /**
   *
   */
  private function featureAdvertise(&$form) {

    $form['mo_user_provisioning_scim_server_feature_setting'] = [
      '#type' => 'details',
      '#title' => t('Features '),
      '#attributes' => ['class' => ['mo_details_css']],
      '#open' => TRUE,
    ];

    $form['mo_user_provisioning_scim_server_feature_setting']['set_of_radiobuttons']['miniorange_scim_options'] = [
      '#title' => t('Perform the following action on Drupal user list when user is deleted from Provider:'),
      '#type' => 'radios',
      '#tree' => TRUE,
      '#options' => [
        'NONE' => t('Do Nothing'),
        'DELETE' => t('Delete Users'),
        'DEACTIVATE' => t('Deactivate Users'),
      ],
      '#disabled' => TRUE,
      '#prefix' => '<div class="container-inline">',
      '#suffix' => '</div>',
    ];


      $form['mo_user_provisioning_scim_server_feature_setting']['enable_group_provisioning'] = [
          '#title' => t('Enable Group Provisioning'),
          '#type' => 'checkbox',
          '#default_value' => 0,
          '#description' => t('Enable to allow the SCIM server to synchronize group operations with a SCIM client.'),
          '#disabled' => TRUE,
      ];

      $form['mo_user_provisioning_scim_server_feature_setting']['group_modifications'] = [
          '#type' => 'fieldset',
          '#title' => t('Group Provisioning Settings'),
          '#states' => [
              'visible' => [
                  ':input[name="enable_group_provisioning"]' => ['checked' => FALSE],
              ],
          ],
      ];

      $form['mo_user_provisioning_scim_server_feature_setting']['group_modifications']['mo_user_provisioning_group_create'] = [
          '#title' => t('Create Groups'),
          '#type' => 'checkbox',
          '#default_value' => 0,
          '#description' => t('When a new group is created on the SCIM client, a Drupal role with the same name will be created.'),
          '#disabled' => TRUE,
      ];

      $form['mo_user_provisioning_scim_server_feature_setting']['group_modifications']['mo_user_provisioning_group_delete'] = [
          '#title' => t('Delete Groups'),
          '#type' => 'checkbox',
          '#default_value' => 0,
          '#description' => t('When a group is deleted on the SCIM client, the corresponding Drupal role will also be deleted.'),
          '#disabled' => TRUE,
      ];

      $form['mo_user_provisioning_scim_server_feature_setting']['group_modifications']['mo_user_provisioning_group_update'] = [
          '#title' => t('Update Groups'),
          '#type' => 'checkbox',
          '#default_value' => 0,
          '#description' => t('Changes to existing groups (e.g., renaming) on the SCIM client will be applied on this server.'),
          '#disabled' => TRUE,
      ];

      $form['mo_user_provisioning_scim_server_feature_setting']['mo_user_provisioning_advance_mapping'] = [
          '#type' => 'submit',
          '#button_type' => 'primary',
          '#value' => t('Save Settings'),
          '#disabled' => TRUE,
      ];
  }

  /**
   *
   */
  public function testAPICredentials(array &$form, FormStateInterface $form_state) {
    $this->submitSCIMClientForm($form, $form_state);
    $user_provisioner = new moUserProvisioningUserHandler(User::load(\Drupal::currentUser()->id()));
    [$status_code, $content] = $user_provisioner->searchResource();
    $redirect_step = '';

    if (!is_null($content)) {
      $body = json_decode($content, TRUE);
      if ($status_code == 409 || !is_null($body)) {
        $this->logger->info('<b> ' . __FUNCTION__ . ':</b> ' . '<pre><code>' . print_r($content, TRUE) . '</code></pre>');
        $this->config_factory
          ->set('mo_user_prov_authorization_success', TRUE)
          ->save();
        $this->messenger->addMessage($this->t('Authorization successful! SCIM Client configuration saved successfully. Scroll down to the <a href="#edit-mo-user-prov-scim-client-mapping">Attribute Mapping</a> section and configure it according to your use-case.'));
      }
      else {
        $redirect_step = $this->request->get('summary') == 'configuration' ? 'configuration' : '';
        $this->config_factory
          ->set('mo_user_prov_authorization_success', FALSE)
          ->save();
        $this->logger->error('<b> ' . __FUNCTION__ . ':</b> ' . '<pre><code>' . print_r($content, TRUE) . '</code></pre>');
        $this->messenger->addError('Invalid Authorization.');

      }
    }
    else {
      $this->messenger->addError($this->t('Either base url or bearer token is invalid. Check' . ' <a href="' . $this->base_url . moUserProvisioningConstants::DRUPAL_LOGS_PATH . '" target="_blank">Drupal logs</a> ' . ' for more details.'));
    }

    if (!empty($redirect_step)) {
      $redirect_url = Url::fromRoute('user_provisioning.provisioning', ['summary' => $redirect_step]);
    }
    else {
      $redirect_url = Url::fromRoute('user_provisioning.provisioning');
    }

    $form_state->setRedirectUrl($redirect_url);
  }

  /**
   *
   */
  private function submitSCIMClientForm(array &$form, FormStateInterface $form_state) {
    $form_values = $form_state->getValues();

    $this->config_factory->set('mo_user_prov_scim_client_enable_api_integration', $form_values['mo_user_prov_scim_client_enable_api_integration'])
      ->save();

    $application_name = $this->request->get('app_name');
    if (empty($application_name)) {
      $application_name = $this->config->get('mo_user_provisioning_app_name');
    }

    $form_values_table = ($form_state->getValues())['mo_user_prov_client_conf_table'];

    $data = $this->moUserProvScimClientData();

    if ($form_values['mo_user_prov_scim_client_enable_api_integration']) {
      foreach ($data as $key => $value) {
        $this->config_factory->set($value, trim($form_values_table[$key][$value]))->save();
      }
      $this->config_factory->set('mo_user_provisioning_app_name', $application_name)->save();
    }
  }

  /**
   *
   */
  public function resetConfigurations(array &$form, FormStateInterface $form_state) {
    moUserProvisioningUtilities::moDeleteConfigurations();
    $form_state->setRedirect('user_provisioning.provisioning');
  }

  /**
   *
   */
  private function moUserProvMappingTable(array &$form, FormStateInterface $form_state) {

    $mapped_data = $this->config->get('mo_user_prov_mapping_conf') !== NULL ? json_decode($this->config->get('mo_user_prov_mapping_conf'), TRUE) : '';

    if (isset($mapped_data) && !empty($mapped_data)) {
      $options = $mapped_data;
    }
    else {
      $options = [
        '1' => ['scim_attr' => 'userName', 'drupal_attr' => 'name'],
        '2' => ['scim_attr' => 'displayName', 'drupal_attr' => 'name'],
        '3' => ['scim_attr' => 'preferredLanguage', 'drupal_attr' => 'preferred_langcode'],
        '4' => ['scim_attr' => 'timezone', 'drupal_attr' => 'timezone'],
        '5' => ['scim_attr' => 'name.familyName' , 'drupal_attr' => 'name'],
        '6' => ['scim_attr' => 'name.givenName' , 'drupal_attr' => 'name'],
        '7' => ['scim_attr' => 'emails[type eq "work"].value', 'drupal_attr' => 'mail'],
      ];
    }

    $default_rows = ['1', '2', '3', '4', '5', '6', '7'];
    $form_state->set('default_rows', $default_rows);

    $header = [
      'scim_attr' => $this->t('SCIM Provider Attribute'),
      'drupal_attr' => $this->t('Drupal User Attribute'),
      'delete' => '',
    ];

    $select_list = [
      1 => [
        'userName' => 'userName',
        'displayName' => 'displayName',
        'preferredLanguage' => 'preferredLanguage',
        'timezone' => 'timezone',
        'name.familyName' => 'name.familyName',
        'name.givenName' => 'name.givenName',
        'emails[type eq "work"].value' => 'emails[type eq "work"].value',
      ],
      2 => moUserProvisioningUtilities::customUserFields(),
    ];

    $fields = $this->getFieldsList();
    $unique_array_id = AjaxTables::getUniqueID($form_state->get('unique_id'), $options);
    $form_state->set('unique_id', $unique_array_id);
    $form['mo_user_prov_scim_client_mapping']['mapping_table'] = AjaxTables::generateTables('names-fieldset-wrapper', $fields, $unique_array_id, $options, $header, $select_list, $default_rows);
    return $form;
  }

  /**
   *
   */
  public function ajaxCallback(array &$form, FormStateInterface $form_state) {
    return $form['mo_user_prov_scim_client_mapping']['mapping_table'];
  }

  /**
   * Ajax callback to show premium feature modal.
   */
  public function showPremiumFeatureModal() {
    $response = new AjaxResponse();
    $modal_content = '<div class="premium-feature-content">
      <p>' . $this->t('Adding additional attributes is a Premium feature and requires an upgrade to a higher plan.') . '</p>
      <p>' . $this->t('For assistance or questions, please reach out to our support team at: <a href="mailto:drupalsupport@xecurify.com">drupalsupport@xecurify.com</a>') . '</p>
      <a href="' . $this->base_url . moUserProvisioningConstants::UPGRADE_PLANS . '" class="button button--primary">' . $this->t('View Upgrade Plans') . '</a>
    </div>';

    $response->addCommand(new OpenModalDialogCommand(
      $this->t('Premium Feature'),
      $modal_content,
      [
        'width' => '1000',
        'height' => '300',
        'dialogClass' => 'user-provisioning-premium-modal',
        'closeOnEscape' => TRUE,
      ]
    ));
    return $response;
  }

  /**
   *
   */
  public function getFieldsList() {
    return [
      'scim_attr' => [
        'type' => 'select',
        'disabled' => TRUE,
      ],

      'drupal_attr' => [
        'type' => 'select',
      ],

      'delete_button' => [
        'type' => 'submit',
        'disabled' => 'disabled',
        'submit' => '::removeRow',
        'callback' => '::ajaxCallback',
        'wrapper' => 'names-fieldset-wrapper',
      ],
    ];
  }

  /**
   *
   */
  private function moProvisioningOperations(&$form,$field) {
    $form[$field]['read_user'] = [
      '#type' => 'checkbox',
      '#title' => t('Read user'),
      '#default_value' => TRUE,
      '#disabled' => TRUE,
      '#prefix' => '<div class="user_provisioning_checkboxes">'
    ];

    $form[$field]['create_user'] = [
      '#type' => 'checkbox',
      '#title' => t('Create user'),
      '#default_value' => $this->config->get('mo_user_provisioning_create_user'),
    ];

    $form[$field]['update_user'] = [
      '#type' => 'checkbox',
      '#title' => t('Update user'),
      '#disabled' => TRUE,
    ];

    $form[$field]['deactivate_user'] = [
      '#type' => 'checkbox',
      '#title' => t('Deactivate user'),
      '#disabled' => TRUE,
    ];

    $form[$field]['delete_user'] = [
      '#type' => 'checkbox',
      '#title' => t('Delete user'),
      '#disabled' => TRUE,
      '#suffix' => '</div>',
    ];
  }

  /**
   *
   */
  public function moUserProvAllDone(array &$form, FormStateInterface $form_state) {

    $form_values = $form_state->getValues();
    $manual_prov = $form_values['user_prov_manual_provisioning'];
    $auto_prov = $form_values['user_prov_automatic_provisioning'];
    $create_user = $form_values['create_user'];

    $this->config_factory
      ->set('mo_user_provisioning_create_user', $create_user)
      ->set('event_based_provisioning', $auto_prov)
      ->set('manual_provisioning', $manual_prov)
      ->set('mo_user_prov_scim_client_step', 'step3')
      ->save();

    $this->messenger->addMessage($this->t('Configuration saved successfully. Now, you can perform the sync operations.'));
    $redirect_url = Url::fromRoute('user_provisioning.provisioning');
    $form_state->setRedirectUrl($redirect_url);
  }

  /**
   *
   */
  private function moUserProvScimClientProvSummary(array &$form, FormStateInterface $form_state) {
    $form['mo_user_prov_header_style'] = [
      '#markup' => t('<h3>Summary</h3><hr>'),
    ];

    $this->moUserProvScimClientProvConf($form, $form_state, TRUE);
    $this->moUserProvConf($form, $form_state, TRUE);

    $form['mo_user_provisioning_save_all_wrapper'] = [
        '#type' => 'container',
        '#attributes' => [
            'style' => 'text-align: center; margin-top: 20px;',
        ],
    ];

    $form['mo_user_provisioning_save_all_wrapper']['mo_user_provisioning_save_all'] = [
        '#type' => 'submit',
        '#button_type' => 'primary',
        '#value' => $this->t('Save Summary Configuration'),
        '#submit' => ['::moUserProvAllDone'],
    ];
  }

      /**
   * Ajax callback to show premium feature modal.
   */
  public function fetchExistingGroupModal(array &$form, FormStateInterface $form_state) {
      $response = new AjaxResponse();
      $modal_content = '<div class="premium-feature-content">
         <p>' . $this->t('Group Provisioning is a Premium feature and requires an upgrade to a higher plan.') . '</p>
         <p>' . $this->t('To enable automatic role/group creation and management, please upgrade your plan.') . '</p>
         <p>' . $this->t('For assistance or questions, please reach out to our support team at: <a href="mailto:drupalsupport@xecurify.com">drupalsupport@xecurify.com</a>') . '</p>
         <a href="' . $this->base_url . moUserProvisioningConstants::UPGRADE_PLANS . '" class="button button--primary">' . $this->t('View Upgrade Plans') . '</a>
       </div>';

      $response->addCommand(new OpenModalDialogCommand(
          $this->t('Premium Feature'),
          $modal_content,
          [
              'width' => '1000',
              'height' => '300',
              'dialogClass' => 'user-provisioning-premium-modal',
              'closeOnEscape' => TRUE,
          ]
      ));
      return $response;
  }



}
