<?php

namespace Drupal\lingotek\Form;

use Drupal\Core\Routing\UrlGeneratorInterface;
use Drupal\Core\Utility\LinkGeneratorInterface;
use Drupal\lingotek\LingotekInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Form\ConfigFormBase;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Configure Lingotek
 */
abstract class LingotekConfigFormBase extends ConfigFormBase {

  /**
   * @var \Drupal\lingotek\LingotekInterface
   */
  protected $lingotek;

  /**
   * The URL generator.
   *
   * @var \Drupal\Core\Routing\UrlGeneratorInterface
   */
  protected $urlGenerator;

  /**
   * The link generator.
   *
   * @var \Drupal\Core\Utility\LinkGeneratorInterface
   */
  protected $linkGenerator;

  /**
   * Constructs a \Drupal\lingotek\Form\LingotekConfigFormBase object.
   *
   * @param \Drupal\lingotek\LingotekInterface $lingotek
   *   The lingotek service.
   * @param \Drupal\Core\Config\ConfigFactoryInterface $config
   *   The factory for configuration objects.
   * @param \Drupal\Core\Routing\UrlGeneratorInterface $url_generator
   *   The url generator.
   * @param \Drupal\Core\Utility\LinkGeneratorInterface $link_generator
   *   The link generator.
   */
  public function __construct(LingotekInterface $lingotek, ConfigFactoryInterface $config, UrlGeneratorInterface $url_generator, LinkGeneratorInterface $link_generator) {
    $typed_config_manager = \Drupal::service('config.typed');
    parent::__construct(config_factory: $config, typedConfigManager: $typed_config_manager);
    $this->lingotek = $lingotek;
    $this->urlGenerator = $url_generator;
    $this->linkGenerator = $link_generator;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('lingotek'),
      $container->get('config.factory'),
      $container->get('url_generator'),
      $container->get('link_generator')
    );
  }

  public function getEditableConfigNames() {
    return [];
  }

  /**
   * Generates and pushes Basic Auth credentials for the project callback.
   *
   * @param string $project_id
   *   The Lingotek project ID.
   * @param string $callback_url
   *   The callback URL.
   *
   * @return bool
   *   TRUE if pushing succeeded, FALSE otherwise.
   *
   * @throws \Drupal\lingotek\Exception\LingotekApiException
   */
  protected function pushProjectCallbackCredentials($project_id, $callback_url) {
    $site_uuid = $this->configFactory()->get('system.site')->get('uuid');
    if (empty($site_uuid)) {
      $site_uuid = \Drupal::service('uuid')->generate();
    }
    $username = 'drupal-' . $site_uuid;
    $password = base64_encode(random_bytes(32));

    if (!$this->lingotek->setProjectCallbackAuth($project_id, $callback_url, $username, $password)) {
      return FALSE;
    }

    $this->configFactory()->getEditable('lingotek.account')
      ->set('callback_url', $callback_url)
      ->set('notify_auth_username', $username)
      ->set('notify_auth_password_hash', password_hash($password, PASSWORD_BCRYPT))
      ->save();

    return TRUE;
  }

}
