{
	"$schema": "https://playground.wordpress.net/blueprint-schema.json",
	"meta": {
		"title": "Smart Cycle Discounts — Automatic WooCommerce Discount Campaigns",
		"description": "Explore a populated demo store: 8 active and scheduled campaigns spanning every discount type, 30 days of analytics, a live activity feed, and 20 sample products across 6 categories."
	},
	"landingPage": "/wp-admin/admin.php?page=smart-cycle-discounts",
	"preferredVersions": {
		"php": "8.0",
		"wp": "latest"
	},
	"phpExtensionBundles": [
		"kitchen-sink"
	],
	"features": {
		"networking": true
	},
	"steps": [
		{
			"step": "installPlugin",
			"pluginData": {
				"resource": "wordpress.org/plugins",
				"slug": "woocommerce"
			}
		},
		{
			"step": "installPlugin",
			"pluginData": {
				"resource": "wordpress.org/plugins",
				"slug": "smart-cycle-discounts"
			}
		},
		{
			"step": "installTheme",
			"themeData": {
				"resource": "wordpress.org/themes",
				"slug": "storefront"
			}
		},
		{
			"step": "activateTheme",
			"themeFolderName": "storefront"
		},
		{
			"step": "setSiteOptions",
			"options": {
				"blogname": "Smart Cycle Discounts Demo",
				"blogdescription": "Automatic product discounts for WooCommerce — explore campaigns, analytics, and activity",
				"permalink_structure": "/%postname%/",
				"timezone_string": "UTC",
				"woocommerce_task_list_hidden": "yes",
				"woocommerce_task_list_complete": "yes",
				"woocommerce_admin_notices": [],
				"woocommerce_default_country": "US:CA",
				"woocommerce_currency": "USD",
				"wsscd_setup_wizard_completed": true
			}
		},
		{
			"step": "runPHP",
			"code": "<?php require '/wordpress/wp-load.php'; delete_transient('_wc_activation_redirect'); update_option('woocommerce_onboarding_profile', array('completed' => true)); update_user_meta(1, 'wsscd_auto_update_notice_dismissed', true); update_user_meta(1, 'wsscd_review_notice_dismissed', true); update_user_meta(1, 'wsscd_first_sale_notice_dismissed', true); if ( class_exists('WC_Install') ) { WC_Install::create_pages(); } flush_rewrite_rules(); ?>"
		},
		{
			"step": "runPHP",
			"code": "<?php\nrequire '/wordpress/wp-load.php';\n$cats = array('clothing' => 'Clothing', 'electronics' => 'Electronics', 'accessories' => 'Accessories', 'home-garden' => 'Home & Garden', 'books' => 'Books', 'sports' => 'Sports & Outdoors');\nforeach ($cats as $slug => $name) {\n\tif ( ! term_exists($slug, 'product_cat') ) {\n\t\twp_insert_term($name, 'product_cat', array('slug' => $slug));\n\t}\n}\n?>"
		},
		{
			"step": "runPHP",
			"code": "<?php\nrequire '/wordpress/wp-load.php';\n$by_slug = function($slug) { $t = get_term_by('slug', $slug, 'product_cat'); return $t ? $t->term_id : 0; };\n$products = array(\n\tarray('Classic Cotton T-Shirt',      '24.99', 'clothing'),\n\tarray('Slim Fit Denim Jeans',        '79.99', 'clothing'),\n\tarray('Summer Linen Dress',          '59.99', 'clothing'),\n\tarray('Wool Pullover Sweater',       '89.99', 'clothing'),\n\tarray('Wireless Noise-Canceling Headphones', '149.99', 'electronics'),\n\tarray('Smartphone Leather Case',     '24.99', 'electronics'),\n\tarray('Fast-Charge USB-C Adapter',   '34.99', 'electronics'),\n\tarray('Portable Bluetooth Speaker',  '79.99', 'electronics'),\n\tarray('Leather Bifold Wallet',       '49.99', 'accessories'),\n\tarray('Polarized Sunglasses',        '89.99', 'accessories'),\n\tarray('Sport Smartwatch Band',       '19.99', 'accessories'),\n\tarray('Hand-Thrown Ceramic Vase',    '44.99', 'home-garden'),\n\tarray('Linen Throw Pillow Set',      '39.99', 'home-garden'),\n\tarray('Indoor Plant Pot Set (3pc)',  '49.99', 'home-garden'),\n\tarray('Bestselling Cookbook',        '29.99', 'books'),\n\tarray('Mystery Novel Boxed Set',     '54.99', 'books'),\n\tarray('Insulated Hiking Bottle',     '32.99', 'sports'),\n\tarray('Yoga Mat — Eco-Friendly',     '44.99', 'sports'),\n\tarray('Camping Lantern (LED)',       '28.99', 'sports'),\n\tarray('Resistance Band Set',         '24.99', 'sports')\n);\nforeach ($products as $p) {\n\tif ( wc_get_product_id_by_sku('demo-' . sanitize_title($p[0])) ) { continue; }\n\t$product = new WC_Product_Simple();\n\t$product->set_name($p[0]);\n\t$product->set_regular_price($p[1]);\n\t$product->set_sku('demo-' . sanitize_title($p[0]));\n\t$product->set_stock_status('instock');\n\t$product->set_status('publish');\n\t$id = $product->save();\n\t$cat_id = $by_slug($p[2]);\n\tif ( $cat_id ) { wp_set_object_terms($id, $cat_id, 'product_cat'); }\n}\n?>"
		},
		{
			"step": "runPHP",
			"code": "<?php\nrequire '/wordpress/wp-load.php';\nglobal $wpdb;\n$t = $wpdb->prefix . 'wsscd_campaigns';\n$by_slug = function($slug) { $term = get_term_by('slug', $slug, 'product_cat'); return $term ? $term->term_id : 0; };\n$now = current_time('mysql');\n$campaigns = array(\n\tarray('name' => '20% Off All Clothing',             'slug' => 'clothing-percent',  'status' => 'active',    'priority' => 1, 'type' => 'percentage',      'value' => 20.00, 'cat' => 'clothing',     'starts' => -30, 'ends' => 365,  'color' => '#2271b1', 'icon' => 'tag',       'desc' => 'Save 20% on every item in our Clothing category — applies automatically at checkout.'),\n\tarray('name' => '$5 Off Accessories',               'slug' => 'accessories-fixed', 'status' => 'active',    'priority' => 3, 'type' => 'fixed',           'value' => 5.00,  'cat' => 'accessories',  'starts' => -25, 'ends' => 90,   'color' => '#00a32a', 'icon' => 'money-alt', 'desc' => 'Fixed $5 discount on accessories — no minimums, applied per item.'),\n\tarray('name' => 'Buy 2, Get 1 Free — Books',        'slug' => 'books-bogo',        'status' => 'active',    'priority' => 2, 'type' => 'bogo',            'value' => 100.00,'cat' => 'books',        'starts' => -14, 'ends' => 60,   'color' => '#9b59b6', 'icon' => 'book-alt',  'desc' => 'Buy any two books and get the cheapest one free — perfect summer reading promotion.'),\n\tarray('name' => 'Tiered Discount: 10/15/20% Off Electronics', 'slug' => 'electronics-tiered', 'status' => 'active', 'priority' => 2, 'type' => 'tiered',          'value' => 20.00, 'cat' => 'electronics',  'starts' => -10, 'ends' => 45,   'color' => '#e67e22', 'icon' => 'screenoptions','desc' => 'Spend $100 → 10% off, spend $200 → 15% off, spend $300 → 20% off. Stacks automatically as your cart grows.'),\n\tarray('name' => 'Spend $75 — Get Free Sports Gift', 'slug' => 'sports-threshold',  'status' => 'active',    'priority' => 4, 'type' => 'spend_threshold', 'value' => 15.00, 'cat' => 'sports',       'starts' => -7,  'ends' => 30,   'color' => '#16a085', 'icon' => 'awards',    'desc' => 'Spend $75 in the Sports category and we add a free water bottle to your cart.'),\n\tarray('name' => 'Summer Flash Sale — 30% Off Home', 'slug' => 'summer-flash',      'status' => 'scheduled', 'priority' => 1, 'type' => 'percentage',      'value' => 30.00, 'cat' => 'home-garden',  'starts' => 7,   'ends' => 21,   'color' => '#f0b849', 'icon' => 'calendar',  'desc' => 'Coming next week! 30% off everything Home & Garden for two weeks only.'),\n\tarray('name' => 'Weekend-Only 15% Storewide',       'slug' => 'weekend-recurring', 'status' => 'active',    'priority' => 5, 'type' => 'percentage',      'value' => 15.00, 'cat' => '',             'starts' => -60, 'ends' => 365,  'color' => '#3498db', 'icon' => 'calendar-alt','desc' => 'Recurring campaign — automatically activates every Saturday + Sunday, pauses Mon–Fri.'),\n\tarray('name' => 'New Year Clearance (closed)',      'slug' => 'newyear-archive',   'status' => 'expired',   'priority' => 5, 'type' => 'percentage',      'value' => 40.00, 'cat' => 'clothing',     'starts' => -120,'ends' => -60,  'color' => '#7f8c8d', 'icon' => 'archive',   'desc' => 'Archived campaign from last quarter — kept for analytics history.')\n);\nforeach ($campaigns as $c) {\n\t$cat_ids = $c['cat'] ? array($by_slug($c['cat'])) : array();\n\t$starts  = gmdate('Y-m-d H:i:s', time() + $c['starts'] * DAY_IN_SECONDS);\n\t$ends    = gmdate('Y-m-d H:i:s', time() + $c['ends']   * DAY_IN_SECONDS);\n\t$wpdb->insert($t, array(\n\t\t'uuid'                   => wp_generate_uuid4(),\n\t\t'name'                   => $c['name'],\n\t\t'slug'                   => $c['slug'],\n\t\t'description'            => $c['desc'],\n\t\t'status'                 => $c['status'],\n\t\t'priority'               => $c['priority'],\n\t\t'product_selection_type' => $c['cat'] ? 'category' : 'all_products',\n\t\t'category_ids'           => wp_json_encode($cat_ids),\n\t\t'discount_type'          => $c['type'],\n\t\t'discount_value'         => $c['value'],\n\t\t'discount_rules'         => wp_json_encode(array('discount_type' => $c['type'], 'discount_value' => $c['value'])),\n\t\t'starts_at'              => $starts,\n\t\t'ends_at'                => $ends,\n\t\t'timezone'               => 'UTC',\n\t\t'created_by'             => 1,\n\t\t'created_at'             => $starts,\n\t\t'updated_at'             => $now,\n\t\t'color_theme'            => $c['color'],\n\t\t'icon'                   => $c['icon']\n\t));\n}\n?>"
		},
		{
			"step": "runPHP",
			"code": "<?php\nrequire '/wordpress/wp-load.php';\nglobal $wpdb;\n$campaigns_table = $wpdb->prefix . 'wsscd_campaigns';\n$active_table    = $wpdb->prefix . 'wsscd_active_discounts';\n$now             = current_time('mysql');\n// Map each campaign to the products it discounts, then write rows so the\n// 'Active Discounts' view + product-page price strikethroughs both show data.\n$mapping = array(\n\t'clothing-percent'   => array('clothing',    20.00, 'percentage'),\n\t'accessories-fixed'  => array('accessories', 5.00,  'fixed'),\n\t'electronics-tiered' => array('electronics', 10.00, 'tiered'),\n\t'books-bogo'         => array('books',       100.00,'bogo')\n);\nforeach ($mapping as $campaign_slug => $info) {\n\t$campaign = $wpdb->get_row($wpdb->prepare(\"SELECT id FROM {$campaigns_table} WHERE slug = %s\", $campaign_slug));\n\tif ( ! $campaign ) { continue; }\n\t$cat_term = get_term_by('slug', $info[0], 'product_cat');\n\tif ( ! $cat_term ) { continue; }\n\t$products = get_posts(array('post_type' => 'product', 'numberposts' => -1, 'tax_query' => array(array('taxonomy' => 'product_cat', 'field' => 'term_id', 'terms' => $cat_term->term_id))));\n\tforeach ($products as $product_post) {\n\t\t$product = wc_get_product($product_post->ID);\n\t\tif ( ! $product ) { continue; }\n\t\t$original = (float) $product->get_regular_price();\n\t\tif ( 'percentage' === $info[2] ) {\n\t\t\t$discounted = round($original * (1 - $info[1] / 100), 2);\n\t\t} elseif ( 'fixed' === $info[2] ) {\n\t\t\t$discounted = max(0, round($original - $info[1], 2));\n\t\t} else {\n\t\t\t$discounted = $original;\n\t\t}\n\t\t$amount = round($original - $discounted, 2);\n\t\t$wpdb->insert($active_table, array(\n\t\t\t'uuid'              => wp_generate_uuid4(),\n\t\t\t'campaign_id'       => $campaign->id,\n\t\t\t'product_id'        => $product->get_id(),\n\t\t\t'original_price'    => $original,\n\t\t\t'discounted_price'  => $discounted,\n\t\t\t'discount_amount'   => $amount,\n\t\t\t'discount_percentage'=> 'percentage' === $info[2] ? $info[1] : ($original > 0 ? round(($amount / $original) * 100, 2) : 0),\n\t\t\t'discount_type'     => $info[2],\n\t\t\t'discount_rules'    => wp_json_encode(array('discount_type' => $info[2], 'discount_value' => $info[1])),\n\t\t\t'valid_from'        => gmdate('Y-m-d H:i:s', time() - 14 * DAY_IN_SECONDS),\n\t\t\t'valid_until'       => gmdate('Y-m-d H:i:s', time() + 30 * DAY_IN_SECONDS),\n\t\t\t'timezone'          => 'UTC',\n\t\t\t'status'            => 'active',\n\t\t\t'priority'          => 3,\n\t\t\t'application_count' => rand(8, 64),\n\t\t\t'revenue_generated' => round(rand(120, 980) + (rand(0, 99) / 100), 2),\n\t\t\t'last_applied_at'   => gmdate('Y-m-d H:i:s', time() - rand(1, 48) * HOUR_IN_SECONDS),\n\t\t\t'created_at'        => $now,\n\t\t\t'updated_at'        => $now\n\t\t));\n\t}\n}\n?>"
		},
		{
			"step": "runPHP",
			"code": "<?php\nrequire '/wordpress/wp-load.php';\nglobal $wpdb;\n$analytics_table = $wpdb->prefix . 'wsscd_analytics';\n$campaigns_table = $wpdb->prefix . 'wsscd_campaigns';\n// Seed 30 days of daily analytics for each active campaign so the Analytics\n// page renders real trend charts (revenue, impressions, conversions, AOV).\n// Numbers chosen to look like a real growing-then-stabilising campaign.\n$active = $wpdb->get_results(\"SELECT id, slug FROM {$campaigns_table} WHERE status = 'active'\");\nforeach ($active as $campaign) {\n\t// Each campaign gets a slightly different baseline so the analytics page\n\t// shows interesting comparative bars instead of identical rows.\n\t$base_impr = rand(80, 220);\n\t$base_conv_rate = rand(35, 80) / 1000.0;  // 3.5%–8% conversion\n\t$base_aov  = rand(45, 120);\n\tfor ($d = 29; $d >= 0; $d--) {\n\t\t$date = gmdate('Y-m-d', time() - $d * DAY_IN_SECONDS);\n\t\t// Realistic noise: weekend bump, gradual growth, occasional spike.\n\t\t$dow = (int) gmdate('N', time() - $d * DAY_IN_SECONDS);\n\t\t$weekend_mult = ($dow >= 6) ? 1.4 : 1.0;\n\t\t$growth_mult  = 1.0 + (29 - $d) * 0.015;\n\t\t$noise        = (rand(80, 120) / 100.0);\n\t\t$impressions = (int) round($base_impr * $weekend_mult * $growth_mult * $noise);\n\t\t$clicks      = (int) round($impressions * (rand(8, 18) / 100.0));\n\t\t$conversions = (int) round($impressions * $base_conv_rate * $weekend_mult);\n\t\t$revenue     = round($conversions * $base_aov * (rand(80, 120) / 100.0), 2);\n\t\t$discount    = round($revenue * (rand(15, 25) / 100.0), 2);\n\t\t$wpdb->insert($analytics_table, array(\n\t\t\t'campaign_id'         => $campaign->id,\n\t\t\t'date_recorded'       => $date,\n\t\t\t'hour_recorded'       => null,\n\t\t\t'impressions'         => $impressions,\n\t\t\t'clicks'              => $clicks,\n\t\t\t'conversions'         => $conversions,\n\t\t\t'revenue'             => $revenue,\n\t\t\t'discount_given'      => $discount,\n\t\t\t'cart_total'          => round($revenue + $discount, 2),\n\t\t\t'products_shown'      => $impressions,\n\t\t\t'products_purchased'  => $conversions,\n\t\t\t'unique_customers'    => max(1, (int) round($conversions * 0.85)),\n\t\t\t'returning_customers' => max(0, (int) round($conversions * 0.15)),\n\t\t\t'cart_additions'      => $clicks,\n\t\t\t'checkout_starts'     => (int) round($clicks * 0.6),\n\t\t\t'checkout_completions'=> $conversions,\n\t\t\t'average_order_value' => $conversions > 0 ? round($revenue / $conversions, 2) : 0,\n\t\t\t'device_mobile'       => (int) round($impressions * 0.55),\n\t\t\t'device_desktop'      => (int) round($impressions * 0.35),\n\t\t\t'device_tablet'       => (int) round($impressions * 0.10),\n\t\t\t'traffic_organic'     => (int) round($impressions * 0.40),\n\t\t\t'traffic_direct'      => (int) round($impressions * 0.25),\n\t\t\t'traffic_social'      => (int) round($impressions * 0.20),\n\t\t\t'traffic_email'       => (int) round($impressions * 0.10),\n\t\t\t'traffic_paid'        => (int) round($impressions * 0.05)\n\t\t));\n\t}\n}\n?>"
		},
		{
			"step": "runPHP",
			"code": "<?php\nrequire '/wordpress/wp-load.php';\nglobal $wpdb;\n$log_table       = $wpdb->prefix . 'wsscd_activity_log';\n$campaigns_table = $wpdb->prefix . 'wsscd_campaigns';\n$first_campaign_id = (int) $wpdb->get_var(\"SELECT id FROM {$campaigns_table} WHERE slug = 'clothing-percent' LIMIT 1\");\n$flash_campaign_id = (int) $wpdb->get_var(\"SELECT id FROM {$campaigns_table} WHERE slug = 'summer-flash' LIMIT 1\");\n$weekend_id        = (int) $wpdb->get_var(\"SELECT id FROM {$campaigns_table} WHERE slug = 'weekend-recurring' LIMIT 1\");\n$tiered_id         = (int) $wpdb->get_var(\"SELECT id FROM {$campaigns_table} WHERE slug = 'electronics-tiered' LIMIT 1\");\n$events = array(\n\tarray('campaign_activated',    array('campaign_name' => '20% Off All Clothing', 'by' => 'admin'),       $first_campaign_id, 2 * DAY_IN_SECONDS),\n\tarray('discount_applied',      array('order_id' => 1058, 'discount_amount' => 16.00, 'subtotal' => 80), $first_campaign_id, 4 * HOUR_IN_SECONDS),\n\tarray('discount_applied',      array('order_id' => 1057, 'discount_amount' => 24.00, 'subtotal' => 120),$first_campaign_id, 9 * HOUR_IN_SECONDS),\n\tarray('threshold_reached',     array('campaign_name' => 'Spend $75 — Get Free Sports Gift', 'cart_total' => 86.50), null, 12 * HOUR_IN_SECONDS),\n\tarray('campaign_scheduled',    array('campaign_name' => 'Summer Flash Sale — 30% Off Home', 'starts_at' => gmdate('Y-m-d H:i:s', time() + 7 * DAY_IN_SECONDS)), $flash_campaign_id, 18 * HOUR_IN_SECONDS),\n\tarray('recurring_activated',   array('campaign_name' => 'Weekend-Only 15% Storewide', 'period' => 'Saturday 00:00 → Sunday 23:59 UTC'), $weekend_id, 1 * DAY_IN_SECONDS),\n\tarray('tier_unlocked',         array('campaign_name' => 'Tiered Electronics', 'tier' => '15% off', 'cart_total' => 215.00), $tiered_id, 1 * DAY_IN_SECONDS + 6 * HOUR_IN_SECONDS),\n\tarray('discount_applied',      array('order_id' => 1051, 'discount_amount' => 9.00,  'subtotal' => 60),  $first_campaign_id, 2 * DAY_IN_SECONDS),\n\tarray('campaign_created',      array('campaign_name' => 'Weekend-Only 15% Storewide', 'by' => 'admin'),  $weekend_id, 3 * DAY_IN_SECONDS),\n\tarray('campaign_created',      array('campaign_name' => '20% Off All Clothing', 'by' => 'admin'),       $first_campaign_id, 30 * DAY_IN_SECONDS)\n);\nforeach ($events as $ev) {\n\t$wpdb->insert($log_table, array(\n\t\t'event_type'  => $ev[0],\n\t\t'event_data'  => wp_json_encode($ev[1]),\n\t\t'campaign_id' => $ev[2],\n\t\t'user_id'     => 1,\n\t\t'created_at'  => gmdate('Y-m-d H:i:s', time() - $ev[3])\n\t));\n}\n?>"
		},
		{
			"step": "runPHP",
			"code": "<?php\nrequire '/wordpress/wp-load.php';\nglobal $wpdb;\n$usage_table     = $wpdb->prefix . 'wsscd_customer_usage';\n$campaigns_table = $wpdb->prefix . 'wsscd_campaigns';\n// Sample customer-usage rows so the 'Per-customer limits' feature looks real.\n$campaign_id = (int) $wpdb->get_var(\"SELECT id FROM {$campaigns_table} WHERE slug = 'clothing-percent' LIMIT 1\");\nif ( $campaign_id ) {\n\t$now = current_time('mysql');\n\t$customers = array(\n\t\tarray('alex.morgan@demo.test',  3, 47.50, 285.00, $now),\n\t\tarray('jordan.kim@demo.test',   1, 18.00, 120.00, $now),\n\t\tarray('robin.osei@demo.test',   2, 32.00, 200.00, $now),\n\t\tarray('taylor.park@demo.test',  1, 15.00, 75.00,  $now),\n\t\tarray('sam.delgado@demo.test',  4, 78.00, 420.00, $now)\n\t);\n\tforeach ($customers as $u) {\n\t\t$wpdb->insert($usage_table, array(\n\t\t\t'campaign_id'           => $campaign_id,\n\t\t\t'customer_email'        => $u[0],\n\t\t\t'usage_count'           => $u[1],\n\t\t\t'first_used_at'         => gmdate('Y-m-d H:i:s', time() - 20 * DAY_IN_SECONDS),\n\t\t\t'last_used_at'          => gmdate('Y-m-d H:i:s', time() - rand(1, 5) * DAY_IN_SECONDS),\n\t\t\t'total_discount_amount' => $u[2],\n\t\t\t'total_order_value'     => $u[3],\n\t\t\t'status'                => 'active',\n\t\t\t'created_at'            => $u[4],\n\t\t\t'updated_at'            => $u[4]\n\t\t));\n\t}\n}\n?>"
		},
		{
			"step": "login",
			"username": "admin",
			"password": "password"
		}
	]
}
