<?php

namespace Drupal\nodehive_core\Form;

use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;

/**
 * Provides a edit form for user in space.
 */
class UserEditForm extends UserAddEditBaseForm {

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

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $form = [
      '#type' => "fieldset",
    ];

    $form[] = $this->getBaseUserForm($this->getUser());

    $form['#title'] = $this->t(
      "Edit @user",
      [
        '@user' => $this->getUser()->getAccountName(),
      ]
    );

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

    $form['cancel_account'] = [
      '#type' => 'link',
      '#title' => $this->t('Cancel account'),
      '#url' => Url::fromRoute(
        "nodehive_core.cancel_user_form",
        [
          'user' => $this->getUser()->id(),
        ]
      ),
      '#attributes' => [
        'class' => ['button', 'button--danger'],
      ],
    ];

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function validateForm(array &$form, FormStateInterface $form_state) {
    $values = $form_state->getValues();

    if ($values['password'] && $values['password'] != $values['confirm_password']) {
      $form_state->setErrorByName(
        'password',
        $this->t(
          "Passwords does not match."
        ),
      );

      return FALSE;
    }
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $values = $form_state->getValues();
    $user = $this->getUser();

    $user->setEmail($values['mail']);
    $user->setUsername($values['name']);
    $user->set('status', $values['status']);

    if ($values['password']) {
      $user->setPassword($values['password']);
    }

    $existing_roles = $user->getRoles();
    foreach ($values['roles'] as $rid => $enabled) {
      if (!$enabled) {
        foreach ($existing_roles as $key => $existing_rid) {
          if ($existing_rid == $rid) {
            unset($existing_roles[$key]);
          }
        }

        continue;
      }

      $existing_roles[] = $rid;
    }

    $user->set('roles', $existing_roles);
    $user->set('user_picture', $values['picture']);
    $user->set('timezone', $values['timezone']);
    $user->set('preferred_langcode', $values['language']);

    $user->save();

    // Set spaces.
    foreach ($values['spaces'] as $id => $is_enabled) {
      $space_entity = $this->entityTypeManager()
        ->getStorage('nodehive_space')
        ->load($id);

      if (!$space_entity || !$space_entity->editors) {
        continue;
      }

      if (!$is_enabled) {
        $saved_users_values = $space_entity->editors->getValue();
        foreach ($saved_users_values as $key => $item) {
          if ($item['target_id'] == $this->getUser()->id()) {
            unset($saved_users_values[$key]);
          }
        }

        $space_entity->editors = $saved_users_values;
        $space_entity->save();
        continue;
      }

      $saved_users_values = $space_entity->editors->getValue();
      $saved_users = [];
      foreach ($saved_users_values as $item) {
        $saved_users[$item['target_id']] = $item['target_id'];
      }

      $saved_users[$user->id()] = $user->id();

      $space_entity->editors = $saved_users;
      $space_entity->save();
    }

    $this->messenger()->addMessage(
      $this->t(
        "User @username has been updated successfully.",
        [
          '@username' => $user->getAccountName(),
        ]
      ),
    );
  }

  /**
   * Get the user entity.
   *
   * @return \Drupal\user\UserInterface
   *   User entity.
   */
  protected function getUser() {
    $user_id = $this->getRouteMatch()
      ->getParameter('user');

    if (!$user_id) {
      throw new \Exception("Missing user entity.");
    }

    return $this->entityTypeManager()
      ->getStorage('user')
      ->load($user_id);
  }

}
