<?php

namespace Drupal\azure_ad\Form;

use Drupal\Component\Serialization\Json;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Config\ImmutableConfig;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\ReplaceCommand;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Messenger\MessengerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Psr\Log\LoggerInterface;
use Drupal\Core\Logger\LoggerChannelFactoryInterface;

/**
 * Review Azure Config Form.
 */
class MoReviewAzureConfig extends FormBase {

  /**
   * Immutable Azure AD module configuration.
   *
   * @var \Drupal\Core\Config\ImmutableConfig
   */
  private ImmutableConfig $config;

  /**
   * Logger for Azure AD module.
   *
   * @var \Psr\Log\LoggerInterface
   */
  protected LoggerInterface $logger;

  /**
   * Azure overview form service.
   *
   * @var \Drupal\azure_ad\Form\MoAzureOverview
   */
  protected MoAzureOverview $overviewForm;

  /**
   * Constructor for MoReviewAzureConfig.
   */
  public function __construct(ConfigFactoryInterface $config_factory, MessengerInterface $messenger, LoggerChannelFactoryInterface $logger_factory, MoAzureOverview $overview_form) {
    $this->setConfigFactory($config_factory);
    $this->config = $config_factory->get('azure_ad.settings');
    $this->setMessenger($messenger);
    $this->logger = $logger_factory->get('azure_ad');
    $this->overviewForm = $overview_form;
  }

  /**
   * Creates the class instance.
   */
  public static function create(ContainerInterface $container): static {
    return new static(
          $container->get('config.factory'),
          $container->get('messenger'),
          $container->get('logger.factory'),
          $container->get('azure_ad.form.mo_azure_overview')
      );
  }

  /**
   * Get the form ID.
   */
  public function getFormId() {
    return 'mo_azure_review_config';
  }

  /**
   * Build the form.
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $form['#prefix'] = '<div id="modal_support_form">';
    $form['#suffix'] = '</div>';

    $form['status_messages'] = [
      '#type' => 'status_messages',
      '#weight' => -10,
    ];

    $form['mo_azure_ad_to_drupal_library'] = [
      '#attached' => [
        'library' => [
          'azure_ad/azure_ad.admin',
          'azure_ad/azure_ad.update_summary_form',
          'core/drupal.dialog.ajax',
        ],
      ],
    ];

    $this->overviewForm->AzureADConfigurationTable($form, $form_state, 'summary');

    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'))) {
      $result = $this->moAzureTestResultajax();
      $form['azure_test_config_result'] = $result;
    }

    $form['actions'] = ['#type' => 'actions'];
    $form['actions']['send'] = [
      '#type' => 'submit',
      '#value' => $this->t('Save and Test Configuration'),
      '#attributes' => [
        'class' => [
          'use-ajax',
          'button--primary',
        ],
      ],
      '#ajax' => [
        'callback' => [$this, 'submitModalFormAjax'],
        'event' => 'click',
      ],
    ];

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

  /**
   * Submit the form.
   */
  public function submitModalFormAjax(array $form, FormStateInterface $form_state) {

    $response = new AjaxResponse();
    // If there are any form errors, AJAX replace the form.
    if ($form_state->hasAnyErrors()) {
      $response->addCommand(new ReplaceCommand('#modal_support_form', $form));
    }
    else {
      $form_values = ($form_state->getValues())['mo_configure_azure_configuration'];
      $this->logger->notice('Form data: @data', [
        '@data' => json_encode($form['azure_ad_summary_details']['mo_configure_azure_configuration']),
      ]);
      $this->overviewForm->moAzureStep1SaveButton($form, $form_state);

      $result = $this->moAzureTestResultajax($form, $form_state);

      $response->addCommand(new ReplaceCommand('#modal_support_form', $form));
      $response->addCommand(new ReplaceCommand('#test_config_result', $result));
    }
    return $response;
  }

  /**
   * Validate the form.
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {}

  /**
   * Test the Azure configuration.
   */
  public function moAzureTestResultajax() {
    $azure_test_data = Json::decode($this->config->get('mo_azure_attr_list_from_server'));

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

    $testresult['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="mo-success-message">SUCCESS</div>'),

    ];

    if (isset($azure_test_data['Profile Picture'])) {
      $testresult['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'],
              ]
          ),
      ];
    }

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

    $this->configFactory->getEditable('azure_ad.settings')->set('test_azure_config_result', isset($azure_test_data["error_code"]))->save();

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

    $testresult['div_test_close'] = [
      '#markup' => '</div>',
    ];

    return $testresult;
  }

}
