<?php

/**
 * WooCommerce sandbox steps for Plugin Builder Playground blueprints.
 *
 * @package LolaCore\PluginBuilder\Playground
 * @license GPL-2.0-or-later
 */

declare(strict_types=1);

namespace LolaCore\PluginBuilder\Playground;

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

/**
 * Adds WooCommerce demo store setup after the WooCommerce plugin step.
 */
class WooCommercePlaygroundBootstrap {

	public const DEPENDENCY_SLUG = 'woocommerce';

	/**
	 * Curated allowlist of real WordPress.org plugin slugs that may appear as
	 * dependencies in generated plugins. Only slugs on this list will produce
	 * an `installPlugin` blueprint step. Everything else (script handles like
	 * `jquery`, `wc-cart-fragments`, or hallucinated slugs) is silently dropped.
	 *
	 * This inverts the previous denylist approach, which was a whack-a-mole:
	 * every new handle the LLM invented would 404 as
	 * `downloads.wordpress.org/plugin/{handle}.latest-stable.zip` and abort
	 * the entire Playground boot.
	 *
	 * Extend via the `lolacore_known_plugin_slugs` filter if needed.
	 */
	private const KNOWN_PLUGIN_SLUGS = array(
		'woocommerce',
		'elementor',
		'contact-form-7',
		'wpforms-lite',
		'wordpress-seo',
		'yoast-seo',
		'akismet',
		'jetpack',
		'advanced-custom-fields',
		'buddypress',
		'bbpress',
		'easy-digital-downloads',
		'memberpress',
		'fluent-support',
		'fluent-crm',
		'wp-mail-smtp',
		'wp-super-cache',
		'w3-total-cache',
		'wordfence',
		'sucuri-scanner',
		'redirection',
		'classic-editor',
		'gutenberg',
		'litespeed-cache',
		'all-in-one-seo-pack',
		'tablepress',
		'duplicator',
		'updraftplus',
		'ninja-forms',
		'formidable',
		'gravityforms',
	);

	/**
	 * Whether the generated plugin code or metadata implies a WooCommerce sandbox.
	 */
	public static function isWooCommercePlugin( array $dependencies, string $php ): bool {
		foreach ($dependencies as $dependency) {
			if (is_string($dependency) && sanitize_title($dependency) === self::DEPENDENCY_SLUG) {
				return true;
			}
		}

		return self::phpReferencesWooCommerce($php);
	}

	/**
	 * Merge metadata dependencies with WooCommerce when the code clearly needs it.
	 *
	 * @param array<int, string> $dependencies
	 * @return array<int, string>
	 */
	public static function normalizeDependencies( array $dependencies, string $php ): array {
		$normalized = self::filterInstallableSlugs($dependencies);

		if (
			self::phpReferencesWooCommerce($php)
			&& ! in_array(self::DEPENDENCY_SLUG, $normalized, true)
		) {
			$normalized[] = self::DEPENDENCY_SLUG;
		}

		$normalized = array_values(array_unique($normalized));

		usort(
			$normalized,
			static function ( string $a, string $b ): int {
				if ($a === self::DEPENDENCY_SLUG) {
					return -1;
				}
				if ($b === self::DEPENDENCY_SLUG) {
					return 1;
				}
				return strcmp($a, $b);
			}
		);

		return $normalized;
	}

	/**
	 * Keep only slugs that match known, installable WordPress.org plugins.
	 *
	 * This is the gate that prevents hallucinated dependencies (script handles
	 * like `jquery`, `wc-cart-fragments`, or invented slugs) from becoming a
	 * 404'ing `installPlugin` blueprint step.
	 *
	 * @param array<int, mixed> $slugs
	 * @return array<int, string>
	 */
	public static function filterInstallableSlugs( array $slugs ): array {
		$allowed  = self::getAllowedSlugs();
		$filtered = array();

		foreach ($slugs as $slug) {
			if (! is_scalar($slug)) {
				continue;
			}
			$clean = sanitize_title((string) $slug);
			if ($clean === '' || ! in_array($clean, $allowed, true)) {
				continue;
			}
			$filtered[] = $clean;
		}

		return array_values(array_unique($filtered));
	}

	/**
	 * Merged allowlist: built-in constant + filter extensions.
	 *
	 * @return array<int, string>
	 */
	private static function getAllowedSlugs(): array {
		$slugs = self::KNOWN_PLUGIN_SLUGS;

		if (function_exists('apply_filters')) {
			/** @var array<int, string> $slugs */
			$slugs = apply_filters('lolacore_known_plugin_slugs', $slugs);
		}

		return array_values(array_filter(array_map('strval', $slugs)));
	}

	/**
	 * Blueprint steps to run after installPlugin(woocommerce): skip onboarding, pages, sample products.
	 *
	 * @return array<int, array<string, mixed>>
	 */
	public static function sandboxSteps(): array {
		return array(
			array(
				'step' => 'runPHP',
				'code' => self::bootstrapPhp(),
			),
		);
	}

	public static function preferredLandingPage( array $dependencies, string $php ): string {
		return self::isWooCommercePlugin($dependencies, $php) ? '/shop/' : '/wp-admin/plugins.php';
	}

	private static function phpReferencesWooCommerce( string $php ): bool {
		if ($php === '') {
			return false;
		}

		return (bool) preg_match(
			'/(WooCommerce|woocommerce|WC_|wc_)/i',
			$php
		);
	}

	/**
	 * Compact PHP executed in Playground after WooCommerce is installed.
	 */
	private static function bootstrapPhp(): string {
		return <<<'PHP'
<?php
require '/wordpress/wp-load.php';

if ( ! function_exists( 'wc_get_product' ) ) {
	return;
}

delete_transient( '_wc_activation_redirect' );
update_option( 'woocommerce_task_list_hidden', 'yes' );
update_option( 'woocommerce_onboarding_profile_completed', 'yes' );

if ( function_exists( 'wc_create_page' ) ) {
	$pages = array(
		'shop'      => array( 'title' => 'Shop', 'option' => 'woocommerce_shop_page_id' ),
		'cart'      => array( 'title' => 'Cart', 'option' => 'woocommerce_cart_page_id' ),
		'checkout'  => array( 'title' => 'Checkout', 'option' => 'woocommerce_checkout_page_id' ),
		'myaccount' => array( 'title' => 'My account', 'option' => 'woocommerce_myaccount_page_id' ),
	);
	foreach ( $pages as $slug => $page ) {
		if ( ! (int) get_option( $page['option'], 0 ) ) {
			$id = wc_create_page( esc_html( $page['title'] ), $slug, '', '' );
			if ( $id ) {
				update_option( $page['option'], $id );
			}
		}
	}
}

$cat_apparel = wp_insert_term( 'Apparel', 'product_cat' );
$cat_home    = wp_insert_term( 'Home', 'product_cat' );
$cat_ids     = array();
if ( ! is_wp_error( $cat_apparel ) ) {
	$cat_ids[] = (int) $cat_apparel['term_id'];
}
if ( ! is_wp_error( $cat_home ) ) {
	$cat_ids[] = (int) $cat_home['term_id'];
}

$demo_products = array(
	array( 'Demo T-Shirt', '29.99' ),
	array( 'Demo Hoodie', '59.99' ),
	array( 'Demo Jeans', '49.99' ),
	array( 'Demo Mug', '14.99' ),
	array( 'Demo Lamp', '39.99' ),
);

foreach ( $demo_products as $index => $item ) {
	$post_id = wp_insert_post(
		array(
			'post_title'  => $item[0],
			'post_type'   => 'product',
			'post_status' => 'publish',
		),
		true
	);
	if ( is_wp_error( $post_id ) || ! $post_id ) {
		continue;
	}
	$price = $item[1];
	update_post_meta( $post_id, '_regular_price', $price );
	update_post_meta( $post_id, '_price', $price );
	update_post_meta( $post_id, '_manage_stock', 'no' );
	update_post_meta( $post_id, '_stock_status', 'instock' );
	if ( ! empty( $cat_ids ) ) {
		wp_set_object_terms( $post_id, array( $cat_ids[ $index % count( $cat_ids ) ] ), 'product_cat' );
	}
	wp_set_object_terms( $post_id, 'simple', 'product_type' );
}
PHP;
	}
}
