<?php

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

use Drupal\user\RoleInterface;

/**
 * Implements hook_install().
 */
function social_album_install() {
  // Grant the default permissions for this feature.
  user_role_grant_permissions(
    RoleInterface::ANONYMOUS_ID,
    [
      'view node.album.field_content_visibility:public content',
    ]
  );
  user_role_grant_permissions(
    RoleInterface::AUTHENTICATED_ID,
    [
      'view node.album.field_content_visibility:public content',
    ]
  );
  user_role_grant_permissions(
    'verified',
    [
      'create album content',
      'delete own album content',
      'edit own album content',
      'override album published option',
      'view node.album.field_content_visibility:community content',
    ]
  );
  user_role_grant_permissions(
    'contentmanager',
    [
      'create album content',
      'delete own album content',
      'edit own album content',
      'override album published option',
      'view node.album.field_content_visibility:community content',
    ]
  );
  user_role_grant_permissions(
    'sitemanager',
    [
      'create album content',
      'delete own album content',
      'edit own album content',
      'override album published option',
      'view node.album.field_content_visibility:community content',
      'administer social_album settings',
    ]
  );

  _social_album_set_group_permissions();

  module_set_weight('social_album', 5);

  _social_album_blocks();
}

/**
 * Add new paths where blocks should be displayed.
 *
 * @param string $pages
 *   The current sequence of block paths.
 * @param array $paths
 *   List of blocks which should be updated and paths which should be added.
 *
 * @deprecated in social:11.4.0 and is removed from social:13.0.0. Use
 *   _social_core_blocks_paths instead.
 *
 * @see https://www.drupal.org/node/3291491
 *
 * @return string
 *   List of block paths with new paths.
 */
function _social_album_install_blocks(string $pages, array $paths) {
  return _social_core_blocks_paths($pages, $paths);
}

/**
 * Implements hook_uninstall().
 */
function social_album_uninstall() {
  _social_album_blocks('_social_core_blocks_unset_paths');
}

/**
 * Function to set group permissions.
 */
function _social_album_set_group_permissions() {
  $common_permissions = [
    'anonymous' => [
      'view group_node:album content',
      'view group_node:album entity',
    ],
    'outsider' => [
      'update own group_node:album entity',
      'view group_node:album content',
      'view group_node:album entity',
    ],
    'member' => [
      'create group_node:album entity',
      'create group_node:album content',
      'delete own group_node:album entity',
      'view group_node:album entity',
      'view group_node:album content',
    ],
    'group_manager' => [
      'delete any group_node:album entity',
    ],
    'group_admin' => [
      'update any group_node:album entity',
      'view unpublished group_node:album entity',
      'create group_node:album content',
      'delete any group_node:album content',
      'delete own group_node:album content',
      'update any group_node:album content',
      'update own group_node:album content',
    ],
    // Content manager.
    '83776d798' => [],
    // Site manager.
    'ba5854c29' => [],
    // Administrator.
    'a416e6833' => [],
  ];

  $previous = [];

  foreach ($common_permissions as &$current) {
    $current = $previous = array_merge($previous, $current);
  }

  $permissions = [
    'open_group' => [
      'outsider' => [
        'view group_node:album entity',
        'view group_node:album content',
      ],
    ],
    'public_group' => [
      'anonymous' => [
        'view group_node:album entity',
        'view group_node:album content',
      ],
    ],
  ];

  foreach ($permissions as &$type_permissions) {
    $all_type_permissions = $previous = [];

    foreach ($common_permissions as $role_id => $common_permissions_list) {
      if (isset($type_permissions[$role_id])) {
        $previous = array_merge($previous, $type_permissions[$role_id]);
      }

      $all_type_permissions[$role_id] = array_unique(array_merge($common_permissions_list, $previous));
    }

    $type_permissions = $all_type_permissions;
  }

  $type_storage = \Drupal::entityTypeManager()->getStorage('group_type');

  /** @var \Drupal\group\Entity\Storage\GroupRoleStorageInterface $role_storage */
  $role_storage = \Drupal::entityTypeManager()->getStorage('group_role');

  foreach (\Drupal::entityQuery('group_type')->execute() as $type_id) {
    /** @var \Drupal\group\Entity\GroupTypeInterface $type */
    $type = $type_storage->load($type_id);

    if (!$type->hasContentPlugin('group_node:album')) {
      continue;
    }

    foreach ($type->getRoleIds() as $type_role_id) {
      $role_id = explode('-', $type_role_id)[1];

      if (isset($common_permissions[$role_id])) {
        /** @var \Drupal\group\Entity\GroupRoleInterface $role */
        $role = $role_storage->load($type_role_id);

        $role
          ->grantPermissions($permissions[$type_id][$role_id] ?? $common_permissions[$role_id])
          ->save();
      }
    }
  }
}

/**
 * Process list of pages where chosen blocks should be shown.
 *
 * @param callable|null $function
 *   (optional) The function which updates the pages set. Defaults to NULL.
 * @param array $items
 *   (optional) Paths of blocks. Defaults to NULL.
 */
function _social_album_blocks(callable $function = NULL, array $items = [
  'socialblue_profile_hero_block' => '/user/*/albums',
  'socialblue_pagetitleblock_content' => [
    '/user/*/albums',
    '/group/*/albums',
    '/group/*/albums/add',
  ],
  'socialblue_profile_statistic_block' => '/user/*/albums',
  'socialblue_groupheroblock' => '/group/*/albums',
  'socialblue_group_statistic_block' => '/group/*/albums',
]): void {
  _social_core_install_blocks($items, $function);
}

/**
 * Set some default group permissions and check them on the group albums page.
 */
function social_album_update_8901() {
  // Set some default group permissions.
  _social_album_set_group_permissions();

  /** @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_album', 'social_album_update_8901');

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

/**
 * Delete references to not exists albums in posts.
 */
function social_album_update_8902() {
  \Drupal::database()->delete('post__field_album')
    ->condition('field_album_target_id', "0")
    ->execute();
}

/**
 * Limitate styling for modal windows only by post modal windows.
 */
function social_album_update_8903() {
  /** @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_album', 'social_album_update_8902');

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

/**
 * Delete duplicate of title from the group album creation page.
 */
function social_album_update_8904() {
  _social_core_install_blocks([
    'socialblue_pagetitleblock_content' => [
      '/group/*/albums/add',
    ],
  ]);
}

/**
 * Update album form labels.
 */
function social_album_update_10201() {
  /** @var \Drupal\update_helper\Updater $updateHelper */
  $updateHelper = \Drupal::service('update_helper.updater');

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

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

/**
 * Implements hook_update_dependencies().
 */
function social_album_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'][11001] = [
    'social_core' => 11002,
  ];

  return $dependencies;
}

/**
 * Grant Profile permissions for the Authenticated user role.
 */
function social_album_update_11001(): void {
  // Authenticated user role permissions.
  user_role_grant_permissions(
    RoleInterface::AUTHENTICATED_ID,
    [
      'view node.album.field_content_visibility:public content',
    ]
  );
}

/**
 * Update exposed filter button name.
 */
function social_album_update_11401(): string {
  /** @var \Drupal\update_helper\Updater $updateHelper */
  $updateHelper = \Drupal::service('update_helper.updater');

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

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

/**
 * Update Album permissions.
 */
function social_album_update_11402(): void {
  user_role_grant_permissions(
    RoleInterface::ANONYMOUS_ID,
    [
      'view node.album.field_content_visibility:public content',
    ]
  );

  user_role_grant_permissions(
    'verified',
    [
      'view node.album.field_content_visibility:community content',
    ]
  );
}

/**
 * Update Album permissions.
 */
function social_album_update_11403(): void {
  _social_album_set_group_permissions();
}

/**
 * Update entity_reference display, remove contextual filter.
 */
function social_album_update_11470(): string {
  /** @var \Drupal\update_helper\Updater $updateHelper */
  $updateHelper = \Drupal::service('update_helper.updater');

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

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

/**
 * Update pager.
 */
function social_album_update_11471(): string {
  /** @var \Drupal\update_helper\Updater $updateHelper */
  $updateHelper = \Drupal::service('update_helper.updater');

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

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