<?php

/**
 * @file
 */

use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Form\FormStateInterface;

/**
 * @file
 * Primary module hooks for Intercept Guest module.
 */

/**
 * Implements hook_form_BASE_FORM_ID_alter().
 *
 * @param $form
 *   Nested array of form elements that comprise the form.
 * @param \Drupal\Core\Form\FormStateInterface $form_state
 *   The current state of the form.
 * @param $form_id
 *   String representing the name of the form itself.
 */
function intercept_guest_form_room_reservation_form_alter(&$form, FormStateInterface $form_state, $form_id) {

  // Abort if user does not have permissions to register guests.
  $user = \Drupal::currentUser();
  if (!$user->hasPermission('add intercept guest entity')) {
    return;
  };

  // Abort if user cannot reserve this room.
  if (array_key_exists('user_cannot_reserve_room', $form)) {
    return;
  }

  $options = [
    'member' => t('Member'),
    'guest' => t('Guest'),
  ];

  $default = ['member'];
  $entity = $form_state->getformObject()->getEntity();
  if (isset($entity->get('field_guest')->target_id)) {
    $guest_entity = \Drupal::entityTypeManager()->getStorage('intercept_guest')->load($entity->get('field_guest')->target_id);
    if (!$guest_entity->get('field_first_name')->isEmpty()) {
      $default = ['guest'];
    }
  }

  $form['type'] = [
    '#type' => 'select',
    '#name' => 'reservation_member_guest',
    '#title' => t('Is the reservation for a member or a guest?'),
    '#options' => $options,
    '#default_value' => $default,
    '#weight' => 2,
  ];

  if ($default[0] === 'guest') {
    // Update the reservation entity's user to be the guest user.
    $config = \Drupal::config('intercept_guest.settings');
    $guest_uid = (!empty($config->get('guest_user'))) ? $config->get('guest_user') : '1';
    $guest_user = \Drupal\user\Entity\User::load($guest_uid);
    $form['field_user']['widget'][0]['target_id']['#default_value'] = $guest_user;
    $form_state->setValue('field_user', [0 => ['target_id' => $guest_uid]]);
  }

  // Use form API's #states system to hide/show make required/optional
  // field_user and field_guest.
  $form['field_user']['#states'] = [
    'invisible' => [
      'select[name="reservation_member_guest"]' => ['value' => 'guest'],
    ],
  ];
  $form['reservation_for_me']['#states'] = [
    'invisible' => [
      'select[name="reservation_member_guest"]' => ['value' => 'guest'],
    ],
  ];

  $form['field_user']['widget'][0]['target_id']['#states'] = [
    'required' => [
      '#' . $form['#id'] . ' select[name="reservation_member_guest"]' => ['value' => 'member'],
    ],
  ];

  $form['field_guest']['#states'] = [
    'invisible' => [
      'select[name="reservation_member_guest"]' => ['value' => 'member'],
    ],
    'required' => [
      'select[name="reservation_member_guest"]' => ['value' => 'guest'],
    ],
  ];

  $form['guest_information'] = [
    '#type' => 'container',
    '#weight' => 2,
    '#prefix' => '<div id="guest-information">',
    '#suffix' => '</div>',
    '#states' => [
      'visible' => [
        'select[name="reservation_member_guest"]' => ['value' => 'guest'],
      ],
    ],
  ];

  $form['guest_information']['info'] = [
    '#type' => 'item',
    '#markup' => '<h2>' . t('Guest Information') . '</h2><p>' . t('All guest fields are required. *') . '</p>',
  ];

  // Add a validate callback.
  $form['#validate'][] = 'intercept_guest_reservation_form_validate';

}

/**
 * Validation function for the room reservation form.
 *
 * @param array $form
 * @param \Drupal\Core\Form\FormStateInterface $form_state
 *
 * @return void
 */
function intercept_guest_reservation_form_validate($form, FormStateInterface &$form_state) {
  $input = $form_state->getUserInput();
  switch ($input['reservation_member_guest']) {
    case 'member':
      // If we're here because of ajax and we haven't submitted the form, return.
      if (!$form_state->isSubmitted()) {
        return;
      }
      // The form has been submitted. Make it fail validation if field_user is not
      // set.
      if (empty($input['field_user'][0]['target_id'])) {
        $form_state->setErrorByName('field_user', t('The "Reserved for" field is required for member reservations.'));
      }
      break;

    case 'guest':
      // Update the reservation entity's user to be the guest user.
      $config = \Drupal::config('intercept_guest.settings');
      $guest_uid = (!empty($config->get('guest_user'))) ? $config->get('guest_user') : '1';
      $form_state->setValue('field_user', [0 => ['target_id' => $guest_uid]]);
  }
}

/**
 * Perform alterations before an entity form is included in the IEF widget.
 *
 * @param array $entity_form
 *   Nested array of form elements that comprise the entity form.
 * @param \Drupal\Core\Form\FormStateInterface $form_state
 *   The form state of the parent form.
 */
function intercept_guest_inline_entity_form_entity_form_alter(array &$entity_form, FormStateInterface &$form_state) {
  // Only alter IEF for intercept_guest entities.
  if ($entity_form['#entity_type'] !== 'intercept_guest') {
    return;
  }

  // Hide field_room_reservations and populate it with this reservation's id.
  $entity_form['field_room_reservations']['#access'] = 'false';

  // Set owner to the current user and hide the field.
  $entity_form['user_id']['#type'] = 'hidden';
  $entity_form['user_id']['#default_value'] = \Drupal::currentUser()->id();

}

/**
 * Implements hook_ENTITY_TYPE_presave().
 *
 * @param Drupal\Core\Entity\EntityInterface $reservation
 *   The room_reservation entity.
 */
function intercept_guest_room_reservation_presave(EntityInterface $reservation) {
  if (empty($reservation->field_user->entity)) {
    // This is a guest room reservation; set field_user as the site's official
    // guest account.
    $guestUserId = 0;
    $config = \Drupal::config('intercept_guest.settings');
    if (!empty($config->get('guest_user'))) {
      $guestUserId = $config->get('guest_user');
    }

    $reservation->set('field_user', $guestUserId);
  }
}
