<?php

/**
 * @file
 * The Social activity install.
 */

use Drupal\Core\Entity\Entity\EntityViewDisplay;
use Drupal\Core\Entity\Entity\EntityViewMode;
use Drupal\Core\Config\FileStorage;
use Drupal\menu_link_content\Entity\MenuLinkContent;
use Drupal\message\Entity\MessageTemplate;
use Symfony\Component\Yaml\Yaml;

/**
 * Social activity install function.
 */
function social_activity_install() {
  // Add menu item.
  $parents = \Drupal::entityTypeManager()->getStorage('menu_link_content')
    ->loadByProperties(['menu_name' => 'main', 'title' => 'Explore', 'expanded' => TRUE]);
  $parent = reset($parents);
  if ($parent !== FALSE) {
    MenuLinkContent::create([
      'title' => t('Community'),
      'link' => ['uri' => 'internal:/explore'],
      'menu_name' => 'main',
      'expanded' => FALSE,
      'weight' => 10,
      'parent' => 'menu_link_content:' . $parent->uuid(),
    ])->save();
  }
}

/**
 * Update all existing Message Templates to work with newest Message version.
 */
function social_activity_update_8002() {
  $templates = MessageTemplate::loadMultiple();

  if (!empty($templates)) {
    foreach ($templates as $name => $template) {
      $new_text = [];

      // Check if text is in the wrong format.
      if (!empty($text_array = $template->get('text'))) {

        foreach ($text_array as $text) {
          if (is_string($text)) {
            $new_text[] = [
              'format' => 'full_html',
              'value' => $text,
            ];
          }
        }

        // If all text was ok this would be empty,
        // no need to update in that case.
        if (!empty($new_text)) {
          $templates[$name]->set('text', $new_text);
          $templates[$name]->save();

          $config_name = "message.template.{$template->getConfigTarget()}";
          $config = \Drupal::service('config.factory')
            ->getEditable($config_name);

          if (!$config->isNew()) {
            $config->set('text', $new_text);
            $config->save();
          }
        }
      }
    }
  }
}

/**
 * Update Dynamic Entity Reference.
 *
 * Related configs to work with latest version of DER.
 */
function social_activity_update_8003() {
  $config = \Drupal::service('config.factory')
    ->getEditable('core.entity_view_display.activity.activity.default');

  // Only update if config exists and this is not a fresh install.
  if (!$config->isNew() && !empty($settings = $config->get('content.field_activity_entity.settings'))) {
    if (!empty($settings['view_mode'])) {
      $config->clear('content.field_activity_entity.settings');

      $config->set('content.field_activity_entity.settings', social_activity_get_der_settings());
      $config->save();
    }
  }
}

/**
 * Get entity view mode settings for Dynamic Entity Reference update.
 *
 * @return array
 *   View mode settings, keyed by entity machine name.
 */
function social_activity_get_der_settings() {
  $result = [];

  $settings = [
    'activity' => [
      'comment',
      'node',
      'post',
    ],
    'stream' => [
      'group',
    ],
    'default' => [
      'crop',
      'event_enrollment',
      'flagging',
      'message',
      'search_api_task',
      'activity',
      'block_content',
      'menu_link_content',
      'file',
      'group_content',
      'profile',
      'taxonomy_term',
      'user',
    ],
  ];

  foreach ($settings as $view_mode => $entities) {
    foreach ($entities as $entity) {
      $result[$entity]['view_mode'] = $view_mode;
    }
  }

  return $result;
}

/**
 * Update activity stream block descriptions.
 */
function social_activity_update_8801() {
  $config_factory = \Drupal::configFactory();
  // Load the activity stream.
  $view = $config_factory->getEditable('views.view.activity_stream');
  $displays = $view->get('display');

  // Update block_descriptions for the stream blocks.
  foreach ($displays as $display_name => &$display) {
    if ($display_name === 'block_stream_homepage') {
      $display['display_options']['block_description'] = t('Activity stream');
    }
    if ($display_name === 'block_stream_homepage_without_post') {
      $display['display_options']['block_description'] = t('Activity stream - Without Post block');
    }
  }

  $view->set('display', $displays);
  $view->save(TRUE);
}

/**
 * Create "Featured" view mode/display for activity.
 */
function social_activity_update_8802() {
  // Create a new activity featured entity view mode.
  EntityViewMode::create([
    'targetEntityType' => 'activity',
    'id' => 'activity.featured',
    'status' => TRUE,
    'label' => t('Featured'),
  ])->save();

  // Create the corresponding entity view display for activity entity type.
  $display = EntityViewDisplay::load('activity.activity.default')->toArray();
  $display['content']['field_activity_entity']['settings']['node'] = [
    'view_mode' => 'featured',
  ];
  $display = array_merge($display, [
    'uuid' => NULL,
    'targetEntityType' => 'activity',
    'bundle' => 'activity',
    'mode' => 'featured',
  ]);
  EntityViewDisplay::create($display)->save();
}

/**
 * Create "Featured" view mode/display for post.
 */
function social_activity_update_8803() {
  // The body of hook_update has been moved to into social_post module.
}

/**
 * Add "Explore Stream" views block.
 */
function social_activity_update_8804() {
  /** @var \Drupal\update_helper\Updater $updateHelper */
  $updateHelper = \Drupal::service('update_helper.updater');

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

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

/**
 * Update display_title for activity stream blocks.
 */
function social_activity_update_8805() {
  /** @var \Drupal\update_helper\Updater $updateHelper */
  $updateHelper = \Drupal::service('update_helper.updater');

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

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

/**
 * Added new filter for activity_stream view's explore displays.
 */
function social_activity_update_8806() {
  /** @var \Drupal\update_helper\Updater $updateHelper */
  $updateHelper = \Drupal::service('update_helper.updater');

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

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

/**
 * Add filter for notifications.
 */
function social_activity_update_8807() {
  /** @var \Drupal\update_helper\Updater $updateHelper */
  $updateHelper = \Drupal::service('update_helper.updater');

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

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

/**
 * Resolve missing filter on Activity Stream view.
 */
function social_activity_update_10301() {
  // Set the key for the filter to remove from all displays.
  $filter_to_remove = 'activity_filter_nodes_from_my_groups_filter';

  $config_factory = \Drupal::configFactory();
  // Load the activity stream.
  $view = $config_factory->getEditable('views.view.activity_stream');
  // Get the displays.
  $displays = $view->get('display');

  // Remove the filter from any displays where it is used.
  $updated = [];
  if (is_array($displays)) {
    foreach ($displays as $display_name => &$display) {
      // Remove the redundant filter.
      if (isset($display['display_options']['filters'][$filter_to_remove])) {
        unset($display['display_options']['filters'][$filter_to_remove]);
        $updated[] = $display_name;
      }
    }
  }

  // Save and log if we changed a display.
  if (count($updated)) {
    $view->set('display', $displays);
    $view->save(TRUE);
    // Log the updates.
    foreach ($updated as $display_name) {
      \Drupal::logger('system')->info('Filter removed from display: %name', ['%name' => $display_name]);
    }
  }
}

/**
 * Update message templates.
 */
function social_activity_update_10302() {
  // Install new configs.
  $config_files = [
    'message.template.create_event_gc' => 'message.template.create_event_gc_10302',
    'message.template.create_topic_gc' => 'message.template.create_topic_gc_10302',
  ];

  $config_storage = \Drupal::service('config.storage');
  $config_path = \Drupal::service('extension.list.module')->getPath('social_activity') . '/config/static/';
  $source = new FileStorage($config_path);
  foreach ($config_files as $origin_name => $update_name) {
    // Add new message templates.
    $config_storage->write($origin_name, $source->read($update_name));
  }

  /** @var \Drupal\update_helper\Updater $updateHelper */
  $updateHelper = \Drupal::service('update_helper.updater');
  $updateHelper->executeUpdate('social_activity', 'social_activity_update_10302');
  return $updateHelper->logger()->output();
}

/**
 * Update the listed below message template files as per new email style.
 *
 * 1. message.template.create_comment_author_node_post
 * 2. message.template.create_comment_post_profile
 * 3. message.template.create_comment_reply
 * 4. message.template.create_content_in_joined_group
 * 5. message.template.create_post_profile
 * 6. message.template.event_request_approved
 * 7. message.template.request_event_enrollment.
 *
 * Added new 'preview' and 'cta_button' tokens to these templates.
 */
function social_activity_update_10303() {
  // Prepare the path.
  $path = \Drupal::service('extension.list.module')->getPath('social_activity') . '/config/static/';

  $message_templates = [
    'message.template.create_comment_author_node_post' => $path . 'message.template.create_comment_author_node_post_10303.yml',
    'message.template.create_comment_post_profile' => $path . 'message.template.create_comment_post_profile_10303.yml',
    'message.template.create_comment_reply' => $path . 'message.template.create_comment_reply_10303.yml',
    'message.template.create_content_in_joined_group' => $path . 'message.template.create_content_in_joined_group_10303.yml',
    'message.template.create_post_profile' => $path . 'message.template.create_post_profile_10303.yml',
    'message.template.event_request_approved' => $path . 'message.template.event_request_approved_10303.yml',
    'message.template.join_to_group' => $path . 'message.template.join_to_group_10303.yml',
    'message.template.request_event_enrollment' => $path . 'message.template.request_event_enrollment_10303.yml',
  ];

  // Retrieves the configuration factory.
  $config_factory = \Drupal::configFactory();

  // Update each template file.
  foreach ($message_templates as $key => $config_file) {
    if (is_file($config_file)) {
      $settings = Yaml::parse(file_get_contents($config_file));
      if (is_array($settings)) {
        $config = $config_factory->getEditable($key);
        $config->setData($settings)->save(TRUE);
      }
    }
  }
}

/**
 * Updating  configuration keys as per underlying schema.
 */
function social_activity_update_11001() : string {
  /** @var \Drupal\update_helper\Updater $updater */
  $updater = \Drupal::service('update_helper.updater');

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

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

/**
 * Update exposed filter button name.
 */
function social_activity_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_activity', __FUNCTION__);

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

/**
 * Fix duplicated names of "Activity Stream: Homepage stream block".
 */
function social_activity_update_11701(): string {
  /** @var \Drupal\update_helper\Updater $updateHelper */
  $updateHelper = \Drupal::service('update_helper.updater');

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

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