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

/* ======================================================================
   247ChatMate — Paid Licence Registry Client
   PAIDLICENCEREGISTRYCLIENT3F5E6
   Manual admin sync helper: PAIDLICENCEREGISTRYMANUALSYNC3F5E7

   Advisory-only mirror client for the future paid licence registry.
   LemonSqueezy remains the primary paid licence source of truth.
   This file must not become the entitlement authority.

   No automatic sync trigger is registered in this file.
   No frontend request is allowed to post to the paid registry.
   No IP address, visitor data, chat content, lead content, raw WhatsApp
   number, raw admin email, or full raw licence key is collected here.
====================================================================== */

if ( ! defined( 'MATEWA_PAID_LICENCE_REGISTRY_ENDPOINT' ) ) {
	define( 'MATEWA_PAID_LICENCE_REGISTRY_ENDPOINT', 'https://247trademate.pro/247chatmate/licence-registry.php' );
}

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

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

if ( ! defined( 'MATEWA_PAID_LICENCE_REGISTRY_LAST_RESULT_OPTION' ) ) {
	define( 'MATEWA_PAID_LICENCE_REGISTRY_LAST_RESULT_OPTION', 'matewa_paid_licence_registry_last_result' );
}

if ( ! defined( 'MATEWA_PAID_LICENCE_REGISTRY_LAST_ERROR_OPTION' ) ) {
	define( 'MATEWA_PAID_LICENCE_REGISTRY_LAST_ERROR_OPTION', 'matewa_paid_licence_registry_last_error' );
}

if ( ! defined( 'MATEWA_PAID_LICENCE_REGISTRY_LAST_SYNC_OPTION' ) ) {
	define( 'MATEWA_PAID_LICENCE_REGISTRY_LAST_SYNC_OPTION', 'matewa_paid_licence_registry_last_sync' );
}

if ( ! defined( 'MATEWA_PAID_LICENCE_REGISTRY_PENDING_SYNC_OPTION' ) ) {
	define( 'MATEWA_PAID_LICENCE_REGISTRY_PENDING_SYNC_OPTION', 'matewa_paid_licence_registry_pending_sync' );
}

if ( ! defined( 'MATEWA_PAID_LICENCE_REGISTRY_SYNC_LOCK_TRANSIENT' ) ) {
	define( 'MATEWA_PAID_LICENCE_REGISTRY_SYNC_LOCK_TRANSIENT', 'matewa_paid_licence_registry_sync_lock' );
}

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

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

if ( ! function_exists( 'matewa_paid_licence_registry_is_configured' ) ) {
	function matewa_paid_licence_registry_is_configured() {
		return '' !== matewa_paid_licence_registry_get_endpoint() && '' !== matewa_paid_licence_registry_get_secret();
	}
}

if ( ! function_exists( 'matewa_paid_licence_registry_is_cron_request' ) ) {
	function matewa_paid_licence_registry_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_licence_registry_can_request' ) ) {
	function matewa_paid_licence_registry_can_request() {
		// Paid registry requests are manual admin-only in this phase. Normal
		// frontend page loads and cron/background requests must never trigger a
		// paid registry request unless a future cron phase deliberately changes this.
		return is_admin();
	}
}

if ( ! function_exists( 'matewa_paid_licence_registry_get_domain' ) ) {
	function matewa_paid_licence_registry_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_licence_registry_hash_licence_key' ) ) {
	function matewa_paid_licence_registry_hash_licence_key( $licence_key = '' ) {
		$licence_key = trim( (string) $licence_key );

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

		$secret = matewa_paid_licence_registry_get_secret();

		if ( '' === $secret ) {
			$salt = function_exists( 'wp_salt' ) ? wp_salt( 'auth' ) : home_url( '/' );

			return hash( 'sha256', $licence_key . '|' . $salt );
		}

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

if ( ! function_exists( 'matewa_paid_licence_registry_advisory_result' ) ) {
	function matewa_paid_licence_registry_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 ),
			'entitlement_decision' => 'unchanged',
			'advisory_only'        => true,
			'source'               => 'paid_licence_registry_client',
			'checked_at'           => time(),
			'privacy_note'         => 'No IP address, visitor data, chat content, lead content, raw WhatsApp number, raw admin email, or full raw licence key is collected by this advisory client.',
		);

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

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

		return $result;
	}
}

if ( ! function_exists( 'matewa_paid_licence_registry_get_stored_paid_result' ) ) {
	function matewa_paid_licence_registry_get_stored_paid_result( $licence_key = '' ) {
		if ( '' === trim( (string) $licence_key ) || ! function_exists( 'matewa_get_stored_license_validation_result' ) ) {
			return array();
		}

		$stored = matewa_get_stored_license_validation_result( $licence_key );

		return is_array( $stored ) ? $stored : array();
	}
}

if ( ! function_exists( 'matewa_paid_licence_registry_build_payload' ) ) {
	function matewa_paid_licence_registry_build_payload( $licence_key = '', $extra = array() ) {
		$licence_key = trim( (string) $licence_key );

		if ( '' === $licence_key && function_exists( 'matewa_get_license_key' ) ) {
			$licence_key = matewa_get_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;

		$paid_licence_key_for_hash = $is_founder_beta_key ? '' : $licence_key;
		$stored_paid_result        = $is_founder_beta_key ? array() : matewa_paid_licence_registry_get_stored_paid_result( $licence_key );
		$local_paid_valid          = ! empty( $stored_paid_result['valid'] );

		$founder_beta_last           = function_exists( 'matewa_founder_beta_get_last_result' ) ? matewa_founder_beta_get_last_result() : array();
		$founder_beta_last           = is_array( $founder_beta_last ) ? $founder_beta_last : array();
		$founder_beta_status         = sanitize_key( (string) ( $founder_beta_last['status'] ?? '' ) );
		$founder_beta_record_present = ! empty( $founder_beta_last['success'] ) && in_array( $founder_beta_status, array( 'active', 'converted', 'expired' ), true );
		$founder_beta_active         = function_exists( 'matewa_founder_beta_is_active' ) ? matewa_founder_beta_is_active() : false;

		if ( function_exists( 'matewa_trial_active' ) && matewa_trial_active() ) {
			$trial_status = 'trial_active';
		} elseif ( function_exists( 'matewa_trial_expired' ) && matewa_trial_expired() ) {
			$trial_status = 'trial_expired';
		} elseif ( function_exists( 'matewa_trial_has_started' ) && matewa_trial_has_started() ) {
			$trial_status = 'trial_started';
		} else {
			$trial_status = 'trial_not_started';
		}

		$conversion_observed = $local_paid_valid && $founder_beta_record_present;

		$payload = array(
			'action'                 => 'paid_licence_registry_mirror',
			'plugin'                 => '247chatmate',
			'plugin_version'         => defined( 'MATEWA_VERSION' ) ? (string) MATEWA_VERSION : '',
			'site_url'               => esc_url_raw( home_url( '/' ) ),
			'domain'                 => matewa_paid_licence_registry_get_domain(),
			'licence_key_hash'       => matewa_paid_licence_registry_hash_licence_key( $paid_licence_key_for_hash ),
			'local_paid_valid'       => $local_paid_valid,
			'local_paid_code'        => sanitize_key( (string) ( $stored_paid_result['code'] ?? '' ) ),
			'local_paid_source'      => sanitize_key( (string) ( $stored_paid_result['source'] ?? '' ) ),
			'local_plan_status'      => function_exists( 'matewa_license_status' ) ? sanitize_key( (string) matewa_license_status() ) : '',
			'founder_beta_active'    => (bool) $founder_beta_active,
			'founder_beta_status'    => $founder_beta_status,
			'founder_beta_source'    => $founder_beta_record_present ? 'founder_beta_registry' : '',
			'trial_status'           => sanitize_key( $trial_status ),
			'conversion_observed'    => (bool) $conversion_observed,
			'conversion_type'        => $conversion_observed ? 'founder_beta_to_paid' : '',
			'entitlement_decision'   => 'unchanged',
			'advisory_only'          => true,
			'request_created'        => time(),
		);

		if ( is_array( $extra ) && ! empty( $extra ) ) {
			foreach ( $extra as $key => $value ) {
				$key = sanitize_key( (string) $key );

				if ( '' === $key || in_array( $key, array( 'ip', 'ip_address', 'ip_hash', 'hashed_ip', 'visitor_id', 'visitor_identifier', 'chat_content', 'chat_message', 'lead_content', 'lead_message', 'whatsapp_number', 'raw_whatsapp_number', 'admin_email', 'raw_admin_email', 'licence_key', 'license_key', 'raw_licence_key', 'raw_license_key', 'beta_code', 'founder_beta_code', 'founder_beta_invite_code', 'access_code', 'raw_founder_beta_invite_code' ), true ) ) {
					continue;
				}

				if ( is_scalar( $value ) || null === $value ) {
					$payload[ $key ] = sanitize_text_field( (string) $value );
				}
			}
		}

		return $payload;
	}
}

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

		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'] ?? '' ) ),
			'entitlement_decision' => 'unchanged',
			'advisory_only'        => true,
			'source'               => sanitize_key( (string) ( $result['source'] ?? 'paid_licence_registry_client' ) ),
			'checked_at'           => isset( $result['checked_at'] ) ? (int) $result['checked_at'] : time(),
			'privacy_note'         => 'No IP address, visitor data, chat content, lead content, raw WhatsApp number, raw admin email, or full raw licence key is collected by this advisory client.',
		);
	}
}

if ( ! function_exists( 'matewa_paid_licence_registry_store_result' ) ) {
	function matewa_paid_licence_registry_store_result( $result ) {
		$safe = matewa_paid_licence_registry_sanitise_result( $result );

		update_option( MATEWA_PAID_LICENCE_REGISTRY_LAST_RESULT_OPTION, $safe, false );
		update_option( MATEWA_PAID_LICENCE_REGISTRY_LAST_SYNC_OPTION, time(), false );

		return $safe;
	}
}

if ( ! function_exists( 'matewa_paid_licence_registry_store_error' ) ) {
	function matewa_paid_licence_registry_store_error( $result ) {
		$safe = matewa_paid_licence_registry_sanitise_result( $result );

		update_option( MATEWA_PAID_LICENCE_REGISTRY_LAST_ERROR_OPTION, $safe, false );
		update_option( MATEWA_PAID_LICENCE_REGISTRY_LAST_SYNC_OPTION, time(), false );

		return $safe;
	}
}


if ( ! function_exists( 'matewa_paid_licence_registry_get_last_result' ) ) {
	function matewa_paid_licence_registry_get_last_result() {
		$result = get_option( MATEWA_PAID_LICENCE_REGISTRY_LAST_RESULT_OPTION, array() );

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

if ( ! function_exists( 'matewa_paid_licence_registry_get_last_error' ) ) {
	function matewa_paid_licence_registry_get_last_error() {
		$result = get_option( MATEWA_PAID_LICENCE_REGISTRY_LAST_ERROR_OPTION, array() );

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

if ( ! function_exists( 'matewa_paid_licence_registry_get_last_sync' ) ) {
	function matewa_paid_licence_registry_get_last_sync() {
		return (int) get_option( MATEWA_PAID_LICENCE_REGISTRY_LAST_SYNC_OPTION, 0 );
	}
}

if ( ! function_exists( 'matewa_paid_licence_registry_manual_admin_sync' ) ) {
	function matewa_paid_licence_registry_manual_admin_sync() {
		if ( ! is_admin() || ! current_user_can( 'manage_options' ) ) {
			return matewa_paid_licence_registry_store_error(
				matewa_paid_licence_registry_advisory_result(
					'admin_required',
					'Paid licence registry manual sync requires an authorised WordPress admin.',
					'blocked'
				)
			);
		}

		if ( matewa_paid_licence_registry_is_cron_request() ) {
			return matewa_paid_licence_registry_store_error(
				matewa_paid_licence_registry_advisory_result(
					'cron_blocked',
					'Paid licence registry manual sync is not available to cron in this phase.',
					'blocked'
				)
			);
		}

		if ( get_transient( MATEWA_PAID_LICENCE_REGISTRY_SYNC_LOCK_TRANSIENT ) ) {
			return matewa_paid_licence_registry_store_error(
				matewa_paid_licence_registry_advisory_result(
					'sync_locked',
					'Paid licence registry manual sync is already running. Try again shortly.',
					'locked'
				)
			);
		}

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

		$payload = matewa_paid_licence_registry_build_payload(
			'',
			array(
				'source_marker' => 'manual_admin_sync',
				'sync_mode'     => 'manual_admin_sync',
			)
		);

		$result = matewa_paid_licence_registry_post( $payload, true );
		delete_transient( MATEWA_PAID_LICENCE_REGISTRY_SYNC_LOCK_TRANSIENT );

		return $result;
	}
}

if ( ! function_exists( 'matewa_paid_licence_registry_post' ) ) {
	function matewa_paid_licence_registry_post( $payload = array(), $store_result = false ) {
		if ( ! matewa_paid_licence_registry_can_request() ) {
			$result = matewa_paid_licence_registry_advisory_result(
				'frontend_blocked',
				'Paid licence registry sync is blocked on normal frontend requests.',
				'blocked'
			);

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

		if ( ! matewa_paid_licence_registry_is_configured() ) {
			$result = matewa_paid_licence_registry_advisory_result(
				'registry_not_configured',
				'Paid licence registry client is not configured.',
				'not_configured'
			);

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

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

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

		$body = wp_json_encode( $payload, JSON_UNESCAPED_SLASHES );

		if ( ! is_string( $body ) || '' === $body ) {
			$result = matewa_paid_licence_registry_advisory_result(
				'invalid_payload',
				'Paid licence registry payload could not be created.',
				'invalid'
			);

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

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

		$response = wp_remote_post(
			matewa_paid_licence_registry_get_endpoint(),
			array(
				'timeout' => MATEWA_PAID_LICENCE_REGISTRY_TIMEOUT,
				'headers' => array(
					'Content-Type'       => 'application/json; charset=utf-8',
					'X-Matewa-Timestamp' => $timestamp,
					'X-Matewa-Signature' => $signature,
					'X-Matewa-Registry'  => 'paid-licence-v1',
				),
				'body'    => $body,
			)
		);

		if ( is_wp_error( $response ) ) {
			$result = matewa_paid_licence_registry_advisory_result(
				'registry_unavailable',
				'Paid licence registry could not be reached.',
				'unavailable'
			);

			return $store_result ? matewa_paid_licence_registry_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_licence_registry_advisory_result(
				'invalid_registry_response',
				'Paid licence registry returned an invalid response.',
				'invalid'
			);

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

		$data['source']               = 'paid_licence_registry';
		$data['entitlement_decision'] = 'unchanged';
		$data['advisory_only']        = true;

		$result = matewa_paid_licence_registry_sanitise_result( $data );

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