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

/**
 * CAS Support Diagnostics Log Bridge
 *
 * The public Free package keeps only the signed, time-limited Support Diagnostics
 * runtime. Persistent debug settings and filesystem log writing are not
 * included in this package. Diagnostic rows are redacted before being stored
 * in a bounded wp_options buffer and are available only to authorized support
 * capabilities.
 */
/* -----------------------------------------------------------------------------
 * Support Diagnostics state helpers
 * -------------------------------------------------------------------------- */

if (!function_exists('custausu_debug_support_diagnostics_state')) {
  function custausu_debug_support_diagnostics_state(): array {
    foreach (['custausu_support_diagnostics_get_state', 'cas_support_diagnostics_state'] as $fn) {
      if (function_exists($fn)) {
        $state = $fn();
        if (is_array($state)) {
          return $state;
        }
      }
    }

    $raw = get_option('custausu_support_diagnostics_state', []);
    return is_array($raw) ? $raw : [];
  }
}

if (!function_exists('custausu_debug_support_diagnostics_capabilities_from_state')) {
  function custausu_debug_support_diagnostics_capabilities_from_state(array $state): array {
    $raw_caps = [];

    foreach (['capabilities', 'allowed_capabilities', 'diagnostics'] as $key) {
      if (isset($state[$key]) && is_array($state[$key])) {
        $raw_caps = array_merge($raw_caps, $state[$key]);
      }
    }

    if (isset($state['validation']['capabilities']) && is_array($state['validation']['capabilities'])) {
      $raw_caps = array_merge($raw_caps, $state['validation']['capabilities']);
    }

    $caps = [];

    foreach ($raw_caps as $k => $v) {
      if (is_int($k)) {
        $cap = sanitize_key((string)$v);
        if ($cap !== '') {
          $caps[] = $cap;
        }
      } else {
        $cap = sanitize_key((string)$k);
        if ($cap !== '' && !empty($v)) {
          $caps[] = $cap;
        }
      }
    }

    return array_values(array_unique($caps));
  }
}

if (!function_exists('custausu_debug_support_diagnostics_is_active')) {
  function custausu_debug_support_diagnostics_is_active(): bool {
    if (function_exists('custausu_support_diagnostics_is_active')) {
      return (bool) custausu_support_diagnostics_is_active();
    }

    $state = custausu_debug_support_diagnostics_state();

    if (empty($state) || !is_array($state)) {
      return false;
    }

    $status = sanitize_key((string)($state['status'] ?? ($state['validation']['status'] ?? '')));
    $active = !empty($state['active']) || $status === 'active';

    if (!$active) {
      return false;
    }

    $expires_at = trim((string)($state['expires_at'] ?? ($state['validation']['expires_at'] ?? '')));

    if ($expires_at !== '') {
      $ts = strtotime($expires_at . ' UTC');

      if (is_int($ts) && $ts > 0 && $ts <= time()) {
        return false;
      }
    }

    return true;
  }
}

if (!function_exists('custausu_debug_support_diagnostics_can')) {
  function custausu_debug_support_diagnostics_can(string $capability): bool {
    $capability = sanitize_key($capability);

    if ($capability === '') {
      return false;
    }

    if (function_exists('custausu_support_diagnostics_can')) {
      return (bool) custausu_support_diagnostics_can($capability);
    }

    if (!custausu_debug_support_diagnostics_is_active()) {
      return false;
    }

    $state = custausu_debug_support_diagnostics_state();
    $caps = custausu_debug_support_diagnostics_capabilities_from_state($state);

    return in_array($capability, $caps, true);
  }
}

if (!function_exists('custausu_debug_support_diagnostics_collects_logs')) {
  function custausu_debug_support_diagnostics_collects_logs(): bool {
    if (!custausu_debug_support_diagnostics_is_active()) {
      return false;
    }

    foreach ([
      'logs_read',
      'diagnostic_export',
      'package_context_read',
      'rest_connectivity',
      'health_check',
      'settings_snapshot',
    ] as $capability) {
      if (custausu_debug_support_diagnostics_can($capability)) {
        return true;
      }
    }

    return false;
  }
}

if (!function_exists('custausu_debug_support_diagnostics_can_log')) {
  function custausu_debug_support_diagnostics_can_log(string $channel, string $level): bool {
    if (!custausu_debug_support_diagnostics_collects_logs()) {
      return false;
    }

    $channel = sanitize_key(strtolower(trim($channel ?: 'general')));
    $level   = strtolower(trim($level ?: 'info'));

    if ($channel === '') {
      $channel = 'general';
    }

    if (!in_array($level, ['error', 'warn', 'info', 'debug'], true)) {
      $level = 'info';
    }

    /*
     * Full support token:
     * collect every CAS log produced by the installed package/modules.
     */
    if (
      custausu_debug_support_diagnostics_can('diagnostic_export') ||
      custausu_debug_support_diagnostics_can('logs_read')
    ) {
      return true;
    }

    /*
     * Narrow support tokens.
     */
    if (
      custausu_debug_support_diagnostics_can('package_context_read') &&
      in_array($channel, ['package_context', 'http', 'rest'], true)
    ) {
      return true;
    }

    if (
      custausu_debug_support_diagnostics_can('rest_connectivity') &&
      in_array($channel, ['http', 'rest'], true)
    ) {
      return true;
    }

    if (
      custausu_debug_support_diagnostics_can('health_check') &&
      in_array($channel, ['health', 'health_check'], true)
    ) {
      return true;
    }

    if (
      custausu_debug_support_diagnostics_can('settings_snapshot') &&
      in_array($channel, ['settings', 'admin', 'health', 'health_check'], true)
    ) {
      return true;
    }

    return false;
  }
}

/* -----------------------------------------------------------------------------
 * Temporary support-diagnostics availability
 * -------------------------------------------------------------------------- */

if (!function_exists('custausu_debug_runtime_available')) {
  function custausu_debug_runtime_available(): bool {
    return custausu_debug_support_diagnostics_collects_logs();
  }
}

/* -----------------------------------------------------------------------------
 * Support-diagnostics compatibility helpers
 * -------------------------------------------------------------------------- */

/* -----------------------------------------------------------------------------
 * Public Debug helpers used by CAS modules
 * -------------------------------------------------------------------------- */

if (!function_exists('custausu_debug_enabled')) {
  function custausu_debug_enabled(): bool {
    return custausu_debug_support_diagnostics_collects_logs();
  }
}

if (!function_exists('custausu_debug_level_enabled')) {
  function custausu_debug_level_enabled(string $level): bool {
    unset($level);
    return custausu_debug_support_diagnostics_collects_logs();
  }
}

if (!function_exists('custausu_debug_feature_enabled')) {
  function custausu_debug_feature_enabled(string $channel): bool {
    unset($channel);
    return custausu_debug_support_diagnostics_collects_logs();
  }
}

/* -----------------------------------------------------------------------------
 * No filesystem logging in the public Free package
 * -------------------------------------------------------------------------- */

/* -----------------------------------------------------------------------------
 * Support Diagnostics option-based runtime log
 * -------------------------------------------------------------------------- */


if (!function_exists('custausu_debug_privacy_hash_tag')) {
  function custausu_debug_privacy_hash_tag($value): string {
    $value = trim((string)$value);

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

    return substr(
      hash_hmac(
        'sha256',
        strtolower($value),
        wp_salt('auth')
      ),
      0,
      12
    );
  }
}

if (!function_exists('custausu_debug_privacy_mask_email')) {
  function custausu_debug_privacy_mask_email($value): string {
    $value = sanitize_email((string)$value);

    if ($value === '' || strpos($value, '@') === false) {
      return '[redacted-email]';
    }

    [, $domain] = array_pad(
      explode('@', strtolower($value), 2),
      2,
      ''
    );

    $tag = custausu_debug_privacy_hash_tag($value);

    return '[email:' . $tag
      . ($domain !== '' ? '@' . $domain : '')
      . ']';
  }
}

if (!function_exists('custausu_debug_privacy_text_summary')) {
  function custausu_debug_privacy_text_summary(
    $value,
    string $kind = 'text'
  ): string {
    $value = is_scalar($value) ? (string)$value : '';
    $length = function_exists('mb_strlen')
      ? mb_strlen($value)
      : strlen($value);

    return '[redacted-' . sanitize_key($kind)
      . ' chars=' . max(0, (int)$length)
      . ' hash=' . custausu_debug_privacy_hash_tag($value)
      . ']';
  }
}

if (!function_exists('custausu_debug_redact_sensitive_value')) {
  function custausu_debug_redact_sensitive_value(
    $value,
    int $depth = 0,
    string $key_hint = ''
  ) {
    if ($depth > 6) {
      return '[max-depth]';
    }

    $key_hint = strtolower(trim($key_hint));

    if (is_array($value)) {
      $out = [];

      foreach ($value as $key => $item) {
        $key_text = is_scalar($key)
          ? strtolower((string)$key)
          : '';

        if (
          preg_match(
            '/(password|passwd|pwd|secret|token|license[_-]?key|api[_-]?key|private[_-]?key|authorization|cookie|client_secret|signature|nonce)/i',
            $key_text
          )
        ) {
          $out[$key] = '[redacted]';
          continue;
        }

        if (
          preg_match(
            '/(^|[-_])(email|e-mail|user_email|customer_email|your-email)([-_]|$)/i',
            $key_text
          )
        ) {
          $out[$key] = is_scalar($item)
            ? custausu_debug_privacy_mask_email($item)
            : '[redacted-email-data]';
          continue;
        }

        if (
          preg_match(
            '/(^|[-_])(jti)([-_]|$)/i',
            $key_text
          )
        ) {
          $raw_jti = is_scalar($item) ? (string)$item : '';

          $out[$key] = '[redacted-jti hash='
            . custausu_debug_privacy_hash_tag($raw_jti)
            . (
              strlen($raw_jti) >= 6
                ? ' tail=' . substr($raw_jti, -6)
                : ''
            )
            . ']';

          continue;
        }

        if (
          preg_match(
            '/(session[_-]?hash|activated_by_session_hash)/i',
            $key_text
          )
        ) {
          $out[$key] = '[redacted-session-hash]';
          continue;
        }

        if (
          preg_match(
            '/(^|[-_])(ip|ip_address|remote_addr)([-_]|$)/i',
            $key_text
          )
        ) {
          $out[$key] = '[redacted-ip hash='
            . custausu_debug_privacy_hash_tag(
              is_scalar($item) ? $item : ''
            )
            . ']';

          continue;
        }

        if (
          preg_match(
            '/(^|[-_])(username|user_login|display_name|first_name|last_name|customer_name|full_name|your-name)([-_]|$)/i',
            $key_text
          )
        ) {
          $out[$key] = '[redacted-identity hash='
            . custausu_debug_privacy_hash_tag(
              is_scalar($item) ? $item : ''
            )
            . ']';

          continue;
        }

        if (
          preg_match(
            '/(^|[-_])(your-message|your-subject|message_body|message_content|body|content|subject)([-_]|$)/i',
            $key_text
          )
        ) {
          $out[$key] = custausu_debug_privacy_text_summary(
            $item,
            'form-text'
          );

          continue;
        }

        $out[$key] = custausu_debug_redact_sensitive_value(
          $item,
          $depth + 1,
          $key_text
        );
      }

      return $out;
    }

    if (is_object($value)) {
      return custausu_debug_redact_sensitive_value(
        get_object_vars($value),
        $depth + 1,
        $key_hint
      );
    }

    if (!is_scalar($value)) {
      return $value;
    }

    $string = (string)$value;

    /*
     * Email addresses can also be embedded in labels or free-form technical
     * strings rather than stored under an email-named array key.
     */
    $string = preg_replace_callback(
      '/[A-Z0-9._%+\-]+@[A-Z0-9.\-]+\.[A-Z]{2,}/i',
      static function (array $match): string {
        return custausu_debug_privacy_mask_email(
          (string)($match[0] ?? '')
        );
      },
      $string
    ) ?? $string;

    $string = preg_replace(
      '/CAS-[A-Z0-9][A-Z0-9\-]{16,}/',
      'CAS-[redacted]',
      $string
    ) ?? $string;

    $string = preg_replace(
      '/-----BEGIN (?:RSA )?PRIVATE KEY-----.*?-----END (?:RSA )?PRIVATE KEY-----/s',
      '[redacted-private-key]',
      $string
    ) ?? $string;

    $string = preg_replace(
      '/([?&](?:token|key|license_key|password|secret|nonce)=)[^&\s]+/i',
      '$1[redacted]',
      $string
    ) ?? $string;

    return $string;
  }
}

if (!function_exists('custausu_debug_stringify_log_value')) {
  function custausu_debug_stringify_log_value($value, int $max_chars = 5000): string {
    $value = custausu_debug_redact_sensitive_value($value);

    if (is_array($value) || is_object($value)) {
      $encoded = wp_json_encode($value, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
      $out = is_string($encoded) ? $encoded : '[unserializable]';
    } else {
      $out = (string) $value;
    }

    $out = wp_strip_all_tags($out);
    $out = trim($out);

    if ($max_chars > 0 && strlen($out) > $max_chars) {
      $out = substr($out, 0, $max_chars) . '… [truncated]';
    }

    return $out;
  }
}

if (!function_exists('custausu_debug_support_diagnostics_logs_option_name')) {
  function custausu_debug_support_diagnostics_logs_option_name(): string {
    return 'custausu_support_diagnostics_runtime_logs';
  }
}

if (!function_exists('custausu_debug_support_diagnostics_get_runtime_logs')) {
  function custausu_debug_support_diagnostics_get_runtime_logs(): array {
    if (
      isset(
        $GLOBALS[
          'custausu_support_diagnostics_runtime_logs_buffer'
        ]
      )
      && is_array(
        $GLOBALS[
          'custausu_support_diagnostics_runtime_logs_buffer'
        ]
      )
    ) {
      return $GLOBALS[
        'custausu_support_diagnostics_runtime_logs_buffer'
      ];
    }

    $rows = get_option(
      custausu_debug_support_diagnostics_logs_option_name(),
      []
    );

    return is_array($rows) ? $rows : [];
  }
}

if (!function_exists('custausu_debug_support_diagnostics_set_runtime_logs')) {
  function custausu_debug_support_diagnostics_set_runtime_logs(
    array $rows
  ): bool {
    $rows = array_values($rows);

    $GLOBALS[
      'custausu_support_diagnostics_runtime_logs_buffer'
    ] = $rows;

    $GLOBALS[
      'custausu_support_diagnostics_runtime_logs_dirty'
    ] = false;

    return (bool) update_option(
      custausu_debug_support_diagnostics_logs_option_name(),
      $rows,
      false
    );
  }
}

if (!function_exists('custausu_debug_support_diagnostics_clear_runtime_logs')) {
  function custausu_debug_support_diagnostics_clear_runtime_logs(): void {
    unset(
      $GLOBALS[
        'custausu_support_diagnostics_runtime_logs_buffer'
      ],
      $GLOBALS[
        'custausu_support_diagnostics_runtime_logs_dirty'
      ]
    );

    delete_option(
      custausu_debug_support_diagnostics_logs_option_name()
    );

    /*
     * Legacy cleanup from the first support diagnostics draft.
     */
    delete_option('cas_support_diagnostics_runtime_log');
  }
}

if (!function_exists('custausu_debug_support_diagnostics_append_runtime_log')) {
  
if (!function_exists('custausu_debug_support_diagnostics_flush_runtime_logs')) {
  function custausu_debug_support_diagnostics_flush_runtime_logs(): void {
    if (
      empty(
        $GLOBALS[
          'custausu_support_diagnostics_runtime_logs_dirty'
        ]
      )
      || !isset(
        $GLOBALS[
          'custausu_support_diagnostics_runtime_logs_buffer'
        ]
      )
      || !is_array(
        $GLOBALS[
          'custausu_support_diagnostics_runtime_logs_buffer'
        ]
      )
    ) {
      return;
    }

    update_option(
      custausu_debug_support_diagnostics_logs_option_name(),
      array_values(
        $GLOBALS[
          'custausu_support_diagnostics_runtime_logs_buffer'
        ]
      ),
      false
    );

    $GLOBALS[
      'custausu_support_diagnostics_runtime_logs_dirty'
    ] = false;
  }
}

function custausu_debug_support_diagnostics_append_runtime_log(
    array $row
  ): void {
    if (!custausu_debug_support_diagnostics_is_active()) {
      return;
    }

    $level = strtolower(
      trim((string)($row['level'] ?? 'info'))
    );

    if (
      !in_array(
        $level,
        ['error', 'warn', 'info', 'debug'],
        true
      )
    ) {
      $level = 'info';
    }

    $channel = sanitize_key(
      strtolower(
        trim((string)($row['channel'] ?? 'general'))
      )
    );

    if ($channel === '') {
      $channel = 'general';
    }

    $time_utc = sanitize_text_field(
      (string)($row['time_utc'] ?? '')
    );

    if ($time_utc === '') {
      $time_utc = gmdate('Y-m-d H:i:s');
    }

    /*
     * Redaction occurs before the event reaches persistent storage.
     */
    $message = custausu_debug_stringify_log_value(
      $row['message'] ?? '',
      3000
    );

    $context = custausu_debug_stringify_log_value(
      $row['context'] ?? '',
      6000
    );

    if (
      !isset(
        $GLOBALS[
          'custausu_support_diagnostics_runtime_logs_buffer'
        ]
      )
      || !is_array(
        $GLOBALS[
          'custausu_support_diagnostics_runtime_logs_buffer'
        ]
      )
    ) {
      $stored = get_option(
        custausu_debug_support_diagnostics_logs_option_name(),
        []
      );

      $GLOBALS[
        'custausu_support_diagnostics_runtime_logs_buffer'
      ] = is_array($stored)
        ? array_values($stored)
        : [];
    }

    $GLOBALS[
      'custausu_support_diagnostics_runtime_logs_buffer'
    ][] = [
      'time_utc' => $time_utc,
      'level'    => $level,
      'channel'  => $channel,
      'message'  => $message,
      'context'  => $context,
    ];

    $max = (int) apply_filters(
      'custausu_support_diagnostics_runtime_logs_max_entries',
      300
    );

    $max = max(25, min(1000, $max));

    if (
      count(
        $GLOBALS[
          'custausu_support_diagnostics_runtime_logs_buffer'
        ]
      ) > $max
    ) {
      $GLOBALS[
        'custausu_support_diagnostics_runtime_logs_buffer'
      ] = array_slice(
        $GLOBALS[
          'custausu_support_diagnostics_runtime_logs_buffer'
        ],
        -$max
      );
    }

    $GLOBALS[
      'custausu_support_diagnostics_runtime_logs_dirty'
    ] = true;

    if (
      empty(
        $GLOBALS[
          'custausu_support_diagnostics_runtime_shutdown_registered'
        ]
      )
    ) {
      $GLOBALS[
        'custausu_support_diagnostics_runtime_shutdown_registered'
      ] = true;

      register_shutdown_function(
        'custausu_debug_support_diagnostics_flush_runtime_logs'
      );
    }
  }
}

if (!function_exists('custausu_debug_support_diagnostics_log_cell_text')) {
  function custausu_debug_support_diagnostics_log_cell_text($value): string {
    if (is_array($value) || is_object($value)) {
      $encoded = wp_json_encode($value, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
      $value = is_string($encoded) ? $encoded : '[unserializable]';
    } elseif ($value === null) {
      $value = '';
    } else {
      $value = (string)$value;
    }

    $value = trim($value);

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

    return $value;
  }
}

if (!function_exists('custausu_debug_support_diagnostics_log_rows')) {
  function custausu_debug_support_diagnostics_log_rows(int $limit = 80): array {
    $limit = max(1, min(300, $limit));

    $rows = custausu_debug_support_diagnostics_get_runtime_logs();
    if (empty($rows)) {
      return [];
    }

    $normalized = [];

    foreach ((array)$rows as $row) {
      if (!is_array($row)) {
        continue;
      }

      $level = strtolower(sanitize_key((string)($row['level'] ?? 'info')));
      if (!in_array($level, ['error', 'warn', 'info', 'debug'], true)) {
        $level = 'info';
      }

      $channel = sanitize_key((string)($row['channel'] ?? 'general'));
      if ($channel === '') {
        $channel = 'general';
      }

      $normalized[] = [
        'time'    => (string)($row['time_utc'] ?? ''),
        'level'   => $level,
        'channel' => $channel,
        'message' => custausu_debug_support_diagnostics_log_cell_text($row['message'] ?? ''),
        'context' => custausu_debug_support_diagnostics_log_cell_text($row['context'] ?? ''),
      ];
    }

    $normalized = array_reverse($normalized);

    return array_slice($normalized, 0, $limit);
  }
}

if (!function_exists('custausu_debug_support_diagnostics_render_log_viewer')) {
  function custausu_debug_support_diagnostics_render_log_viewer(callable $T): string {
    $rows = custausu_debug_support_diagnostics_log_rows(80);

    ob_start();

    echo '<div class="custausu-support-diagnostics-logviewer">';

    echo '<div class="custausu-support-diagnostics-logviewer__head">';
    echo '<div>';
    echo '<h4 class="custausu-support-diagnostics-logviewer__title">'
      . esc_html($T('Runtime diagnostics log', 'Log diagnostica runtime'))
      . '</h4>';
    echo '<p class="custausu-support-diagnostics-logviewer__note">'
      . esc_html($T(
        'Newest entries first. This viewer is available only while the support diagnostics token is active.',
        'Voci più recenti in alto. Questo visore è disponibile solo mentre il token diagnostica supporto è attivo.'
      ))
      . '</p>';
    echo '</div>';

    echo '<span class="custausu-support-diagnostics-logviewer__counter">'
      . esc_html(sprintf($T('%d entries', '%d voci'), count($rows)))
      . '</span>';
    echo '</div>';

    echo '<div class="custausu-support-diagnostics-logviewer__body">';

    if (empty($rows)) {
      echo '<div class="custausu-support-diagnostics-logviewer__empty">';
      echo esc_html($T(
        'No runtime diagnostics collected yet. Reproduce the issue while the support token is active, then refresh this page.',
        'Nessuna diagnostica runtime raccolta. Riproduci il problema mentre il token supporto è attivo, poi aggiorna questa pagina.'
      ));
      echo '</div>';
    } else {
      echo '<table class="custausu-support-diagnostics-logtable">';
      echo '<thead>';
      echo '<tr>';
      echo '<th>' . esc_html($T('UTC time', 'Ora UTC')) . '</th>';
      echo '<th>' . esc_html($T('Level', 'Livello')) . '</th>';
      echo '<th>' . esc_html($T('Channel', 'Canale')) . '</th>';
      echo '<th>' . esc_html($T('Message', 'Messaggio')) . '</th>';
      echo '<th>' . esc_html($T('Context', 'Contesto')) . '</th>';
      echo '</tr>';
      echo '</thead>';
      echo '<tbody>';

      foreach ($rows as $row) {
        $level = sanitize_key((string)($row['level'] ?? 'info'));
        if (!in_array($level, ['error', 'warn', 'info', 'debug'], true)) {
          $level = 'info';
        }

        echo '<tr>';

        echo '<td data-label="' . esc_attr($T('UTC time', 'Ora UTC')) . '" class="custausu-support-diagnostics-logtable__time"><pre>'
          . esc_html((string)($row['time'] ?? '—'))
          . '</pre></td>';

        echo '<td data-label="' . esc_attr($T('Level', 'Livello')) . '" class="custausu-support-diagnostics-logtable__level custausu-support-diagnostics-logtable__level--'
          . esc_attr($level)
          . '"><pre>'
          . esc_html(strtoupper($level))
          . '</pre></td>';

        echo '<td data-label="' . esc_attr($T('Channel', 'Canale')) . '" class="custausu-support-diagnostics-logtable__channel"><pre>'
          . esc_html((string)($row['channel'] ?? 'general'))
          . '</pre></td>';

        echo '<td data-label="' . esc_attr($T('Message', 'Messaggio')) . '" class="custausu-support-diagnostics-logtable__message"><pre>'
          . esc_html((string)($row['message'] ?? '—'))
          . '</pre></td>';

        echo '<td data-label="' . esc_attr($T('Context', 'Contesto')) . '" class="custausu-support-diagnostics-logtable__context"><pre>'
          . esc_html((string)($row['context'] ?? '—'))
          . '</pre></td>';

        echo '</tr>';
      }

      echo '</tbody>';
      echo '</table>';
    }

    echo '</div>';
    echo '</div>';

    return (string) ob_get_clean();
  }
}

/* -----------------------------------------------------------------------------
 * Support Diagnostics initial snapshots
 * -------------------------------------------------------------------------- */

if (!function_exists('custausu_debug_support_diagnostics_t')) {
  function custausu_debug_support_diagnostics_t(string $en, string $it = ''): string {
    if (function_exists('custausu_admin_t')) {
      return (string) custausu_admin_t($en, $it !== '' ? $it : $en);
    }

    return $en;
  }
}

if (!function_exists('custausu_debug_support_diagnostics_check_rows_summary')) {
  function custausu_debug_support_diagnostics_check_rows_summary(array $checks, int $limit = 120): array {
    $out = [];

    foreach ($checks as $row) {
      if (!is_array($row)) {
        continue;
      }

      $out[] = [
        'group'  => sanitize_key((string)($row['group'] ?? '')),
        'key'    => sanitize_key((string)($row['key'] ?? '')),
        'sev'    => sanitize_key((string)($row['sev'] ?? '')),
        'reason' => sanitize_key((string)($row['reason'] ?? '')),
        'ok'     => !empty($row['ok']),
        'label'  => (string)($row['label'] ?? ''),
        'value'  => (string)($row['value'] ?? ''),
        'hint'   => (string)($row['hint'] ?? ''),
      ];

      if (count($out) >= $limit) {
        break;
      }
    }

    return $out;
  }
}

if (!function_exists('custausu_debug_support_diagnostics_health_snapshot')) {
  function custausu_debug_support_diagnostics_health_snapshot(): array {
    $T = 'custausu_debug_support_diagnostics_t';

    $snapshot = [
      'source' => 'fallback_environment_snapshot',
      'summary' => [
        'wp_version'          => function_exists('get_bloginfo') ? get_bloginfo('version') : '',
        'php_version'         => PHP_VERSION,
        'environment_type'    => function_exists('wp_get_environment_type') ? wp_get_environment_type() : '',
        'is_ssl'              => function_exists('is_ssl') ? is_ssl() : null,
        'permalink_structure' => function_exists('get_option') ? (string)get_option('permalink_structure', '') : '',
        'home_url'            => function_exists('home_url') ? home_url('/') : '',
        'site_url'            => function_exists('site_url') ? site_url('/') : '',
        'rest_pretty_url'     => function_exists('rest_url') ? rest_url('/') : '',
        'rest_fallback_url'   => function_exists('home_url') ? home_url('/?rest_route=/') : '',
      ],
      'checks' => [],
    ];

    if (function_exists('custausu_admin_health_check_run')) {
      try {
        $checks = custausu_admin_health_check_run($T);

        if (is_array($checks)) {
          $snapshot['source'] = 'custausu_admin_health_check_run';
          $snapshot['checks'] = custausu_debug_support_diagnostics_check_rows_summary($checks, 140);

          $counts = [
            'ok'     => 0,
            'warn'   => 0,
            'err'    => 0,
            'info'   => 0,
            'preview' => 0,
            'other'  => 0,
          ];

          foreach ($checks as $row) {
            if (!is_array($row)) {
              continue;
            }

            $sev = sanitize_key((string)($row['sev'] ?? 'other'));
            if (!isset($counts[$sev])) {
              $sev = 'other';
            }

            $counts[$sev]++;
          }

          $snapshot['summary']['checks_count'] = count($checks);
          $snapshot['summary']['severity_counts'] = $counts;
        }
      } catch (Throwable $e) {
        $snapshot['source'] = 'fallback_after_health_check_error';
        $snapshot['summary']['health_check_error'] = $e->getMessage();
      }
    }

    return $snapshot;
  }
}

if (!function_exists('custausu_debug_support_diagnostics_package_context_snapshot')) {
  function custausu_debug_support_diagnostics_package_context_snapshot(): array {
    return function_exists('custausu_free_package_support_context')
      ? custausu_free_package_support_context()
      : [
        'source' => 'public_free_package',
        'package' => [
          'edition' => 'freemium_wporg',
          'plan' => 'freemium',
          'separate_package_runtime_available' => false,
        ],
        'stored_compatibility' => [
          'present' => false,
        ],
        'remote_requests' => false,
        'scheduled_validation' => false,
      ];
  }
}

if (!function_exists('custausu_debug_support_diagnostics_rest_snapshot')) {
  function custausu_debug_support_diagnostics_rest_snapshot(): array {
    $revocation_url = function_exists(
      'custausu_support_diagnostics_safe_revocation_url'
    )
      ? custausu_support_diagnostics_safe_revocation_url('')
      : '';

    return [
      'source' => 'free_rest_connectivity_snapshot',
      'site_rest' => [
        'pretty_root' => function_exists('rest_url')
          ? rest_url('/')
          : '',
        'fallback_root' => function_exists('home_url')
          ? home_url('/?rest_route=/')
          : '',
      ],
      'external_support_service' => [
        'revocation_endpoint_configured' => $revocation_url !== '',
      ],
      'checks' => [],
    ];
  }
}

if (!function_exists('custausu_debug_support_diagnostics_settings_snapshot')) {
  function custausu_debug_support_diagnostics_settings_snapshot(): array {
    $opt = get_option('custausu_global_settings', []);
    $opt = is_array($opt) ? $opt : [];

    $default_lang = sanitize_key((string)($opt['routes_default_lang'] ?? ''));

    if ($default_lang === '') {
      if (function_exists('determine_locale')) {
        $locale = (string)determine_locale();
      } elseif (function_exists('get_locale')) {
        $locale = (string)get_locale();
      } else {
        $locale = (string)get_option('WPLANG', 'en_US');
      }

      $locale = strtolower(str_replace('-', '_', trim($locale)));
      $default_lang = sanitize_key((string)strtok($locale, '_'));
    }

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

    $single_language_map = static function($value) use ($default_lang): array {
      $value = is_array($value) ? $value : [];

      if (!array_key_exists($default_lang, $value)) {
        return [];
      }

      return [$default_lang => $value[$default_lang]];
    };

    $routes_paths = $single_language_map($opt['routes_paths'] ?? []);
    $routes_page_ids = $single_language_map($opt['routes_page_ids'] ?? []);
    $legal_links = $single_language_map($opt['legal_links'] ?? []);
    $email_tpl = $single_language_map($opt['email_tpl'] ?? []);

    $logout_source = is_array($opt['routes_logout_redirect'] ?? null)
      ? $opt['routes_logout_redirect']
      : [];
    $logout_redirect = [];

    if (array_key_exists('default', $logout_source)) {
      $logout_redirect['default'] = $logout_source['default'];
    }

    if (array_key_exists($default_lang, $logout_source)) {
      $logout_redirect[$default_lang] = $logout_source[$default_lang];
    }

    $protected_paths_raw = trim((string)($opt['protected_paths'] ?? ''));
    $protected_paths_count = 0;

    if ($protected_paths_raw !== '') {
      $tokens = preg_split('/(?:\r\n|\r|\n|[\t ,;]+)/', $protected_paths_raw);
      $protected_paths_count = count(array_filter((array)$tokens, static function($value) {
        return trim((string)$value) !== '';
      }));
    }

    $free_options = [
      'routes_default_lang' => $default_lang,
      'protected_paths' => $protected_paths_raw,
      'auth_theme' => is_array($opt['auth_theme'] ?? null) ? $opt['auth_theme'] : [],
      'email_theme' => is_array($opt['email_theme'] ?? null) ? $opt['email_theme'] : [],
      'email_tpl' => $email_tpl,
      'keep_data_on_uninstall' => !empty($opt['keep_data_on_uninstall']),
      'routes_paths' => $routes_paths,
      'routes_page_ids' => $routes_page_ids,
      'legal_links' => $legal_links,
      'routes_logout_redirect' => $logout_redirect,
    ];

    return [
      'source' => 'free_plan_settings_snapshot',
      'summary' => [
        'routes_default_lang' => $default_lang,
        'keep_data_on_uninstall' => !empty($opt['keep_data_on_uninstall']),
        'protected_paths_count' => $protected_paths_count,
        'routes_paths_languages' => array_keys($routes_paths),
        'routes_page_ids_languages' => array_keys($routes_page_ids),
      ],
      'sanitized_options' => custausu_debug_redact_sensitive_value($free_options),
    ];
  }
}

if (!function_exists('custausu_debug_support_diagnostics_seed_runtime_logs')) {
  function custausu_debug_support_diagnostics_seed_runtime_logs(): void {
    if (!custausu_debug_support_diagnostics_is_active()) {
      return;
    }

    if (custausu_debug_support_diagnostics_can('health_check')) {
      custausu_debug_support_diagnostics_append_runtime_log([
        'time_utc' => gmdate('Y-m-d H:i:s'),
        'level'    => 'info',
        'channel'  => 'health',
        'message'  => 'Health Check diagnostics snapshot executed',
        'context'  => custausu_debug_support_diagnostics_health_snapshot(),
      ]);
    }

    if (custausu_debug_support_diagnostics_can('package_context_read')) {
      custausu_debug_support_diagnostics_append_runtime_log([
        'time_utc' => gmdate('Y-m-d H:i:s'),
        'level'    => 'info',
        'channel'  => 'package_context',
        'message'  => 'Installed package context snapshot executed',
        'context'  => custausu_debug_support_diagnostics_package_context_snapshot(),
      ]);
    }

    if (custausu_debug_support_diagnostics_can('rest_connectivity')) {
      custausu_debug_support_diagnostics_append_runtime_log([
        'time_utc' => gmdate('Y-m-d H:i:s'),
        'level'    => 'info',
        'channel'  => 'rest',
        'message'  => 'REST/API connectivity snapshot executed',
        'context'  => custausu_debug_support_diagnostics_rest_snapshot(),
      ]);
    }

    if (custausu_debug_support_diagnostics_can('settings_snapshot')) {
      custausu_debug_support_diagnostics_append_runtime_log([
        'time_utc' => gmdate('Y-m-d H:i:s'),
        'level'    => 'info',
        'channel'  => 'settings',
        'message'  => 'Sanitized settings snapshot executed',
        'context'  => custausu_debug_support_diagnostics_settings_snapshot(),
      ]);
    }

    if (custausu_debug_support_diagnostics_can('logs_read')) {
      custausu_debug_support_diagnostics_append_runtime_log([
        'time_utc' => gmdate('Y-m-d H:i:s'),
        'level'    => 'info',
        'channel'  => 'support',
        'message'  => 'Runtime diagnostics log viewer enabled',
        'context'  => [
          'storage' => custausu_debug_support_diagnostics_logs_option_name(),
          'max_entries' => (int) apply_filters('custausu_support_diagnostics_runtime_logs_max_entries', 300),
        ],
      ]);
    }

    if (custausu_debug_support_diagnostics_can('diagnostic_export')) {
      custausu_debug_support_diagnostics_append_runtime_log([
        'time_utc' => gmdate('Y-m-d H:i:s'),
        'level'    => 'info',
        'channel'  => 'support',
        'message'  => 'Full diagnostic export capability',
        'context'  => [
          'status' => 'local_export_available',
          'note' => 'A local diagnostic export is available to the authorized support session. No automatic report upload is performed.',
        ],
      ]);
    }
  }
}

/* -----------------------------------------------------------------------------
 * Logger principale
 * -------------------------------------------------------------------------- */

if (!function_exists('custausu_log')) {
  function custausu_log(string $channel, $message, $context = null, string $level = 'info'): void {
    $channel = sanitize_key(strtolower(trim($channel ?: 'general')));
    $level   = strtolower(trim($level ?: 'info'));

    if ($channel === '') {
      $channel = 'general';
    }

    if (!in_array($level, ['error', 'warn', 'info', 'debug'], true)) {
      $level = 'info';
    }

    if (!custausu_debug_support_diagnostics_can_log($channel, $level)) {
      return;
    }

    custausu_debug_support_diagnostics_append_runtime_log([
      'time_utc' => gmdate('Y-m-d H:i:s'),
      'level'    => $level,
      'channel'  => $channel,
      'message'  => $message,
      'context'  => ($context !== null ? $context : ''),
    ]);
  }
}

/* -----------------------------------------------------------------------------
 * Email failures -> CAS log
 * -------------------------------------------------------------------------- */

if (!defined('CUSTAUSU_WP_MAIL_FAILED_HOOK')) {
  define('CUSTAUSU_WP_MAIL_FAILED_HOOK', true);

  add_action('wp_mail_failed', function($wp_error) {
    if (!function_exists('custausu_log')) return;
    if (!is_wp_error($wp_error)) return;

    custausu_log('email', 'wp_mail_failed', [
      'error' => $wp_error->get_error_message(),
      'data'  => $wp_error->get_error_data(),
    ], 'error');
  });
}