<?php

/**
 * @file
 * Install, update and uninstall functions for the social_user module.
 */

use Drupal\Core\Entity\Entity\EntityFormDisplay;
use Drupal\user\RoleInterface;
use Symfony\Component\Yaml\Yaml;

/**
 * Implements hook_install().
 *
 * Perform actions related to the installation of social_user.
 */
function social_user_install() {
  // Grant the default permissions for this feature.
  user_role_grant_permissions(
    RoleInterface::AUTHENTICATED_ID,
    [
      'cancel account',
      'change own username',
    ]
  );
  user_role_grant_permissions(
    'verified',
    [
      'access user profiles',
    ]
  );
  user_role_grant_permissions(
    'contentmanager',
    [
      'access user profiles',
    ]
  );
  user_role_grant_permissions(
    'sitemanager',
    [
      'access user profiles',
      'view users',
      'block users',
      'administer navigation settings',
      'administer social_user settings',
      'assign contentmanager role',
      'assign sitemanager role',
      'assign verified role',
      'view blocked user',
    ]
  );
}

/**
 * Implements hook_update_last_removed().
 */
function social_user_update_last_removed() : int {
  // Removed all update hooks before 10.0.
  return 8810;
}

/**
 * Implements hook_update_dependencies().
 */
function social_user_update_dependencies(): array {
  // Run the update hook with the "Grant Profile permissions for the
  // Authenticated user role" only after an update hook "Reassign permissions
  // between roles" in social_core.
  $dependencies['social_user'][11002] = [
    'social_core' => 11002,
  ];

  // Add variationcache hook update from group as required to fix update path.
  $dependencies['social_user'][11201] = [
    'group' => 8020,
  ];

  return $dependencies;
}

/**
 * Create the default configuration for the verified immediately site setting.
 */
function social_user_update_11001(): void {
  $config = \Drupal::getContainer()->get('config.factory')->getEditable('social_user.settings');
  $config->set('verified_immediately', TRUE)->save();
}

/**
 * Grant Profile permissions for the Authenticated user role.
 */
function social_user_update_11002(): void {
  // Grant the Authenticated user new permissions.
  user_role_grant_permissions(
    RoleInterface::AUTHENTICATED_ID,
    [
      'cancel account',
      'change own username',
    ]
  );
}

/**
 * Update permissions for the sitemanager role.
 */
function social_user_update_11003(): void {
  // Grant the sitemanagers new permissions.
  user_role_grant_permissions('sitemanager', [
    'assign verified role',
  ]);
}

/**
 * Update the views filter to limit operators in admin/people.
 */
function social_user_update_11004(): string {
  /** @var \Drupal\update_helper\Updater $updateHelper */
  $updateHelper = \Drupal::service('update_helper.updater');

  // Execute configuration update definitions with logging of success.
  $updateHelper->executeUpdate('social_user', 'social_user_update_11004');

  // Output logged messages to related channel of update execution.
  return $updateHelper->logger()->output();
}

/**
 * Revoke the permission select account cancellation method .
 */
function social_user_update_11005(): void {
  user_role_revoke_permissions(RoleInterface::AUTHENTICATED_ID, [
    'select account cancellation method',
  ]);
}

/**
 * Update 'views.view.user_admin_people'.
 */
function social_user_update_11006(array &$sandbox): void {
  $config_file = \Drupal::service('extension.list.module')->getPath('social_user') . '/config/static/social_user_update_11006.yml';

  if (is_file($config_file)) {
    $settings = Yaml::parse((string) file_get_contents($config_file));
    if (is_array($settings)) {
      $config = \Drupal::configFactory()
        ->getEditable('views.view.user_admin_people');

      $config->setData($settings)->save(TRUE);
    }
  }
}

/**
 * Allow select few items in group filter on the users overview admin page.
 */
function social_user_update_11201(): string {
  /** @var \Drupal\update_helper\UpdaterInterface $update_helper */
  $update_helper = \Drupal::service('update_helper.updater');

  // Execute configuration update definitions with logging of success.
  $update_helper->executeUpdate('social_user', __FUNCTION__);

  // Output logged messages to related channel of update execution.
  return $update_helper->logger()->output();
}

/**
 * Allow to filter users by Profile tag(s).
 */
function social_user_update_11401(): string {
  /** @var \Drupal\update_helper\UpdaterInterface $update_helper */
  $update_helper = \Drupal::service('update_helper.updater');

  // Execute configuration update definitions with logging of success.
  $update_helper->executeUpdate('social_user', __FUNCTION__);

  // Output logged messages to related channel of update execution.
  return $update_helper->logger()->output();
}

/**
 * Add privacy user form group.
 */
function social_user_update_11402() : void {
  $form_mode = EntityFormDisplay::load("user.user.default");
  if ($form_mode === NULL) {
    throw new \RuntimeException("Default user form mode is missing, Drupal is not correctly installed.");
  }
  $field_groups = $form_mode->getThirdPartySettings("field_group");
  if (isset($field_groups['group_locale_settings']['weight']) && $field_groups['group_locale_settings']['weight'] === 1) {
    $field_groups['group_locale_settings']['weight'] = 10;
    $form_mode->setThirdPartySetting('field_group', 'group_locale_settings', $field_groups['group_locale_settings']);
  }
  $form_mode->setThirdPartySetting("field_group", "group_privacy", [
    "children" => [],
    "label" => "Privacy",
    "region" => "content",
    "parent_name" => "",
    "weight" => 5,
    "format_type" => "fieldset",
    "format_settings" => [
      "id" => '',
      "classes" => '',
      "description" => '',
      "required_fields" => TRUE,
      "show_empty_fields" => FALSE,
    ],
  ]);
  $form_mode->save();
}

/**
 * Update 'views.view.user_admin_people'.
 *
 * Replace the login filter to last access and change label of access field.
 */
function social_user_update_12001(array &$sandbox): void {
  $config = \Drupal::configFactory()
    ->getEditable('views.view.user_admin_people');

  $data = $config->getRawData();

  // Replace the login filter to last access.
  if (isset($data['display']['default']['display_options']['filters']['login'])) {
    $filters = $data['display']['default']['display_options']['filters'];
    $filters['login']['id'] = 'access';
    $filters['login']['field'] = 'access';
    $filters['login']['entity_field'] = 'access';

    if (isset($filters['login']['expose'])) {
      $filters['login']['expose']['operator_id'] = 'access_op';
      $filters['login']['expose']['label'] = 'Last activity';
      $filters['login']['expose']['operator'] = 'access_op';
      $filters['login']['expose']['identifier'] = 'access';
    }

    // Replace key 'login' to 'access'.
    $keys = array_keys($filters);
    $keys[array_search('login', $keys)] = 'access';
    $filters_updated = array_combine($keys, $filters);

    // Set updated filters.
    $data['display']['default']['display_options']['filters'] = $filters_updated;
  }

  // Change label of access field.
  if (isset($data['display']['default']['display_options']['fields']['access'])) {
    $data['display']['default']['display_options']['fields']['access']['label'] = 'Last activity';
  }

  $config->setData($data)->save(TRUE);
}

/**
 * Enable views_ef_fieldset module and reorganize filters in admin/people page.
 */
function social_user_update_12002(array &$sandbox): string {
  // Enable views_ef_fieldset module.
  \Drupal::service('module_installer')->install(['views_ef_fieldset'], TRUE);

  /** @var \Drupal\update_helper\UpdaterInterface $update_helper */
  $update_helper = \Drupal::service('update_helper.updater');

  // Execute configuration update definitions with logging of success.
  $update_helper->executeUpdate('social_user', __FUNCTION__);

  // Output logged messages to related channel of update execution.
  return $update_helper->logger()->output();
}

/**
 * Change search operator in views.view.user_admin_people.
 */
function social_user_update_12201(): string {
  /** @var \Drupal\update_helper\Updater $updater */
  $updater = \Drupal::service('update_helper.updater');

  // Execute configuration update definitions with logging of success.
  $updater->executeUpdate('social_user', __FUNCTION__);

  // Output logged messages to related channel of update execution.
  return $updater->logger()->output();
}

/**
 * Copy show-main-in-messages to new structure and delete old structure.
 */
function social_user_update_12301(): void {
  $system_config = \Drupal::configFactory()
    ->get('system.site');

  // Return early when this configuration is empty.
  if (empty($system_config->get('show_mail_in_messages'))) {
    return;
  }

  // Copy configuration to new structure.
  \Drupal::configFactory()
    ->getEditable('social_user.settings')
    ->set('show_mail_in_messages', (boolean) $system_config->get('show_mail_in_messages'))
    ->save();

  // Delete old structure.
  \Drupal::configFactory()
    ->getEditable('system.site')
    ->clear('show_mail_in_messages')
    ->save();
}

/**
 * Copy show-main-in-messages to new structure and delete old structure.
 */
function social_user_update_12302(): void {
  $system_config = \Drupal::configFactory()
    ->get('system.site');

  // Return early when this configuration is empty.
  if (is_null($system_config->get('show_mail_in_messages'))) {
    return;
  }

  // Copy configuration to new structure.
  \Drupal::configFactory()
    ->getEditable('social_user.settings')
    ->set('show_mail_in_messages', (boolean) $system_config->get('show_mail_in_messages'))
    ->save();

  // Delete old structure.
  \Drupal::configFactory()
    ->getEditable('system.site')
    ->clear('show_mail_in_messages')
    ->save();
}
