<?php
/**
 * Fired during plugin deactivation.
 *
 * @link       https://github.com/sitestaffr/sitestaffr-plugin
 * @since      1.0.0
 *
 * @package    SiteStaffr
 * @subpackage SiteStaffr/includes
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Fired during plugin deactivation.
 *
 * This class defines all code necessary to run during the plugin's deactivation.
 *
 * @since      1.0.0
 * @package    SiteStaffr
 * @subpackage SiteStaffr/includes
 * @author     SiteStaffr
 */
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- Cleanup uses direct option-table transient purges during controlled deactivation lifecycle.
class SiteStaffr_Deactivator {
	/**
	 * Register plugins-page warning hooks for subscription persistence.
	 *
	 * @since 0.14.171
	 * @return void
	 */
	public static function register_admin_warning_hooks() {
		if ( ! is_admin() ) {
			return;
		}

		$plugin_basename = self::get_plugin_basename();
		add_filter( 'plugin_action_links_' . $plugin_basename, array( __CLASS__, 'add_plugin_action_links' ) );
		add_action( 'admin_enqueue_scripts', array( __CLASS__, 'enqueue_deactivation_assets' ) );
		add_action( 'wp_ajax_sitestaffr_submit_deactivation_feedback', array( __CLASS__, 'ajax_submit_deactivation_feedback' ) );
	}

    /**
     * Deactivate the plugin.
     *
     * Clean up temporary data and flush rewrite rules.
     *
     * @since    1.0.0
     */
    public static function deactivate() {
		self::cleanup_deactivation_runtime_data();

        // Flush rewrite rules
        flush_rewrite_rules();
    }

	/**
	 * Cleanup temporary/runtime data on deactivation.
	 *
	 * Keeps customer history/settings intact; only removes ephemeral cache/scheduled jobs.
	 *
	 * @since 0.14.181
	 * @return void
	 */
	private static function cleanup_deactivation_runtime_data() {
		global $wpdb;

		// Clear scheduled events (autopilot reschedules itself on reactivation
		// via the settings save / next tick).
		wp_clear_scheduled_hook( 'sitestaffr_blog_autopilot_tick' );
		wp_clear_scheduled_hook( 'sitestaffr_blog_index_rebuild' );
		wp_clear_scheduled_hook( 'sitestaffr_blog_pickup_poll' );
		// Visibility tracker's monthly tick re-arms itself via activation / the
		// admin_init self-heal in class-sitestaffr.php.
		wp_clear_scheduled_hook( 'sitestaffr_visibility_tick' );

		// Clear known transients.
		delete_transient( 'sitestaffr_site_registration_recent' );
		delete_transient( 'sitestaffr_db_upgrade_completed' );

		// Clear all SiteStaffr-prefixed transients (including token/rate-limit transients).
		$transient_like = $wpdb->esc_like( '_transient_sitestaffr_' ) . '%';
		$timeout_like   = $wpdb->esc_like( '_transient_timeout_sitestaffr_' ) . '%';

		$wpdb->query(
			$wpdb->prepare(
				"DELETE FROM {$wpdb->options} WHERE option_name LIKE %s",
				$transient_like
			)
		);

		$wpdb->query(
			$wpdb->prepare(
				"DELETE FROM {$wpdb->options} WHERE option_name LIKE %s",
				$timeout_like
			)
		);
	}

	/**
	 * Add billing portal quick action to plugin row links.
	 *
	 * @since 0.14.171
	 * @param array $links Existing action links.
	 * @return array
	 */
	public static function add_plugin_action_links( $links ) {
		$portal_link = sprintf(
			'<a href="%1$s">%2$s</a>',
			esc_url( self::get_billing_portal_url() ),
			esc_html__( 'Billing Portal', 'sitestaffr' )
		);

		array_unshift( $links, $portal_link );

		return $links;
	}

	/**
	 * Enqueue deactivation modal CSS and JS on plugins.php only.
	 *
	 * @since 1.2.3
	 * @param string $hook The current admin page hook suffix.
	 * @return void
	 */
	public static function enqueue_deactivation_assets( $hook ) {
		if ( 'plugins.php' !== $hook ) {
			return;
		}

		wp_enqueue_style(
			'sitestaffr-modal',
			SITESTAFFR_PLUGIN_URL . 'admin/css/sitestaffr-modal.css',
			array(),
			SITESTAFFR_VERSION
		);
		wp_enqueue_style(
			'sitestaffr-deactivation-modal',
			SITESTAFFR_PLUGIN_URL . 'admin/css/sitestaffr-deactivation-modal.css',
			array( 'sitestaffr-modal' ),
			SITESTAFFR_VERSION
		);

		// Shared modal component supplies the dialog chrome (focus trap, Esc,
		// focus-return, popup-block notice).
		if ( class_exists( 'SiteStaffr_Admin' ) ) {
			SiteStaffr_Admin::enqueue_modal_component();
		}

		wp_enqueue_script(
			'sitestaffr-deactivation-modal',
			SITESTAFFR_PLUGIN_URL . 'admin/js/sitestaffr-deactivation-modal.js',
			array( 'sitestaffr-modal' ),
			SITESTAFFR_VERSION,
			true
		);

		wp_localize_script( 'sitestaffr-deactivation-modal', 'sitestaffrDeactivationData', array(
			'pluginBasename' => plugin_basename( SITESTAFFR_PLUGIN_DIR . 'sitestaffr.php' ),
			'feedbackNonce'  => wp_create_nonce( 'sitestaffr_deactivation_feedback' ),
			'logoUrl'        => SITESTAFFR_PLUGIN_URL . 'assets/images/logo.png',
			'portalUrl'      => self::get_billing_portal_url(),
			'ajaxUrl'        => admin_url( 'admin-ajax.php' ),
			'i18n'           => array(
				'modalMessage'      => __( 'Important: Deactivating SiteStaffr DOES NOT cancel your paid subscription.', 'sitestaffr' ),
				'modalDescription'  => __( 'If you want to stop future charges, click "Cancel Subscription in Billing Portal" and cancel your subscription there first. You can still deactivate now, but billing will continue until you cancel.', 'sitestaffr' ),
				'keepActive'        => __( 'Keep Active', 'sitestaffr' ),
				'confirmLabel'      => __( 'Deactivate Only', 'sitestaffr' ),
				'finalConfirmLabel' => __( 'Submit & Deactivate Only', 'sitestaffr' ),
				'portalLabel'       => __( 'Cancel Subscription in Billing Portal', 'sitestaffr' ),
				'feedbackLabel'     => __( 'Reason for canceling (optional)', 'sitestaffr' ),
				'feedbackPlaceholder' => __( 'Anything we can improve? This helps us prioritize fixes.', 'sitestaffr' ),
				'selectReason'      => _x( 'Select a reason', 'deactivation feedback', 'sitestaffr' ),
				'reasonLowUsage'    => _x( 'No longer needed / low usage', 'deactivation feedback', 'sitestaffr' ),
				'reasonTechnical'   => _x( 'Technical issues', 'deactivation feedback', 'sitestaffr' ),
				'reasonMissingFeatures' => _x( 'Missing features', 'deactivation feedback', 'sitestaffr' ),
				'reasonSwitching'   => _x( 'Switching to another service', 'deactivation feedback', 'sitestaffr' ),
				'reasonExpensive'   => _x( 'Too expensive', 'deactivation feedback', 'sitestaffr' ),
				'reasonOther'       => _x( 'Other', 'deactivation feedback', 'sitestaffr' ),
			),
		) );
	}

	/**
	 * Handle deactivation feedback submission.
	 *
	 * @since 0.14.174
	 * @return void
	 */
	public static function ajax_submit_deactivation_feedback() {
		if ( ! current_user_can( 'activate_plugins' ) ) {
			wp_send_json_error( array( 'message' => 'forbidden' ), 403 );
		}

		check_ajax_referer( 'sitestaffr_deactivation_feedback', 'nonce' );

		$reason  = isset( $_POST['reason'] ) ? sanitize_text_field( wp_unslash( $_POST['reason'] ) ) : '';
		$details = isset( $_POST['details'] ) ? sanitize_textarea_field( wp_unslash( $_POST['details'] ) ) : '';

		$current_user = wp_get_current_user();
		$user_email   = ( $current_user && ! empty( $current_user->user_email ) ) ? sanitize_email( $current_user->user_email ) : '';

		$middleware_payload = array(
			'account_id'      => sanitize_text_field( get_option( 'sitestaffr_account_id', '' ) ),
			'installation_id' => sanitize_text_field( get_option( 'sitestaffr_installation_id', '' ) ),
			'site_url'        => esc_url_raw( get_site_url() ),
			'admin_email'     => sanitize_email( get_option( 'admin_email', '' ) ),
			'wp_user_id'      => (int) get_current_user_id(),
			'wp_user_email'   => $user_email,
			'reason'          => $reason,
			'details'         => $details,
			'source'          => 'plugin_deactivation_modal',
		);

		$remote_result = self::post_billing_endpoint( '/api/billing/cancellation-feedback', $middleware_payload );
		$remote_saved  = ! is_wp_error( $remote_result ) && ! empty( $remote_result['success'] );

		if ( ! $remote_saved && is_wp_error( $remote_result ) ) {
			SiteStaffr_Logger::legacy( 'SiteStaffr: Failed to send cancellation feedback to middleware - ' . $remote_result->get_error_message() );
		}

		wp_send_json_success(
			array(
				'remote_saved' => $remote_saved,
			)
		);
	}

	/**
	 * Build plugin basename.
	 *
	 * @since 0.14.171
	 * @return string
	 */
	private static function get_plugin_basename() {
		return plugin_basename( SITESTAFFR_PLUGIN_DIR . 'sitestaffr.php' );
	}

	/**
	 * Build signed admin-post URL for billing portal.
	 *
	 * @since 0.14.171
	 * @return string
	 */
	private static function get_billing_portal_url() {
		return wp_nonce_url(
			admin_url( 'admin-post.php?action=sitestaffr_billing_portal' ),
			'sitestaffr_billing_portal'
		);
	}

	/**
	 * Get API secret used for middleware HMAC signing.
	 *
	 * @since 0.14.175
	 * @return string
	 */
	private static function get_billing_api_secret() {
		$site_api_secret = get_option( 'sitestaffr_site_api_secret' );
		if ( ! empty( $site_api_secret ) ) {
			return $site_api_secret;
		}

		$global_api_secret = get_option( 'sitestaffr_api_secret' );
		if ( ! empty( $global_api_secret ) ) {
			return $global_api_secret;
		}

		return '';
	}

	/**
	 * Post a signed billing request to middleware.
	 *
	 * @since 0.14.175
	 * @param string $path Endpoint path.
	 * @param array  $payload Request payload.
	 * @return array|WP_Error
	 */
	private static function post_billing_endpoint( $path, $payload ) {
		$api_secret = self::get_billing_api_secret();
		if ( empty( $api_secret ) ) {
			return new WP_Error( 'missing_api_secret', __( 'Billing API secret is missing.', 'sitestaffr' ) );
		}

		$middleware_url = defined( 'SITESTAFFR_MIDDLEWARE_URL' ) ? SITESTAFFR_MIDDLEWARE_URL : '';
		if ( empty( $middleware_url ) ) {
			return new WP_Error( 'missing_middleware_url', __( 'Middleware URL is missing.', 'sitestaffr' ) );
		}

		$payload_json = wp_json_encode( $payload );
		if ( false === $payload_json ) {
			return new WP_Error( 'encode_failed', __( 'Failed to encode billing request payload.', 'sitestaffr' ) );
		}

		$timestamp     = (string) time();
		$payload_to_sign = $timestamp . '.' . $payload_json;
		$signature_raw = hash_hmac( 'sha256', $payload_to_sign, $api_secret, true );
		$signature_b64 = base64_encode( $signature_raw );

		$response = wp_remote_post(
			rtrim( $middleware_url, '/' ) . $path,
			array(
				'timeout' => 8,
				'headers' => array(
					'Content-Type'          => 'application/json',
					'X-SiteStaffr-Signature' => $signature_b64,
					'X-SiteStaffr-Timestamp' => $timestamp,
					'X-SiteStaffr-Site-URL'  => esc_url_raw( get_site_url() ),
				),
				'body'    => $payload_json,
			)
		);

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

		$status = wp_remote_retrieve_response_code( $response );
		$body   = wp_remote_retrieve_body( $response );

		$data = json_decode( $body, true );
		if ( ! is_array( $data ) ) {
			return new WP_Error( 'invalid_response', __( 'Invalid middleware response.', 'sitestaffr' ) );
		}

		if ( $status < 200 || $status >= 300 ) {
			return new WP_Error(
				'middleware_error',
				isset( $data['error'] ) ? sanitize_text_field( $data['error'] ) : __( 'Billing request failed.', 'sitestaffr' )
			);
		}

		return $data;
	}
}
// phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
