<?php

namespace Drupal\nodehive_api_key_management\Form;

use Drupal\Core\Url;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\TempStore\PrivateTempStoreFactory;
use Drupal\nodehive_api_key_management\Service\ApiKeyManager;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Form for adding a new API key.
 */
class ApiKeyAddForm extends FormBase {

  /**
   * The API key manager service.
   *
   * @var \Drupal\nodehive_api_key_management\Service\ApiKeyManager
   */
  protected $apiKeyManager;

  /**
   * The private temp store factory.
   *
   * @var \Drupal\Core\TempStore\PrivateTempStoreFactory
   */
  protected $privateTempStoreFactory;

  /**
   * Constructs an ApiKeyAddForm object.
   */
  public function __construct(ApiKeyManager $api_key_manager, PrivateTempStoreFactory $private_temp_store_factory) {
    $this->apiKeyManager = $api_key_manager;
    $this->privateTempStoreFactory = $private_temp_store_factory;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('nodehive_api_key_management.api_key_manager'),
      $container->get('tempstore.private')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'nodehive_api_key_add_form';
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $form['name'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Key Name'),
      '#description' => $this->t('A human-readable name to identify this API key.'),
      '#required' => TRUE,
    ];

    $form['uid'] = [
      '#type' => 'entity_autocomplete',
      '#target_type' => 'user',
      '#title' => $this->t('User'),
      '#description' => $this->t('The user account this API key will authenticate as. The key will have all permissions assigned to this user.'),
      '#required' => TRUE,
    ];

    $form['rate_limit'] = [
      '#type' => 'number',
      '#title' => $this->t('Rate Limit'),
      '#description' => $this->t('Maximum requests per hour. Use 0 for unlimited.'),
      '#default_value' => 0,
      '#min' => 0,
      '#required' => TRUE,
    ];

    $form['expiry'] = [
      '#type' => 'datetime',
      '#title' => $this->t('Expiry Date'),
      '#description' => $this->t('When this key expires. Leave empty for no expiration.'),
    ];

    $form['ip_allowlist'] = [
      '#type' => 'textarea',
      '#title' => $this->t('IP Allowlist (JSON)'),
      '#description' => $this->t('Optional JSON array of allowed IP addresses. Leave empty to allow all IPs.'),
      '#rows' => 3,
    ];

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

    $form['actions']['submit'] = [
      '#type' => 'submit',
      '#value' => $this->t('Create API Key'),
      '#button_type' => 'primary',
    ];

    $form['actions']['cancel'] = [
      '#type' => 'link',
      '#title' => $this->t('Cancel'),
      '#url' => Url::fromRoute('nodehive_api_key_management.list'),
      '#attributes' => ['class' => ['button']],
    ];

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function validateForm(array &$form, FormStateInterface $form_state) {
    // Validate IP allowlist JSON if provided.
    $ip_allowlist = trim($form_state->getValue('ip_allowlist'));
    if (!empty($ip_allowlist)) {
      json_decode($ip_allowlist, TRUE);
      if (json_last_error() !== JSON_ERROR_NONE) {
        $form_state->setErrorByName('ip_allowlist', $this->t('Invalid JSON format for IP allowlist.'));
      }
    }
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    // Generate a new API key.
    $key = $this->apiKeyManager->generateKey();

    // Prepare options.
    $options = [
      'rate_limit' => $form_state->getValue('rate_limit'),
    ];

    // Handle expiry.
    $expiry = $form_state->getValue('expiry');
    if ($expiry) {
      $options['expiry'] = $expiry->getTimestamp();
    }

    // Handle IP allowlist.
    $ip_allowlist = trim($form_state->getValue('ip_allowlist'));
    if (!empty($ip_allowlist)) {
      $options['ip_allowlist'] = json_decode($ip_allowlist, TRUE);
    }

    // Create the key.
    $key_id = $this->apiKeyManager->createKey(
      $form_state->getValue('name'),
      $key,
      $form_state->getValue('uid'),
      $options
    );

    if ($key_id) {
      // Store the full key in user's session to display once.
      $tempstore = $this->privateTempStoreFactory->get('nodehive_api_key_management');
      $tempstore->set('new_key', $key);
      $tempstore->set('new_key_id', $key_id);

      $this->messenger()->addStatus($this->t('API key created successfully.'));
      $form_state->setRedirect('nodehive_api_key_management.list');
    }
    else {
      $this->messenger()->addError($this->t('Failed to create API key. Please try again.'));
    }
  }

}
