<?php

/**
 * @file
 * Functions to support theming content in the Toc Master theme.
 */

use Drupal\Core\Render\Markup;
use Drupal\nre_stations_entity_type\Constants as NreStationsEntityTypeConstants;

/**
 * Preprocess hook for eck_entity__link_block__$ID().
 *
 * @param array<string,mixed> $vars
 *   Variables array for the template.
 */
function toc_emr_preprocess_eck_entity__link_block__signup_link(array &$vars): void {
  $vars['block_class'] = 'bl-vh cbelianr bg-purple bl-lilfr py-lg-2 px-lg-3 mb-4 emr-lb-signup ';
  $vars['title_display'] = 'noflex';
}

/**
 * Preprocess hook for eck_entity__nres_ee_nre_station().
 *
 * @param array<string,mixed> $vars
 *   Variables array for the template.
 */
function toc_emr_preprocess_eck_entity__nres_ee_nre_station(array &$vars): void {
  $entity = $vars['eck_entity'];
  $station_crs = _tm_misc_get_field_content($entity, NreStationsEntityTypeConstants::FIELD_CRS);
  // Use the extended header version.
  $vars['header_use_extended'] = TRUE;

  // Data for extended header.
  $office = _tm_misc_get_field_content($entity, 'field_nres_eeb_par_ticket_office', 'reference');
  if ($office) {
    $times = _tm_misc_get_field_content($office, 'field_nres_eeb_par_open', 'reference');
    if ($times) {
      $data = _tm_misc_get_field_content($times, 'field_nres_eeb_par_day_and_time', 'render', [], -1);
      if ($data) {
        $vars['ticket_office'] = $data;
      }
      $annotation = _tm_misc_get_field_content($times, 'field_nres_eeb_sta_annotation', 'render');
      if ($annotation) {
        $vars['ticket_office'][] = $annotation;
      }
    }
  }
  if (!isset($vars['ticket_office'])) {
    $vars['ticket_office'] = [
      [
        '#type' => 'markup',
        '#markup' => 'None available',
      ],
    ];
  }

  $vars['post'] = $vars['elements']['post'] ?? '';

  $station_features = nre_stations_entity_type_get_station_features($station_crs);
  if ($station_features) {
    foreach ($station_features['features'] as &$feature) {
      if ($feature == 'Car park' && isset($vars['elements']['car_parks_entities'])) {
        $feature = $vars['elements']['car_parks_entities'];
      }
    }
    $vars['checklist'] = $station_features['features'];
  }
}

/**
 * Preprocess hook for node__destination().
 *
 * @todo We have bundle name class. We need to differentiate them between
 *   GA and WMR
 *
 * @param array<string,mixed> $vars
 *   Variables array for the template.
 */
function toc_emr_preprocess_node__destination(array &$vars): void {
  if (isset($vars['form'])) {
    unset($vars['form']);
  }

  $entity = $vars['node'];
  // FAQs, let's use Routes.
  $vars['faqs'] = _tm_misc_destination_attraction_faqs($entity, 'field_dest_par_faqs');
  // Default area map, no marker required.
  $leaflet_map_format = _tm_leaflet_format(12, 0, 0, ['iconType' => 'html']);
  $map = _tm_misc_get_field_content($entity, 'field_dest_ge_location', 'render', $leaflet_map_format);
  $vars['map'] = $map;
  // Stations, needed for cards and locations.
  $vars['stations'] = _tm_misc_destination_attraction_maps($entity, 'field_dest_tp_stations_crs');
  // Extra info.
  $text_format = _tm_text_format([], 0, 'input', 'full_html');
  $vars['extra'] = _tm_misc_get_field_content($entity, 'field_dest_stf_extra_content', 'render', $text_format);
  $vars['swap_sidebar_form'] = TRUE;
}

/**
 * Preprocess hook for node__dog_offer().
 *
 * @param array<string,mixed> $vars
 *   Variables array for the template.
 */
function toc_emr_preprocess_node__dog_offer(array &$vars): void {
  if (isset($vars['ticket_price']) && $vars['ticket_price'] === '£0.00') {
    $vars['ticket_price'] = '';
  }
}

/**
 * Preprocess hook for node_webform().
 *
 * @param array<string,mixed> $vars
 *   Variables array for the template.
 */
function toc_emr_preprocess_node__webform(array &$vars): void {
  $webform = $vars['content']['webform'][0]['#webform'] ?? NULL;
  if ($webform && $webform->id() === 'talk_passenger_assistance_cards') {
    $form_attributes = $webform->getSetting('form_attributes', []);
    if (!isset($form_attributes['#tabbed']) || !$form_attributes['#tabbed']) {
      return;
    }
    $tab_items = [
      [
        'tbid' => 'list_download',
        'title' => '<i class="far fa-mobile"></i> <span>I would like to download cards to print or show on my phone</span>',
        'content' => [
          '#type' => 'view',
          '#name' => 'talk_cards',
          '#display_id' => 'listing',
        ],
      ],
      [
        'tbid' => 'or',
        'title' => 'OR',
        'content' => '',
      ],
      [
        'tbid' => 'form',
        'title' => '<i class="far fa-envelope"></i> <span>I would like to be sent up to 3 physical cards by post</span>',
        'content' => $vars['content']['webform'],
      ],
    ];

    $tabs = [
      '#type' => 'pattern',
      '#id' => 'bs-tabs-items',
      '#variant' => 'tbi_g',
      '#fields' => [
        'items' => $tab_items,
      ],
      '#settings' => [
        'pid' => 'talk-cards-tabs',
      ],
    ];

    $vars['content']['tabs'] = $tabs;
    unset($vars['content']['webform']);
  }
}

/**
 * Builds the fares accordion content for a station entity.
 *
 * @param mixed $entity
 *   The NRE station entity.
 *
 * @return array<string, mixed>
 *   A render array for the fares accordion table.
 *
 * @see toc_master_preprocess_eck_entity__nres_ee_nre_station()
 */
function _toc_emr_nre_station_accordion_content_fares(mixed $entity): array {
  $rows = [];
  $html = _toc_emr_render_available_facility_location($entity, NreStationsEntityTypeConstants::FIELD_FARES_TICKET_OFFICE);
  $rows = _tm_append_table_row($rows, $html, TRUE, 'Ticket office information');
  $html = _toc_emr_render_available_facility_opening_times($entity, NreStationsEntityTypeConstants::FIELD_FARES_TICKET_OFFICE);
  $rows = _tm_append_table_row($rows, $html, TRUE, 'Ticket office opening times');
  $rows = _tm_append_table_row($rows, NreStationsEntityTypeConstants::FIELD_FARES_PREPURCHASE_COLLECTION, TRUE, 'Pre-purchase collection', $entity, 'field');
  $rows = _tm_append_table_row($rows, NreStationsEntityTypeConstants::FIELD_FARES_TICKET_MACHINE, TRUE, 'Ticket machine', $entity, 'field');
  $rows = _tm_append_table_row($rows, NreStationsEntityTypeConstants::FIELD_FARES_OYSTERCARD_ISSUED, TRUE, 'Oyster cards issued here', $entity, 'field');
  $rows = _tm_append_table_row($rows, NreStationsEntityTypeConstants::FIELD_FARES_OYSTERCARD_TOPUP, TRUE, 'Top up Oyster cards here', $entity, 'field');
  $rows = _tm_append_table_row($rows, NreStationsEntityTypeConstants::FIELD_FARES_USE_OYSTERCARD, TRUE, 'Use Oyster cards here', $entity, 'field');
  $rows = _tm_append_table_row($rows, NreStationsEntityTypeConstants::FIELD_FARES_OYSTER_COMMENTS, TRUE, 'Oyster cards information', $entity, 'field');
  $rows = _tm_append_table_row($rows, NreStationsEntityTypeConstants::FIELD_FARES_SMARTCARD_ISSUED, TRUE, 'Smartcards issued here', $entity, 'field');
  $rows = _tm_append_table_row($rows, NreStationsEntityTypeConstants::FIELD_FARES_SMARTCARD_TOPUP, TRUE, 'Top up Smartcards here', $entity, 'field');
  $rows = _tm_append_table_row($rows, NreStationsEntityTypeConstants::FIELD_FARES_SMARTCARD_VALIDATOR, TRUE, 'Validate Smartcards here', $entity, 'field');
  $rows = _tm_append_table_row($rows, NreStationsEntityTypeConstants::FIELD_FARES_SMARTCARD_COMMENTS, TRUE, 'Smartcards information', $entity, 'field');
  $rows = _tm_append_table_row($rows, NreStationsEntityTypeConstants::FIELD_FARES_TRAVELCARD, TRUE, 'Travel card', $entity, 'field');
  $html = _toc_emr_render_penalty_fares_train_operator($entity);
  $rows = _tm_append_table_row($rows, $html, TRUE, 'Penalty fares');
  $rows = _tm_append_table_row($rows, NreStationsEntityTypeConstants::FIELD_FARES_PENALTY_FARES_URL, TRUE, 'Penalty fares URL', $entity, 'field');
  if (count($rows)) {
    return [
      '#type' => 'table',
      '#header' => [],
      '#rows' => $rows,
    ];
  }
  return [];
}

/**
 * Builds the passenger services accordion content for a station entity.
 *
 * @param mixed $entity
 *   The NRE station entity.
 *
 * @return array<string, mixed>
 *   A render array for the passenger services accordion table.
 */
function _toc_emr_nre_station_accordion_content_passenger_services(mixed $entity): array {
  $rows = [];
  $rows = _tm_append_table_row($rows, NreStationsEntityTypeConstants::FIELD_PASSENGER_SERVICES_CUSTOMER_SERVICE, TRUE, 'Customer service information', $entity, 'field');
  $rows = _tm_append_table_row($rows, NreStationsEntityTypeConstants::FIELD_PASSENGER_SERVICES_TELE_SALES, TRUE, 'Tele sales', $entity, 'field');
  $html = _toc_emr_render_service_available($entity, NreStationsEntityTypeConstants::FIELD_PASSENGER_SERVICES_LEFT_LUGGAGE);
  $rows = _tm_append_table_row($rows, $html, TRUE, 'Left luggage');
  $html = _toc_emr_render_service_contact_details($entity, NreStationsEntityTypeConstants::FIELD_PASSENGER_SERVICES_LEFT_LUGGAGE);
  $rows = _tm_append_table_row($rows, $html, TRUE, 'Left luggage contact details');
  $html = _toc_emr_render_service_opening_times($entity, NreStationsEntityTypeConstants::FIELD_PASSENGER_SERVICES_LOST_PROPERTY);
  $rows = _tm_append_table_row($rows, $html, TRUE, 'Lost property opening times');
  $html = _toc_emr_render_service_contact_details($entity, NreStationsEntityTypeConstants::FIELD_PASSENGER_SERVICES_LOST_PROPERTY);
  $rows = _tm_append_table_row($rows, $html, TRUE, 'Lost property contact details');
  if (count($rows)) {
    return [
      '#type' => 'table',
      '#header' => [],
      '#rows' => $rows,
    ];
  }
  return [];
}

/**
 * Builds the station facilities accordion content for a station entity.
 *
 * @param mixed $entity
 *   The NRE station entity.
 *
 * @return array<string, mixed>
 *   A render array for the station facilities accordion table.
 */
function _toc_emr_nre_station_accordion_content_station_facilities(mixed $entity): array {
  $rows = [];
  $html = _toc_emr_render_available_facility_opening_times($entity, NreStationsEntityTypeConstants::FIELD_STATION_FACILITIES_FIRST_CLASS_LOUNGE);
  $rows = _tm_append_table_row($rows, $html, TRUE, 'First class lounge opening times');
  $html = _toc_emr_render_available_facility_annotation($entity, NreStationsEntityTypeConstants::FIELD_STATION_FACILITIES_FIRST_CLASS_LOUNGE);
  $rows = _tm_append_table_row($rows, $html, TRUE, 'First class lounge information');
  $rows = _tm_append_table_row($rows, NreStationsEntityTypeConstants::FIELD_STATION_FACILITIES_SEATED_AREA, TRUE, 'Seated area available', $entity, 'field');
  $html = _toc_emr_render_available_facility_opening_times($entity, NreStationsEntityTypeConstants::FIELD_STATION_FACILITIES_WAITING_ROOM);
  $rows = _tm_append_table_row($rows, $html, TRUE, 'Waiting room opening times');
  $html = _toc_emr_render_available_facility_location($entity, NreStationsEntityTypeConstants::FIELD_STATION_FACILITIES_WAITING_ROOM);
  $rows = _tm_append_table_row($rows, $html, TRUE, 'Waiting room information');
  $rows = _tm_append_table_row($rows, NreStationsEntityTypeConstants::FIELD_STATION_FACILITIES_TROLLEYS, TRUE, 'Trolleys available', $entity, 'field');
  $html = _toc_emr_render_available_facility_available($entity, NreStationsEntityTypeConstants::FIELD_STATION_FACILITIES_STATION_BUFFET);
  $rows = _tm_append_table_row($rows, $html, TRUE, 'Station buffet available');
  $html = _toc_emr_render_available_facility_annotation($entity, NreStationsEntityTypeConstants::FIELD_STATION_FACILITIES_STATION_BUFFET);
  $rows = _tm_append_table_row($rows, $html, TRUE, 'Station buffet information');
  $html = _toc_emr_render_available_facility_available($entity, NreStationsEntityTypeConstants::FIELD_STATION_FACILITIES_TOILETS);
  $rows = _tm_append_table_row($rows, $html, TRUE, 'Toilets available');
  $html = _toc_emr_render_available_facility_location($entity, NreStationsEntityTypeConstants::FIELD_STATION_FACILITIES_TOILETS);
  $rows = _tm_append_table_row($rows, $html, TRUE, 'Toilets information');
  $html = _toc_emr_render_available_facility_available($entity, NreStationsEntityTypeConstants::FIELD_STATION_FACILITIES_BABY_CHANGE);
  $rows = _tm_append_table_row($rows, $html, TRUE, 'Baby changing facilities available');
  $html = _toc_emr_render_available_facility_location($entity, NreStationsEntityTypeConstants::FIELD_STATION_FACILITIES_BABY_CHANGE);
  $rows = _tm_append_table_row($rows, $html, TRUE, 'Baby changing facilities information');
  $html = _toc_emr_render_available_facility_available($entity, NreStationsEntityTypeConstants::FIELD_STATION_FACILITIES_SHOWERS, TRUE);
  $rows = _tm_append_table_row($rows, $html, TRUE, 'Showers');
  $rows = _tm_append_table_row($rows, NreStationsEntityTypeConstants::FIELD_STATION_FACILITIES_TELEPHONES_EXIST, TRUE, 'Telephones available', $entity, 'field');
  $html = _toc_emr_render_available_facility_available($entity, NreStationsEntityTypeConstants::FIELD_STATION_FACILITIES_WIFI);
  $rows = _tm_append_table_row($rows, $html, TRUE, 'Wifi available');
  $html = _toc_emr_render_available_facility_annotation($entity, NreStationsEntityTypeConstants::FIELD_STATION_FACILITIES_WIFI);
  $rows = _tm_append_table_row($rows, $html, TRUE, 'Wifi information');
  $html = _toc_emr_render_available_facility_available($entity, NreStationsEntityTypeConstants::FIELD_STATION_FACILITIES_WEB_KIOSK);
  $rows = _tm_append_table_row($rows, $html, TRUE, 'Web kiosk available');
  $html = _toc_emr_render_available_facility_location($entity, NreStationsEntityTypeConstants::FIELD_STATION_FACILITIES_WEB_KIOSK);
  $rows = _tm_append_table_row($rows, $html, TRUE, 'Web kiosk information');
  $html = _toc_emr_render_available_facility_available($entity, NreStationsEntityTypeConstants::FIELD_STATION_FACILITIES_POST_BOX);
  $rows = _tm_append_table_row($rows, $html, TRUE, 'Post box available');
  $html = _toc_emr_render_available_facility_location($entity, NreStationsEntityTypeConstants::FIELD_STATION_FACILITIES_POST_BOX);
  $rows = _tm_append_table_row($rows, $html, TRUE, 'Post box information');
  $html = _toc_emr_render_available_facility_available($entity, NreStationsEntityTypeConstants::FIELD_STATION_FACILITIES_TOURIST_INFORMATION);
  $rows = _tm_append_table_row($rows, $html, TRUE, 'Tourist information available');
  $html = _toc_emr_render_available_facility_location($entity, NreStationsEntityTypeConstants::FIELD_STATION_FACILITIES_TOURIST_INFORMATION);
  $rows = _tm_append_table_row($rows, $html, TRUE, 'Tourist information information');
  $html = _toc_emr_render_available_facility_available($entity, NreStationsEntityTypeConstants::FIELD_STATION_FACILITIES_ATM_MACHINE);
  $rows = _tm_append_table_row($rows, $html, TRUE, 'ATM available');
  $html = _toc_emr_render_available_facility_location($entity, NreStationsEntityTypeConstants::FIELD_STATION_FACILITIES_ATM_MACHINE);
  $rows = _tm_append_table_row($rows, $html, TRUE, 'ATM information');
  $html = _toc_emr_render_available_facility_available($entity, NreStationsEntityTypeConstants::FIELD_STATION_FACILITIES_BUREAU_DE_CHANGE, TRUE);
  $rows = _tm_append_table_row($rows, $html, TRUE, 'Bureau de change available');
  $html = _toc_emr_render_available_facility_location($entity, NreStationsEntityTypeConstants::FIELD_STATION_FACILITIES_BUREAU_DE_CHANGE);
  $rows = _tm_append_table_row($rows, $html, TRUE, 'Bureau de change information');
  $html = _toc_emr_render_available_facility_available($entity, NreStationsEntityTypeConstants::FIELD_STATION_FACILITIES_SHOPS);
  $rows = _tm_append_table_row($rows, $html, TRUE, 'Shops available');
  $html = _toc_emr_render_available_facility_annotation($entity, NreStationsEntityTypeConstants::FIELD_STATION_FACILITIES_SHOPS);
  $rows = _tm_append_table_row($rows, $html, TRUE, 'Shops information');
  if (count($rows)) {
    return [
      '#type' => 'table',
      '#header' => [],
      '#rows' => $rows,
    ];
  }
  return [];
}

/**
 * Builds the accessibility accordion content for a station entity.
 *
 * @param mixed $entity
 *   The NRE station entity.
 *
 * @return array<string, mixed>
 *   A render array for the accessibility accordion table.
 */
function _toc_emr_nre_station_accordion_content_accessibility(mixed $entity): array {
  $rows = [];
  $html = _toc_emr_render_service_annotation($entity, NreStationsEntityTypeConstants::FIELD_ACCESSIBILITY_HELPLINE);
  $rows = _tm_append_table_row($rows, $html, TRUE, 'Helpline information');
  $html = _toc_emr_render_service_contact_details($entity, NreStationsEntityTypeConstants::FIELD_ACCESSIBILITY_HELPLINE);
  $rows = _tm_append_table_row($rows, $html, TRUE, 'Helpline contact details');
  $html = _toc_emr_render_available_facility_annotation($entity, NreStationsEntityTypeConstants::FIELD_ACCESSIBILITY_STAFF_HELP_AVAILABLE);
  $rows = _tm_append_table_row($rows, $html, TRUE, 'Staff help information');
  $html = _toc_emr_render_available_facility_opening_times($entity, NreStationsEntityTypeConstants::FIELD_ACCESSIBILITY_STAFF_HELP_AVAILABLE);
  $rows = _tm_append_table_row($rows, $html, TRUE, 'Staff help opening times');
  $rows = _tm_append_table_row($rows, NreStationsEntityTypeConstants::FIELD_ACCESSIBILITY_INDUCTION_LOOP, TRUE, 'Induction loop available', $entity, 'field');
  $html = _toc_emr_render_available_facility_available($entity, NreStationsEntityTypeConstants::FIELD_ACCESSIBILITY_ACCESSIBLE_TICKET_MACHINES);
  $rows = _tm_append_table_row($rows, $html, TRUE, 'Accessible ticket machines available');
  $html = _toc_emr_render_available_facility_annotation($entity, NreStationsEntityTypeConstants::FIELD_ACCESSIBILITY_ACCESSIBLE_TICKET_MACHINES);
  $rows = _tm_append_table_row($rows, $html, TRUE, 'Accessible ticket machines information');
  $rows = _tm_append_table_row($rows, NreStationsEntityTypeConstants::FIELD_ACCESSIBILITY_HEIGHT_ADJUSTED_TICKET_OFFICE_COUNTER, TRUE, 'Accessible booking office counter available', $entity, 'field');
  $rows = _tm_append_table_row($rows, NreStationsEntityTypeConstants::FIELD_ACCESSIBILITY_RAMP_FOR_TRAIN_ACCESS, TRUE, 'Ramp for train access available', $entity, 'field');
  $rows = _tm_append_table_row($rows, NreStationsEntityTypeConstants::FIELD_ACCESSIBILITY_ACCESSIBLE_TAXIS, TRUE, 'Accessible taxis information', $entity, 'field');
  $rows = _tm_append_table_row($rows, NreStationsEntityTypeConstants::FIELD_ACCESSIBILITY_ACCESSIBLE_PUBLIC_TELEPHONES, TRUE, 'Accessible public telephones information', $entity, 'field');
  $rows = _tm_append_table_row($rows, NreStationsEntityTypeConstants::FIELD_ACCESSIBILITY_NEAREST_STATIONS_WITH_MORE_FACILITIES_ANNOTATION, TRUE, 'Nearest station with more facilities', $entity, 'field');
  $html = _toc_emr_render_available_facility_available($entity, NreStationsEntityTypeConstants::FIELD_ACCESSIBILITY_NATIONAL_KEY_TOILETS);
  $rows = _tm_append_table_row($rows, $html, TRUE, 'National Key toilets available');
  $html = _toc_emr_render_available_facility_location($entity, NreStationsEntityTypeConstants::FIELD_ACCESSIBILITY_NATIONAL_KEY_TOILETS);
  $rows = _tm_append_table_row($rows, $html, TRUE, 'National Key toilets information');
  $html = _toc_emr_render_step_free_access($entity);
  $rows = _tm_append_table_row($rows, $html, TRUE, 'Step free access coverage');
  $rows = _tm_append_table_row($rows, NreStationsEntityTypeConstants::FIELD_ACCESSIBILITY_STEP_FREE_ACCESS_ANNOTATION, TRUE, 'Step free access information', $entity, 'field');
  $rows = _tm_append_table_row($rows, NreStationsEntityTypeConstants::FIELD_ACCESSIBILITY_TICKET_GATES, TRUE, 'Ticket gates exist', $entity, 'field');
  $html = _toc_emr_render_available_facility_available($entity, NreStationsEntityTypeConstants::FIELD_ACCESSIBILITY_IMPAIRED_MOBILITY_SET_DOWN);
  $rows = _tm_append_table_row($rows, $html, TRUE, 'Impaired mobility set down available');
  $html = _toc_emr_render_available_facility_annotation($entity, NreStationsEntityTypeConstants::FIELD_ACCESSIBILITY_IMPAIRED_MOBILITY_SET_DOWN);
  $rows = _tm_append_table_row($rows, $html, TRUE, 'Impaired mobility set down information');
  $rows = _tm_append_table_row($rows, NreStationsEntityTypeConstants::FIELD_ACCESSIBILITY_WHEELCHAIRS_AVAILABLE, TRUE, 'Wheelchairs', $entity, 'field');
  if (count($rows)) {
    return [
      '#type' => 'table',
      '#header' => [],
      '#rows' => $rows,
    ];
  }
  return [];
}

/**
 * Builds the interchange accordion content for a station entity.
 *
 * @param mixed $entity
 *   The NRE station entity.
 *
 * @return array<string, mixed>
 *   A render array for the interchange accordion table.
 */
function _toc_nre_station_accordion_content_interchange(mixed $entity): array {
  $rows = [];

  _tm_nre_stations_accordion_content_interchange_cycle($rows, $entity, 'Cycle storage number of spaces');
  _tm_nre_stations_accordion_content_interchange_car_parks($rows, $entity);
  _tm_nre_stations_accordion_content_interchange_replacement_map($rows, $entity);

  $rows = _tm_append_table_row($rows, NreStationsEntityTypeConstants::FIELD_INTERCHANGE_TAXI_RANK, TRUE, 'Taxi rank information', $entity, 'field');
  $rows = _tm_append_table_row($rows, NreStationsEntityTypeConstants::FIELD_INTERCHANGE_ONWARD_TRAVEL, TRUE, 'Bus services information', $entity, 'field');
  $rows = _tm_append_table_row($rows, NreStationsEntityTypeConstants::FIELD_INTERCHANGE_METRO_SERVICES, TRUE, 'Metro services information', $entity, 'field');
  $rows = _tm_append_table_row($rows, NreStationsEntityTypeConstants::FIELD_INTERCHANGE_AIRPORT, TRUE, 'Airport information', $entity, 'field');
  $rows = _tm_append_table_row($rows, NreStationsEntityTypeConstants::FIELD_INTERCHANGE_PORT, TRUE, 'Port information', $entity, 'field');
  $rows = _tm_append_table_row($rows, NreStationsEntityTypeConstants::FIELD_INTERCHANGE_CAR_HIRE, TRUE, 'Car hire information', $entity, 'field');
  $rows = _tm_append_table_row($rows, NreStationsEntityTypeConstants::FIELD_INTERCHANGE_CYCLE_HIRE, TRUE, 'Cycle hire information', $entity, 'field');

  if (count($rows)) {
    return [
      '#type' => 'table',
      '#header' => [],
      '#rows' => $rows,
    ];
  }
  return [];
}

/**
 * Renders the penalty fares train operator markup for a station entity.
 *
 * @param mixed $entity
 *   The NRE station entity.
 *
 * @return \Drupal\Core\Render\Markup|string
 *   The rendered markup or an empty string.
 */
function _toc_emr_render_penalty_fares_train_operator(mixed $entity): Markup|string {
  $html = '';
  $operators = _tm_misc_get_field_content($entity, NreStationsEntityTypeConstants::FIELD_FARES_PENALTY_FARES_TRAIN_OPERATOR, 'render', [], -1);
  if ($operators) {
    $html .= 'Applicable Operators: ' . implode(', ', $operators);
  }
  if ($html) {
    $html = Markup::create($html);
  }
  return $html;
}

/**
 * Renders the available facility location markup for a station entity.
 *
 * @param mixed $entity
 *   The NRE station entity.
 * @param string $available_facility_field
 *   The field name for the available facility.
 *
 * @return \Drupal\Core\Render\Markup|string
 *   The rendered markup or an empty string.
 */
function _toc_emr_render_available_facility_location(mixed $entity, string $available_facility_field): Markup|string {
  $available_facility_paragraph = _tm_misc_get_field_content($entity, $available_facility_field, 'reference');
  if (!$available_facility_paragraph) {
    return '';
  }
  return _tm_misc_get_field_content($available_facility_paragraph, NreStationsEntityTypeConstants::PARAGRAPH_AVAILABLE_FACILITY_FIELD_LOCATION, 'render');
}

/**
 * Renders the available facility annotation markup for a station entity.
 *
 * @param mixed $entity
 *   The NRE station entity.
 * @param string $available_facility_field
 *   The field name for the available facility.
 *
 * @return \Drupal\Core\Render\Markup|string
 *   The rendered markup or an empty string.
 */
function _toc_emr_render_available_facility_annotation(mixed $entity, string $available_facility_field): Markup|string {
  $available_facility_paragraph = _tm_misc_get_field_content($entity, $available_facility_field, 'reference');
  if (!$available_facility_paragraph) {
    return '';
  }
  return _tm_misc_get_field_content($available_facility_paragraph, NreStationsEntityTypeConstants::PARAGRAPH_OPENING_HOURS_FIELD_ANNOTATION, 'render');
}

/**
 * Renders the available facility opening times markup for a station entity.
 *
 * @param mixed $entity
 *   The NRE station entity.
 * @param string $available_facility_field
 *   The field name for the available facility.
 *
 * @return \Drupal\Core\Render\Markup|string
 *   The rendered markup or an empty string.
 */
function _toc_emr_render_available_facility_opening_times(mixed $entity, string $available_facility_field): Markup|string {
  $available_facility_paragraph = _tm_misc_get_field_content($entity, $available_facility_field, 'reference');
  if ($available_facility_paragraph) {
    $opening_hours_paragraph = _tm_misc_get_field_content($available_facility_paragraph, NreStationsEntityTypeConstants::PARAGRAPH_AVAILABLE_FACILITY_FIELD_OPEN, 'reference');
    if ($opening_hours_paragraph) {
      return _toc_emr_render_opening_times($opening_hours_paragraph);
    }
  }
  return '';
}

/**
 * Renders the available facility availability for a station entity.
 *
 * @param mixed $entity
 *   The NRE station entity.
 * @param string $available_facility_field
 *   The field name for the available facility.
 * @param bool $return_unknown
 *   Whether to return 'Unknown' if the value is not set.
 *
 * @return string|false
 *   'Yes', 'No', 'Unknown', or FALSE.
 */
function _toc_emr_render_available_facility_available(mixed $entity, string $available_facility_field, bool $return_unknown = FALSE): string|false {
  $available_facility_paragraph = _tm_misc_get_field_content($entity, $available_facility_field, 'reference');
  return _toc_emr_render_available($available_facility_paragraph, NreStationsEntityTypeConstants::PARAGRAPH_AVAILABLE_FACILITY_FIELD_AVAILABLE, $return_unknown);
}

/**
 * Renders the service annotation markup for a station entity.
 *
 * @param mixed $entity
 *   The NRE station entity.
 * @param string $available_facility_field
 *   The field name for the available facility.
 *
 * @return \Drupal\Core\Render\Markup|string
 *   The rendered markup or an empty string.
 */
function _toc_emr_render_service_annotation(mixed $entity, string $available_facility_field): Markup|string {
  $available_facility_paragraph = _tm_misc_get_field_content($entity, $available_facility_field, 'reference');
  if (!$available_facility_paragraph) {
    return '';
  }
  return _tm_misc_get_field_content($available_facility_paragraph, NreStationsEntityTypeConstants::PARAGRAPH_AVAILABLE_FACILITY_FIELD_ANNOTATION, 'render');
}

/**
 * Renders the service availability for a station entity.
 *
 * @param mixed $entity
 *   The NRE station entity.
 * @param string $service_field
 *   The field name for the service.
 * @param bool $return_unknown
 *   Whether to return 'Unknown' if the value is not set.
 *
 * @return string|false
 *   'Yes', 'No', 'Unknown', or FALSE.
 */
function _toc_emr_render_service_available(mixed $entity, string $service_field, bool $return_unknown = FALSE): string|false {
  $service_paragraph = _tm_misc_get_field_content($entity, $service_field, 'reference');
  return _toc_emr_render_available($service_paragraph, NreStationsEntityTypeConstants::PARAGRAPH_SERVICE_FIELD_AVAILABLE, $return_unknown);
}

/**
 * Renders the service contact details markup for a station entity.
 *
 * @param mixed $entity
 *   The NRE station entity.
 * @param string $service_field
 *   The field name for the service.
 *
 * @return \Drupal\Core\Render\Markup|string
 *   The rendered markup or an empty string.
 */
function _toc_emr_render_service_contact_details(mixed $entity, string $service_field): Markup|string {
  $service_paragraph = _tm_misc_get_field_content($entity, $service_field, 'reference');
  if ($service_paragraph) {
    $contact_details_paragraph = _tm_misc_get_field_content($service_paragraph, NreStationsEntityTypeConstants::PARAGRAPH_SERVICE_FIELD_CONTACT_DETAILS, 'reference');
    if ($contact_details_paragraph) {
      return _toc_emr_render_contact_details($contact_details_paragraph);
    }
  }
  return '';
}

/**
 * Renders the service opening times markup for a station entity.
 *
 * @param mixed $entity
 *   The NRE station entity.
 * @param string $service_field
 *   The field name for the service.
 *
 * @return \Drupal\Core\Render\Markup|string
 *   The rendered markup or an empty string.
 */
function _toc_emr_render_service_opening_times(mixed $entity, string $service_field): Markup|string {
  $service_paragraph = _tm_misc_get_field_content($entity, $service_field, 'reference');
  if ($service_paragraph) {
    $opening_hours_paragraph = _tm_misc_get_field_content($service_paragraph, NreStationsEntityTypeConstants::PARAGRAPH_SERVICE_FIELD_OPEN, 'reference');
    if ($opening_hours_paragraph) {
      return _toc_emr_render_opening_times($opening_hours_paragraph);
    }
  }
  return '';
}

/**
 * Renders the opening times markup for a paragraph entity.
 *
 * @param mixed $opening_hours_paragraph
 *   The opening hours paragraph entity.
 *
 * @return \Drupal\Core\Render\Markup|string
 *   The rendered markup or an empty string.
 */
function _toc_emr_render_opening_times(mixed $opening_hours_paragraph): Markup|string {
  $html = '';
  $opening_times = _tm_misc_get_field_content($opening_hours_paragraph, NreStationsEntityTypeConstants::PARAGRAPH_OPENING_HOURS_FIELD_DAY_AND_TIME_AVAILABILITY, 'render', [], -1);
  if ($opening_times) {
    $html .= '<ul>';
    foreach ($opening_times as $opening_time) {
      $html .= '<li>' . $opening_time . '</li>';
    }
    $html .= '</ul>';
  }
  $annotation = _tm_misc_get_field_content($opening_hours_paragraph, NreStationsEntityTypeConstants::PARAGRAPH_OPENING_HOURS_FIELD_ANNOTATION, 'render');
  if ($annotation) {
    $html .= '<p>Note:</p>' . $annotation;
  }
  if ($html) {
    $html = Markup::create($html);
  }
  return $html;
}

/**
 * Renders the contact details markup for a contact details paragraph entity.
 *
 * @param object $contact_details_paragraph
 *   The contact details paragraph entity.
 *
 * @return \Drupal\Core\Render\Markup|string
 *   The rendered markup or an empty string.
 */
function _toc_emr_render_contact_details(object $contact_details_paragraph): Markup|string {
  $html = '';
  $annotation = _tm_misc_get_field_content($contact_details_paragraph, NreStationsEntityTypeConstants::PARAGRAPH_CONTACT_DETAILS_FIELD_ANNOTATION, 'render');
  if ($annotation) {
    $html .= '<p>Note: ' . $annotation . '</p>';
  }
  $primary_telephone = _tm_misc_get_field_content($contact_details_paragraph, NreStationsEntityTypeConstants::PARAGRAPH_CONTACT_DETAILS_FIELD_PRIMARY_TELEPHONE_NUMBER, 'render');
  if ($primary_telephone) {
    $html .= '<p>Telephone: ' . $primary_telephone . '</p>';
  }
  $alternative_telephones = _tm_misc_get_field_content($contact_details_paragraph, NreStationsEntityTypeConstants::PARAGRAPH_CONTACT_DETAILS_FIELD_ALTERNATE_PUBLIC_TELEPHONE_NUMBERS, 'render', [], -1);
  if ($alternative_telephones) {
    $html .= '<p>Alternate numbers:</p><ul>';
    foreach ($alternative_telephones as $alternative_telephone) {
      $html .= '<li>' . $alternative_telephone . '</li>';
    }
    $html .= '</ul>';
  }
  $alternative_international_telephones = _tm_misc_get_field_content($contact_details_paragraph, NreStationsEntityTypeConstants::PARAGRAPH_CONTACT_DETAILS_FIELD_ALTERNATE_INTERNAL_TELEPHONE_NUMBERS, 'render', [], -1);
  if ($alternative_international_telephones) {
    $html .= '<p>International numbers:</p><ul>';
    foreach ($alternative_international_telephones as $alternative_international_telephone) {
      $html .= '<li>' . $alternative_international_telephone . '</li>';
    }
    $html .= '</ul>';
  }
  $fax = _tm_misc_get_field_content($contact_details_paragraph, NreStationsEntityTypeConstants::PARAGRAPH_CONTACT_DETAILS_FIELD_FAX_NUMBER, 'render');
  if ($fax) {
    $html .= '<p>Fax: ' . $fax . '</p>';
  }
  $primary_minicom = _tm_misc_get_field_content($contact_details_paragraph, NreStationsEntityTypeConstants::PARAGRAPH_CONTACT_DETAILS_FIELD_PRIMARY_MINICOM_NUMBER, 'render');
  if ($primary_minicom) {
    $html .= '<p>Minicom number: ' . $primary_minicom . '</p>';
  }
  $alternate_minicom = _tm_misc_get_field_content($contact_details_paragraph, NreStationsEntityTypeConstants::PARAGRAPH_CONTACT_DETAILS_FIELD_ALTERNATE_MINICOM_NUMBER, 'render');
  if ($alternate_minicom) {
    $html .= '<p>Alternative minicom number: ' . $alternate_minicom . '</p>';
  }
  $url = _tm_misc_get_field_content($contact_details_paragraph, NreStationsEntityTypeConstants::PARAGRAPH_CONTACT_DETAILS_FIELD_URL, 'render');
  if ($url) {
    $html .= '<p>URL: ' . $url . '</p>';
  }
  if ($html) {
    $html = Markup::create($html);
  }
  return $html;
}

/**
 * Renders the availability for a given field on an entity.
 *
 * @param mixed $entity
 *   The entity or paragraph to read from.
 * @param string $available_field
 *   The field name for availability.
 * @param bool $return_unknown
 *   Whether to return 'Unknown' if the value is not set.
 *
 * @return string|false
 *   'Yes', 'No', 'Unknown', or FALSE.
 */
function _toc_emr_render_available(mixed $entity, string $available_field, bool $return_unknown): string|false {
  if ($entity) {
    $available = _tm_misc_get_field_content($entity, $available_field);
    if ($available === '1' || $available === '0') {
      return ($available === '1' ? 'Yes' : 'No');
    }
  }
  return $return_unknown ? 'Unknown' : FALSE;
}

/**
 * Renders the step free access coverage for a station entity.
 *
 * @param mixed $entity
 *   The NRE station entity.
 *
 * @return string|false
 *   The step free access coverage or FALSE if not available.
 */
function _toc_emr_render_step_free_access(mixed $entity): string|false {
  $access = _tm_misc_get_field_content($entity, NreStationsEntityTypeConstants::FIELD_ACCESSIBILITY_STEP_FREE_ACCESS_COVERAGE);

  switch ($access) {
    case 'wholeStation':
      return 'Whole station';

    case 'partialStation':
      return 'Partial station';

    case 'allPlatforms':
      return 'All platforms';

    case 'noPartOfStation':
      return 'No';

    case 'unknown':
      return 'Unknown';
  }

  return FALSE;
}
