<?php
defined( 'ABSPATH' ) || exit;

/* ======================================================================
   247ChatMate — Paid Lifecycle Read-only Admin Client
   PAIDLIFECYCLEREADONLYADMINDISPLAY3F5E16

   Advisory-only lifecycle status display helper.
   LemonSqueezy/local paid licence validation remains the paid Pro source of truth.
   This file must not become an entitlement authority.

   No automatic sync trigger is registered in this file.
   No frontend request is allowed to call the lifecycle status endpoint.
   No cron/background request is allowed to call the lifecycle status endpoint.
   No IP address, visitor data, chat content, lead content, raw WhatsApp
   number, raw admin email, raw Founder Beta invite code, raw webhook payload,
   or full raw licence key is collected here.
====================================================================== */

if ( ! defined( 'MATEWA_PAID_LIFECYCLE_STATUS_ENDPOINT' ) ) {
	define( 'MATEWA_PAID_LIFECYCLE_STATUS_ENDPOINT', 'https://247trademate.pro/247chatmate/paid-lifecycle-status.php' );
}

if ( ! defined( 'MATEWA_PAID_LIFECYCLE_STATUS_SECRET' ) ) {
	define( 'MATEWA_PAID_LIFECYCLE_STATUS_SECRET', '' );
}

if ( ! defined( 'MATEWA_PAID_LIFECYCLE_STATUS_TIMEOUT' ) ) {
	define( 'MATEWA_PAID_LIFECYCLE_STATUS_TIMEOUT', 5 );
}

if ( ! defined( 'MATEWA_PAID_LIFECYCLE_STATUS_LAST_RESULT_OPTION' ) ) {
	define( 'MATEWA_PAID_LIFECYCLE_STATUS_LAST_RESULT_OPTION', 'matewa_paid_lifecycle_status_last_result' );
}

if ( ! defined( 'MATEWA_PAID_LIFECYCLE_STATUS_LAST_ERROR_OPTION' ) ) {
	define( 'MATEWA_PAID_LIFECYCLE_STATUS_LAST_ERROR_OPTION', 'matewa_paid_lifecycle_status_last_error' );
}

if ( ! defined( 'MATEWA_PAID_LIFECYCLE_STATUS_LAST_REFRESH_OPTION' ) ) {
	define( 'MATEWA_PAID_LIFECYCLE_STATUS_LAST_REFRESH_OPTION', 'matewa_paid_lifecycle_status_last_refresh' );
}

if ( ! defined( 'MATEWA_PAID_LIFECYCLE_STATUS_REFRESH_LOCK_TRANSIENT' ) ) {
	define( 'MATEWA_PAID_LIFECYCLE_STATUS_REFRESH_LOCK_TRANSIENT', 'matewa_paid_lifecycle_status_refresh_lock' );
}

if ( ! function_exists( 'matewa_paid_lifecycle_status_get_endpoint' ) ) {
	function matewa_paid_lifecycle_status_get_endpoint() {
		return defined( 'MATEWA_PAID_LIFECYCLE_STATUS_ENDPOINT' )
			? esc_url_raw( (string) MATEWA_PAID_LIFECYCLE_STATUS_ENDPOINT )
			: '';
	}
}

if ( ! function_exists( 'matewa_paid_lifecycle_status_get_secret' ) ) {
	function matewa_paid_lifecycle_status_get_secret() {
		return defined( 'MATEWA_PAID_LIFECYCLE_STATUS_SECRET' )
			? trim( (string) MATEWA_PAID_LIFECYCLE_STATUS_SECRET )
			: '';
	}
}

if ( ! function_exists( 'matewa_paid_lifecycle_status_is_configured' ) ) {
	function matewa_paid_lifecycle_status_is_configured() {
		return '' !== matewa_paid_lifecycle_status_get_endpoint() && '' !== matewa_paid_lifecycle_status_get_secret();
	}
}

if ( ! function_exists( 'matewa_paid_lifecycle_status_is_cron_request' ) ) {
	function matewa_paid_lifecycle_status_is_cron_request() {
		if ( function_exists( 'wp_doing_cron' ) && wp_doing_cron() ) {
			return true;
		}

		return defined( 'DOING_CRON' ) && DOING_CRON;
	}
}

if ( ! function_exists( 'matewa_paid_lifecycle_status_can_request' ) ) {
	function matewa_paid_lifecycle_status_can_request() {
		// Lifecycle status refresh is manual admin-only in this phase.
		// Frontend page loads, widget requests, and cron/background requests must never trigger it.
		return is_admin() && ! matewa_paid_lifecycle_status_is_cron_request();
	}
}

if ( ! function_exists( 'matewa_paid_lifecycle_status_get_domain' ) ) {
	function matewa_paid_lifecycle_status_get_domain() {
		$host = wp_parse_url( home_url( '/' ), PHP_URL_HOST );
		$host = is_string( $host ) ? strtolower( trim( $host ) ) : '';
		$host = preg_replace( '/^www\./', '', $host );
		$host = preg_replace( '/[^a-z0-9.-]/', '', $host );

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

if ( ! function_exists( 'matewa_paid_lifecycle_status_hash_value' ) ) {
	function matewa_paid_lifecycle_status_hash_value( $value = '' ) {
		$value  = trim( (string) $value );
		$secret = matewa_paid_lifecycle_status_get_secret();

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

		return hash_hmac( 'sha256', $value . '|' . home_url( '/' ), $secret );
	}
}

if ( ! function_exists( 'matewa_paid_lifecycle_status_get_install_uuid' ) ) {
	function matewa_paid_lifecycle_status_get_install_uuid() {
		if ( function_exists( 'matewa_pro_trial_registry_get_install_uuid' ) ) {
			return matewa_pro_trial_registry_get_install_uuid();
		}

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

		return '';
	}
}

if ( ! function_exists( 'matewa_paid_lifecycle_status_advisory_result' ) ) {
	function matewa_paid_lifecycle_status_advisory_result( $code, $message = '', $status = 'invalid', $extra = array() ) {
		$result = array(
			'ok'                         => false,
			'code'                       => sanitize_key( (string) $code ),
			'status'                     => sanitize_key( (string) $status ),
			'message'                    => sanitize_text_field( (string) $message ),
			'lifecycle_only'             => true,
			'advisory_only'              => true,
			'entitlement_decision'       => 'unchanged',
			'source'                     => 'paid_lifecycle_status_client',
			'checked_at'                 => time(),
			'checked_utc'                => gmdate( 'c' ),
			'last_lifecycle_event'       => '',
			'terminal_event'             => '',
			'event_category'             => '',
			'stored_lifecycle_status'    => '',
			'current_state_updated'      => null,
			'requires_fresh_validation'  => true,
			'terminal'                   => false,
			'grace_warning'              => false,
			'subscription_status'        => '',
			'last_received_utc'          => '',
			'last_event_utc'             => '',
			'updated_utc'                => '',
			'privacy_note'               => 'No IP address, visitor data, chat content, lead content, raw WhatsApp number, raw admin email, raw Founder Beta invite code, raw webhook payload, or full raw licence key is collected by this advisory client.',
		);

		if ( is_array( $extra ) && ! empty( $extra ) ) {
			$result = array_merge( $result, $extra );
		}

		$result['lifecycle_only']       = true;
		$result['advisory_only']        = true;
		$result['entitlement_decision'] = 'unchanged';

		return $result;
	}
}

if ( ! function_exists( 'matewa_paid_lifecycle_status_build_payload' ) ) {
	function matewa_paid_lifecycle_status_build_payload() {
		$license_key = function_exists( 'matewa_get_license_key' )
			? matewa_get_license_key()
			: trim( (string) get_option( 'matewa_license_key', '' ) );

		$is_founder_beta_key = function_exists( 'matewa_license_key_is_founder_beta_access' )
			? matewa_license_key_is_founder_beta_access( $license_key )
			: false;

		$paid_licence_key_for_hash = $is_founder_beta_key ? '' : $license_key;
		$domain                    = matewa_paid_lifecycle_status_get_domain();
		$install_uuid              = matewa_paid_lifecycle_status_get_install_uuid();

		return array(
			'action'                => 'paid_lifecycle_status_read',
			'plugin'                => '247chatmate',
			'plugin_version'        => defined( 'MATEWA_VERSION' ) ? (string) MATEWA_VERSION : '',
			'site_hash'             => matewa_paid_lifecycle_status_hash_value( home_url( '/' ) ),
			'domain_hash'           => matewa_paid_lifecycle_status_hash_value( $domain ),
			'install_uuid_hash'     => matewa_paid_lifecycle_status_hash_value( $install_uuid ),
			'licence_key_hash'      => matewa_paid_lifecycle_status_hash_value( $paid_licence_key_for_hash ),
			'entitlement_decision'  => 'unchanged',
			'advisory_only'         => true,
			'lifecycle_only'        => true,
			'request_created'       => time(),
		);
	}
}

if ( ! function_exists( 'matewa_paid_lifecycle_status_sanitise_result' ) ) {
	function matewa_paid_lifecycle_status_sanitise_result( $result ) {
		if ( ! is_array( $result ) ) {
			$result = array();
		}

		$current_state_updated = null;
		if ( array_key_exists( 'current_state_updated', $result ) && null !== $result['current_state_updated'] ) {
			$current_state_updated = ! empty( $result['current_state_updated'] );
		}

		$last_lifecycle_event = sanitize_key( (string) ( $result['last_lifecycle_event'] ?? '' ) );
		if ( '' === $last_lifecycle_event ) {
			$last_lifecycle_event = sanitize_key( (string) ( $result['event_name'] ?? '' ) );
		}

		$terminal_event = sanitize_key( (string) ( $result['terminal_event'] ?? '' ) );
		if ( '' === $terminal_event && ! empty( $result['terminal'] ) ) {
			$terminal_event = $last_lifecycle_event;
		}

		$stored_lifecycle_status = sanitize_key( (string) ( $result['stored_lifecycle_status'] ?? '' ) );
		if ( '' === $stored_lifecycle_status ) {
			$stored_lifecycle_status = sanitize_key( (string) ( $result['stored_status'] ?? '' ) );
		}

		return array(
			'ok'                         => ! empty( $result['ok'] ),
			'code'                       => sanitize_key( (string) ( $result['code'] ?? 'unknown' ) ),
			'status'                     => sanitize_key( (string) ( $result['status'] ?? '' ) ),
			'message'                    => sanitize_text_field( (string) ( $result['message'] ?? '' ) ),
			'lifecycle_only'             => true,
			'advisory_only'              => true,
			'entitlement_decision'       => 'unchanged',
			'source'                     => sanitize_key( (string) ( $result['source'] ?? 'paid_lifecycle_status_client' ) ),
			'checked_at'                 => isset( $result['checked_at'] ) ? (int) $result['checked_at'] : time(),
			'checked_utc'                => sanitize_text_field( (string) ( $result['checked_utc'] ?? gmdate( 'c' ) ) ),
			'last_lifecycle_event'       => $last_lifecycle_event,
			'terminal_event'             => $terminal_event,
			'event_category'             => sanitize_key( (string) ( $result['event_category'] ?? '' ) ),
			'stored_lifecycle_status'    => $stored_lifecycle_status,
			'current_state_updated'      => $current_state_updated,
			'requires_fresh_validation'  => array_key_exists( 'requires_fresh_validation', $result ) ? ! empty( $result['requires_fresh_validation'] ) : true,
			'terminal'                   => ! empty( $result['terminal'] ),
			'grace_warning'              => ! empty( $result['grace_warning'] ),
			'subscription_status'        => sanitize_key( (string) ( $result['subscription_status'] ?? '' ) ),
			'last_received_utc'          => sanitize_text_field( (string) ( $result['last_received_utc'] ?? '' ) ),
			'last_event_utc'             => sanitize_text_field( (string) ( $result['last_event_utc'] ?? '' ) ),
			'updated_utc'                => sanitize_text_field( (string) ( $result['updated_utc'] ?? '' ) ),
			'privacy_note'               => 'No IP address, visitor data, chat content, lead content, raw WhatsApp number, raw admin email, raw Founder Beta invite code, raw webhook payload, or full raw licence key is collected by this advisory client.',
		);
	}
}

if ( ! function_exists( 'matewa_paid_lifecycle_status_store_result' ) ) {
	function matewa_paid_lifecycle_status_store_result( $result ) {
		$safe = matewa_paid_lifecycle_status_sanitise_result( $result );

		update_option( MATEWA_PAID_LIFECYCLE_STATUS_LAST_RESULT_OPTION, $safe, false );
		update_option( MATEWA_PAID_LIFECYCLE_STATUS_LAST_REFRESH_OPTION, time(), false );

		return $safe;
	}
}

if ( ! function_exists( 'matewa_paid_lifecycle_status_store_error' ) ) {
	function matewa_paid_lifecycle_status_store_error( $result ) {
		$safe = matewa_paid_lifecycle_status_sanitise_result( $result );

		update_option( MATEWA_PAID_LIFECYCLE_STATUS_LAST_ERROR_OPTION, $safe, false );
		update_option( MATEWA_PAID_LIFECYCLE_STATUS_LAST_REFRESH_OPTION, time(), false );

		return $safe;
	}
}

if ( ! function_exists( 'matewa_paid_lifecycle_status_get_last_result' ) ) {
	function matewa_paid_lifecycle_status_get_last_result() {
		$result = get_option( MATEWA_PAID_LIFECYCLE_STATUS_LAST_RESULT_OPTION, array() );

		return is_array( $result ) ? matewa_paid_lifecycle_status_sanitise_result( $result ) : array();
	}
}

if ( ! function_exists( 'matewa_paid_lifecycle_status_get_last_error' ) ) {
	function matewa_paid_lifecycle_status_get_last_error() {
		$result = get_option( MATEWA_PAID_LIFECYCLE_STATUS_LAST_ERROR_OPTION, array() );

		return is_array( $result ) ? matewa_paid_lifecycle_status_sanitise_result( $result ) : array();
	}
}

if ( ! function_exists( 'matewa_paid_lifecycle_status_get_last_refresh' ) ) {
	function matewa_paid_lifecycle_status_get_last_refresh() {
		return (int) get_option( MATEWA_PAID_LIFECYCLE_STATUS_LAST_REFRESH_OPTION, 0 );
	}
}

if ( ! function_exists( 'matewa_paid_lifecycle_status_manual_admin_refresh' ) ) {
	function matewa_paid_lifecycle_status_manual_admin_refresh() {
		if ( ! is_admin() || ! current_user_can( 'manage_options' ) ) {
			return matewa_paid_lifecycle_status_store_error(
				matewa_paid_lifecycle_status_advisory_result(
					'admin_required',
					'Paid lifecycle status refresh requires an authorised WordPress admin.',
					'blocked'
				)
			);
		}

		if ( matewa_paid_lifecycle_status_is_cron_request() ) {
			return matewa_paid_lifecycle_status_store_error(
				matewa_paid_lifecycle_status_advisory_result(
					'cron_blocked',
					'Paid lifecycle status refresh is not available to cron in this phase.',
					'blocked'
				)
			);
		}

		if ( get_transient( MATEWA_PAID_LIFECYCLE_STATUS_REFRESH_LOCK_TRANSIENT ) ) {
			return matewa_paid_lifecycle_status_store_error(
				matewa_paid_lifecycle_status_advisory_result(
					'refresh_locked',
					'Paid lifecycle status refresh is already running. Try again shortly.',
					'locked'
				)
			);
		}

		$lock_ttl = defined( 'MINUTE_IN_SECONDS' ) ? MINUTE_IN_SECONDS : 60;
		set_transient( MATEWA_PAID_LIFECYCLE_STATUS_REFRESH_LOCK_TRANSIENT, 1, $lock_ttl );

		$result = matewa_paid_lifecycle_status_post( matewa_paid_lifecycle_status_build_payload(), true );
		delete_transient( MATEWA_PAID_LIFECYCLE_STATUS_REFRESH_LOCK_TRANSIENT );

		return $result;
	}
}

if ( ! function_exists( 'matewa_paid_lifecycle_status_post' ) ) {
	function matewa_paid_lifecycle_status_post( $payload = array(), $store_result = false ) {
		if ( ! matewa_paid_lifecycle_status_can_request() ) {
			$result = matewa_paid_lifecycle_status_advisory_result(
				'frontend_blocked',
				'Paid lifecycle status refresh is blocked on frontend, widget, cron, and background requests.',
				'blocked'
			);

			return $store_result ? matewa_paid_lifecycle_status_store_error( $result ) : $result;
		}

		if ( ! matewa_paid_lifecycle_status_is_configured() ) {
			$result = matewa_paid_lifecycle_status_advisory_result(
				'status_not_configured',
				'Paid lifecycle status client is not configured.',
				'not_configured'
			);

			return $store_result ? matewa_paid_lifecycle_status_store_error( $result ) : $result;
		}

		if ( empty( $payload ) || ! is_array( $payload ) ) {
			$payload = matewa_paid_lifecycle_status_build_payload();
		}

		$payload['entitlement_decision'] = 'unchanged';
		$payload['advisory_only']        = true;
		$payload['lifecycle_only']       = true;

		$body = wp_json_encode( $payload, JSON_UNESCAPED_SLASHES );

		if ( ! is_string( $body ) || '' === $body ) {
			$result = matewa_paid_lifecycle_status_advisory_result(
				'invalid_payload',
				'Paid lifecycle status payload could not be created.',
				'invalid'
			);

			return $store_result ? matewa_paid_lifecycle_status_store_error( $result ) : $result;
		}

		$timestamp = (string) time();
		$signature = hash_hmac( 'sha256', $timestamp . '.' . $body, matewa_paid_lifecycle_status_get_secret() );

		$response = wp_remote_post(
			matewa_paid_lifecycle_status_get_endpoint(),
			array(
				'timeout' => MATEWA_PAID_LIFECYCLE_STATUS_TIMEOUT,
				'headers' => array(
					'Content-Type'        => 'application/json; charset=utf-8',
					'X-Matewa-Timestamp'  => $timestamp,
					'X-Matewa-Signature'  => $signature,
					'X-Matewa-Lifecycle'  => 'paid-lifecycle-status-v1',
				),
				'body'    => $body,
			)
		);

		if ( is_wp_error( $response ) ) {
			$result = matewa_paid_lifecycle_status_advisory_result(
				'status_unavailable',
				'Paid lifecycle status endpoint could not be reached.',
				'unavailable'
			);

			return $store_result ? matewa_paid_lifecycle_status_store_error( $result ) : $result;
		}

		$status_code   = (int) wp_remote_retrieve_response_code( $response );
		$response_body = (string) wp_remote_retrieve_body( $response );
		$data          = json_decode( $response_body, true );

		if ( $status_code < 200 || $status_code >= 300 || ! is_array( $data ) ) {
			$result = matewa_paid_lifecycle_status_advisory_result(
				'invalid_status_response',
				'Paid lifecycle status endpoint returned an invalid response.',
				'invalid'
			);

			return $store_result ? matewa_paid_lifecycle_status_store_error( $result ) : $result;
		}

		$data['source']               = 'paid_lifecycle_status';
		$data['entitlement_decision'] = 'unchanged';
		$data['advisory_only']        = true;
		$data['lifecycle_only']       = true;
		$data['checked_at']           = time();

		$result = matewa_paid_lifecycle_status_sanitise_result( $data );

		return $store_result ? matewa_paid_lifecycle_status_store_result( $result ) : $result;
	}
}


if ( ! function_exists( 'matewa_paid_lifecycle_status_get_warning_bridge' ) ) {
	function matewa_paid_lifecycle_status_get_warning_bridge() {
		$source_of_truth           = 'LemonSqueezy/local paid validation remains the source of truth.';
		$default_recommended_action = 'Run fresh LemonSqueezy/local licence validation before relying on paid entitlement.';

		$bridge = array(
			'advisory_only'              => true,
			'lifecycle_only'              => true,
			'entitlement_decision'        => 'unchanged',
			'source'                      => 'paid_lifecycle_warning_bridge',
			'code'                        => 'lifecycle_warning_unavailable',
			'severity'                    => 'info',
			'warning_level'               => 'info',
			'message'                     => 'Lifecycle warning bridge is available for admin display only.',
			'source_of_truth'             => $source_of_truth,
			'recommended_action'          => $default_recommended_action,
			'fresh_validation_required'   => false,
			'terminal_guard_active'       => false,
			'terminal_guard_reason'       => '',
			'local_plan_status'           => '',
			'local_paid_valid'            => false,
			'local_paid_code'             => '',
			'local_paid_source'           => '',
			'paid_registry_code'          => '',
			'paid_registry_status'        => '',
			'lifecycle_code'              => '',
			'lifecycle_status'            => '',
			'lifecycle_event'             => '',
			'lifecycle_event_category'    => '',
			'lifecycle_terminal_event'    => '',
			'lifecycle_subscription_status' => '',
			'lifecycle_terminal'          => false,
			'lifecycle_grace_warning'     => false,
			'lifecycle_checked_at'        => 0,
			'lifecycle_stale'             => false,
			'privacy_note'                => 'No IP address, visitor data, chat content, lead content, raw WhatsApp number, raw admin email, raw Founder Beta invite code, raw webhook payload, or full raw licence key is collected, stored, or displayed by this advisory warning bridge.',
		);

		if ( ! is_admin() ) {
			return $bridge;
		}

		$licence_key = function_exists( 'matewa_get_license_key' ) ? matewa_get_license_key() : trim( (string) get_option( 'matewa_license_key', '' ) );
		$is_founder_beta_key = function_exists( 'matewa_license_key_is_founder_beta_access' )
			? matewa_license_key_is_founder_beta_access( $licence_key )
			: false;

		$stored_paid = array();
		if ( '' !== $licence_key && ! $is_founder_beta_key && function_exists( 'matewa_get_stored_license_validation_result' ) ) {
			$stored_paid = matewa_get_stored_license_validation_result( $licence_key );
			$stored_paid = is_array( $stored_paid ) ? $stored_paid : array();
		}

		$bridge['local_plan_status'] = function_exists( 'matewa_license_status' )
			? sanitize_key( (string) matewa_license_status() )
			: '';
		$bridge['local_paid_valid']  = ! empty( $stored_paid['valid'] );
		$bridge['local_paid_code']   = sanitize_key( (string) ( $stored_paid['code'] ?? '' ) );
		$bridge['local_paid_source'] = sanitize_key( (string) ( $stored_paid['source'] ?? '' ) );

		$paid_registry = array();
		if ( function_exists( 'matewa_paid_licence_registry_get_last_result' ) ) {
			$paid_registry = matewa_paid_licence_registry_get_last_result();
		}
		if ( empty( $paid_registry ) && function_exists( 'matewa_paid_licence_registry_get_last_error' ) ) {
			$paid_registry = matewa_paid_licence_registry_get_last_error();
		}
		$paid_registry = is_array( $paid_registry ) ? $paid_registry : array();

		$bridge['paid_registry_code']   = sanitize_key( (string) ( $paid_registry['code'] ?? '' ) );
		$bridge['paid_registry_status'] = sanitize_key( (string) ( $paid_registry['status'] ?? '' ) );

		$lifecycle = matewa_paid_lifecycle_status_get_last_result();
		if ( empty( $lifecycle ) ) {
			$lifecycle = matewa_paid_lifecycle_status_get_last_error();
		}
		$lifecycle = is_array( $lifecycle ) ? $lifecycle : array();

		if ( empty( $lifecycle ) ) {
			$bridge['code']                      = 'no_lifecycle_data';
			$bridge['severity']                  = 'warning';
			$bridge['warning_level']             = 'warning';
			$bridge['fresh_validation_required'] = true;
			$bridge['message']                   = 'No lifecycle data is available yet. This is an advisory warning only; paid access is still controlled by LemonSqueezy/local validation.';
			return $bridge;
		}

		$lifecycle_code   = sanitize_key( (string) ( $lifecycle['code'] ?? '' ) );
		$lifecycle_status = sanitize_key( (string) ( $lifecycle['stored_lifecycle_status'] ?? '' ) );
		if ( '' === $lifecycle_status ) {
			$lifecycle_status = sanitize_key( (string) ( $lifecycle['stored_status'] ?? '' ) );
		}
		if ( '' === $lifecycle_status ) {
			$lifecycle_status = sanitize_key( (string) ( $lifecycle['status'] ?? '' ) );
		}

		$bridge['lifecycle_code']                = $lifecycle_code;
		$bridge['lifecycle_status']              = $lifecycle_status;
		$bridge['lifecycle_event']               = sanitize_key( (string) ( $lifecycle['last_lifecycle_event'] ?? '' ) );
		$bridge['lifecycle_event_category']      = sanitize_key( (string) ( $lifecycle['event_category'] ?? '' ) );
		$bridge['lifecycle_terminal_event']      = sanitize_key( (string) ( $lifecycle['terminal_event'] ?? '' ) );
		$bridge['lifecycle_subscription_status'] = sanitize_key( (string) ( $lifecycle['subscription_status'] ?? '' ) );
		$bridge['lifecycle_terminal']            = ! empty( $lifecycle['terminal'] );
		$bridge['lifecycle_grace_warning']       = ! empty( $lifecycle['grace_warning'] );
		$bridge['lifecycle_checked_at']          = isset( $lifecycle['checked_at'] ) ? (int) $lifecycle['checked_at'] : 0;
		$bridge['fresh_validation_required']     = ! empty( $lifecycle['requires_fresh_validation'] );

		$terminal_statuses = array(
			'cancelled',
			'canceled',
			'refunded',
			'refund',
			'expired',
			'disabled',
			'deactivated',
			'terminal',
			'terminal_candidate',
			'cancelled_candidate',
			'canceled_candidate',
			'refunded_candidate',
			'refund_candidate',
			'expired_candidate',
			'disabled_candidate',
			'deactivated_candidate',
			'chargeback',
			'chargebacked',
			'dispute_lost',
			'disputed',
		);
		$terminal_events = array(
			'subscription_cancelled',
			'subscription_canceled',
			'subscription_expired',
			'subscription_refunded',
			'subscription_chargeback',
			'subscription_chargebacked',
			'order_refunded',
			'order_chargeback',
			'order_chargebacked',
			'license_disabled',
			'licence_disabled',
			'license_deactivated',
			'licence_deactivated',
		);
		$active_statuses = array( 'active', 'active_candidate', 'valid', 'valid_candidate' );
		$warning_statuses = array(
			'grace',
			'grace_warning',
			'grace_warning_candidate',
			'past_due',
			'past_due_candidate',
			'unpaid',
			'unpaid_candidate',
			'payment_failed',
			'payment_failed_candidate',
			'failed_payment',
			'failed_payment_candidate',
			'on_grace_period',
			'paused',
			'paused_candidate',
		);
		$warning_events = array(
			'subscription_payment_failed',
			'subscription_payment_retry',
			'subscription_paused',
			'subscription_unpaid',
			'subscription_past_due',
		);
		$terminal_categories = array( 'terminal', 'negative', 'blocked', 'cancelled', 'canceled', 'refunded', 'chargeback', 'expired' );
		$warning_categories  = array( 'warning', 'grace', 'risk', 'payment_warning', 'payment_failed', 'requires_validation' );

		$lifecycle_values = array_filter(
			array(
				$lifecycle_status,
				$bridge['lifecycle_subscription_status'],
				$bridge['lifecycle_event_category'],
			),
			'strlen'
		);
		$lifecycle_event_values = array_filter(
			array(
				$bridge['lifecycle_event'],
				$bridge['lifecycle_terminal_event'],
			),
			'strlen'
		);

		$now         = time();
		$stale_after = 7 * ( defined( 'DAY_IN_SECONDS' ) ? (int) DAY_IN_SECONDS : 86400 );
		$is_stale    = $bridge['lifecycle_checked_at'] > 0 && ( $now - $bridge['lifecycle_checked_at'] ) > $stale_after;
		$is_terminal = $bridge['lifecycle_terminal'];
		$is_warning  = $bridge['lifecycle_grace_warning'];

		foreach ( $lifecycle_values as $lifecycle_value ) {
			if ( in_array( $lifecycle_value, $terminal_statuses, true ) || in_array( $lifecycle_value, $terminal_categories, true ) ) {
				$is_terminal = true;
			}

			if ( in_array( $lifecycle_value, $warning_statuses, true ) || in_array( $lifecycle_value, $warning_categories, true ) ) {
				$is_warning = true;
			}
		}

		foreach ( $lifecycle_event_values as $lifecycle_event_value ) {
			if ( in_array( $lifecycle_event_value, $terminal_events, true ) ) {
				$is_terminal = true;
			}

			if ( in_array( $lifecycle_event_value, $warning_events, true ) ) {
				$is_warning = true;
			}
		}

		$is_active         = in_array( $lifecycle_status, $active_statuses, true );
		$registry_terminal = in_array( $bridge['paid_registry_status'], $terminal_statuses, true );
		$registry_active   = in_array( $bridge['paid_registry_status'], $active_statuses, true );

		$bridge['lifecycle_stale']       = $is_stale;
		$bridge['terminal_guard_active'] = $is_terminal || $is_warning;

		if ( $is_terminal ) {
			$bridge['code']                      = 'lifecycle_terminal_block_active';
			$bridge['severity']                  = 'critical';
			$bridge['warning_level']             = 'guarded_terminal';
			$bridge['fresh_validation_required'] = true;
			$bridge['terminal_guard_reason']     = 'Stored lifecycle advisory data indicates a terminal paid lifecycle candidate.';
			$bridge['recommended_action']        = $default_recommended_action;
			$bridge['message']                   = 'Guarded terminal lifecycle warning active. Stored lifecycle advisory data indicates a possible terminal paid lifecycle state. This is admin-only and advisory only; it does not activate, restore, remove, downgrade, or extend Pro.';
		} elseif ( $is_warning ) {
			$bridge['code']                      = 'lifecycle_grace_warning_detected';
			$bridge['severity']                  = 'warning';
			$bridge['warning_level']             = 'guarded_grace_risk';
			$bridge['fresh_validation_required'] = true;
			$bridge['terminal_guard_reason']     = 'Stored lifecycle advisory data indicates a grace, payment, or review-risk candidate.';
			$bridge['recommended_action']        = $default_recommended_action;
			$bridge['message']                   = 'Guarded lifecycle warning active. Stored lifecycle advisory data indicates a possible grace, payment, or review-risk state. This is admin-only and advisory only; it does not change Pro access.';
		} elseif ( '' === $lifecycle_status ) {
			$bridge['code']                      = 'no_matching_lifecycle_status';
			$bridge['severity']                  = 'warning';
			$bridge['warning_level']             = 'warning';
			$bridge['fresh_validation_required'] = true;
			$bridge['message']                   = 'Lifecycle data was found, but no matching lifecycle status is available for comparison. This warning does not change entitlement.';
		} elseif ( $is_stale ) {
			$bridge['code']                      = 'stale_lifecycle_data';
			$bridge['severity']                  = 'warning';
			$bridge['warning_level']             = 'warning';
			$bridge['fresh_validation_required'] = true;
			$bridge['message']                   = 'Lifecycle data appears stale. Run the manual lifecycle refresh if needed. This warning does not change entitlement.';
		} elseif ( ( $registry_active && $is_terminal ) || ( $registry_terminal && $is_active ) ) {
			$bridge['code']                      = 'lifecycle_paid_registry_disagreement';
			$bridge['severity']                  = 'warning';
			$bridge['warning_level']             = 'warning';
			$bridge['fresh_validation_required'] = true;
			$bridge['message']                   = 'Lifecycle advisory status and paid registry mirror status appear to disagree. LemonSqueezy/local validation remains the source of truth.';
		} elseif ( ( $bridge['local_paid_valid'] && $is_terminal ) || ( ! $bridge['local_paid_valid'] && $is_active && 'pro' !== $bridge['local_plan_status'] && 'master' !== $bridge['local_plan_status'] ) ) {
			$bridge['code']                      = 'lifecycle_local_paid_disagreement';
			$bridge['severity']                  = 'warning';
			$bridge['warning_level']             = 'warning';
			$bridge['fresh_validation_required'] = true;
			$bridge['message']                   = 'Lifecycle advisory status and local paid validation appear to disagree. LemonSqueezy/local validation remains the source of truth.';
		} else {
			$bridge['code']                      = 'lifecycle_status_ok';
			$bridge['severity']                  = 'ok';
			$bridge['warning_level']             = 'ok';
			$bridge['fresh_validation_required'] = ! empty( $lifecycle['requires_fresh_validation'] );
			$bridge['recommended_action']        = 'No guarded terminal action is required from lifecycle data. Paid access still depends on LemonSqueezy/local validation.';
			$bridge['message']                   = 'No lifecycle entitlement warning detected. LemonSqueezy/local validation remains the source of truth.';
		}

		$bridge['advisory_only']       = true;
		$bridge['lifecycle_only']       = true;
		$bridge['entitlement_decision'] = 'unchanged';

		return $bridge;
	}
}
