<?php
/**
 * Custom Post Order premium screens — packed only in the Pro add-on overlay.
 *
 * Secure design (rafter-secure-design):
 * - Identity: WordPress users who already pass the module reorder capability.
 * - AuthZ: Reset uses the same nonce + capability + post-type checks as save.
 *   Lite cannot run this file; Freemium::unlocked requires Pro + license.
 * - Mutation: Reset sets menu_order to 0 for one post type (optional parent
 *   scope). It does not delete posts.
 *
 * @package CustomPostOrder
 */

namespace CustomPostOrder;

use CustomPostOrder\Includes\PostTypeHelper;

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

/**
 * CPT query surfaces and bulk reset — not shipped in Lite.
 */
final class Premium {

	public static function boot( Module $module ): void {
		if ( ! function_exists( 'wp_powersuite_is_license_valid' ) || ! wp_powersuite_is_license_valid() ) {
			return;
		}

		add_filter( 'wp_powersuite_custom_post_order_matches_premium_context', [ self::class, 'filterPremiumContext' ], 10, 4 );
		add_action(
			'wp_ajax_wpps_cpo_reset_order',
			static function () use ( $module ): void {
				self::ajaxResetOrder( $module );
			}
		);
	}

	/**
	 * @param array<string, mixed> $settings
	 */
	public static function filterPremiumContext( bool $match, \WP_Query $query, string $post_type, array $settings ): bool {
		unset( $post_type );

		if ( $match ) {
			return true;
		}

		if ( is_admin() ) {
			return ! empty( $settings['apply_admin'] );
		}

		if ( ! empty( $settings['apply_frontend_search'] ) && $query->is_search() ) {
			return true;
		}

		if ( ! empty( $settings['apply_frontend_archive'] ) && $query->is_archive() ) {
			return true;
		}

		return false;
	}

	public static function ajaxResetOrder( Module $module ): void {
		$module->assertAjaxAllowed();

		$post_type = isset( $_POST['post_type'] ) ? sanitize_key( wp_unslash( (string) $_POST['post_type'] ) ) : '';
		$settings  = $module->getSettings();

		if ( ! in_array( $post_type, $settings['post_types'], true ) ) {
			wp_send_json_error( [ 'message' => __( 'Invalid post type.', 'wppowersuite-lite' ) ] );
		}

		$parent_id = isset( $_POST['parent_id'] ) ? max( 0, (int) $_POST['parent_id'] ) : 0;

		// A full reset must clear order for every hierarchy level, not just the
		// currently scoped parent.
		$reset_all = ! empty( $_POST['reset_all'] );
		$mode      = $reset_all ? 'global' : 'within_parent';

		$result = self::resetOrder(
			$post_type,
			$settings['reorder_capability'],
			$parent_id,
			$mode
		);

		if ( ! $result['success'] ) {
			wp_send_json_error( [ 'message' => $result['message'] ] );
		}

		wp_send_json_success( [ 'message' => $result['message'], 'updated' => $result['updated'] ] );
	}

	/**
	 * @return array{success: bool, message: string, updated: int}
	 */
	private static function resetOrder(
		string $post_type,
		string $reorder_capability,
		int $parent_id = 0,
		string $hierarchical_mode = 'within_parent'
	): array {
		$post_type = sanitize_key( $post_type );
		if ( ! PostTypeHelper::userCanReorderPostType( $post_type, $reorder_capability ) ) {
			return [
				'success' => false,
				'message' => __( 'You do not have permission to reset order for this content.', 'wppowersuite-lite' ),
				'updated' => 0,
			];
		}

		global $wpdb;

		$parent_id = max( 0, $parent_id );
		$sql       = "UPDATE {$wpdb->posts} SET menu_order = 0 WHERE post_type = %s AND post_status != 'trash'";
		$params    = [ $post_type ];

		if ( PostTypeHelper::isHierarchical( $post_type ) && $hierarchical_mode === 'within_parent' ) {
			$sql     .= ' AND post_parent = %d';
			$params[] = $parent_id;
		}

		// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter -- placeholders built above.
		$result = $wpdb->query( $wpdb->prepare( $sql, ...$params ) );

		if ( $result === false ) {
			return [
				'success' => false,
				'message' => __( 'Failed to reset order. Please try again.', 'wppowersuite-lite' ),
				'updated' => 0,
			];
		}

		return [
			'success' => true,
			'message' => __( 'Order reset successfully.', 'wppowersuite-lite' ),
			'updated' => (int) $result,
		];
	}
}
