<?php

namespace Drupal\component_builder_toolbar\Controller;

use Drupal\component_builder_toolbar\ToolbarManagerInterface;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\InvokeCommand;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Routing\RouteMatchInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;

/**
 * Provides a controller for toolbar.
 */
class ToolBarController extends ControllerBase {

  /**
   * The current route match.
   *
   * @var \Drupal\Core\Routing\RouteMatchInterface
   */
  protected $routeMatch;

  /**
   * The toolbar manager interface.
   *
   * @var \Drupal\component_builder_toolbar\ToolbarManagerInterface
   */
  protected $toolbarManager;

  /**
   * Constructs a new ToolBarController object.
   *
   * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
   *   The route match.
   * @param \Drupal\component_builder_toolbar\ToolbarManagerInterface $toolbar_manager
   *   The entity type manager.
   */
  public function __construct(RouteMatchInterface $route_match, ToolbarManagerInterface $toolbar_manager) {
    $this->routeMatch = $route_match;
    $this->toolbarManager = $toolbar_manager;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('current_route_match'),
      $container->get('component_builder_toolbar.manager')
    );
  }

  /**
   * Render page.
   */
  public function page(Request $request) {
    $entity_type_id = $this->routeMatch->getRouteObject()
      ->getDefault('entity_type_id');
    $entity = $this->routeMatch->getParameter($entity_type_id);
    $view_builder = $this->entityTypeManager()->getViewBuilder($entity_type_id);

    $output = $view_builder->view($entity);
    $output['#attached']['library'][] = 'component_builder_toolbar/ui.page';

    return $output;
  }

  /**
   * Move wrapper to region or change wrapper weight.
   */
  public function moveWrapper(Request $request) {
    $entity_type_id = $request->get('entity_type_id');
    $entity = $request->get($entity_type_id);
    $component_wrapper = $request->get('component_wrapper');
    $field_name = $request->get('field_name');
    $from_region = $request->get('from_region');
    $from = $request->get('from');
    $to_region = $request->get('to_region');
    $to = $request->get('to');

    $response = new AjaxResponse();
    if ($this->toolbarManager->moveWrapper($entity, $component_wrapper, $field_name, $from_region, $from, $to_region, $to)) {
      /** @var \Drupal\component_builder\Entity\ComponentWrapperInterface[] $referenced_component_wrappers */
      $referenced_component_wrappers = $entity->get($field_name)
        ->referencedEntities();
      foreach ($referenced_component_wrappers as $delta => $referenced_component_wrapper) {
        $region_weight = $delta;
        $display_in_region = $component_wrapper->get('display_in_region')->value;
        if ($display_in_region) {
          $region_weight = $component_wrapper->get('field_weight_in_region')->value;
        }
        $wrapper_selector = "[data-wrapper-id='{$referenced_component_wrapper->id()}']";
        $response->addCommand(new InvokeCommand($wrapper_selector, 'attr', [
          [
            'data-field-delta' => $delta,
            'data-region-weight' => $region_weight,
          ],
        ]));
      }
    }

    return $response;
  }

  /**
   * Check user can move wrapper.
   *
   * @return \Drupal\Core\Access\AccessResultInterface
   *   The access result.
   */
  public function checkMoveWrapperAccess() {
    return AccessResult::allowed();
  }

  /**
   * Render form to add new component to entity.
   */
  public function addNewComponent(Request $request) {
    $entity_type_id = $request->get('entity_type_id');
    /** @var \Drupal\Core\Entity\EntityInterface $entity */
    $entity = $request->get($entity_type_id);
    $field_name = $request->get('field_name');
    $is_ajax = $request->get('_drupal_ajax');

    $new_wrapper = $this->entityTypeManager()
      ->getStorage('component_wrapper')
      ->create();
    return $this->entityFormBuilder()->getForm($new_wrapper, 'toolbar-form', [
      'entity_type_id' => $entity_type_id,
      'current_entity' => $entity,
      'field_name' => $field_name,
      'toolbar_form_mode' => 'add',
      'is_ajax' => $is_ajax,
    ]);
  }

  /**
   * Edit component.
   */
  public function editComponent(Request $request) {
    $entity_type_id = $request->get('entity_type_id');
    /** @var \Drupal\Core\Entity\EntityInterface $entity */
    $entity = $request->get($entity_type_id);
    $field_name = $request->get('field_name');
    $is_ajax = $request->get('_drupal_ajax');

    $component_wrapper = $request->get('component_wrapper');
    return $this->entityFormBuilder()
      ->getForm($component_wrapper, 'toolbar-form', [
        'entity_type_id' => $entity_type_id,
        'current_entity' => $entity,
        'field_name' => $field_name,
        'toolbar_form_mode' => 'edit',
        'is_ajax' => $is_ajax,
      ]);
  }

  /**
   * Tmp.
   */
  public function tmp() {
    /** @var \Drupal\component_builder\ComponentBuilderHelperInterface $component_builder_helper */
    $component_builder_helper = \Drupal::service('component_builder.helper');
    $referenced_entities = $component_builder_helper->getFieldsReferencedComponent();
    foreach ($referenced_entities as $entity_type_id => $entity_info) {
      $entity_type = \Drupal::entityTypeManager()
        ->getDefinition($entity_type_id);
      $detail_link = $entity_type->getLinkTemplate('canonical');
    }
  }

}
