<?php

namespace Drupal\user_provisioning\Controller;

use Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException;
use Drupal\Component\Plugin\Exception\PluginNotFoundException;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\OpenModalDialogCommand;
use Drupal\Core\Config\Config;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Config\ImmutableConfig;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormBuilder;
use Drupal\Core\Logger\LoggerChannelFactoryInterface;
use Drupal\Core\Url;
use Psr\Log\LoggerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Response;

/**
 * User provisioning controller.
 */
class user_provisioningController extends ControllerBase {
  /**
   * The user storage.
   *
   * @var \Drupal\user\Entity\UserStorageInterface
   */

  private ImmutableConfig $config;
  /**
   * Editable user provisioning configuration.
   *
   * @var \Drupal\Core\Config\Config
   *   Editable configuration object.
   */
  protected Config $editableConfig;

  /**
   * The form builder object.
   *
   * @var FormBuilder
   *   The form builder object.
   */
  protected $formBuilder;

  /**
   * Logger channel for this module.
   *
   * @var \Psr\Log\LoggerInterface
   *   Logger instance.
   */
  private LoggerInterface $logger;

  /**
   * The entity type manager service.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * Scim_clientController constructor.
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   */
  public function __construct(
    ConfigFactoryInterface $config_factory,
    FormBuilder $formBuilder,
    LoggerChannelFactoryInterface $logger_factory,
    EntityTypeManagerInterface $entity_type_manager,
  ) {
    $this->config = $config_factory->get('user_provisioning.settings');
    $this->editableConfig = $config_factory->getEditable('user_provisioning.settings');
    $this->formBuilder = $formBuilder;
    $this->logger = $logger_factory->get('user_provisioning');
    $this->entityTypeManager = $entity_type_manager;
  }

  /**
   * Create form.
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   */
  public static function create(ContainerInterface $container) {
    return new static(
          $container->get('config.factory'),
          $container->get("form_builder"),
          $container->get('logger.factory'),
          $container->get('entity_type.manager'),
      );
  }

  /**
   * Export the user in json or csv file.
   *
   * @return RedirectResponse|Response
   *   return json or csv file
   */
  public function exportUsers(): RedirectResponse|Response {
    // Required attribute to export.
    $users_export = $this->config->get('mo_user_provisioning_export_config');
    // File extension.
    $fil_extension = $this->config->get('mo_user_provisioning_file_extension');
    $this->editableConfig->clear('mo_export_config')->save();

    $configuration_array = [];

    $header = [];
    if ($fil_extension == 'csv') {
      foreach ($users_export as $key => $value) {
        if ($value) {
          $header[] = $key;
        }
      }
      $configuration_array[] = $header;
    }

    // Loading all the users.
    $users = [];
    try {
      $users = $this->entityTypeManager->getStorage('user')->loadMultiple();
      // Un-setting the Anonymous user which has uid=0.
      unset($users[0]);
    }
    catch (InvalidPluginDefinitionException | PluginNotFoundException $e) {
      $this->logger->error($e->getMessage());
    }

    foreach ($users as $user) {
      $user_details = [];
      foreach ($users_export as $key => $val) {
        if ($val) {
          $user_key_value = $user->get($key)->value;
          $user_details[$key] = $user_key_value;
        }
      }
      if (!empty($user_details)) {
        $configuration_array[$user->getDisplayName()] = $user_details;
      }

    }

    // To unset the anonymous user.
    unset($configuration_array["Anonymous"]);

    if ($fil_extension == 'json') {
      $json = json_encode($configuration_array, JSON_PRETTY_PRINT);
      $response = new Response($json);
      $response->headers->set('Content-Type', 'application/json');
      $response->headers->set('Content-Disposition', 'attachment; filename="mo_user_provisioning_export.json"');
      return $response;
    }
    elseif ($fil_extension == 'csv') {
      $f = fopen('php://memory', 'w');
      // Loop over the input array.
      foreach ($configuration_array as $line) {
        // Generate csv lines from the inner arrays.
        fputcsv($f, $line, ';');
      }
      // Reset the file pointer to the start of the file.
      rewind($f);
      // Read the CSV content from memory.
      $csv_content = stream_get_contents($f);
      fclose($f);

      // Create Response object with CSV content.
      $response = new Response($csv_content);
      $response->headers->set('Content-Type', 'text/csv');
      $response->headers->set('Content-Disposition', 'attachment; filename="mo_user_provisioning_export.csv"');
      return $response;
    }

    return new RedirectResponse(Url::fromRoute('user_provisioning.advanced_settings')->toString());
  }

  /**
   * Function to open form request form.
   *
   * @return \Drupal\Core\Ajax\AjaxResponse
   *   The AJAX response with the support request modal.
   */
  public function openSupportRequestForm() {
    $response = new AjaxResponse();
    $modal_form = $this->formBuilder->getForm('\Drupal\user_provisioning\Form\MoUserProvisioningRequestSupport');
    $response->addCommand(new OpenModalDialogCommand('Support Request/Contact Us', $modal_form, ['width' => '40%']));
    return $response;
  }

  /**
   * Open the support request form.
   */
  public function openModalForm() {
    $response = new AjaxResponse();
    $modal_form = $this->formBuilder->getForm('\Drupal\user_provisioning\Form\MoUserProvisioningRemoveAccount');
    $response->addCommand(new OpenModalDialogCommand('Remove Account', $modal_form, ['width' => '40%']));
    return $response;
  }

  /**
   * Open the customer request form.
   */
  public function openCustomerRequestForm() {
    $response = new AjaxResponse();
    $modal_form = $this->formBuilder->getForm('\Drupal\user_provisioning\Form\MoUserProvisioningCustomerRequest');
    $response->addCommand(new OpenModalDialogCommand('Contact miniOrange Support', $modal_form, ['width' => '45%']));
    return $response;
  }

  /**
   * Open the manual sync form.
   */
  public function openManualSyncFormAction() {
    $response = new AjaxResponse();
    $modal_form = $this->formBuilder->getForm('\Drupal\user_provisioning\Form\MoUserProvisioningManualSync');
    $response->addCommand(new OpenModalDialogCommand('Perform Manual Sync', $modal_form, ['width' => '80%']));
    return $response;
  }

  /**
   * Open the configure app form.
   */
  public function openConfigureAppForm($app_name): AjaxResponse {
    $response = new AjaxResponse();
    $modal_form = $this->formBuilder->getForm('\Drupal\user_provisioning\Form\MoUserProvisioningChooseApp', $app_name);
    $response->addCommand(new OpenModalDialogCommand('Choose the sync', $modal_form, ['width' => '80%']));
    return $response;
  }

}
