<?php

/**
 * @file
 * Module file for  Social Swiftmailer.
 */

use Drupal\Component\Utility\Xss;
use Drupal\Core\Url;
use Drupal\Core\Link;
use Drupal\file\Entity\File;
use Drupal\file\FileInterface;
use Drupal\social_swiftmail\Element\SocialSwiftmailTextFormat;
use Drupal\symfony_mailer\AddressInterface;
use Drupal\user\UserInterface;

/**
 * Gets a logo for emails from the theme.
 *
 * @param string $theme_id
 *   The theme id.
 */
function social_swiftmail_get_logo(string $theme_id): string {
  global $base_url;

  $email_logo = theme_get_setting('email_logo', $theme_id);

  if (!empty($email_logo[0])) {
    $file = File::load($email_logo[0]);

    if ($file instanceof FileInterface && !is_null($file->getFileUri())) {
      $file_url_generator = \Drupal::service('file_url_generator');
      $logo = $file_url_generator->generateAbsoluteString($file->getFileUri());
    }
  }

  return $logo ?? $base_url . theme_get_setting('logo.url', $theme_id);
}

/**
 * Implements hook_preprocess_HOOK().
 */
function social_swiftmail_preprocess_email(array &$variables): void {
  // Load default theme (not active).
  $theme_id = \Drupal::config('system.theme')->get('default');

  $logo = social_swiftmail_get_logo($theme_id);
  $variables['logo'] = $logo;

  // Need to check this, since otherwise site-install will fail.
  if (\Drupal::service('module_handler')->moduleExists('color')) {
    $colors = color_get_palette($theme_id);
    $variables['primary'] = $colors['brand-primary'];
    $variables['secondary'] = $colors['brand-secondary'];
    $variables['accent'] = $colors['brand-accent'];
    $variables['link'] = $colors['brand-link'];
  }

  $card_radius = Xss::filter(theme_get_setting('card_radius', $theme_id) ?? '');
  $button_radius = Xss::filter(theme_get_setting('button_radius', $theme_id) ?? '');
  $variables['border_radius'] = $card_radius;
  $variables['button_border_radius'] = $button_radius;

  // Check if custom e-mail setting for branding removal is enabled.
  $email_config = \Drupal::config('social_swiftmail.settings');

  if ($email_config->get('remove_open_social_branding') === TRUE) {
    $site_config = \Drupal::config('system.site');
    // When branding should be removed, check if the default site settings are
    // set and override variables.
    $variables['site_link'] = TRUE;
    $variables['site_name'] = $site_config->get('name');

    if ($site_config->get('slogan')) {
      $variables['site_slogan'] = $site_config->get('slogan');
    }
  }
  else {
    // Create URL with UTM tags eg. https://www.getopensocial.com/
    // ?utm_source=Distro&utm_medium=Email&utm_campaign=Footer-Link
    $options = [
      'query' => [
        'utm_source' => 'Distro',
        'utm_medium' => 'Email',
        'utm_campaign' => 'Footer-link',
      ],
      'attributes' => [
        'target' => '_blank',
      ],
    ];
    $variables['site_name'] = Link::fromTextAndUrl(t('Open Social'), Url::fromUri('https://www.getopensocial.com/', $options));
    $variables['site_slogan'] = '"' . t('Create digital spaces that empower your members to share') . '"';
    $variables['site_sub_slogan'] = Link::fromTextAndUrl(t('#MadeToShare'), Url::fromUri('https://twitter.com/search?q=%23MadeToShare%20%23opensocial'));
  }

  /** @var \Drupal\Core\Render\RendererInterface $renderer */
  $renderer = \Drupal::service('renderer');

  // Check if a custom e-mail header is set and apply the configuration
  // to the render array.
  if (($header_config = $email_config->get('template_header'))
    && (!empty($header_config['value']) && !empty($header_config['format']))) {
    $header_markup = [
      '#type' => 'processed_text',
      '#text' => $header_config['value'],
      '#format' => $header_config['format'],
    ];
    $variables['header'] = $renderer->renderRoot($header_markup);
  }

  // Check if a custom e-mail footer is set and apply the configuration
  // to the render array.
  if (($footer_config = $email_config->get('template_footer'))
    && (!empty($footer_config['value']) && !empty($footer_config['format']))) {
    $footer_markup = [
      '#type' => 'processed_text',
      '#text' => $footer_config['value'],
      '#format' => $footer_config['format'],
    ];
    $variables['footer'] = $renderer->renderRoot($footer_markup);
  }

  /** @var \Drupal\symfony_mailer\EmailInterface $email */
  $email = $variables['email'];
  $context = $email->getParam('context');

  // In our Symfony Mailer we have the EmailAdjuster reroute plugin.
  // If this is being applied to the emails we need a different way of getting
  // the email address correctly.
  if ($to = $email->getHeaders()->getHeaderBody('X-Rerouted-Original-to')) {
    $mail = $to;
  }
  else {
    $to = $email->getTo();
    $mail = isset($to[0]) ? _addresses_to_string($to)[0] : FALSE;
  }

  if ($mail && ($user = user_load_by_mail($mail)) instanceof UserInterface) {
    $display_name = $user->getDisplayName();
  }
  elseif (!empty($context['display_name'])) {
    $display_name = $context['display_name'];
  }
  else {
    return;
  }

  $variables['heading'] = t('Hi <strong>@display_name</strong>', [
    '@display_name' => $display_name,
  ], [
    'langcode' => $email->getLangcode(),
  ]);
}

/**
 * Render array of addresses as array of strings.
 *
 * @param \Drupal\symfony_mailer\AddressInterface[] $addresses
 *   An array of Address objects.
 *
 * @return array
 *   An array of strings.
 */
function _addresses_to_string(array $addresses): array {
  return array_map(function (AddressInterface $address) {
    return $address->getEmail();
  }, $addresses);
}

/**
 * Implements hook_element_info_alter().
 */
function social_swiftmail_element_info_alter(array &$info): void {
  if (isset($info['text_format'])) {
    if (!isset($info['text_format']['#process'])) {
      $info['text_format']['#process'] = [];
    }

    $info['text_format']['#process'][] = [
      SocialSwiftmailTextFormat::class,
      'process',
    ];
  }
}

/**
 * Implements hook_mailer_builder_info_alter().
 */
function social_swiftmail_mailer_builder_info_alter(array &$email_builders): void {
  if (isset($email_builders['user'])) {
    $email_builders['user']['class'] = 'Drupal\social_swiftmail\Plugin\EmailBuilder\UserEmailBuilder';
  }
}
