<?php

namespace Drupal\pagedesigner\Form;

use Drupal\Component\Render\FormattableMarkup;
use Drupal\Core\Datetime\DrupalDateTime;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface;
use Drupal\pagedesigner\Service\Locker;
use Psr\Container\ContainerInterface;

/**
 * Provides a form to list and remove locks from Pagedesigner.
 *
 * @ingroup pagedesigner
 */
class PagedesignerLockForm extends FormBase {

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

  /**
   * PagedesignerLockForm constructor.
   *
   * @param \Drupal\pagedesigner\Service\Locker $locker
   *   The locker service.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
   *   The entity type manager.
   * @param \Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface $store
   *   The expirable  storage.
   */
  public function __construct(protected Locker $locker, protected EntityTypeManagerInterface $entityTypeManager, protected KeyValueStoreExpirableInterface $store) {
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('pagedesigner.locker'),
      $container->get('entity_type.manager'),
      $container->get('keyvalue.expirable')->get('tempstore.shared.pagedesigner.lock'),
    );
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {

    // Get the list of locks from the configuration.
    $locks = $this->store->getAll();

    $form['locks'] = [
      '#type' => 'table',
      '#header' => [
        $this->t('Node'),
        $this->t('User'),
        $this->t('Last updated'),
        '',
      ],
      '#empty' => $this->t('No locks found.'),
    ];

    $node_storage = $this->entityTypeManager->getStorage('node');
    $user_storage = $this->entityTypeManager->getStorage('user');

    foreach ($locks as $key => $data) {
      // Get the lock key and metadata.
      $key_parts = explode(':', $key);

      /** @var \Drupal\node\Entity\Node $node */
      $node = $node_storage->load($key_parts[1]);
      /** @var \Drupal\user\Entity\User $user */
      $user = $user_storage->load($data->owner);

      // Add the lock information to the form.
      $form['locks'][$key]['lock_id'] = [
        '#plain_text' => new FormattableMarkup(
          ':label (ID: :id, Language: :language)',
        [
          ':label' => $node->label(),
          ':id' => $node->id(),
          ':language' => $key_parts[2],
        ]),
      ];
      $form['locks'][$key]['locked_by'] = [
        '#plain_text' => new FormattableMarkup(
          ':label (ID: :id)',
        [':label' => $user->getDisplayName(), ':id' => $user->id()]),
      ];

      $form['locks'][$key]['updated'] = [
        '#plain_text' => DrupalDateTime::createFromTimestamp($data->updated)->format('Y-m-d H:i:s'),
      ];

      // Add the remove lock button.
      $form['locks'][$key]['remove_lock'] = [
        '#type' => 'submit',
        '#value' => $this->t('Remove'),
        '#name' => 'remove_lock_' . $key,
        '#submit' => ['::removeLockSubmit'],
        '#lock_id' => $key,
      ];
    }
    if (count($locks) > 0) {
      // Add button to delete all locks.
      $form['locks']['all']['lock_id'] = ['#plain_text' => ''];
      $form['locks']['all']['locked_by'] = ['#plain_text' => ''];
      $form['locks']['all']['updated'] = ['#plain_text' => ''];
      $form['locks']['all']['remove_lock'] = [
        '#type' => 'submit',
        '#value' => $this->t('Delete all'),
        '#name' => 'remove_lock_all',
        '#submit' => ['::removeAllLocksSubmit'],
      ];
    }

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    // Handle form submission.
  }

  /**
   * Submit handler for removing a lock.
   */
  public function removeLockSubmit(array &$form, FormStateInterface $form_state) {
    $lock_id = $form_state->getTriggeringElement()['#lock_id'];
    $this->locker->forceRelease($lock_id);
    // Display a message indicating that the lock has been removed.
    $this->messenger()->addStatus($this->t('Lock removed successfully.'));
  }

  /**
   * Submit handler for removing all locks.
   */
  public function removeAllLocksSubmit(array &$form, FormStateInterface $form_state) {
    $this->store->deleteAll();
    // Display a message indicating that the locks have been removed.
    $this->messenger()->addStatus($this->t('All locks removed successfully.'));
  }

}
