<?php

namespace Drupal\user_provisioning\Controller;

use Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException;
use Drupal\Component\Plugin\Exception\PluginNotFoundException;
use Drupal\Component\Utility\Html;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\OpenModalDialogCommand;
use Drupal\Core\Config\Config;
use Drupal\Core\Config\ImmutableConfig;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Form\FormBuilder;
use Drupal\Core\Url;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Drupal\user_provisioning\moUserProvisioningUtilities;
use Symfony\Component\HttpFoundation\Response;

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

  private ImmutableConfig $config;
  private Config $config_factory;
  protected $formBuilder;

  /**
   * Scim_clientController constructor.
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   */
  public function __construct(FormBuilder $formBuilder) {
    $this->config = \Drupal::config('user_provisioning.settings');
    $this->config_factory = \Drupal::configFactory()->getEditable('user_provisioning.settings');
    $this->formBuilder = $formBuilder;
  }

  /**
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   */
  public static function create(ContainerInterface $container) {
    return new static(
          $container->get("form_builder")
      );
  }

  /**
   * Export the user in json or csv file.
   *
   * @return RedirectResponse|Response
   */
  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->config_factory->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 = \Drupal::entityTypeManager()->getStorage('user')->loadMultiple();
      // Un-setting the Anonymous user which has uid=0.
      unset($users[0]);
    } catch (InvalidPluginDefinitionException|PluginNotFoundException $e) {
      \Drupal::logger('user_provisioning')->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());
  }

  // Ajax Response for Contact Us / Support Request form.

  /**
   * @return \Drupal\Core\Ajax\AjaxResponse
   */
  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;
  }

  /**
   *
   */
  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;
  }

  /**
   *
   */
  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;
  }

  /**
   *
   */
  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;
  }

  /**
   *
   */
  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;
  }

  /**
   *
   */
  public static function resetConfigurations(): RedirectResponse
  {
    moUserProvisioningUtilities::moDeleteConfigurations();
    return new RedirectResponse(Url::fromRoute('user_provisioning.provisioning')->toString());
  }

}
