<?php

declare(strict_types=1);

namespace Drupal\simple_interactive_maps\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
use Drupal\simple_interactive_maps\GroupTableGeneratorTrait;
use Drupal\simple_interactive_maps\InteractiveMapFormTempStoreTrait;
use Drupal\simple_interactive_maps\InteractiveMapInterface;
use Drupal\simple_interactive_maps\MapDataLoader;
use Symfony\Component\HttpKernel\Exception\HttpException;

/**
 * Provides a Simple Interactive Maps form.
 */
final class GroupManagementForm extends FormBase {

  use GroupTableGeneratorTrait, InteractiveMapFormTempStoreTrait;

  /**
   * {@inheritDoc}
   */
  public function getFormId(): string {
    return 'simple_interactive_maps_map_group';
  }

  /**
   * {@inheritDoc}
   *
   * @throws \Drupal\Core\TempStore\TempStoreException
   */
  public function buildForm(array $form, FormStateInterface $form_state, ?InteractiveMapInterface $interactive_map = NULL): array {
    if (!($interactive_map instanceof InteractiveMapInterface)) {
      throw new HttpException(404, 'Interactive map not found.');
    }

    $tempStore = $this->getMapTempStore($interactive_map);

    // Load group data from the tempstore.
    if ($tempStore->getMetadata(MapDataLoader::MAP_TEMP_STORE_GROUPS_KEY) !== NULL) {
      $groups = $tempStore->get(MapDataLoader::MAP_TEMP_STORE_GROUPS_KEY);
      if (!$interactive_map->compareGroupsData($groups)) {
        $this->messenger()->addWarning('You have unsaved changes.');
      }

    }
    else {
      // No data in tempstore, new session, init from map config.
      $groups = $interactive_map->get('groups');
      $tempStore->set(MapDataLoader::MAP_TEMP_STORE_GROUPS_KEY, $groups);
    }

    $form['map'] = [
      '#type' => 'value',
      '#value' => $interactive_map,
    ];

    $form['add_group'] = [
      '#type' => 'link',
      '#title' => $this->t('Add group'),
      '#url' => Url::fromRoute('simple_interactive_maps.map_group_add_form', ['interactive_map' => $interactive_map->id()]),
      '#attributes' => [
        'class' => [
          'button',
          'button--primary',
          'use-ajax',
        ],
        'data-dialog-type' => 'modal',
        'data-dialog-options' => json_encode([
          'width' => 1000,
          'minHeight' => 600,
        ]),
      ],
    ];

    $form['groups'] = $this->generateGroupsTable($groups, $interactive_map);

    $form['actions'] = [
      '#type' => 'actions',
      'submit' => [
        '#type' => 'submit',
        '#value' => $this->t('Save'),
      ],
    ];

    return $form;
  }

  /**
   * {@inheritDoc}
   */
  public function validateForm(array &$form, FormStateInterface $form_state): void {}

  /**
   * {@inheritDoc}
   *
   * @throws \Drupal\Core\TempStore\TempStoreException
   */
  public function submitForm(array &$form, FormStateInterface $form_state): void {
    $interactive_map = $form_state->getValue('map');
    $mapTempStore = $this->getMapTempStore($interactive_map);
    $groups = $mapTempStore->get(MapDataLoader::MAP_TEMP_STORE_GROUPS_KEY);
    $interactive_map->set('groups', $groups);
    $interactive_map->save();
    $mapTempStore->delete(MapDataLoader::MAP_TEMP_STORE_GROUPS_KEY);

    $route_name = $this->getRouteMatch()->getRouteName();
    $route_parameters = $this->getRouteMatch()->getRawParameters()->all();
    $url = Url::fromRoute($route_name, $route_parameters);
    $this->messenger()->addStatus('Group data saved.');
    $form_state->setRedirectUrl($url);
  }

}
