<?php

namespace BricksExtras;

// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

class BricksExtrasLicense {

	static $prefix    = '';
	static $title     = '';
	static $store_url = '';
	static $item_id   = null;
	static $menu_slug = '';

	static function init( $prefix, $title, $store_url, $item_id ) {

		self::$prefix    = $prefix;
		self::$title     = $title;
		self::$store_url = $store_url;
		self::$item_id   = $item_id;
		self::$menu_slug = $prefix . 'menu';

		add_action( 'admin_init', array( __CLASS__, 'register_option' ) );
		add_action( 'admin_init', array( __CLASS__, 'maybe_auto_activate_constant' ) );
		add_action( 'admin_action_update', array( __CLASS__, 'activate_license' ) );
		add_action( 'admin_action_update', array( __CLASS__, 'revalidate_license' ) );
		add_action( 'admin_action_update', array( __CLASS__, 'deactivate_license' ) );
		add_action( 'admin_notices', array( __CLASS__, 'admin_notices' ) );
	}

	static function is_activated_license() {
		
		$status = get_option( self::$prefix . 'license_status' );

		if ( $status && $status === 'valid' ) {
			return true;
		}

		return false;
	}

	/**
	 * Get license key from wp-config.php constant or database
	 */
	static function get_license_key() {
		// Check for wp-config.php constant first
		if ( defined( 'BRICKSEXTRAS_LICENSE_KEY' ) && ! empty( BRICKSEXTRAS_LICENSE_KEY ) ) {
			return trim( BRICKSEXTRAS_LICENSE_KEY );
		}
		
		// Fallback to database
		return trim( get_option( self::$prefix . 'license_key' ) );
	}

	/**
	 * Get MD5 hash of license key for tracking auto-activation attempts
	 */
	static function get_license_key_hash( $license_key ) {
		return md5( $license_key );
	}

	/**
	 * Auto-activate license when BRICKSEXTRAS_LICENSE_KEY constant is defined
	 * Uses hash to ensure activation only runs once per unique license key
	 */
	static function maybe_auto_activate_constant() {
		// Only run for admin users
		if ( ! current_user_can( 'manage_options' ) ) {
			return;
		}

		// Check if constant is defined
		if ( ! defined( 'BRICKSEXTRAS_LICENSE_KEY' ) || empty( BRICKSEXTRAS_LICENSE_KEY ) ) {
			return;
		}

		$license_key = trim( BRICKSEXTRAS_LICENSE_KEY );
		$license_key_hash = self::get_license_key_hash( $license_key );
		$stored_hash = get_option( self::$prefix . 'license_key_hash' );

		// If hash matches, we've already tried activating this key
		if ( $stored_hash === $license_key_hash ) {
			return;
		}

		// Store the hash so we only try once
		update_option( self::$prefix . 'license_key_hash', $license_key_hash );

		// Attempt to activate the license
		$api_params = array(
			'edd_action' => 'activate_license',
			'license'    => $license_key,
			'item_name'  => urlencode( self::$title ),
			'url'        => home_url(),
		);

		$response = wp_remote_post(
			self::$store_url,
			array(
				'timeout'   => 15,
				'sslverify' => false,
				'body'      => $api_params,
			)
		);

		// Check response and update status
		if ( ! is_wp_error( $response ) && 200 === wp_remote_retrieve_response_code( $response ) ) {
			$license_data = json_decode( wp_remote_retrieve_body( $response ) );
			
			if ( isset( $license_data->license ) ) {
				update_option( self::$prefix . 'license_status', $license_data->license );
				
				if ( $license_data->license === 'valid' ) {
					update_option( self::$prefix . 'license_url', md5( home_url() ) );
				}
			}
		}
	}

	/**
	 * Verify license is valid for current domain
	 * Makes API call to check license status for current URL
	 */
	static function verify_license_for_current_domain() {
		$license_key = self::get_license_key();
		
		if ( empty( $license_key ) ) {
			return;
		}

		// Make EDD check_license API call
		$api_params = array(
			'edd_action' => 'check_license',
			'license'    => $license_key,
			'item_name'  => urlencode( self::$title ),
			'url'        => home_url(),
		);

		$response = wp_remote_post(
			self::$store_url,
			array(
				'timeout'   => 15,
				'sslverify' => false,
				'body'      => $api_params,
			)
		);

		// Check response and update status
		if ( ! is_wp_error( $response ) && 200 === wp_remote_retrieve_response_code( $response ) ) {
			$license_data = json_decode( wp_remote_retrieve_body( $response ) );
			
			if ( isset( $license_data->license ) ) {
				// Update status based on current domain
				update_option( self::$prefix . 'license_status', $license_data->license );
				
				// Always store URL hash to prevent repeated verification attempts
				update_option( self::$prefix . 'license_url', md5( home_url() ) );
			}
		}
	}

	static function license_page() {
		$status = get_option( self::$prefix . 'license_status' );
		$license_key = self::get_license_key();
		$constant_defined = defined( 'BRICKSEXTRAS_LICENSE_KEY' ) && ! empty( BRICKSEXTRAS_LICENSE_KEY );
		$stored_url = get_option( self::$prefix . 'license_url' );
		$current_url = home_url();
		
		// If status is valid but no license key exists, treat as inactive
		if ( $status === 'valid' && empty( $license_key ) ) {
			$status = false;
		}
		
		// Verify license for current domain if URL hash doesn't match or is missing
		// This handles existing users upgrading to the new version
		$current_url_hash = md5( $current_url );
		
		$should_verify = $license_key && $status === 'valid' && (
			! $stored_url || // No stored URL hash (legacy users)
			$stored_url !== $current_url_hash // URL hash changed (migration)
		);
		
		// Store for debug output
		$did_verify = $should_verify;
		
		if ( $should_verify ) {
			self::verify_license_for_current_domain();
			// Re-fetch status after verification
			$status = get_option( self::$prefix . 'license_status' );
			$stored_url = get_option( self::$prefix . 'license_url' );
		}
		?>

		<h2><?php echo esc_html__( 'License', 'bricksextras' ); ?></h2>

		<div style="background-color: #fff; padding: 15px 20px; border: 1px solid #ddd">
		<?php if ( ! $constant_defined ) : ?>
			<p><?php echo esc_html__( 'Follow the steps below to license the plugin:', 'bricksextras' ); ?></p>

			<ol>
				<li><?php echo esc_html__( 'Paste your key in the License Key field', 'bricksextras' ); ?></li>
				<li><?php echo esc_html__( 'Click "Activate License" button', 'bricksextras' ); ?></li>
			</ol>
		<?php endif; ?>

		<form method="post" action="options.php">

				<?php settings_fields( self::$prefix . 'license' ); ?>

				<table class="form-table">
					<tbody>
						<tr valign="top">
							<th scope="row" valign="top">
								<?php esc_html_e( 'License Key', 'bricksextras' ); ?>
							</th>
							<td>
								<input id="<?php echo esc_attr( self::$prefix ); ?>license_key" name="<?php echo esc_attr( self::$prefix ); ?>license_key" type="text" class="regular-text" placeholder="<?php echo ( $license_key || $constant_defined ) ? '********************************' : ''; ?>" value="" <?php echo $constant_defined ? 'readonly' : ''; ?> />
								<?php if ( ! $license_key && ! $constant_defined ) { ?>
									<label class="description" for="<?php echo esc_attr( self::$prefix ); ?>license_key"><?php esc_html_e( 'Enter your license key', 'bricksextras' ); ?></label>
								<?php } ?>
							</td>
						</tr>
						
						
					</tbody>
			</table>
			<?php if ( $constant_defined ) : ?>
				<?php wp_nonce_field( self::$prefix . 'nonce', self::$prefix . 'nonce' ); ?>
				<input type="submit" class="button-primary" name="<?php echo esc_attr( self::$prefix ); ?>license_revalidate" value="<?php esc_attr_e( 'Re-validate license', 'bricks' ); ?>" style="margin-right: 10px;"/>
				<?php if ( $status !== false && $status == 'valid' ) : ?>
					<span class="bricksextras-license-active"><?php esc_html_e( 'Active', 'bricks' ); ?></span>
				<?php endif; ?>
			<?php elseif ( $status !== false && $status == 'valid' ) : ?>
				<?php wp_nonce_field( self::$prefix . 'nonce', self::$prefix . 'nonce' ); ?>
				<input type="submit" class="button-primary" name="<?php echo esc_attr( self::$prefix ); ?>license_revalidate" value="<?php esc_attr_e( 'Re-validate license', 'bricks' ); ?>" style="margin-right: 10px;"/>
				<input type="submit" class="button-secondary" name="<?php echo esc_attr( self::$prefix ); ?>license_deactivate" value="<?php esc_attr_e( 'Deactivate license', 'bricks' ); ?>"/>
				<span class="bricksextras-license-active"><?php esc_html_e( 'Active', 'bricks' ); ?></span>
			<?php elseif ( $license_key && $status !== false ) : ?>
				<?php wp_nonce_field( self::$prefix . 'nonce', self::$prefix . 'nonce' ); ?>
				<input type="submit" class="button-primary" name="<?php echo esc_attr( self::$prefix ); ?>license_revalidate" value="<?php esc_attr_e( 'Re-validate license', 'bricks' ); ?>"/>
			<?php else : ?>
				<?php wp_nonce_field( self::$prefix . 'nonce', self::$prefix . 'nonce' ); ?>
				<input type="submit" class="button button-primary button-large" name="<?php echo esc_attr( self::$prefix ); ?>license_activate" value="<?php esc_attr_e( 'Activate License', 'bricksextras' ); ?>"/>
			<?php endif; ?>
				

			</form>

				

			<?php

			echo '<hr style="margin: 30px 0 20px 0;" /><p style="margin-top: 2.5em;">';
				echo esc_html__( 'NOTE: If your site has changed to a new location (migration, staging), click "Re-validate license" to license the new domain and receive updates.', 'bricksextras' );
			echo '</p>';
			
			
			echo '<hr style="margin: 30px 0 20px 0;" /><p>';

				echo esc_html__( 'The selected elements can be found inside the Bricks editor in the elements list under EXTRAS section near the bottom.', 'bricksextras' );

			echo '</p>';

			printf( '<img src="%s" alt="%s" width="300" />', esc_url( plugins_url( 'img/bricksextras-in-add-panel.png', __FILE__ ) ), esc_attr( 'BricksExtras in Add panel' ) );
			echo '</div>';


			

	}

	static function register_option() {
		// creates our settings in the options table
		register_setting( self::$prefix . 'license', self::$prefix . 'license_key', array( __CLASS__, 'edd_sanitize_license' ) );
	}

	static function edd_sanitize_license( $new ) {
		$old = get_option( self::$prefix . 'license_key' );
		if ( $old && $old != $new ) {
			delete_option( self::$prefix . 'license_status' ); // new license has been entered, so must reactivate
		}
		return $new;
	}

	private static function process_license_activation( $license ) {
		ob_start();

		// data to send in our API request
		$api_params = array(
			'edd_action' => 'activate_license',
			'license'    => $license,
			'item_name'  => urlencode( self::$title ),
			'url'        => home_url(),
		);

		// Call the custom API.
		$response = wp_remote_post(
			self::$store_url,
			array(
				'timeout'   => 15,
				'sslverify' => false,
				'body'      => $api_params,
			)
		);

		// make sure the response came back okay
		if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) {

			if ( is_wp_error( $response ) ) {
				$message = $response->get_error_message();
			} else {
				$message = esc_html__( 'An error occurred, please try again.', 'bricksextras' );
			}
		} else {

			$license_data = json_decode( wp_remote_retrieve_body( $response ) );

			if ( false === $license_data->success ) {

				switch ( $license_data->error ) {

					case 'expired':
						$message = esc_html( sprintf(
							__( 'Your license key expired on %s.', 'bricksextras' ),
							date_i18n( get_option( 'date_format' ), strtotime( $license_data->expires, current_time( 'timestamp' ) ) )
						));
						break;

					case 'disabled':
					case 'revoked':
						$message = esc_html__( 'Your license key has been disabled.', 'bricksextras' );
						break;

					case 'missing':
						$message = esc_html__( 'Invalid license.', 'bricksextras' );
						break;

					case 'invalid':
					case 'site_inactive':
						$message = esc_html__( 'Your license is not active for this URL.', 'bricksextras' );
						break;

					case 'item_name_mismatch':
						$message = esc_html( sprintf( __( 'This appears to be an invalid license key for %s.', 'bricksextras' ), self::$title ));
						break;

					case 'no_activations_left':
						$message = esc_html__( 'Your license key has reached its activation limit.', 'bricksextras' );
						break;

					default:
						$message = esc_html__( 'An error occurred, please try again.', 'bricksextras' );
						break;
				}
			}
		}

		// Check if anything passed on a message constituting a failure
		if ( ! empty( $message ) ) {
			$base_url = add_query_arg( 'tab', 'license', menu_page_url( self::$menu_slug ) );
			$redirect = add_query_arg(
				array(
					'sl_activation' => 'false',
					'message'       => urlencode( $message ),
					'nonce'         => wp_create_nonce( self::$prefix . 'license_nonce' )
				),
				$base_url
			);

			wp_safe_redirect( $redirect );
			exit();
		}

		// $license_data->license will be either "valid" or "invalid"
		update_option( self::$prefix . 'license_status', $license_data->license );
		
		// Store the URL for auto-revalidation on domain change
		if ( 'valid' === $license_data->license ) {
			update_option( self::$prefix . 'license_url', md5( home_url() ) );
		}
		
		wp_safe_redirect( add_query_arg( 'tab', 'license', menu_page_url( self::$menu_slug ) ) );
		exit();
	}

	static function activate_license() {

		// listen for our activate button to be clicked
		if ( isset( $_POST[ self::$prefix . 'license_activate' ] ) ) {
			// run a quick security check
			if ( ! check_admin_referer( self::$prefix . 'nonce', self::$prefix . 'nonce' ) ) {
				return; // get out if we didn't click the Activate button
			}

			// retrieve the license from the database
			$license = Helpers::get_post_value( self::$prefix . 'license_key' );
			$license = $license ? $license : false;

			update_option( self::$prefix . 'license_key', $license );
			
			self::process_license_activation( $license );
		}
	}

	static function revalidate_license() {

		// listen for our revalidate button to be clicked
		if ( isset( $_POST[ self::$prefix . 'license_revalidate' ] ) ) {
			// run a quick security check
			if ( ! check_admin_referer( self::$prefix . 'nonce', self::$prefix . 'nonce' ) ) {
				return; // get out if we didn't click the Re-validate button
			}

			// retrieve the license from constant or database
			$license = self::get_license_key();

			if ( ! $license ) {
				$message = __( 'No license key found. Please enter your license key and activate.', 'bricksextras' );
				$base_url = add_query_arg( 'tab', 'license', menu_page_url( self::$menu_slug ) );
				$redirect = add_query_arg(
					array(
						'sl_activation' => 'false',
						'message'       => urlencode( $message ),
						'nonce'         => wp_create_nonce( self::$prefix . 'license_nonce' )
					),
					$base_url
				);
				wp_safe_redirect( $redirect );
				exit();
			}

			self::process_license_activation( $license );
		}
	}

	static function deactivate_license() {

		// listen for our activate button to be clicked
		if ( isset( $_POST[ self::$prefix . 'license_deactivate' ] ) ) {
			ob_start();
			// run a quick security check
			if ( ! check_admin_referer( self::$prefix . 'nonce', self::$prefix . 'nonce' ) ) {
				return; // get out if we didn't click the Activate button
			}

			// retrieve the license from the database
			$license = trim( get_option( self::$prefix . 'license_key' ) );
			$post_license = Helpers::get_post_value( self::$prefix . 'license_key' );
			$license = $post_license && strlen( $post_license ) > 8 ? $post_license : $license;

			// data to send in our API requestf
			$api_params = array(
				'edd_action' => 'deactivate_license',
				'license'    => $license,
				'item_id'    => self::$item_id,
				'item_name'  => urlencode( self::$title ), // the name of our product in EDD
				'url'        => home_url(),
			);

			// Call the custom API.
			$response = wp_remote_post(
				self::$store_url,
				array(
					'timeout'   => 15,
					'sslverify' => false,
					'body'      => $api_params,
				)
			);


			// make sure the response came back okay
			if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) {

				if ( is_wp_error( $response ) ) {
					$message = $response->get_error_message();
				} else {
					$message = esc_html__( 'An error occurred, please try again.', 'bricksextras' );
				}

				$base_url = add_query_arg( 'tab', 'license', menu_page_url( self::$menu_slug ) );
				$redirect = add_query_arg(
					array(
						'sl_activation' => 'false',
						'message'       => urlencode( $message ),
						'nonce'		=> wp_create_nonce( self::$prefix . 'license_nonce' )
					),
					$base_url
				);

				wp_safe_redirect( $redirect );
				exit();
			}

			// decode the license data
			$license_data = json_decode( wp_remote_retrieve_body( $response ) );

			// $license_data->license will be either "deactivated" or "failed"
			// if($license_data->license == 'deactivated' ) {
			// delete_option( self::$prefix.'license_status' );
			// }

			delete_option( self::$prefix . 'license_status' );
			delete_option( self::$prefix . 'license_key' );
			delete_option( self::$prefix . 'license_key_hash' );

			wp_safe_redirect( add_query_arg( 'tab', 'license', menu_page_url( self::$menu_slug ) ) );
			exit();

		}
	}

	static function admin_notices() {
		$nonce = Helpers::get_get_value( 'nonce' );
		$sl_activation = Helpers::get_get_value( 'sl_activation' );
		$message_param = Helpers::get_get_value( 'message' );

		if ( $sl_activation && $message_param && $nonce && wp_verify_nonce( $nonce, self::$prefix . 'license_nonce' ) ) {

			switch ( $sl_activation ) {

				case 'false':
					$message = urldecode( $message_param );
					?>
					<div class="error">
						<p><?php echo esc_html( $message ); ?></p>
					</div>
					<?php
					break;

				case 'true':
				default:
					// Developers can put a custom success message here for when activation is successful if they way.
					break;

			}
		}
	}

	static function check_license() {

		global $wp_version;

		$license = trim( get_option( self::$prefix . 'license_key' ) );

		$api_params = array(
			'edd_action' => 'check_license',
			'license'    => $license,
			'item_name'  => urlencode( self::$title ),
			'url'        => home_url(),
		);

		// Call the custom API.
		$response = wp_remote_post(
			self::$store_url,
			array(
				'timeout'   => 15,
				'sslverify' => false,
				'body'      => $api_params,
			)
		);

		if ( is_wp_error( $response ) ) {
			return false;
		}

		$license_data = json_decode( wp_remote_retrieve_body( $response ) );

		if ( 'valid' === $license_data->license ) {
			echo 'valid';
			exit;
			// this license is still valid
		} else {
			echo 'invalid';
			exit;
			// this license is no longer valid
		}
	}


}