<?php
/**
 * Review engine: asks for a WordPress.org review only when the user is
 * predictably happy — the plugin has demonstrably worked for them (enough
 * products auto-assigned, enough days of use). Shown only on the plugin's own
 * screens, fully dismissible (guideline 11 friendly).
 *
 * @package SmartCategories
 */

defined( 'ABSPATH' ) || exit;

/**
 * Class SCWC_Review
 */
class SCWC_Review {

	const OPTION     = 'scwc_review';
	const REVIEW_URL = 'https://wordpress.org/support/plugin/smart-categories-for-woocommerce/reviews/#new-post';

	/**
	 * Wire hooks (admin only).
	 */
	public static function init() {
		add_action( 'admin_notices', array( __CLASS__, 'maybe_render' ) );
		add_action( 'admin_init', array( __CLASS__, 'handle_action' ) );
	}

	/**
	 * Current notice state.
	 *
	 * @return array{status:string,snooze_until:int}
	 */
	private static function state() {
		$state = get_option( self::OPTION, array() );
		return array(
			'status'       => isset( $state['status'] ) ? $state['status'] : 'pending',
			'snooze_until' => isset( $state['snooze_until'] ) ? (int) $state['snooze_until'] : 0,
		);
	}

	/**
	 * Whether the ask should be shown right now. All thresholds are proof of
	 * value: at least one working smart category that has actually organised
	 * a meaningful number of products, over at least a week of use.
	 *
	 * @return bool
	 */
	public static function should_show() {
		$state = self::state();
		if ( 'pending' !== $state['status'] ) {
			return false;
		}
		if ( $state['snooze_until'] > time() ) {
			return false;
		}

		$activated = (int) get_option( 'scwc_activated_at', 0 );
		/**
		 * Filter the minimum days of use before asking for a review.
		 *
		 * @param int $days Default 7.
		 */
		$min_days = (int) apply_filters( 'scwc_review_min_days', 7 );
		if ( ! $activated || ( time() - $activated ) < $min_days * DAY_IN_SECONDS ) {
			return false;
		}

		if ( count( SCWC_Term_Rules::get_smart_term_ids() ) < 1 ) {
			return false;
		}

		global $wpdb;
		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- count over the plugin's own tracking table.
		$managed = (int) $wpdb->get_var( $wpdb->prepare( 'SELECT COUNT(*) FROM %i', SCWC_Install::table_name() ) );
		/**
		 * Filter the minimum auto-assigned products before asking for a review.
		 *
		 * @param int $count Default 20.
		 */
		return $managed >= (int) apply_filters( 'scwc_review_min_products', 20 );
	}

	/**
	 * Render the ask — only on the plugin's own screens.
	 */
	public static function maybe_render() {
		$screen = function_exists( 'get_current_screen' ) ? get_current_screen() : null;
		if ( ! $screen || ! in_array( $screen->id, array( 'toplevel_page_scwc-overview', 'edit-product_cat' ), true ) ) {
			return;
		}
		if ( ! current_user_can( 'manage_woocommerce' ) || ! self::should_show() ) {
			return;
		}

		global $wpdb;
		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- count over the plugin's own tracking table.
		$managed = (int) $wpdb->get_var( $wpdb->prepare( 'SELECT COUNT(*) FROM %i', SCWC_Install::table_name() ) );

		$url = function ( $action ) {
			return wp_nonce_url( add_query_arg( 'scwc_review', $action ), 'scwc_review' );
		};
		// Deliberately NOT using the .notice class: several hosts/plugins hide
		// all .notice elements globally; a self-styled banner survives them.
		?>
		<div class="scwc-review-notice" style="display:flex;align-items:center;gap:14px;padding:12px 16px;margin:12px 20px 8px 2px;background:#fff;border:1px solid #dcdcde;border-left:4px solid #2271b1;border-radius:4px;box-shadow:0 1px 2px rgba(0,0,0,.05);">
			<span style="font-size:26px;line-height:1;">🎉</span>
			<div style="flex:1;">
				<p style="margin:0 0 2px;font-weight:600;">
					<?php
					printf(
						/* translators: %d: number of auto-assigned products */
						esc_html__( 'Smart Categories has automatically organised %d products in your store.', 'smart-categories-for-woocommerce' ),
						(int) $managed
					);
					?>
				</p>
				<p style="margin:0;color:#50575e;">
					<?php esc_html_e( 'If it saves you time, a quick review on WordPress.org would help us a lot. Thank you!', 'smart-categories-for-woocommerce' ); ?>
				</p>
			</div>
			<a class="button button-primary" target="_blank" rel="noopener" href="<?php echo esc_url( $url( 'done' ) ); ?>" onclick="window.open('<?php echo esc_url( self::REVIEW_URL ); ?>','_blank');">
				<?php esc_html_e( '⭐ Leave a review', 'smart-categories-for-woocommerce' ); ?>
			</a>
			<a class="button" href="<?php echo esc_url( $url( 'later' ) ); ?>"><?php esc_html_e( 'Maybe later', 'smart-categories-for-woocommerce' ); ?></a>
			<a href="<?php echo esc_url( $url( 'never' ) ); ?>" style="color:#757575;text-decoration:none;"><?php esc_html_e( 'Don’t ask again', 'smart-categories-for-woocommerce' ); ?></a>
		</div>
		<?php
	}

	/**
	 * Persist the user's choice (done / later / never) and clean the URL.
	 */
	public static function handle_action() {
		if ( ! isset( $_GET['scwc_review'] ) || ! current_user_can( 'manage_woocommerce' ) ) {
			return;
		}
		check_admin_referer( 'scwc_review' );

		$action = sanitize_key( wp_unslash( $_GET['scwc_review'] ) );
		$state  = self::state();

		if ( 'done' === $action || 'never' === $action ) {
			$state['status'] = ( 'done' === $action ) ? 'done' : 'never';
		} elseif ( 'later' === $action ) {
			/**
			 * Filter the snooze duration in days for "maybe later".
			 *
			 * @param int $days Default 14.
			 */
			$state['snooze_until'] = time() + (int) apply_filters( 'scwc_review_snooze_days', 14 ) * DAY_IN_SECONDS;
		} else {
			return;
		}

		update_option( self::OPTION, $state, false );
		wp_safe_redirect( remove_query_arg( array( 'scwc_review', '_wpnonce' ) ) );
		exit;
	}
}
