<?php
if (!defined('ABSPATH')) exit;

/**
 * Custom Auth Suite™ — Auth Pages Layer
 *
 * Central source of truth for CAS authentication page templates.
 *
 * Used by:
 * - frontend template resolution;
 * - block editor / classic editor template registry;
 * - Wizard / Settings page creation tools;
 * - Installation Doctor / Compatibility Layer;
 * - Support Report / Doctor Report.
 */


if (!function_exists('custausu_auth_pages_request_uri')) {
  function custausu_auth_pages_request_uri(): string {
    if (!isset($_SERVER['REQUEST_URI'])) {
      return '';
    }

    // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Request URI is read-only route context and is unslashed/sanitized immediately below.
    $value = wp_unslash($_SERVER['REQUEST_URI']);

    if (is_array($value)) {
      return '';
    }

    return sanitize_text_field((string) $value);
  }
}

if (!function_exists('custausu_auth_pages_frontend_route_lang')) {
  function custausu_auth_pages_frontend_route_lang(): string {
    $settings = get_option('custausu_global_settings', []);
    $settings = is_array($settings) ? $settings : [];

    $default = !empty($settings['routes_default_lang']) && is_scalar($settings['routes_default_lang'])
      ? sanitize_key((string) $settings['routes_default_lang'])
      : '';

    if ($default === '') {
      $locale = function_exists('determine_locale')
        ? determine_locale()
        : get_locale();
      $locale = strtolower(str_replace('_', '-', (string) $locale));
      $parts = explode('-', $locale);
      $default = sanitize_key((string) ($parts[0] ?? ''));
    }

    if (!in_array($default, ['en', 'it'], true)) {
      $default = 'en';
    }

    $allowed = [$default];

    $normalize = static function ($lang) use ($allowed): string {
      $lang = strtolower(trim((string) $lang));

      if ($lang === '') {
        return '';
      }

      $lang = str_replace('_', '-', $lang);
      $lang = sanitize_key($lang);

      if ($lang !== '' && in_array($lang, $allowed, true)) {
        return $lang;
      }

      $parts = explode('-', $lang);
      $base  = sanitize_key((string) ($parts[0] ?? ''));

      if ($base !== '' && in_array($base, $allowed, true)) {
        return $base;
      }

      return '';
    };

    $candidates = [];
    $queried_id = function_exists('get_queried_object_id') ? absint(get_queried_object_id()) : 0;

    if ($queried_id > 0) {
      $candidates[] = get_post_meta($queried_id, '_cas_auth_page_language', true);
    }

    global $post;

    if ($post instanceof WP_Post && !empty($post->ID)) {
      $candidates[] = get_post_meta((int) $post->ID, '_cas_auth_page_language', true);
    }

    $request_uri = function_exists('custausu_auth_pages_request_uri')
      ? custausu_auth_pages_request_uri()
      : '';

    if ($request_uri !== '') {
      $path = (string) wp_parse_url($request_uri, PHP_URL_PATH);
      $path = trim($path, '/');

      if ($path !== '') {
        $segments = explode('/', $path);
        $first_segment = sanitize_key((string) ($segments[0] ?? ''));

        if ($first_segment !== '') {
          $candidates[] = $first_segment;
        }
      }
    }

    $candidates[] = $default;

    foreach ($candidates as $candidate) {
      $lang = $normalize($candidate);

      if ($lang !== '') {
        return $lang;
      }
    }

    return $default;
  }
}

if (!function_exists('custausu_auth_page_definitions')) {
  function custausu_auth_page_definitions(): array {
    return [
      'login' => [
        'template'      => 'account-login.php',
        'template_file' => CUSTAUSU_PLUGIN_DIR . 'templates/account-login.php',
        'label'         => __('CAS — Account Login', 'custom-auth-suite'),
        'title'         => __('Account Login', 'custom-auth-suite'),
        'slug'          => 'account-login',
        'hide_from_auto_menus' => false,
      ],
      'register' => [
        'template'      => 'account-register.php',
        'template_file' => CUSTAUSU_PLUGIN_DIR . 'templates/account-register.php',
        'label'         => __('CAS — Account Registration', 'custom-auth-suite'),
        'title'         => __('Account Registration', 'custom-auth-suite'),
        'slug'          => 'account-register',
        'hide_from_auto_menus' => true,
      ],
      'lostpassword' => [
        'template'      => 'lost-password.php',
        'template_file' => CUSTAUSU_PLUGIN_DIR . 'templates/lost-password.php',
        'label'         => __('CAS — Lost Password', 'custom-auth-suite'),
        'title'         => __('Lost Password', 'custom-auth-suite'),
        'slug'          => 'lost-password',
        'hide_from_auto_menus' => true,
      ],
      'lostpassword_confirm' => [
        'template'      => 'lost-password-confirm.php',
        'template_file' => CUSTAUSU_PLUGIN_DIR . 'templates/lost-password-confirm.php',
        'label'         => __('CAS — Lost Password Confirm', 'custom-auth-suite'),
        'title'         => __('Lost Password Confirm', 'custom-auth-suite'),
        'slug'          => 'lost-password-confirm',
        'hide_from_auto_menus' => true,
      ],
    ];
  }
}

if (!function_exists('custausu_auth_page_route_keys')) {
  function custausu_auth_page_route_keys(): array {
    return array_keys(custausu_auth_page_definitions());
  }
}

if (!function_exists('custausu_auth_page_template_labels')) {
  function custausu_auth_page_template_labels(): array {
    $labels = [];

    foreach (custausu_auth_page_definitions() as $def) {
      $template = (string) ($def['template'] ?? '');
      $label    = (string) ($def['label'] ?? '');

      if ($template !== '' && $label !== '') {
        $labels[$template] = $label;
      }
    }

    return $labels;
  }
}

if (!function_exists('custausu_auth_page_template_paths')) {
  function custausu_auth_page_template_paths(): array {
    $paths = [];

    foreach (custausu_auth_page_definitions() as $def) {
      $template = (string) ($def['template'] ?? '');
      $file     = (string) ($def['template_file'] ?? '');

      if ($template !== '' && $file !== '') {
        $paths[$template] = $file;
      }
    }

    return $paths;
  }
}

if (!function_exists('custausu_auth_page_route_for_template')) {
  function custausu_auth_page_route_for_template(string $template): string {
    $template = trim($template);

    foreach (custausu_auth_page_definitions() as $route => $def) {
      if (($def['template'] ?? '') === $template) {
        return (string) $route;
      }
    }

    return '';
  }
}

if (!function_exists('custausu_auth_page_expected_template')) {
  function custausu_auth_page_expected_template(string $route): string {
    $defs = custausu_auth_page_definitions();
    return isset($defs[$route]['template']) ? (string) $defs[$route]['template'] : '';
  }
}

if (!function_exists('custausu_auth_page_default_title')) {
  function custausu_auth_page_default_title(string $route): string {
    $defs = custausu_auth_page_definitions();
    return isset($defs[$route]['title']) ? (string) $defs[$route]['title'] : '';
  }
}

if (!function_exists('custausu_auth_page_default_slug')) {
  function custausu_auth_page_default_slug(string $route): string {
    $defs = custausu_auth_page_definitions();
    return isset($defs[$route]['slug']) ? (string) $defs[$route]['slug'] : '';
  }
}

if (!function_exists('custausu_auth_page_template_exists')) {
  function custausu_auth_page_template_exists(string $route): bool {
    $defs = custausu_auth_page_definitions();

    if (empty($defs[$route]['template_file'])) {
      return false;
    }

    return is_file((string) $defs[$route]['template_file']);
  }
}

if (!function_exists('custausu_auth_page_templates_enable_support')) {
  function custausu_auth_page_templates_enable_support(): void {
    if (post_type_exists('page')) {
      add_post_type_support('page', 'page-attributes');
    }
  }
}

add_action('init', 'custausu_auth_page_templates_enable_support', 1);
add_action('admin_init', 'custausu_auth_page_templates_enable_support', 1);

if (!function_exists('custausu_auth_page_templates_register')) {
  function custausu_auth_page_templates_register($templates, $theme = null, $post = null, $post_type = 'page') {
    $templates = is_array($templates) ? $templates : [];

    $effective_post_type = is_string($post_type) && $post_type !== ''
      ? $post_type
      : '';

    if ($effective_post_type === '' && $post instanceof WP_Post) {
      $effective_post_type = (string) $post->post_type;
    }

    if ($effective_post_type !== '' && $effective_post_type !== 'page') {
      return $templates;
    }

    foreach (custausu_auth_page_template_labels() as $slug => $label) {
      $templates[$slug] = $label;
    }

    return $templates;
  }
}

add_filter('theme_templates', 'custausu_auth_page_templates_register', 99, 4);
add_filter('theme_page_templates', 'custausu_auth_page_templates_register', 99, 4);

if (!function_exists('custausu_auth_page_templates_editor_settings')) {
  function custausu_auth_page_templates_editor_settings(array $settings, $context): array {
    $post = null;

    if (is_object($context) && isset($context->post) && $context->post instanceof WP_Post) {
      $post = $context->post;
    }

    if (!$post instanceof WP_Post || $post->post_type !== 'page') {
      return $settings;
    }

    $available = [];

    if (isset($settings['availableTemplates']) && is_array($settings['availableTemplates'])) {
      $available = $settings['availableTemplates'];
    }

    foreach (custausu_auth_page_template_labels() as $slug => $label) {
      $available[$slug] = $label;
    }

    $settings['availableTemplates'] = $available;

    return $settings;
  }
}

add_filter('block_editor_settings_all', 'custausu_auth_page_templates_editor_settings', 99, 2);

if (!function_exists('custausu_auth_page_templates_include')) {
  function custausu_auth_page_templates_include(string $template): string {
    if (!is_singular('page')) {
      return $template;
    }

    $post_id = get_queried_object_id();

    if (!$post_id) {
      return $template;
    }

    $slug = (string) get_page_template_slug($post_id);

    if ($slug === '' || $slug === 'default') {
      return $template;
    }

    $map = custausu_auth_page_template_paths();

    if (isset($map[$slug]) && is_file($map[$slug])) {
      return $map[$slug];
    }

    return $template;
  }
}

add_filter('template_include', 'custausu_auth_page_templates_include', 50);

if (!function_exists('custausu_auth_page_assign_template')) {
  function custausu_auth_page_assign_template(int $page_id, string $route_or_template) {
    $page_id = absint($page_id);

    if ($page_id <= 0 || get_post_type($page_id) !== 'page') {
      return new WP_Error('custausu_invalid_page', __('Invalid page.', 'custom-auth-suite'));
    }

    $template = custausu_auth_page_expected_template($route_or_template);

    if ($template === '') {
      $template = trim($route_or_template);
    }

    if (!isset(custausu_auth_page_template_paths()[$template])) {
      return new WP_Error('custausu_invalid_template', __('Invalid CAS auth template.', 'custom-auth-suite'));
    }

    update_post_meta($page_id, '_wp_page_template', $template);

    $route = custausu_auth_page_route_for_template($template);
    if ($route !== '') {
      update_post_meta($page_id, '_cas_auth_page_route', $route);
      update_post_meta($page_id, '_cas_auth_page', '1');
    }

    return true;
  }
}

if (!function_exists('custausu_auth_page_status')) {
  function custausu_auth_page_status(string $route, int $page_id = 0): array {
    $defs = custausu_auth_page_definitions();
    $route = sanitize_key($route);

    $expected = isset($defs[$route]['template']) ? (string) $defs[$route]['template'] : '';
    $page_id  = absint($page_id);
    $post     = $page_id > 0 ? get_post($page_id) : null;

    $exists = ($post instanceof WP_Post && $post->post_type === 'page' && $post->post_status !== 'trash');
    $actual = $exists ? (string) get_page_template_slug($page_id) : '';

    return [
      'route'             => $route,
      'page_id'           => $exists ? $page_id : 0,
      'exists'            => $exists,
      'post_status'       => $exists ? (string) $post->post_status : '',
      'expected_template' => $expected,
      'actual_template'   => $actual,
      'template_ok'       => ($exists && $expected !== '' && $actual === $expected),
      'template_exists'   => custausu_auth_page_template_exists($route),
      'title'             => $exists ? get_the_title($page_id) : '',
      'permalink'         => $exists ? get_permalink($page_id) : '',
      'path'              => $exists ? custausu_auth_page_route_path_from_id($page_id) : '',
      'edit_url'          => $exists ? get_edit_post_link($page_id, '') : '',
    ];
  }
}

if (!function_exists('custausu_auth_page_public_route_path_from_url')) {
  /**
   * Convert a public page URL into the route path CAS stores in settings.
   *
   * The result is relative to home_url(), so WordPress installations living
   * in a subdirectory do not duplicate that base path when CAS later calls
   * home_url($path). Existing language prefixes remain part of the route.
   */
  function custausu_auth_page_public_route_path_from_url($url): string {
    $url = is_scalar($url) ? trim((string) $url) : '';

    if ($url === '') {
      return '';
    }

    $path = wp_parse_url($url, PHP_URL_PATH);

    if (!is_string($path) || $path === '') {
      return '';
    }

    $path = '/' . ltrim($path, '/');

    $home_path = wp_parse_url(home_url('/'), PHP_URL_PATH);
    $home_path = is_string($home_path)
      ? '/' . trim($home_path, '/')
      : '/';

    if ($home_path !== '/') {
      $home_prefix = rtrim($home_path, '/');

      if ($path === $home_prefix || $path === $home_prefix . '/') {
        $path = '/';
      } elseif (strpos($path, $home_prefix . '/') === 0) {
        $path = substr($path, strlen($home_prefix));
      }
    }

    $path = '/' . trim($path, '/');

    return $path === '/'
      ? '/'
      : rtrim($path, '/') . '/';
  }
}

if (!function_exists('custausu_auth_page_path_from_id')) {
  function custausu_auth_page_path_from_id(int $page_id): string {
    $page_id = absint($page_id);

    if ($page_id <= 0 || get_post_type($page_id) !== 'page') {
      return '';
    }

    $url = get_permalink($page_id);

    return function_exists('custausu_auth_page_public_route_path_from_url')
      ? custausu_auth_page_public_route_path_from_url($url)
      : '';
  }
}

if (!function_exists('custausu_auth_page_route_path_from_id')) {
  /**
   * Resolve the public route path for an Auth page.
   *
   * get_page_uri() is intentionally not used here: it returns WordPress'
   * internal page URI and can omit public language prefixes such as /it/.
   */
  function custausu_auth_page_route_path_from_id(int $page_id): string {
    $page_id = absint($page_id);

    if ($page_id <= 0 || get_post_type($page_id) !== 'page') {
      return '';
    }

    $public_path = function_exists('custausu_auth_page_path_from_id')
      ? custausu_auth_page_path_from_id($page_id)
      : '';

    if ($public_path !== '') {
      return $public_path;
    }

    /*
     * Conservative fallback for unusual permalink failures. This keeps the
     * historical single-language behavior without overriding a valid public
     * permalink when one is available.
     */
    $uri = trim((string) get_page_uri($page_id), '/');

    return $uri === ''
      ? ''
      : '/' . $uri . '/';
  }
}


if (!function_exists('custausu_auth_page_find_by_template')) {
  function custausu_auth_page_template_candidate_ids(string $route): array {
    $template = custausu_auth_page_expected_template($route);

    if ($template === '') {
      return [];
    }

    $ids = get_posts([
      'post_type'              => 'page',
      'post_status'            => ['publish', 'draft', 'private', 'pending', 'future'],
      'numberposts'            => -1,
      'fields'                 => 'ids',
      'orderby'                => 'ID',
      'order'                  => 'ASC',
      'no_found_rows'          => true,
      'update_post_meta_cache' => false,
      'update_post_term_cache' => false,
      // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key -- Auth-page discovery is limited to the internally registered CAS template slug.
      'meta_key'               => '_wp_page_template',
      // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value -- Auth-page discovery is limited to the internally registered CAS template slug.
      'meta_value'             => $template,
    ]);

    return array_values(array_filter(array_map('absint', (array) $ids)));
  }

  function custausu_auth_page_stored_language(int $page_id): string {
    if ($page_id <= 0) {
      return '';
    }

    return sanitize_key((string) get_post_meta(
      $page_id,
      '_cas_auth_page_language',
      true
    ));
  }

  function custausu_auth_page_find_by_template(string $route, string $lang = ''): int {
    $route = sanitize_key($route);
    $lang = sanitize_key($lang);
    $ids = custausu_auth_page_template_candidate_ids($route);

    if (!$ids) {
      return 0;
    }

    $settings = get_option('custausu_global_settings', []);
    $settings = is_array($settings) ? $settings : [];

    if ($lang !== '') {
      $mapped = absint($settings['routes_page_ids'][$lang][$route] ?? 0);

      if ($mapped > 0 && in_array($mapped, $ids, true)) {
        return $mapped;
      }

      $language_matches = array_values(array_filter(
        $ids,
        static fn($page_id) => (
          custausu_auth_page_stored_language((int) $page_id) === $lang
        )
      ));

      if (count($language_matches) === 1) {
        return (int) $language_matches[0];
      }
    }

    $canonical = [
      'en' => [
        'login'                => ['account-login'],
        'register'             => ['account-register'],
        'lostpassword'         => ['lost-password'],
        'lostpassword_confirm' => ['lost-password-confirm'],
      ],
      'it' => [
        'login'                => ['login-account'],
        'register'             => ['registra-account'],
        'lostpassword'         => ['recupero-password'],
        'lostpassword_confirm' => ['password-reset-confermato'],
      ],
    ];

    $preferred_slugs = $canonical[$lang][$route] ?? [];

    if ($preferred_slugs) {
      $slug_matches = array_values(array_filter(
        $ids,
        static function ($page_id) use ($preferred_slugs): bool {
          $post = get_post((int) $page_id);

          return (
            $post instanceof WP_Post &&
            in_array(
              (string) $post->post_name,
              $preferred_slugs,
              true
            )
          );
        }
      ));

      if (count($slug_matches) === 1) {
        return (int) $slug_matches[0];
      }
    }

    if (count($ids) === 1) {
      return (int) $ids[0];
    }

    return 0;
  }
}

if (!function_exists('custausu_auth_page_create_or_update')) {
  function custausu_auth_page_create_or_update(string $route, array $args = []) {
    $route = sanitize_key($route);
    $defs  = custausu_auth_page_definitions();

    if (empty($defs[$route])) {
      return new WP_Error('custausu_invalid_auth_route', __('Invalid CAS auth route.', 'custom-auth-suite'));
    }

    $page_id = isset($args['page_id']) ? absint($args['page_id']) : 0;

    if ($page_id <= 0) {
      $lang = isset($args['lang']) && is_scalar($args['lang'])
        ? sanitize_key((string) $args['lang'])
        : '';

      $page_id = custausu_auth_page_find_by_template($route, $lang);

      if (
        $page_id <= 0 &&
        custausu_auth_page_template_candidate_ids($route)
      ) {
        return new WP_Error(
          'custausu_ambiguous_auth_page',
          __('Multiple CAS Auth pages use the same template. Select the intended page explicitly.', 'custom-auth-suite')
        );
      }
    }

    $title = isset($args['title']) && is_scalar($args['title'])
      ? sanitize_text_field((string) $args['title'])
      : custausu_auth_page_default_title($route);

    $slug = isset($args['slug']) && is_scalar($args['slug'])
      ? sanitize_title((string) $args['slug'])
      : custausu_auth_page_default_slug($route);

    if ($title === '') {
      $title = ucfirst(str_replace('_', ' ', $route));
    }

    if ($slug === '') {
      $slug = sanitize_title($title);
    }

    if ($page_id > 0 && get_post_type($page_id) === 'page') {
      $updated = wp_update_post([
        'ID'         => $page_id,
        'post_title' => $title,
        'post_name'  => $slug,
      ], true);

      if (is_wp_error($updated)) {
        return $updated;
      }
    } else {
      $page_id = wp_insert_post([
        'post_type'    => 'page',
        'post_status'  => 'draft',
        'post_title'   => $title,
        'post_name'    => $slug,
        'post_content' => '',
      ], true);

      if (is_wp_error($page_id)) {
        return $page_id;
      }

      $page_id = absint($page_id);
    }

    $assigned = custausu_auth_page_assign_template($page_id, $route);

    if (is_wp_error($assigned)) {
      return $assigned;
    }

    return custausu_auth_page_status($route, $page_id);
  }
}

if (!function_exists('custausu_auth_pages_status_from_settings')) {
  function custausu_auth_pages_status_from_settings(array $settings, string $lang = ''): array {
    $lang = sanitize_key($lang);

    if ($lang === '') {
      $lang = isset($settings['default_lang']) && is_scalar($settings['default_lang'])
        ? sanitize_key((string) $settings['default_lang'])
        : 'en';
    }

    $pages = isset($settings['routes_pages'][$lang]) && is_array($settings['routes_pages'][$lang])
      ? $settings['routes_pages'][$lang]
      : [];

    $out = [];

    foreach (custausu_auth_page_route_keys() as $route) {
      $page_id = isset($pages[$route]) ? absint($pages[$route]) : 0;
      $out[$route] = custausu_auth_page_status($route, $page_id);
    }

    return $out;
  }
}


if (!function_exists('custausu_auth_page_hide_from_auto_menus')) {
  function custausu_auth_page_hide_from_auto_menus(string $route): bool {
    $defs = custausu_auth_page_definitions();
    $route = sanitize_key($route);

    return !empty($defs[$route]['hide_from_auto_menus']);
  }
}

if (!function_exists('custausu_auth_page_ids_for_auto_menu_exclusion')) {
  function custausu_auth_page_ids_for_auto_menu_exclusion(): array {
    $ids = [];

    foreach (custausu_auth_page_route_keys() as $route) {
      if (!custausu_auth_page_hide_from_auto_menus($route)) {
        continue;
      }

      $id = custausu_auth_page_find_by_template($route);
      if ($id > 0) {
        $ids[$id] = true;
      }
    }

    return array_map('absint', array_keys($ids));
  }
}

if (!function_exists('custausu_auth_pages_exclude_from_wp_list_pages')) {
  function custausu_auth_pages_exclude_from_wp_list_pages(array $exclude): array {
    foreach (custausu_auth_page_ids_for_auto_menu_exclusion() as $id) {
      $exclude[] = $id;
    }

    return array_values(array_unique(array_map('absint', $exclude)));
  }
}

/*
 * Minimal, non-invasive exclusion:
 * affects automatic wp_list_pages/page-list outputs only.
 * It does not alter manual menus and does not touch CAS menu-login.php.
 */
add_filter('wp_list_pages_excludes', 'custausu_auth_pages_exclude_from_wp_list_pages', 20);


if (!function_exists('custausu_auth_pages_exclude_from_page_list_block')) {
  function custausu_auth_pages_exclude_from_page_list_block(array $parsed_block, $source_block = null, $parent_block = null): array {
    if (($parsed_block['blockName'] ?? '') !== 'core/page-list') {
      return $parsed_block;
    }

    if (!function_exists('custausu_auth_page_ids_for_auto_menu_exclusion')) {
      return $parsed_block;
    }

    $exclude_ids = custausu_auth_page_ids_for_auto_menu_exclusion();

    if (empty($exclude_ids)) {
      return $parsed_block;
    }

    if (empty($parsed_block['attrs']) || !is_array($parsed_block['attrs'])) {
      $parsed_block['attrs'] = [];
    }

    $current = [];

    if (!empty($parsed_block['attrs']['exclude']) && is_array($parsed_block['attrs']['exclude'])) {
      $current = array_map('absint', $parsed_block['attrs']['exclude']);
    }

    // phpcs:ignore WordPressVIPMinimum.Performance.WPQueryParams.PostNotIn_exclude -- This is a core/page-list block attribute, not a post query; CAS only injects known auth page IDs to hide secondary auth pages from automatic menus.
    $parsed_block['attrs']['exclude'] = array_values(array_unique(array_merge($current, $exclude_ids)));

    return $parsed_block;
  }
}

/*
 * Block-theme support:
 * wp_navigation often contains <!-- wp:page-list /-->, which does not use
 * wp_list_pages_excludes directly. Inject the same exclusions into the block attrs.
 */
add_filter('render_block_data', 'custausu_auth_pages_exclude_from_page_list_block', 20, 3);


if (!function_exists('custausu_auth_pages_should_hide_secondary_pages_from_menus')) {
  function custausu_auth_pages_should_hide_secondary_pages_from_menus(): bool {
    return (bool) apply_filters('custausu_auth_pages_hide_secondary_auth_pages_from_menus', true);
  }
}

if (!function_exists('custausu_auth_pages_hidden_menu_page_ids')) {
  function custausu_auth_pages_hidden_menu_page_ids(): array {
    if (!custausu_auth_pages_should_hide_secondary_pages_from_menus()) {
      return [];
    }

    if (function_exists('custausu_auth_page_ids_for_auto_menu_exclusion')) {
      return custausu_auth_page_ids_for_auto_menu_exclusion();
    }

    $ids = [];

    foreach (['register', 'lostpassword', 'lostpassword_confirm'] as $route) {
      if (function_exists('custausu_auth_page_find_by_template')) {
        $id = absint(custausu_auth_page_find_by_template($route));
        if ($id > 0) {
          $ids[$id] = true;
        }
      }
    }

    return array_map('absint', array_keys($ids));
  }
}

if (!function_exists('custausu_auth_pages_exclude_from_wp_page_menu_args')) {
  function custausu_auth_pages_exclude_from_wp_page_menu_args(array $args): array {
    $ids = custausu_auth_pages_hidden_menu_page_ids();

    if (empty($ids)) {
      return $args;
    }

    $existing = [];

    if (!empty($args['exclude'])) {
      $existing = array_filter(array_map('absint', explode(',', (string) $args['exclude'])));
    }

    // phpcs:ignore WordPressVIPMinimum.Performance.WPQueryParams.PostNotIn_exclude -- wp_page_menu_args supports exclude natively; CAS only hides known secondary auth page IDs from automatic page menus.
    $args['exclude'] = implode(',', array_values(array_unique(array_merge($existing, $ids))));

    return $args;
  }
}

add_filter('wp_page_menu_args', 'custausu_auth_pages_exclude_from_wp_page_menu_args', 20);

if (!function_exists('custausu_auth_pages_exclude_from_classic_nav_menu_objects')) {
  function custausu_auth_pages_exclude_from_classic_nav_menu_objects(array $items, $args = null): array {
    $ids = custausu_auth_pages_hidden_menu_page_ids();

    if (empty($ids)) {
      return $items;
    }

    $ids = array_fill_keys(array_map('absint', $ids), true);

    return array_values(array_filter($items, static function($item) use ($ids): bool {
      $object_id = isset($item->object_id) ? absint($item->object_id) : 0;

      if ($object_id > 0 && isset($ids[$object_id])) {
        return false;
      }

      return true;
    }));
  }
}

add_filter('wp_nav_menu_objects', 'custausu_auth_pages_exclude_from_classic_nav_menu_objects', 20, 2);

if (!function_exists('custausu_auth_pages_strip_hidden_menu_links_from_html')) {
  function custausu_auth_pages_strip_hidden_menu_links_from_html(string $html): string {
    $ids = custausu_auth_pages_hidden_menu_page_ids();

    if ($html === '' || empty($ids)) {
      return wp_kses_post($html);
    }

    foreach ($ids as $id) {
      $url = get_permalink($id);

      if (!is_string($url) || $url === '') {
        continue;
      }

      $quoted = preg_quote($url, '~');

      /*
       * Remove a complete list item when the hidden auth page appears inside
       * automatic navigation/page-list markup. This is intentionally frontend-only
       * and affects only CAS secondary auth pages.
       */
      $html = preg_replace(
        '~<li\b[^>]*>\s*<a\b[^>]*href=["\']' . $quoted . '["\'][\s\S]*?</a>\s*</li>~i',
        '',
        $html
      );

      $path = wp_parse_url($url, PHP_URL_PATH);
      if (is_string($path) && $path !== '') {
        $quoted_path = preg_quote($path, '~');
        $html = preg_replace(
          '~<li\b[^>]*>\s*<a\b[^>]*href=["\']' . $quoted_path . '["\'][\s\S]*?</a>\s*</li>~i',
          '',
          $html
        );
      }
    }

    return wp_kses_post(is_string($html) ? $html : '');
  }
}

if (!function_exists('custausu_auth_pages_filter_page_list_block_html')) {
  function custausu_auth_pages_filter_page_list_block_html(string $block_content, array $block): string {
    return wp_kses_post(custausu_auth_pages_strip_hidden_menu_links_from_html($block_content));
  }
}

add_filter('render_block_core/page-list', 'custausu_auth_pages_filter_page_list_block_html', 20, 2);
add_filter('render_block_core/navigation', 'custausu_auth_pages_filter_page_list_block_html', 20, 2);


if (!function_exists('custausu_legal_url')) {
  function custausu_legal_url(string $key = 'privacy_cookies', string $lang = ''): string {
    $key = sanitize_key($key);

    if ($key === '') {
      $key = 'privacy_cookies';
    }

    if ($lang === '') {
      $lang = function_exists('custausu_auth_pages_frontend_route_lang')
        ? custausu_auth_pages_frontend_route_lang()
        : 'en';
    }

    $lang = sanitize_key($lang);
    if ($lang === '') {
      $lang = 'en';
    }

    $settings = get_option('custausu_global_settings', []);
    $settings = is_array($settings) ? $settings : [];

    $legal_links = isset($settings['legal_links']) && is_array($settings['legal_links'])
      ? $settings['legal_links']
      : [];

    $entry = [];

    if (isset($legal_links[$lang][$key]) && is_array($legal_links[$lang][$key])) {
      $entry = $legal_links[$lang][$key];
    } elseif (isset($legal_links[$lang]) && is_array($legal_links[$lang])) {
      /*
       * Backward/flexible read support for possible flat storage:
       * legal_links[lang][privacy_cookies_page_id]
       * legal_links[lang][privacy_cookies_url]
       */
      $entry = [
        'page_id' => $legal_links[$lang][$key . '_page_id'] ?? 0,
        'url'     => $legal_links[$lang][$key . '_url'] ?? '',
      ];
    }

    $page_id = absint($entry['page_id'] ?? 0);

    if ($page_id > 0 && get_post_type($page_id) === 'page') {
      $permalink = get_permalink($page_id);
      if (is_string($permalink) && $permalink !== '') {
        return $permalink;
      }
    }

    $raw_url = isset($entry['url']) && is_scalar($entry['url'])
      ? trim((string) $entry['url'])
      : '';

    if ($raw_url !== '') {
      if (preg_match('#^https?://#i', $raw_url)) {
        $url = esc_url_raw($raw_url);
        if ($url !== '') {
          return $url;
        }
      }

      if ($raw_url[0] === '/' || strpos($raw_url, '#') !== 0) {
        $path = '/' . ltrim($raw_url, '/');
        $path = strtok($path, '#') ?: $path;
        $path = strtok($path, '?') ?: $path;

        $path = '/' . trim($path, '/');
        if ($path !== '/') {
          return home_url($path . '/');
        }
      }
    }

    $fallback = function_exists('get_privacy_policy_url') ? get_privacy_policy_url() : '';

    return is_string($fallback) ? $fallback : '';
  }
}


if (!function_exists('custausu_auth_page_normalize_route_path_for_compare')) {
  function custausu_auth_page_normalize_route_path_for_compare($value): string {
    $value = is_scalar($value) ? trim((string) $value) : '';

    if ($value === '') {
      return '';
    }

    $path = wp_parse_url($value, PHP_URL_PATH);
    if (is_string($path) && $path !== '') {
      $value = $path;
    }

    $value = '/' . trim($value, '/');

    if ($value === '/') {
      return '/';
    }

    return rtrim($value, '/') . '/';
  }
}

if (!function_exists('custausu_auth_page_route_consistency_issues')) {
  function custausu_auth_page_route_consistency_issues(?array $settings = null): array {
    if ($settings === null) {
      $settings = get_option('custausu_global_settings', []);
    }

    $settings = is_array($settings) ? $settings : [];

    $routes_paths = isset($settings['routes_paths']) && is_array($settings['routes_paths'])
      ? $settings['routes_paths']
      : [];

    $routes_page_ids = isset($settings['routes_page_ids']) && is_array($settings['routes_page_ids'])
      ? $settings['routes_page_ids']
      : [];

    $langs = array_unique(array_filter(array_map('sanitize_key', array_merge(
      array_keys($routes_paths),
      array_keys($routes_page_ids),
      [sanitize_key((string)($settings['routes_default_lang'] ?? ''))]
    ))));

    if (empty($langs)) {
      $langs = ['en'];
    }

    $issues = [];

    foreach ($langs as $lang) {
      $lang_paths = isset($routes_paths[$lang]) && is_array($routes_paths[$lang])
        ? $routes_paths[$lang]
        : [];

      $lang_ids = isset($routes_page_ids[$lang]) && is_array($routes_page_ids[$lang])
        ? $routes_page_ids[$lang]
        : [];

      foreach (custausu_auth_page_route_keys() as $route) {
        $stored_path = custausu_auth_page_normalize_route_path_for_compare($lang_paths[$route] ?? '');
        $stored_page_id = absint($lang_ids[$route] ?? 0);

        /*
         * Primary source: explicit selected page ID.
         * Fallback source: CAS Auth page found by expected template.
         *
         * This is important because admins may configure routes by path only,
         * while CAS still created/knows the underlying Auth pages by template.
         */
        $page_id = $stored_page_id;

        if ($page_id <= 0 && function_exists('custausu_auth_page_find_by_template')) {
          $page_id = absint(custausu_auth_page_find_by_template($route, $lang));
        }

        if ($page_id <= 0) {
          continue;
        }

        $post = get_post($page_id);

        if (!$post || $post->post_type !== 'page' || $post->post_status === 'trash') {
          /*
           * Only flag missing pages when an explicit saved page ID existed.
           * If we only had a manual path and no CAS page was found, the path may
           * intentionally point to a custom/dynamic theme route.
           */
          if ($stored_page_id > 0) {
            $issues[] = [
              'reason'       => 'auth_route_page_missing',
              'lang'         => $lang,
              'route'        => $route,
              'page_id'      => $stored_page_id,
              'stored_path'  => $stored_path,
              'current_path' => '',
              'template'     => '',
              'expected'     => custausu_auth_page_expected_template($route),
            ];
          }

          continue;
        }

        $current_path = custausu_auth_page_normalize_route_path_for_compare(
          function_exists('custausu_auth_page_route_path_from_id')
            ? custausu_auth_page_route_path_from_id($page_id)
            : get_permalink($page_id)
        );

        $actual_template = (string) get_page_template_slug($page_id);
        $expected_template = custausu_auth_page_expected_template($route);

        if ($actual_template !== $expected_template) {
          $issues[] = [
            'reason'       => 'auth_route_template_mismatch',
            'lang'         => $lang,
            'route'        => $route,
            'page_id'      => $page_id,
            'stored_path'  => $stored_path,
            'current_path' => $current_path,
            'template'     => $actual_template,
            'expected'     => $expected_template,
          ];
        }

        if ($stored_path !== '' && $current_path !== '' && $stored_path !== $current_path) {
          $issues[] = [
            'reason'       => 'auth_route_stale_path',
            'lang'         => $lang,
            'route'        => $route,
            'page_id'      => $page_id,
            'stored_path'  => $stored_path,
            'current_path' => $current_path,
            'template'     => $actual_template,
            'expected'     => $expected_template,
          ];
        }
      }
    }

    return $issues;
  }
}


/**
 * Render the proper outer shell for CAS auth PHP templates.
 *
 * Classic themes use get_header()/get_footer().
 * Block themes need their block template parts, otherwise WordPress falls back
 * to theme-compat/header.php and the site navigation disappears.
 */
if (!function_exists('custausu_auth_template_uses_block_theme_shell')) {
  function custausu_auth_template_uses_block_theme_shell(): bool {
    return function_exists('wp_is_block_theme')
      && wp_is_block_theme()
      && function_exists('block_template_part');
  }
}

if (!function_exists('custausu_auth_template_header')) {
  function custausu_auth_template_header(): void {
    if (!custausu_auth_template_uses_block_theme_shell()) {
      get_header();
      return;
    }

    /*
     * Pre-render the block theme header before wp_head().
     * Block themes can register/layout dynamic styles while blocks render.
     */
    ob_start();
    block_template_part('header');
    $custausu_auth_block_header_safe = (string) ob_get_clean();

    ?><!doctype html>
<html <?php language_attributes(); ?>>
<head>
  <meta charset="<?php echo esc_attr(get_bloginfo('charset')); ?>">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <?php wp_head(); ?>
</head>
<body <?php body_class('custausu-auth-template custausu-auth-template--block-theme'); ?>>
<?php wp_body_open(); ?>
<div class="wp-site-blocks">
  <?php
  // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- $custausu_auth_block_header_safe is WordPress-generated block template part markup.
  echo $custausu_auth_block_header_safe;
  ?>
  <main id="wp--skip-link--target" class="custausu-auth-template-main wp-block-group">
<?php
  }
}

if (!function_exists('custausu_auth_template_footer')) {
  function custausu_auth_template_footer(): void {
    if (!custausu_auth_template_uses_block_theme_shell()) {
      get_footer();
      return;
    }

    ?>
  </main>
</div>
<?php wp_footer(); ?>
</body>
</html>
<?php
  }
}

