<?php

namespace Drupal\azure_ad\Form;

use Drupal\azure_ad\Helper\moAzureADHelper;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\Core\Url;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Response;

/**
 * Provides the Azure AD to Drupal sync form.
 */
class MoAzureToDrupalSync extends FormBase {
  /**
   * Entity type manager service.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  private EntityTypeManagerInterface $entityTypeManager;

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

  /**
   * Constructs a new MoAzureToDrupalSync object.
   */
  public function __construct(
    ConfigFactoryInterface $configFactory,
    RequestStack $request_stack,
    EntityTypeManagerInterface $entity_type_manager,
    AccountProxyInterface $current_user,
  ) {
    $this->configFactory = $configFactory->getEditable('azure_ad.settings');
    $this->requestStack = $request_stack;
    $this->entityTypeManager = $entity_type_manager;
    $this->currentUser = $current_user;
  }

  /**
   * {@inheritDoc}
   */
  public static function create(ContainerInterface $container): static {
    return new static(
      $container->get('config.factory'),
      $container->get('request_stack'),
      $container->get('entity_type.manager'),
      $container->get('current_user')
    );
  }

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

  /**
   * 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_to_drupal_library'] = [
      '#attached' => [
        'library' => [
          'azure_ad/azure_ad.admin',
          'core/drupal.dialog.ajax',
        ],
      ],
    ];

    $request = $this->requestStack->getCurrentRequest();
    $isTrialOpened = $request->cookies->get('request_trial');

    if (!isset($isTrialOpened)) {
      $request->cookies->set('request_trial', 'true');
      $form['trial_script'] = [
        '#type' => 'markup',
        '#markup' => '<script type="text/javascript">
        function showtrialform() {
            var url = window.location.pathname;
            url = url.replace("azure_to_drupal_configure", "requestTrialAzure");
            var button = document.getElementById("trial");
            if (button) button.click();
        }
        setTimeout(showtrialform, 5000);
                        </script>',
        '#allowed_tags' => ['script'],
      ];
    }

    $form['azure_ad_to_drupal_back_to_overview'] = [
      '#type' => 'submit',
      '#value' => $this->t('&#11164; &nbsp;Back to Overview'),
      '#attributes' => ['class' => ['button', 'button--danger']],
      '#submit' => ['::moAzureBackToOverview'],
    ];

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

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

    return $form;
  }

  /**
   * Handles form submission.
   *
   * @param array $form
   *   The form array.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The form state.
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {}

  /**
   * Builds the Azure AD to Drupal provisioning fieldset.
   *
   * @param array $form
   *   The form array.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The form state.
   */
  private function azureAdToDrupalProvisioning(array &$form, FormStateInterface $form_state) {
    $url = Url::fromRoute('azure_ad.azure_upgrade_plans')->toString();
    $mo_premium_tag = '<a href="' . $url . '" class="premium-badge">' . $this->t('PREMIUM') . '</a>';
    $form['mo_azure_ad_provisioning_fieldset'] = [
      '#type' => 'fieldset',
      '#title' => $this->t('Manual Provisioning Configuration&nbsp;') . $mo_premium_tag,
    ];

    $form['mo_azure_ad_provisioning_fieldset']['automatic_provisioning_choose_operations'] = [
      '#type' => 'fieldset',
      '#title' => $this->t('Choose Operations in Manual Provisioning') . '<hr>',
    ];

    $this->moProvisioningOperations($form);

    $form['mo_azure_ad_provisioning_fieldset']['create_user_fieldset'] = [
      '#type' => 'fieldset',
      '#title' => $this->t('Sync Users') . '<hr>',
      '#prefix' => '<div class="container-inline">',
      '#suffix' => '</div>',
    ];

    $form['mo_azure_ad_provisioning_fieldset']['create_user_fieldset']['mo_azure_drupal_username'] = [
      '#type' => 'entity_autocomplete',
      '#target_type' => 'user',
      '#attributes' => ['placeholder' => $this->t('Search Azure AD username of user to sync')],
      '#disabled' => TRUE,
      '#prefix' => '<p class="mo_azure_highlight_background"><strong>' . $this->t('Note:') . '</strong>' . $this->t('&nbsp;Search the username of user present in Azure AD to sync it to the Drupal.') . '</p>',
    ];

    $form['mo_azure_ad_provisioning_fieldset']['create_user_fieldset']['mo_azure_sync_button'] = [
      '#type' => 'submit',
      '#value' => $this->t('Sync'),
      '#button_type' => 'primary',
      '#attributes' => ['class' => ['mo_azure_sync_button']],
      '#disabled' => TRUE,
    ];

    $form['mo_azure_ad_provisioning_fieldset']['create_user_fieldset']['mo_azure_sync_all_button'] = [
      '#type' => 'submit',
      '#value' => $this->t('Sync All Users'),
      '#button_type' => 'primary',
      '#attributes' => ['class' => ['mo_azure_sync_all_button']],
      '#disabled' => TRUE,
    ];

    $form['mo_azure_ad_automatic_provisioning_fieldset'] = [
      '#type' => 'fieldset',
      '#title' => $this->t('Automatic Provisioning Configuration&nbsp;') . $mo_premium_tag,
    ];

    $form['mo_azure_ad_automatic_provisioning_fieldset']['auto_prov_note'] = [
      '#markup' => '<p class="mo_azure_highlight_background">' . $this->t('Azure AD / B2C to Drupal user sync can be scheduled at a specific time interval. This will create / update the users automatically after the time specified in the&nbsp;') . '<strong>' . $this->t('Enable Automatic User Creation') . '</strong>' . $this->t('&nbsp;field. Number of users synced per request can be configured here in the&nbsp;') . '<strong>' . $this->t('Number of User Records/Request') . '</strong>' . $this->t('&nbsp;textfield.') . '</p>',
    ];

    $form['mo_azure_ad_automatic_provisioning_fieldset']['create_user_fieldset'] = [
      '#type' => 'fieldset',
      '#title' => $this->t('Sync Users') . '<hr>',
    ];

    $form['mo_azure_ad_automatic_provisioning_fieldset']['create_user_fieldset']['enable_auto_creation'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Enable Automatic User Creation'),
      '#disabled' => TRUE,
    ];

    $form['mo_azure_ad_automatic_provisioning_fieldset']['create_user_fieldset']['records_number'] = [
      '#type' => 'number',
      '#title' => $this->t('Number of User Records/Request'),
      '#disabled' => TRUE,
    ];

    $form['mo_azure_ad_automatic_provisioning_fieldset']['create_user_fieldset']['auto_creation'] = [
      '#type' => 'number',
      '#title' => $this->t('Fetch All users details in next * minutes'),
      '#disabled' => TRUE,
    ];

    $form['mo_azure_ad_profile_sync_fieldset'] = [
      '#type' => 'fieldset',
      '#title' => $this->t('Profile Picture Sync&nbsp;') . $mo_premium_tag,
    ];

    $form['mo_azure_ad_profile_sync_fieldset']['auto_prov_note'] = [
      '#markup' => '<p class="mo_azure_highlight_background">' . $this->t('It provides the feature to sync profile picture of users from your Active Directory. Default profile picture value can be set in the profile mapping settings in case there is no profile picture associated for some user accounts.') . '</p>',
    ];

    $form['mo_azure_ad_profile_sync_fieldset']['enable_auto_creation'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Enable Profile Picture Sync'),
      '#disabled' => TRUE,
    ];

  }

  /**
   * Builds the provisioning operations fieldset.
   *
   * @param array $form
   *   The form array.
   */
  private function moProvisioningOperations(&$form) {
    $form['mo_azure_ad_provisioning_fieldset']['automatic_provisioning_choose_operations']['read_user_azure_ad'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Read user'),
      '#disabled' => TRUE,
      '#prefix' => '<div class="azure_ad_checkboxes">',
    ];

    $form['mo_azure_ad_provisioning_fieldset']['automatic_provisioning_choose_operations']['create_user_azure_ad'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Create user'),
      '#disabled' => TRUE,
    ];

    $form['mo_azure_ad_provisioning_fieldset']['automatic_provisioning_choose_operations']['update_user_azure_ad'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Update user'),
      '#disabled' => TRUE,
    ];

    $form['mo_azure_ad_provisioning_fieldset']['automatic_provisioning_choose_operations']['deactivate_user_azure_ad'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Deactivate user'),
      '#disabled' => TRUE,
    ];

    $form['mo_azure_ad_provisioning_fieldset']['automatic_provisioning_choose_operations']['delete_user_azure_ad'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Delete user'),
      '#disabled' => TRUE,
    ];

    $form['mo_azure_ad_provisioning_fieldset']['automatic_provisioning_choose_operations']['manual_provisioning_save_button'] = [
      '#type' => 'submit',
      '#value' => $this->t('Save'),
      '#button_type' => 'primary',
      '#disabled' => TRUE,
      '#suffix' => '</div>',
    ];
  }

  /**
   * Builds the attribute mapping details fieldset.
   *
   * @param array $form
   *   The form array.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The form state.
   */
  public function attributeMapping(array &$form, FormStateInterface $form_state) {
    $url = Url::fromRoute('azure_ad.azure_upgrade_plans')->toString();
    $mo_premium_tag = '<a href="' . $url . '" class="premium-badge">' . $this->t('PREMIUM') . '</a>';
    $form['mo_azure_attribute_mapping_details'] = [
      '#type' => 'fieldset',
      '#open' => FALSE,
      '#title' => $this->t('Mapping for Azure AD to Drupal Sync&nbsp;') . $mo_premium_tag,
    ];

    $form['mo_azure_attribute_mapping_details']['azure_ad_attribute_mapping'] = [
      '#type' => 'fieldset',
      '#title' => $this->t('Basic Attribute Mapping') . '<hr>',
    ];

    $header = [
      'username' => $this->t('Username Attribute'),
      'email' => $this->t('Email Attribute'),
    ];

    $form['mo_azure_attribute_mapping_details']['azure_ad_attribute_mapping']['azure_ad_attribute_mapping_table'] = [
      '#type' => 'table',
      '#header' => $header,
      '#responsive' => TRUE,
    ];

    $row = $this->moAzureAdAttributeMapTable();
    $form['mo_azure_attribute_mapping_details']['azure_ad_attribute_mapping']['azure_ad_attribute_mapping_table']['attributes'] = $row;

    $form['mo_azure_attribute_mapping_details']['azure_ad_attribute_mapping']['azure_ad_basic_mapping_save_button'] = [
      '#type' => 'submit',
      '#value' => $this->t('Save Configuration&nbsp;'),
      '#button_type' => 'primary',
      '#disabled' => TRUE,
    ];

    $form['mo_azure_attribute_mapping_details']['azure_ad_custom_attribute_mapping'] = [
      '#type' => 'fieldset',
      '#title' => $this->t('Custom Attribute Mapping') . '<hr>',
    ];

    $form['mo_azure_attribute_mapping_details']['azure_ad_custom_attribute_mapping']['attribute_mapping_info'] = [
      '#markup' => '<div class="mo_azure_highlight_background">' . $this->t('This feature allows you to map the user attributes from your Drupal to Azure AD.') . '</div>',
    ];

    $custom_fields = [];
    $usr = $this->entityTypeManager->getStorage('user')->load($this->currentUser->id());
    $usrVal = $usr ? $usr->toArray() : [];
    foreach ($usrVal as $key => $value) {
      $custom_fields[$key] = $key;
    }

    $header = [
      'drupal_attr' => $this->t('Drupal Attribute Name'),
      'azure_attr' => $this->t('Azure AD Attribute Name'),
      'add' => '',
      'delete' => '',
    ];

    $form['mo_azure_attribute_mapping_details']['azure_ad_custom_attribute_mapping']['azure_ad_custom_attribute_mapping_table'] = [
      '#type' => 'table',
      '#header' => $header,
      '#responsive' => TRUE,
    ];

    $row = $this->moAzureAdCustomAttributeMapTable($custom_fields);
    $form['mo_azure_attribute_mapping_details']['azure_ad_custom_attribute_mapping']['azure_ad_custom_attribute_mapping_table']['custom_mapping'] = $row;
  }

  /**
   * Builds the custom attribute mapping table.
   *
   * @param array $custom_fields
   *   The custom fields.
   *
   * @return array
   *   The form array.
   */
  private function moAzureAdCustomAttributeMapTable($custom_fields) {
    $row['azure_ad_drupal_attr_name'] = [
      '#type' => 'select',
      '#options' => $custom_fields,
      '#disabled' => TRUE,
    ];

    $row['azure_ad_attribute_name'] = [
      '#type' => 'textfield',
      '#disabled' => TRUE,
    ];

    $row['azure_ad_add_button'] = [
      '#type' => 'submit',
      '#button_type' => 'primary',
      '#disabled' => TRUE,
      '#value' => '+',
    ];

    $row['azure_ad_sub_button'] = [
      '#type' => 'submit',
      '#button_type' => 'danger',
      '#disabled' => TRUE,
      '#value' => '-',
    ];

    return $row;
  }

  /**
   * Builds the attribute mapping table.
   *
   * @return array
   *   The form array.
   */
  public function moAzureAdAttributeMapTable() {
    $row['username_attribute'] = [
      '#type' => 'select',
      '#options' => [1 => 'name'],
      '#disabled' => TRUE,
    ];

    $row['email_attribute'] = [
      '#type' => 'select',
      '#options' => [1 => 'mail'],
      '#disabled' => TRUE,
    ];

    return $row;
  }

  /**
   * Redirects to the overview page.
   *
   * @return \Symfony\Component\HttpFoundation\RedirectResponse
   *   The redirect response.
   */
  public function moAzureBackToOverview() {
    $response = new RedirectResponse(Url::fromRoute('azure_ad.overview')->toString());
    $response->send();
    return new Response();
  }

}
