<?php

namespace Drupal\miniorange_2fa\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\user\Entity\User;
use Drupal\miniorange_2fa\MoAuthUtilities;
use Drupal\miniorange_2fa\AuthenticationAPIHandler;
use Drupal\miniorange_2fa\MiniorangeCustomerProfile;
use Drupal\Core\Url;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Drupal\Core\Messenger\MessengerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Logger\LoggerChannelFactoryInterface;


/**
 * Provides the end user 2FA configuration form using plugin architecture.
 */
class ConfigureEndUser2fa extends FormBase {

  protected MoAuthUtilities $utilities;
  protected $user;
  protected $user_id;
  protected $authMethod;
  protected $user_email;
  protected MiniorangeCustomerProfile $customer;
  protected AuthenticationAPIHandler $auth_api_handler;
  protected $session;
  protected $moMfaSession;
  protected $messenger;
  public function __construct(MessengerInterface $messenger,LoggerChannelFactoryInterface $logger_factory) {
    $this->messenger = $messenger;
    $this->utilities = new MoAuthUtilities();
    $this->session = $this->utilities->getSession();
    $this->moMfaSession = $this->session->get("mo_auth", null);

    if (isset($this->moMfaSession['uid'])) {
      $this->user = User::load($this->moMfaSession['uid']);
      $this->user_id = $this->user->id();
      $this->user_email = $this->user->get('mail')->value;
    }
    $this->loggerFactory = $logger_factory;
    $this->authMethod = \Drupal::routeMatch()->getParameter('authMethod') ?? '';
    $this->customer = new MiniorangeCustomerProfile();
    $this->auth_api_handler = new AuthenticationAPIHandler(
      $this->customer->getCustomerID(),
      $this->customer->getAPIKey()
    );
  }

  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('messenger'),
      $container->get('logger.factory'),
    );
  }

  public function getFormId(): string {
    return 'mo_auth_configure_enduser_2fa';
  }

  public function buildForm(array $form, FormStateInterface $form_state): array {

    $form['#attached']['library'] = [
      'miniorange_2fa/miniorange_2fa.admin',
      'core/drupal.ajax',
      'miniorange_2fa/miniorange_2fa.country_flag_dropdown',
      'miniorange_2fa/miniorange_2fa.custom_kba_validation',
    ];

    $authentication_js_required = [
      'MOBILE AUTHENTICATION',
      'SOFT TOKEN',
      'PUSH NOTIFICATIONS',
    ];

    if (in_array($this->authMethod, $authentication_js_required)) {
      $form['#attached']['library'][] = 'miniorange_2fa/miniorange_2fa.license';
    }

    try {
      $plugin_manager = \Drupal::service('plugin.manager.miniorange_2fa.authentication_type');
      $auth_method_code = $this->authMethod ?? '';
      $plugin_id = MoAuthUtilities::mapAuthMethodToPluginId($auth_method_code);

      if (!$plugin_id) {
        throw new \Exception("No plugin found for auth method code: {$auth_method_code}");
      }

      $plugin = $plugin_manager->createInstance($plugin_id);
      $form = $plugin->buildConfigurationForm($form, $form_state);

      $plugin_key = str_replace('-', '_', $plugin_id) . '_plugin';
      $form_state->set($plugin_key, $plugin);
    }
    catch (\Exception $e) {
      $this->loggerFactory->get('miniorange_2fa')->error('@method Plugin error: @msg', [  '@method' => $this->authMethod,'@msg' => $e->getMessage(),]);
      $message = 'Plugin configuration failed. Redirecting to traditional method.';
      $this->utilities->redirectUserToLoginPage($message);
    }

    return $form;
  }

  public function submitForm(array &$form, FormStateInterface $form_state): void {

    $auth_method_code = $this->authMethod ?? '';
    $plugin_id = MoAuthUtilities::mapAuthMethodToPluginId($auth_method_code);

    try {
      $plugin_manager = \Drupal::service('plugin.manager.miniorange_2fa.authentication_type');

      if (!$plugin_id) {
        $this->messenger->addError('Invalid authentication method.');
        $form_state->setRedirect('<front>');
      }

      $plugin_key = str_replace('-', '_', $plugin_id) . '_plugin';
      $plugin = $form_state->get($plugin_key);

      if (!$plugin) {
        $plugin = $plugin_manager->createInstance($plugin_id);
      }

      $plugin->submitConfigurationForm($form, $form_state);

      if (!$form_state->getRedirect()) {
        $form_state->setRedirect('<front>');
      }
    }
    catch (\Exception $e) {
      $this->loggerFactory->get('miniorange_2fa')->error('QR plugin submission error: @msg', [
        '@msg' => $e->getMessage(),
      ]);
      $this->messenger->addError('An error occurred while processing your request. Please try again.');
      $form_state->setRedirect('<front>');
    }
  }

  /**
   * Cancel handler for inline registration.
   */
  public function moCancelInlineRegistration() {
    $session = MoAuthUtilities::getSession();
    $moMfaSession = $session->get("mo_auth", null);

    if (isset($moMfaSession['uid'])) {
      $account = User::load($moMfaSession['uid']);
      // Remove user from MO dashboard created in previous step (Select method submit)
      MoAuthUtilities::delete_user_from_UserAuthentication_table($account);
      $session->remove('mo_auth');
    }

    $url = Url::fromRoute('user.login')->toString();
    $response = new RedirectResponse($url);
    $response->send();
    exit;
  }

}
