<?php

namespace Drupal\miniorange_2fa\Plugin\AuthenticationType;

use Drupal\miniorange_2fa\Plugin\AuthenticationTypePluginBase;
use Drupal\miniorange_2fa\Annotation\AuthenticationType;
use Drupal\miniorange_2fa\Helper\FormHelper\MoAuthKBAFields;
use Drupal\miniorange_2fa\MoAuthConstants;
use Drupal\miniorange_2fa\MoAuthUtilities;
use Drupal\miniorange_2fa\UsersAPIHandler;
use Drupal\Core\Form\FormStateInterface;
use Drupal\user\Entity\User;

/**
 * Knowledge-Based Authentication (KBA) type plugin.
 *
 * @AuthenticationType(
 *   id = "kba",
 *   name = @Translation("Security Questions (KBA)"),
 *   code = "KBA",
 *   type = "OTHER",
 *   description = @Translation("You have to answer some knowledge-based security questions which are only known to you."),
 *   supported_devices = {"laptops", "smartphones"},
 *   challenge = true,
 *   oob = false,
 *   doc_link = "https://www.drupal.org/docs/extending-drupal/contributed-modules/contributed-modules/setup-guides-to-configure-various-2fa-mfa-tfa-methods/other-tfa-methods/setup-security-questions-kba-as-2fa-tfa-method",
 *   video_link = ""
 * )
 */
class KbaType extends AuthenticationTypePluginBase {

  /**
   * Number of KBA questions to configure.
   */
  const KBA_QUESTIONS_COUNT = 3;

  /**
   * {@inheritdoc}
   */
  public function buildConfigurationForm(array $form, FormStateInterface $form_state): array {
    $form['#title'] = $this->t('Configure Security Questions (KBA)');
    
    unset($form['#attached']['library']['miniorange_2fa/miniorange_2fa.license']);
    
    $form['#attached']['library'][] = 'miniorange_2fa/miniorange_2fa.custom_kba_validation';

    $pattern = MoAuthConstants::ALPHANUMERIC_LENGTH_PATTERN;

    $form['mo2f_kba_table'] = [
      '#type' => 'table',
      '#attributes' => ['class' => ['mo-kba-table']],
    ];

    for ($row = 0; $row < self::KBA_QUESTIONS_COUNT; $row++) {
      $question_options = MoAuthUtilities::mo_get_kba_questions($row);
      $form = MoAuthKBAFields::generateKbaFields($form, $row, $question_options, $pattern);
    }

    $form['mo2f_kba_action'] = [
      '#type' => 'actions',
    ];

    $form['mo2f_kba_action']['mo_2fa_kba_submit'] = [
      '#type' => 'submit',
      '#button_type' => 'primary',
      '#value' => $this->t('Configure KBA'),
    ];

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function validateConfigurationForm(array &$form, FormStateInterface $form_state): void {
    $values = $form_state->getValues();
  
    for ($row = 0; $row < self::KBA_QUESTIONS_COUNT; $row++) {
      $question = trim($values['mo2f_kba_table'][$row]['question'] ?? '');
      $answer = trim($values['mo2f_kba_table'][$row]['answer'] ?? '');
      
      if (empty($question)) {
        $form_state->setError($form['mo2f_kba_table'][$row]['question'], $this->t('Question @number is required.', ['@number' => $row + 1]));
      }
      
      if (empty($answer)) {
        $form_state->setError($form['mo2f_kba_table'][$row]['answer'], $this->t('Answer for question @number is required.', ['@number' => $row + 1]));
      }
      
      if ($row == 2 && !empty($answer)) {
        $pattern = MoAuthConstants::ALPHANUMERIC_LENGTH_PATTERN;
        if (!preg_match('/' . $pattern . '/', $answer)) {
          $form_state->setError($form['mo2f_kba_table'][$row]['answer'], $this->t('Answer for question @number must contain only alphanumeric characters and be at least @length characters long.', [
            '@number' => $row + 1,
            '@length' => MoAuthConstants::KBA_ANSWER_LENGTH,
          ]));
        }
      }
    }
  }

  /**
   * {@inheritdoc}
   */
  public function submitConfigurationForm(array &$form, FormStateInterface $form_state): void {
    $form_values = $form_state->getValues();
    
    if (!$this->validateUserSession()) {
      $this->handlePostAuthenticationRedirection(
        false,
        '',
        'User session validation failed.',
        $form_state
      );
      return;
    }
    
    $user = $this->getCurrentUser();
    if (!$user) {
      $this->handlePostAuthenticationRedirection(
        false,
        '',
        'User not found.',
        $form_state
      );
      return;
    }
    $session = MoAuthUtilities::getSession();
    $moMfaSession = $session->get('mo_auth');
    $user_id = $user->id();
    $user_email = $this->getUserEmail($user_id) ?: $moMfaSession['email'] ?? '';
   
    if (empty($user_email)) {
      $this->handlePostAuthenticationRedirection(
        false,
        '',
        'User email not found.',
        $form_state
      );
      return;
    }

    $questions = [];
    for ($row = 0; $row < self::KBA_QUESTIONS_COUNT; $row++) {
      $questions[$row] = [
        "question" => trim($form_values['mo2f_kba_table'][$row]['question']),
        "answer" => trim($form_values['mo2f_kba_table'][$row]['answer']),
      ];
    }

    $kba = [$questions[0], $questions[1], $questions[2]];
    
    $customer = $this->createCustomerProfile();
    $auth_api_handler = $this->createAuthApiHandler();
    $user_api_handler = new UsersAPIHandler($customer->getCustomerID(), $customer->getAPIKey());
    
    $miniorange_user = $this->createMiniorangeUser($this->getCode());
    if (!$miniorange_user) {
      $this->handlePostAuthenticationRedirection(
        false,
        '',
        'Failed to create user profile.',
        $form_state
      );
      return;
    }
    
    $response = $auth_api_handler->register($miniorange_user, $this->getCode(), null, null, $kba);
   
    if(is_object($response) && $response->status == 'FAILED'){
      $this->handlePostAuthenticationRedirection(
        false,
        '',
        $response->message ?? 'An error occurred while processing your request.',
        $form_state
      );
      return;
    }

    $result = $this->updateUserAuthenticationMethod($this->getCode(), $miniorange_user, $user_api_handler);
    
    $this->handlePostAuthenticationRedirection(
      $result['success'],
      $result['message'],
      $result['message'],
      $form_state
    );
 

  }

} 