<?php
/**
 * Seeds sample categories, plans, customers, subscriptions, and invoices.
 *
 * @package Lucrativeit_Subscription_Recurring_Billing
 */

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

/**
 * Demo data importer for fresh installs.
 */
class LUCRSURE_Demo_Data {

	const STATE_OPTION = 'lucrsure_demo_import_state';

	/**
	 * Whether demo data can be imported (no existing business records).
	 *
	 * @return bool
	 */
	public static function can_import() {
		if ( get_option( 'lucrsure_demo_data_imported' ) ) {
			return false;
		}

		$plans = new LUCRSURE_Plan_Repository();
		$cust  = new LUCRSURE_Customer_Repository();

		return 0 === $plans->count() && 0 === $cust->count();
	}

	/**
	 * All importable category slugs.
	 *
	 * @return string[]
	 */
	public static function get_all_category_slugs() {
		return array_keys( self::category_definitions() );
	}

	/**
	 * Category slugs pre-selected in the setup wizard.
	 *
	 * @return string[]
	 */
	public static function get_default_setup_categories() {
		return lucrsure_demo_default_category_slugs();
	}

	/**
	 * Category metadata for the setup modal.
	 *
	 * @return array<string,array{name:string,description:string,plan_count:int}>
	 */
	public static function get_category_choices() {
		$defs  = self::category_definitions();
		$plans = self::plan_definitions();
		$out   = array();

		foreach ( $defs as $slug => $data ) {
			$out[ $slug ] = array(
				'name'        => $data['name'],
				'description' => $data['description'],
				'plan_count'  => isset( $plans[ $slug ] ) ? count( $plans[ $slug ] ) : 0,
			);
		}

		return $out;
	}

	/**
	 * Ordered import steps for the progress UI.
	 *
	 * @param string[]|null $selected_categories Category slugs (null = read from import state).
	 * @return array<int,array{key:string,label:string}>
	 */
	public static function get_import_steps( $selected_categories = null ) {
		if ( null === $selected_categories ) {
			$state = get_option( self::STATE_OPTION, array() );
			$selected_categories = ! empty( $state['selected_categories'] )
				? (array) $state['selected_categories']
				: self::get_all_category_slugs();
		}

		$selected_categories = array_values( array_intersect( $selected_categories, self::get_all_category_slugs() ) );
		$choices             = self::get_category_choices();

		$steps = array(
			array(
				'key'   => 'branches',
				'label' => __( 'Creating sample locations…', 'lucrativeit-subscription-recurring-billing' ),
			),
			array(
				'key'   => 'categories',
				'label' => __( 'Creating plan categories…', 'lucrativeit-subscription-recurring-billing' ),
			),
		);

		foreach ( $selected_categories as $slug ) {
			$name    = isset( $choices[ $slug ]['name'] ) ? $choices[ $slug ]['name'] : $slug;
			$steps[] = array(
				'key'   => 'plans-' . $slug,
				'label' => sprintf(
					/* translators: %s: category name */
					__( 'Importing %s plans…', 'lucrativeit-subscription-recurring-billing' ),
					$name
				),
			);
		}

		$steps[] = array(
			'key'   => 'customers',
			'label' => __( 'Creating sample customers…', 'lucrativeit-subscription-recurring-billing' ),
		);
		$steps[] = array(
			'key'   => 'subscriptions',
			'label' => __( 'Generating subscriptions & invoices…', 'lucrativeit-subscription-recurring-billing' ),
		);
		$steps[] = array(
			'key'   => 'pages',
			'label' => __( 'Publishing public plan pages…', 'lucrativeit-subscription-recurring-billing' ),
		);
		$steps[] = array(
			'key'   => 'finalize',
			'label' => __( 'Finishing up…', 'lucrativeit-subscription-recurring-billing' ),
		);

		return $steps;
	}

	/**
	 * Begin a new staged import.
	 *
	 * @param string[] $selected_categories Category slugs to import.
	 * @return bool
	 */
	public static function start_import( array $selected_categories = array() ) {
		if ( ! self::can_import() ) {
			return false;
		}

		$selected = array_values( array_intersect( $selected_categories, self::get_all_category_slugs() ) );
		if ( empty( $selected ) ) {
			return false;
		}

		$existing = get_option( self::STATE_OPTION, array() );
		if ( ! empty( $existing['started_at'] ) && is_array( $existing ) ) {
			$prev = isset( $existing['selected_categories'] ) ? array_values( (array) $existing['selected_categories'] ) : array();
			sort( $prev );
			$compare = $selected;
			sort( $compare );
			if ( $prev === $compare ) {
				return true;
			}
			delete_option( self::STATE_OPTION );
		}

		$settings = get_option( 'lucrsure_settings', array() );
		$currency = isset( $settings['default_currency'] ) ? $settings['default_currency'] : 'USD';

		update_option(
			self::STATE_OPTION,
			array(
				'currency'            => $currency,
				'selected_categories' => $selected,
				'categories'          => array(),
				'plans'               => array(),
				'customers'           => array(),
				'started_at'          => current_time( 'mysql' ),
			)
		);

		return true;
	}

	/**
	 * Run a single import step.
	 *
	 * @param string $step Step key.
	 * @return array{success:bool,message:string,percent:int,done:bool,hub_url?:string}
	 */
	public static function run_step( $step ) {
		$state = get_option( self::STATE_OPTION, array() );
		if ( empty( $state ) || ! is_array( $state ) ) {
			return array(
				'success' => false,
				'message' => __( 'Import session expired. Please try again.', 'lucrativeit-subscription-recurring-billing' ),
				'percent' => 0,
				'done'    => false,
			);
		}

		$steps   = self::get_import_steps( isset( $state['selected_categories'] ) ? $state['selected_categories'] : null );
		$index   = 0;
		$matched = false;

		foreach ( $steps as $i => $row ) {
			if ( $row['key'] === $step ) {
				$index   = $i;
				$matched = true;
				break;
			}
		}

		if ( ! $matched ) {
			return array(
				'success' => false,
				'message' => __( 'Unknown import step.', 'lucrativeit-subscription-recurring-billing' ),
				'percent' => 0,
				'done'    => false,
			);
		}

		$currency = $state['currency'];

		switch ( $step ) {
			case 'branches':
				$branch_ids          = self::seed_branches();
				$state['branches']   = $branch_ids;
				self::apply_demo_branch_settings( $branch_ids );
				break;

			case 'categories':
				$state['categories'] = self::seed_categories( $state['selected_categories'] );
				break;

			default:
				if ( 0 === strpos( $step, 'plans-' ) ) {
					$cat_slug = substr( $step, 6 );
					if ( in_array( $cat_slug, (array) $state['selected_categories'], true ) ) {
						$batch          = self::seed_plans_for_category(
							$cat_slug,
							$state['categories'],
							$currency,
							isset( $state['branches'] ) ? (array) $state['branches'] : array()
						);
						$state['plans'] = array_merge( isset( $state['plans'] ) ? $state['plans'] : array(), $batch );
					}
				}
				break;

			case 'customers':
				$planned_subs = self::ensure_category_subscription_coverage(
					self::subscription_definitions(),
					$state['plans'],
					isset( $state['selected_categories'] ) ? (array) $state['selected_categories'] : array()
				);
				$state['planned_subscriptions'] = $planned_subs;
				$state['customers']               = self::seed_customers( $planned_subs, $state['plans'] );
				break;

			case 'subscriptions':
				$planned_subs = isset( $state['planned_subscriptions'] ) && is_array( $state['planned_subscriptions'] )
					? $state['planned_subscriptions']
					: self::subscription_definitions();
				self::seed_subscriptions_and_invoices( $state['plans'], $state['customers'], $currency, $planned_subs );
				break;

			case 'pages':
				( new LUCRSURE_Plan_Category_Repository() )->consolidate_duplicates();
				LUCRSURE_Plan_Pages::create_demo_pages(
					$state['categories'],
					$state['plans'],
					isset( $state['selected_categories'] ) ? (array) $state['selected_categories'] : array()
				);
				break;

			case 'finalize':
				update_option( 'lucrsure_demo_data_imported', current_time( 'mysql' ) );
				update_option( 'lucrsure_onboarding_dismissed', true );
				delete_option( self::STATE_OPTION );

				$percent = 100;
				$hub_url = LUCRSURE_Plan_Pages::get_hub_url();
				$created = LUCRSURE_Plan_Pages::get_map();
				$page_url = '';
				foreach ( $created as $slug => $page_id ) {
					if ( '__hub__' === $slug ) {
						continue;
					}
					$page_url = get_permalink( (int) $page_id );
					if ( $page_url ) {
						break;
					}
				}

				return array(
					'success' => true,
					'message' => __( 'Sample data imported successfully!', 'lucrativeit-subscription-recurring-billing' ),
					'percent' => $percent,
					'done'    => true,
					'hub_url' => $hub_url ? $hub_url : $page_url,
				);
		}

		update_option( self::STATE_OPTION, $state );

		$percent = (int) round( ( ( $index + 1 ) / count( $steps ) ) * 100 );
		$label   = $steps[ $index ]['label'];

		return array(
			'success' => true,
			'message' => $label,
			'percent' => min( 99, $percent ),
			'done'    => false,
		);
	}

	/**
	 * Import all sample data synchronously (legacy fallback).
	 *
	 * @param string[]|null $selected_categories Category slugs (null = all).
	 * @return bool True on success.
	 */
	public static function import( $selected_categories = null ) {
		$categories = null === $selected_categories ? self::get_default_setup_categories() : $selected_categories;
		if ( ! self::start_import( $categories ) ) {
			return false;
		}

		foreach ( self::get_import_steps( $categories ) as $step ) {
			$result = self::run_step( $step['key'] );
			if ( empty( $result['success'] ) ) {
				delete_option( self::STATE_OPTION );
				return false;
			}
		}

		return true;
	}

	/**
	 * Preview counts for a subset of categories (setup modal).
	 *
	 * @param string[] $selected_slugs Category slugs.
	 * @return array<string,int|string[]>
	 */
	public static function preview_for_categories( array $selected_slugs ) {
		$selected_slugs = array_values( array_intersect( $selected_slugs, self::get_all_category_slugs() ) );
		$plan_defs      = self::plan_definitions();
		$cat_defs       = self::category_definitions();
		$plan_count     = 0;
		$names          = array();

		foreach ( $selected_slugs as $slug ) {
			if ( isset( $plan_defs[ $slug ] ) ) {
				$plan_count += count( $plan_defs[ $slug ] );
			}
			if ( isset( $cat_defs[ $slug ]['name'] ) ) {
				$names[] = $cat_defs[ $slug ]['name'];
			}
		}

		$imported_plan_slugs = array();
		foreach ( $selected_slugs as $slug ) {
			if ( isset( $plan_defs[ $slug ] ) ) {
				$imported_plan_slugs = array_merge( $imported_plan_slugs, array_keys( $plan_defs[ $slug ] ) );
			}
		}

		$customer_keys = array();
		foreach ( self::subscription_definitions() as $def ) {
			if ( in_array( $def['plan'], $imported_plan_slugs, true ) ) {
				$customer_keys[ $def['customer'] ] = true;
			}
		}

		$subscription_count = 0;
		foreach ( self::subscription_definitions() as $def ) {
			if ( in_array( $def['plan'], $imported_plan_slugs, true ) ) {
				++$subscription_count;
			}
		}

		return array(
			'categories'     => count( $selected_slugs ),
			'plans'          => $plan_count,
			'customers'      => count( $customer_keys ),
			'subscriptions'  => $subscription_count,
			'pages'          => count( $selected_slugs ) + ( count( $selected_slugs ) > 1 ? 1 : 0 ),
			'category_names' => $names,
			'intervals'      => array( 'day', 'week', 'month', 'year', 'lifetime' ),
		);
	}

	/**
	 * Human-readable summary for the onboarding card.
	 *
	 * @return array<string,int|string[]>
	 */
	public static function preview() {
		$plan_count = 0;
		foreach ( self::plan_definitions() as $plans ) {
			$plan_count += count( $plans );
		}

		return array(
			'locations'      => 3,
			'categories'     => 5,
			'plans'          => $plan_count,
			'customers'      => 10,
			'subscriptions'  => 12,
			'invoices'         => 20,
			'pages'          => 6,
			'category_names' => array(
				__( 'Software License', 'lucrativeit-subscription-recurring-billing' ),
				__( 'Online Coaching', 'lucrativeit-subscription-recurring-billing' ),
				__( 'SaaS Software', 'lucrativeit-subscription-recurring-billing' ),
				__( 'Internet (ISP)', 'lucrativeit-subscription-recurring-billing' ),
				__( 'Gym Membership', 'lucrativeit-subscription-recurring-billing' ),
			),
			'intervals'      => array( 'day', 'week', 'month', 'year', 'lifetime' ),
		);
	}

	/**
	 * Plan definitions grouped by category slug.
	 *
	 * @return array<string,array<string,array<string,mixed>>>
	 */
	public static function plan_definitions() {
		return array(
			'gym-membership' => array(
				'gym-day-pass'        => array( 'name' => __( 'Day Pass', 'lucrativeit-subscription-recurring-billing' ), 'price' => 12, 'interval' => 'day', 'features' => array( 'Single-day access', 'Locker room', 'Cardio & weights', 'Free towel service', 'Shower facilities', 'Guest orientation' ) ),
				'gym-day-premium'     => array( 'name' => __( 'Premium Day Pass', 'lucrativeit-subscription-recurring-billing' ), 'price' => 18, 'interval' => 'day', 'features' => array( 'All-day access', 'Sauna & steam', '1 group class', 'Premium locker', 'Smoothie bar discount', 'Recovery zone access' ) ),
				'gym-week-flex'       => array( 'name' => __( 'Weekly Flex', 'lucrativeit-subscription-recurring-billing' ), 'price' => 35, 'interval' => 'week', 'features' => array( '7-day access', 'Locker room', '2 classes / week', 'Cardio & weights', 'Mobile app check-in', 'Member support line' ) ),
				'gym-week-plus'       => array( 'name' => __( 'Weekly Plus', 'lucrativeit-subscription-recurring-billing' ), 'price' => 45, 'interval' => 'week', 'features' => array( '7-day access', 'Unlimited classes', 'Guest pass', 'Sauna access', 'Towel service', 'Fitness assessment' ) ),
				'gym-basic'           => array( 'name' => __( 'Basic', 'lucrativeit-subscription-recurring-billing' ), 'price' => 29, 'interval' => 'month', 'features' => array( 'Unlimited gym access', 'Locker room', '2 group classes / week', 'Cardio & strength zones', 'Member mobile app', 'Cancel anytime' ) ),
				'gym-standard'        => array( 'name' => __( 'Standard', 'lucrativeit-subscription-recurring-billing' ), 'price' => 49, 'interval' => 'month', 'features' => array( 'All Basic features', 'Unlimited classes', 'Sauna access', 'Guest pass / month', 'Nutrition tips newsletter', 'Priority class booking' ) ),
				'gym-premium'         => array( 'name' => __( 'Premium', 'lucrativeit-subscription-recurring-billing' ), 'price' => 69, 'interval' => 'month', 'features' => array( 'All Standard features', 'PT session / month', 'Nutrition guide', 'Recovery lounge', '2 guest passes / month', 'Exclusive member events' ) ),
				'gym-annual-basic'    => array( 'name' => __( 'Annual Basic', 'lucrativeit-subscription-recurring-billing' ), 'price' => 299, 'interval' => 'year', 'features' => array( '12 months Basic access', '2 months free', 'Member events', 'Annual fitness review', 'Locker rental included', 'Freeze option available' ) ),
				'gym-vip'             => array( 'name' => __( 'VIP', 'lucrativeit-subscription-recurring-billing' ), 'price' => 599, 'interval' => 'year', 'features' => array( 'All Premium features', 'Priority booking', 'VIP lounge', 'Unlimited guest passes', 'Quarterly PT sessions', 'Concierge support' ) ),
				'gym-lifetime-elite'  => array( 'name' => __( 'Lifetime Elite', 'lucrativeit-subscription-recurring-billing' ), 'price' => 1999, 'interval' => 'lifetime', 'features' => array( 'Lifetime full access', 'All amenities', 'Family add-on discount', 'Founding member status', 'Annual wellness retreat', 'No renewal fees ever' ) ),
			),
			'internet-isp' => array(
				'isp-day-hotspot'     => array( 'name' => __( 'Daily Hotspot', 'lucrativeit-subscription-recurring-billing' ), 'price' => 5, 'interval' => 'day', 'features' => array( '24-hour access', '25 Mbps burst', 'No contract', 'Instant activation', 'Works on any device', 'Email setup guide' ) ),
				'isp-day-boost'       => array( 'name' => __( 'Day Boost', 'lucrativeit-subscription-recurring-billing' ), 'price' => 8, 'interval' => 'day', 'features' => array( '24-hour access', '100 Mbps burst', 'Streaming optimized', 'Low-latency gaming mode', 'No data cap', 'Same-day support' ) ),
				'isp-week-25'         => array( 'name' => __( 'Weekly 25M', 'lucrativeit-subscription-recurring-billing' ), 'price' => 15, 'interval' => 'week', 'features' => array( '25 Mbps', 'Unlimited data', 'Self-install kit', 'Wi-Fi router included', 'Online account portal', '7-day money-back' ) ),
				'isp-week-100'        => array( 'name' => __( 'Weekly 100M', 'lucrativeit-subscription-recurring-billing' ), 'price' => 22, 'interval' => 'week', 'features' => array( '100 Mbps', 'Unlimited data', 'Email support', 'HD streaming ready', 'Parental controls', 'Free speed test tools' ) ),
				'isp-25mbps'          => array( 'name' => __( '25 Mbps', 'lucrativeit-subscription-recurring-billing' ), 'price' => 39, 'interval' => 'month', 'features' => array( '25 Mbps download', 'Unlimited data', 'Free router rental', 'Email & web support', 'No setup fee', 'Month-to-month terms' ) ),
				'isp-100mbps'         => array( 'name' => __( '100 Mbps', 'lucrativeit-subscription-recurring-billing' ), 'price' => 59, 'interval' => 'month', 'features' => array( '100 Mbps download', 'Unlimited data', 'Priority support', 'Wi-Fi 6 router', '4K streaming ready', 'Network security suite' ) ),
				'isp-500mbps'         => array( 'name' => __( '500 Mbps', 'lucrativeit-subscription-recurring-billing' ), 'price' => 99, 'interval' => 'month', 'features' => array( '500 Mbps download', 'Unlimited data', 'Static IP included', 'Pro installation', 'Dedicated support line', 'Business-grade uptime SLA' ) ),
				'isp-annual-100'      => array( 'name' => __( 'Annual 100M', 'lucrativeit-subscription-recurring-billing' ), 'price' => 599, 'interval' => 'year', 'features' => array( '100 Mbps year-round', 'Free installation', 'Wi-Fi 6 router', '2 months free', 'Annual equipment check', 'Price lock guarantee' ) ),
				'isp-annual-500'      => array( 'name' => __( 'Annual 500M', 'lucrativeit-subscription-recurring-billing' ), 'price' => 999, 'interval' => 'year', 'features' => array( '500 Mbps year-round', 'Static IP', 'Dedicated support', 'Premium router upgrade', 'Priority outage response', 'Free mesh extender' ) ),
				'isp-lifetime-fiber'  => array( 'name' => __( 'Fiber for Life', 'lucrativeit-subscription-recurring-billing' ), 'price' => 2499, 'interval' => 'lifetime', 'features' => array( 'Lifetime 500 Mbps', 'No monthly bills', 'Equipment upgrades', 'Transferable to new address', 'Lifetime support', 'Founding customer perks' ) ),
			),
			'online-coaching' => array(
				'coach-day-motivation' => array( 'name' => __( 'Daily Motivation', 'lucrativeit-subscription-recurring-billing' ), 'price' => 9, 'interval' => 'day', 'features' => array( 'Daily prompts', 'Audio lessons', 'Journal template', 'Mindset exercises', 'Progress tracker', 'Mobile-friendly access' ) ),
				'coach-day-intensive'  => array( 'name' => __( 'Intensive Day', 'lucrativeit-subscription-recurring-billing' ), 'price' => 15, 'interval' => 'day', 'features' => array( 'Live mini-session', 'Action worksheet', 'Q&A replay', 'Goal-setting workbook', 'Peer accountability tips', '24-hour resource access' ) ),
				'coach-self'           => array( 'name' => __( 'Self', 'lucrativeit-subscription-recurring-billing' ), 'price' => 25, 'interval' => 'week', 'features' => array( 'Self-paced modules', 'Weekly check-in email', 'Resource library', 'Downloadable templates', 'Habit tracker', 'Community read access' ) ),
				'coach-self-plus'      => array( 'name' => __( 'Self Plus', 'lucrativeit-subscription-recurring-billing' ), 'price' => 35, 'interval' => 'week', 'features' => array( 'All Self features', 'Community forum', 'Monthly webinar', 'Expert Q&A archive', 'Bonus challenge packs', 'Certificate of completion' ) ),
				'coach-group'          => array( 'name' => __( 'Group', 'lucrativeit-subscription-recurring-billing' ), 'price' => 99, 'interval' => 'month', 'features' => array( 'Live group sessions', 'Community access', 'Workbooks', 'Weekly accountability', 'Recorded replays', 'Private group chat' ) ),
				'coach-group-pro'      => array( 'name' => __( 'Group Pro', 'lucrativeit-subscription-recurring-billing' ), 'price' => 149, 'interval' => 'month', 'features' => array( 'Twice-weekly sessions', 'Accountability partner', 'Progress tracking', 'Personalized feedback', 'Advanced workbooks', 'Priority coach access' ) ),
				'coach-1to1'           => array( 'name' => __( '1-to-1', 'lucrativeit-subscription-recurring-billing' ), 'price' => 299, 'interval' => 'month', 'features' => array( 'Weekly 1-to-1 calls', 'Custom action plan', 'Direct messaging', 'Unlimited email support', 'Tailored resources', 'Monthly progress review' ) ),
				'coach-annual-group'   => array( 'name' => __( 'Annual Group', 'lucrativeit-subscription-recurring-billing' ), 'price' => 899, 'interval' => 'year', 'features' => array( 'Full-year group program', '2 bonus intensives', 'Alumni network', 'All session replays', 'Annual retreat discount', 'Lifetime community access' ) ),
				'coach-lifetime'       => array( 'name' => __( 'Lifetime Access', 'lucrativeit-subscription-recurring-billing' ), 'price' => 1499, 'interval' => 'lifetime', 'features' => array( 'All recorded content', 'Future program access', 'Annual live retreat', 'VIP alumni community', 'New course early access', 'No renewal fees ever' ) ),
			),
			'saas-software' => array(
				'saas-day-team'        => array( 'name' => __( 'Daily Team', 'lucrativeit-subscription-recurring-billing' ), 'price' => 7, 'interval' => 'day', 'features' => array( 'Up to 3 users', 'Core features', '24-hour access', 'Cloud sync', 'Basic reporting', 'Email support' ) ),
				'saas-week-starter'    => array( 'name' => __( 'Weekly Starter', 'lucrativeit-subscription-recurring-billing' ), 'price' => 19, 'interval' => 'week', 'features' => array( 'Up to 5 users', 'Core features', 'Email support', 'Team dashboard', 'File sharing', 'Mobile app access' ) ),
				'saas-week-growth'     => array( 'name' => __( 'Weekly Growth', 'lucrativeit-subscription-recurring-billing' ), 'price' => 39, 'interval' => 'week', 'features' => array( 'Up to 10 users', 'Analytics', 'Priority email', 'Custom workflows', 'Integrations hub', 'Usage insights' ) ),
				'saas-team'            => array( 'name' => __( 'Team', 'lucrativeit-subscription-recurring-billing' ), 'price' => 49, 'interval' => 'month', 'features' => array( 'Up to 5 users', 'Core features', 'Email support', 'Shared workspaces', 'Role permissions', '99.9% uptime' ) ),
				'saas-growth'          => array( 'name' => __( 'Growth', 'lucrativeit-subscription-recurring-billing' ), 'price' => 149, 'interval' => 'month', 'features' => array( 'Up to 25 users', 'Advanced analytics', 'Priority support', 'API access', 'Custom branding', 'Audit logs' ) ),
				'saas-pro'             => array( 'name' => __( 'Pro', 'lucrativeit-subscription-recurring-billing' ), 'price' => 299, 'interval' => 'month', 'features' => array( 'Up to 100 users', 'API access', 'SLA support', 'SSO ready', 'Dedicated onboarding', 'Advanced security' ) ),
				'saas-annual-growth'   => array( 'name' => __( 'Annual Growth', 'lucrativeit-subscription-recurring-billing' ), 'price' => 1499, 'interval' => 'year', 'features' => array( '25 users included', '2 months free', 'Onboarding call', 'Annual strategy review', 'Priority feature requests', 'Data export tools' ) ),
				'saas-enterprise'      => array( 'name' => __( 'Enterprise', 'lucrativeit-subscription-recurring-billing' ), 'price' => 4999, 'interval' => 'year', 'features' => array( 'Unlimited users', 'SSO & audit logs', 'Dedicated manager', 'Custom contracts', 'On-premise option', '24/7 phone support' ) ),
				'saas-lifetime'        => array( 'name' => __( 'Perpetual License', 'lucrativeit-subscription-recurring-billing' ), 'price' => 9999, 'interval' => 'lifetime', 'features' => array( 'Unlimited users', 'Lifetime updates', 'Source escrow option', 'Perpetual usage rights', 'Major version upgrades', 'Premium support tier' ) ),
			),
			'software-license' => array(
				'license-day-trial'      => array( 'name' => __( 'Trial Day', 'lucrativeit-subscription-recurring-billing' ), 'price' => 3, 'interval' => 'day', 'features' => array( 'Full features 24h', 'No credit card', 'Export enabled', 'All modules unlocked', 'Sample projects included', 'Quick-start guide' ) ),
				'license-week-personal' => array( 'name' => __( 'Weekly Personal', 'lucrativeit-subscription-recurring-billing' ), 'price' => 12, 'interval' => 'week', 'features' => array( '1 device', 'Weekly updates', 'Email support', 'Cloud backup', 'Offline mode', 'Basic templates' ) ),
				'license-month-personal' => array( 'name' => __( 'Personal Monthly', 'lucrativeit-subscription-recurring-billing' ), 'price' => 15, 'interval' => 'month', 'features' => array( '1 device', 'Monthly updates', 'Community forum', 'Premium templates', 'Auto-save & sync', 'Cancel anytime' ) ),
				'license-month-business' => array( 'name' => __( 'Business Monthly', 'lucrativeit-subscription-recurring-billing' ), 'price' => 49, 'interval' => 'month', 'features' => array( '10 devices', 'Priority updates', 'Chat support', 'Team license manager', 'Volume discounts', 'Invoice billing' ) ),
				'license-personal'     => array( 'name' => __( 'Personal', 'lucrativeit-subscription-recurring-billing' ), 'price' => 99, 'interval' => 'year', 'features' => array( '1 device', 'Annual updates', 'Email support', 'All premium features', 'Free minor upgrades', '30-day refund policy' ) ),
				'license-business'     => array( 'name' => __( 'Business', 'lucrativeit-subscription-recurring-billing' ), 'price' => 299, 'interval' => 'year', 'features' => array( 'Up to 10 devices', 'Priority updates', 'Phone support', 'Centralized admin', 'Deployment tools', 'Annual compliance report' ) ),
				'license-agency'       => array( 'name' => __( 'Agency', 'lucrativeit-subscription-recurring-billing' ), 'price' => 999, 'interval' => 'lifetime', 'features' => array( 'Unlimited devices', 'Lifetime updates', 'White-label rights', 'Client project folders', 'Reseller dashboard', 'Priority bug fixes' ) ),
				'license-enterprise'   => array( 'name' => __( 'Enterprise Lifetime', 'lucrativeit-subscription-recurring-billing' ), 'price' => 2999, 'interval' => 'lifetime', 'features' => array( 'Unlimited seats', 'Dedicated support', 'Custom integrations', 'On-site training', 'SLA guarantee', 'Source code escrow' ) ),
			),
		);
	}

	/**
	 * Sample branch definitions for demo import.
	 *
	 * @return array<string,array<string,mixed>>
	 */
	public static function branch_definitions() {
		return array(
			'downtown' => array(
				'name'         => __( 'Downtown District', 'lucrativeit-subscription-recurring-billing' ),
				'code'         => 'DTN',
				'region'       => __( 'Downtown District', 'lucrativeit-subscription-recurring-billing' ),
				'address'      => __( '123 Main Street, Suite 100', 'lucrativeit-subscription-recurring-billing' ),
				'phone'        => '+1 555-0201',
				'opening_time' => '06:00',
				'closing_time' => '22:00',
				'image'        => 'assets/demo/locations/location-tokyo.png',
				'amenities'    => array(
					__( 'Cardio Zone', 'lucrativeit-subscription-recurring-billing' ),
					__( 'Free Parking', 'lucrativeit-subscription-recurring-billing' ),
					__( 'Sauna', 'lucrativeit-subscription-recurring-billing' ),
				),
				'description'  => __( 'Our flagship downtown location with full cardio and strength facilities.', 'lucrativeit-subscription-recurring-billing' ),
				'is_main'      => 1,
			),
			'westside' => array(
				'name'         => __( 'Green Valley', 'lucrativeit-subscription-recurring-billing' ),
				'code'         => 'GRV',
				'region'       => __( 'Green Valley', 'lucrativeit-subscription-recurring-billing' ),
				'address'      => __( '456 Oak Avenue', 'lucrativeit-subscription-recurring-billing' ),
				'phone'        => '+1 555-0202',
				'opening_time' => '05:30',
				'closing_time' => '23:00',
				'image'        => 'assets/demo/locations/location-sahara.png',
				'amenities'    => array(
					__( '24/7 Access', 'lucrativeit-subscription-recurring-billing' ),
					__( 'Pool', 'lucrativeit-subscription-recurring-billing' ),
					__( 'Personal Training', 'lucrativeit-subscription-recurring-billing' ),
				),
				'description'  => __( 'Extended hours and premium amenities in the Green Valley area.', 'lucrativeit-subscription-recurring-billing' ),
				'is_main'      => 0,
			),
			'eastside' => array(
				'name'         => __( 'Silver Lake', 'lucrativeit-subscription-recurring-billing' ),
				'code'         => 'SLK',
				'region'       => __( 'Silver Lake', 'lucrativeit-subscription-recurring-billing' ),
				'address'      => __( '789 Elm Boulevard', 'lucrativeit-subscription-recurring-billing' ),
				'phone'        => '+1 555-0203',
				'opening_time' => '07:00',
				'closing_time' => '21:00',
				'image'        => 'assets/demo/locations/location-alps.png',
				'amenities'    => array(
					__( 'Group Classes', 'lucrativeit-subscription-recurring-billing' ),
					__( 'Yoga Studio', 'lucrativeit-subscription-recurring-billing' ),
					__( 'Smoothie Bar', 'lucrativeit-subscription-recurring-billing' ),
				),
				'description'  => __( 'Boutique studio focused on group fitness and wellness programs in Silver Lake.', 'lucrativeit-subscription-recurring-billing' ),
				'is_main'      => 0,
			),
		);
	}

	/**
	 * Category metadata keyed by slug.
	 *
	 * @return array<string,array{name:string,description:string}>
	 */
	public static function category_definitions() {
		return array(
			'gym-membership'   => array(
				'name'        => __( 'Gym Membership', 'lucrativeit-subscription-recurring-billing' ),
				'description' => __( 'Fitness club memberships and passes.', 'lucrativeit-subscription-recurring-billing' ),
			),
			'internet-isp'     => array(
				'name'        => __( 'Internet (ISP)', 'lucrativeit-subscription-recurring-billing' ),
				'description' => __( 'Residential and business broadband plans.', 'lucrativeit-subscription-recurring-billing' ),
			),
			'online-coaching'  => array(
				'name'        => __( 'Online Coaching', 'lucrativeit-subscription-recurring-billing' ),
				'description' => __( 'Personal and group coaching programs.', 'lucrativeit-subscription-recurring-billing' ),
			),
			'saas-software'    => array(
				'name'        => __( 'SaaS Software', 'lucrativeit-subscription-recurring-billing' ),
				'description' => __( 'Cloud software for teams and businesses.', 'lucrativeit-subscription-recurring-billing' ),
			),
			'software-license' => array(
				'name'        => __( 'Software License', 'lucrativeit-subscription-recurring-billing' ),
				'description' => __( 'Desktop and productivity software licenses.', 'lucrativeit-subscription-recurring-billing' ),
			),
		);
	}

	/**
	 * Import a branch image for demo data.
	 *
	 * @param array $data Branch definition.
	 * @return int Attachment ID.
	 */
	protected static function import_branch_image( array $data ) {
		if ( empty( $data['image'] ) ) {
			return 0;
		}

		return lucrsure_import_plugin_attachment( $data['image'], $data['name'] );
	}

	/**
	 * Create sample branches with demo images.
	 *
	 * @return int[] Branch IDs.
	 */
	protected static function seed_branches() {
		$repo     = new LUCRSURE_Branch_Repository();
		$existing = $repo->active();
		if ( ! empty( $existing ) ) {
			return array_map( 'intval', wp_list_pluck( $existing, 'id' ) );
		}

		$ids  = array();
		$defs = self::branch_definitions();

		foreach ( $defs as $data ) {
			$image_id = self::import_branch_image( $data );

			$id = $repo->insert(
				array(
					'name'         => $data['name'],
					'code'         => $data['code'],
					'region'       => $data['region'],
					'address'      => $data['address'],
					'phone'        => $data['phone'],
					'opening_time' => $data['opening_time'],
					'closing_time' => $data['closing_time'],
					'image_id'     => $image_id,
					'amenities'    => implode( "\n", $data['amenities'] ),
					'description'  => $data['description'],
					'is_main'      => ! empty( $data['is_main'] ) ? 1 : 0,
					'is_active'    => 1,
				)
			);

			if ( $id ) {
				$ids[] = (int) $id;
			}
		}

		return $ids;
	}

	/**
	 * Enable locations on the frontend and assign demo branch IDs.
	 *
	 * @param int[] $branch_ids Branch IDs.
	 */
	protected static function apply_demo_branch_settings( array $branch_ids ) {
		if ( empty( $branch_ids ) ) {
			return;
		}

		$settings = get_option( 'lucrsure_settings', array() );
		if ( ! isset( $settings['frontend'] ) || ! is_array( $settings['frontend'] ) ) {
			$settings['frontend'] = lucrsure_default_frontend_settings();
		}

		$settings['frontend']['locations_enabled']    = 1;
		$settings['frontend']['locations_branch_ids'] = array_values( array_map( 'absint', $branch_ids ) );
		update_option( 'lucrsure_settings', $settings );
	}

	/**
	 * @param string[]|null $selected_slugs Category slugs to seed (null = all).
	 * @return array<string,int> Slug => ID.
	 */
	protected static function seed_categories( $selected_slugs = null ) {
		if ( null === $selected_slugs ) {
			$selected_slugs = self::get_all_category_slugs();
		}

		$repo = new LUCRSURE_Plan_Category_Repository();
		$repo->consolidate_duplicates();
		$defs = self::category_definitions();
		$map  = array();

		foreach ( $selected_slugs as $slug ) {
			if ( ! isset( $defs[ $slug ] ) ) {
				continue;
			}

			$data     = $defs[ $slug ];
			$existing = $repo->find_by_slug( $slug );

			if ( $existing ) {
				$id = (int) $existing['id'];
				$repo->update(
					$id,
					array(
						'name'        => $data['name'],
						'description' => $data['description'],
						'is_active'   => 1,
					)
				);
			} else {
				$id = $repo->insert(
					array(
						'name'        => $data['name'],
						'slug'        => $slug,
						'description' => $data['description'],
						'is_active'   => 1,
					)
				);
			}

			if ( $id ) {
				$map[ $slug ] = $id;
			}
		}

		return $map;
	}

	/**
	 * @param string            $category_slug Category slug.
	 * @param array<string,int> $categories    Category slug => ID.
	 * @param string            $currency      Currency code.
	 * @param int[]             $branch_ids    Demo branch IDs.
	 * @return array<string,int> Plan slug => ID.
	 */
	protected static function seed_plans_for_category( $category_slug, array $categories, $currency, array $branch_ids = array() ) {
		$all_defs = self::plan_definitions();
		if ( ! isset( $all_defs[ $category_slug ], $categories[ $category_slug ] ) ) {
			return array();
		}

		$repo = new LUCRSURE_Plan_Repository();
		$map  = array();

		$category_id     = (int) $categories[ $category_slug ];
		$branch_ids      = array_values( array_filter( array_map( 'absint', $branch_ids ) ) );
		$assign_branches = ! empty( $branch_ids ) && in_array( $category_slug, array( 'gym-membership', 'internet-isp' ), true );
		$branch_index    = 0;

		foreach ( $all_defs[ $category_slug ] as $slug => $plan ) {
			$plan_data = array(
				'name'             => $plan['name'],
				'slug'             => $slug,
				'description'      => sprintf(
					/* translators: %s: plan name */
					__( 'Sample %s plan for demonstration.', 'lucrativeit-subscription-recurring-billing' ),
					$plan['name']
				),
				'price'            => (float) $plan['price'],
				'currency'         => $currency,
				'billing_interval' => $plan['interval'],
				'interval_count'   => 1,
				'trial_days'       => isset( $plan['trial_days'] ) ? (int) $plan['trial_days'] : 0,
				'features'         => wp_json_encode( $plan['features'] ),
				'category_id'      => $category_id,
				'branch_id'        => 0,
				'is_active'        => 1,
			);

			if ( $assign_branches ) {
				$plan_data['branch_id'] = $branch_ids[ $branch_index % count( $branch_ids ) ];
				++$branch_index;
			}

			$existing = $repo->find_by_slug( $slug );
			if ( $existing ) {
				$id = (int) $existing['id'];
				$repo->update( $id, $plan_data );
			} else {
				$id = $repo->insert( $plan_data );
			}

			if ( $id ) {
				$map[ $slug ] = $id;
			}
		}

		return $map;
	}

	/**
	 * Sample subscription rows keyed by demo customer + plan slugs.
	 *
	 * @return array<int,array{customer:string,plan:string,status:string,months_ago:int}>
	 */
	public static function subscription_definitions() {
		return array(
			array( 'customer' => 'john', 'plan' => 'gym-vip', 'status' => 'active', 'months_ago' => 5 ),
			array( 'customer' => 'sarah', 'plan' => 'saas-growth', 'status' => 'active', 'months_ago' => 4 ),
			array( 'customer' => 'mike', 'plan' => 'isp-100mbps', 'status' => 'active', 'months_ago' => 3 ),
			array( 'customer' => 'emily', 'plan' => 'coach-group', 'status' => 'trialing', 'months_ago' => 0 ),
			array( 'customer' => 'acme', 'plan' => 'saas-enterprise', 'status' => 'active', 'months_ago' => 6 ),
			array( 'customer' => 'david', 'plan' => 'license-business', 'status' => 'past_due', 'months_ago' => 2 ),
			array( 'customer' => 'lisa', 'plan' => 'gym-basic', 'status' => 'active', 'months_ago' => 1 ),
			array( 'customer' => 'james', 'plan' => 'license-agency', 'status' => 'active', 'months_ago' => 2 ),
			array( 'customer' => 'nina', 'plan' => 'gym-week-plus', 'status' => 'active', 'months_ago' => 1 ),
			array( 'customer' => 'alex', 'plan' => 'isp-day-boost', 'status' => 'active', 'months_ago' => 0 ),
			array( 'customer' => 'mike', 'plan' => 'coach-self', 'status' => 'canceled', 'months_ago' => 4 ),
			array( 'customer' => 'sarah', 'plan' => 'saas-week-growth', 'status' => 'active', 'months_ago' => 0 ),
		);
	}

	/**
	 * @param array<int,array{customer:string,plan:string,status:string,months_ago:int}> $subscription_defs Rows to import.
	 * @param array<string,int>                                                          $plans             Imported plan slug => ID.
	 * @return array<string,int> Customer key => ID.
	 */
	protected static function seed_customers( array $subscription_defs = array(), array $plans = array() ) {
		$repo          = new LUCRSURE_Customer_Repository();
		$customer_defs = array(
			'john'  => array( 'name' => 'John Martinez', 'email' => 'john.martinez@example.com', 'phone' => '+1 555-0101', 'company' => '' ),
			'sarah' => array( 'name' => 'Sarah Chen', 'email' => 'sarah.chen@example.com', 'phone' => '+1 555-0102', 'company' => 'Bright Labs' ),
			'mike'  => array( 'name' => 'Mike Thompson', 'email' => 'mike.thompson@example.com', 'phone' => '+1 555-0103', 'company' => '' ),
			'emily' => array( 'name' => 'Emily Davis', 'email' => 'emily.davis@example.com', 'phone' => '+1 555-0104', 'company' => '' ),
			'acme'  => array( 'name' => 'Robert Kim', 'email' => 'billing@acmecorp.example.com', 'phone' => '+1 555-0105', 'company' => 'Acme Corp' ),
			'david' => array( 'name' => 'David Wilson', 'email' => 'david.wilson@example.com', 'phone' => '+1 555-0106', 'company' => 'Wilson Design' ),
			'lisa'  => array( 'name' => 'Lisa Park', 'email' => 'lisa.park@example.com', 'phone' => '+1 555-0107', 'company' => '' ),
			'james' => array( 'name' => 'James Okafor', 'email' => 'james.okafor@example.com', 'phone' => '+1 555-0108', 'company' => 'Okafor Media' ),
			'nina'  => array( 'name' => 'Nina Rodriguez', 'email' => 'nina.rodriguez@example.com', 'phone' => '+1 555-0109', 'company' => 'Rodriguez Fitness' ),
			'alex'  => array( 'name' => 'Alex Turner', 'email' => 'alex.turner@example.com', 'phone' => '+1 555-0110', 'company' => '' ),
		);

		$needed_keys = array();
		foreach ( $subscription_defs as $def ) {
			if ( empty( $plans ) || isset( $plans[ $def['plan'] ] ) ) {
				$needed_keys[ $def['customer'] ] = true;
			}
		}

		$map   = array();
		$index = 0;

		foreach ( $customer_defs as $key => $data ) {
			if ( ! empty( $subscription_defs ) && empty( $needed_keys[ $key ] ) ) {
				continue;
			}
			$months_ago = 6 - ( $index % 6 );
			$created    = gmdate( 'Y-m-d H:i:s', strtotime( "-{$months_ago} months" ) );

			$id = $repo->insert(
				array(
					'name'       => $data['name'],
					'email'      => $data['email'],
					'phone'      => $data['phone'],
					'company'    => $data['company'],
					'branch_id'  => 0,
					'status'     => 'active',
					'notes'      => __( 'Sample customer imported with demo data.', 'lucrativeit-subscription-recurring-billing' ),
					'created_at' => $created,
				)
			);

			if ( $id ) {
				$map[ $key ] = $id;
			}
			++$index;
		}

		return $map;
	}

	/**
	 * @param array<string,int>                                                          $plans             Plan slug => ID.
	 * @param array<string,int>                                                          $customers         Customer key => ID.
	 * @param string                                                                     $currency          Currency code.
	 * @param array<int,array{customer:string,plan:string,status:string,months_ago:int}> $subscription_defs Subscription rows to seed.
	 */
	protected static function seed_subscriptions_and_invoices( array $plans, array $customers, $currency, array $subscription_defs = array() ) {
		$subs_repo = new LUCRSURE_Subscription_Repository();
		$inv_repo  = new LUCRSURE_Invoice_Repository();
		$plan_repo = new LUCRSURE_Plan_Repository();

		$sub_defs = ! empty( $subscription_defs ) ? $subscription_defs : self::subscription_definitions();

		foreach ( $sub_defs as $def ) {
			if ( ! isset( $customers[ $def['customer'] ], $plans[ $def['plan'] ] ) ) {
				continue;
			}

			$plan       = $plan_repo->find( $plans[ $def['plan'] ] );
			$start      = gmdate( 'Y-m-d H:i:s', strtotime( '-' . (int) $def['months_ago'] . ' months' ) );
			$interval   = $plan['billing_interval'];
			$period_end = lucrsure_next_period_end( $interval, (int) $plan['interval_count'], $start );
			$mrr        = self::monthly_value( lucrsure_plan_effective_price( $plan ), $interval, (int) $plan['interval_count'] );

			$sub_id = $subs_repo->insert(
				array(
					'customer_id'          => $customers[ $def['customer'] ],
					'plan_id'              => $plans[ $def['plan'] ],
					'status'               => $def['status'],
					'quantity'             => 1,
					'mrr'                  => $mrr,
					'start_date'           => $start,
					'trial_ends'           => 'trialing' === $def['status'] ? gmdate( 'Y-m-d H:i:s', strtotime( '+14 days' ) ) : null,
					'current_period_start' => $start,
					'current_period_end'   => $period_end,
					'gateway'              => 'manual',
					'auto_renew'           => 1,
					'created_at'           => $start,
				)
			);

			if ( ! $sub_id ) {
				continue;
			}

			self::seed_invoices_for_subscription(
				$inv_repo,
				$plan_repo,
				$sub_id,
				$customers[ $def['customer'] ],
				$plans[ $def['plan'] ],
				$currency,
				$def['status'],
				(int) $def['months_ago']
			);
		}
	}

	/**
	 * Ensure each imported category has at least one sample subscription.
	 *
	 * @param array<int,array{customer:string,plan:string,status:string,months_ago:int}> $sub_defs            Subscription seed rows.
	 * @param array<string,int>                                                          $plans               Imported plan slug => ID.
	 * @param string[]                                                                   $selected_categories Imported category slugs.
	 * @return array<int,array{customer:string,plan:string,status:string,months_ago:int}>
	 */
	protected static function ensure_category_subscription_coverage( array $sub_defs, array $plans, array $selected_categories ) {
		if ( empty( $selected_categories ) || empty( $plans ) ) {
			return $sub_defs;
		}

		$plan_defs     = self::plan_definitions();
		$covered_cats  = array();
		$fallback_plan = array(
			'gym-membership'   => 'gym-basic',
			'internet-isp'     => 'isp-100mbps',
			'online-coaching'  => 'coach-group',
			'saas-software'    => 'saas-growth',
			'software-license' => 'license-business',
		);
		$fallback_customer = array(
			'gym-membership'   => 'lisa',
			'internet-isp'     => 'mike',
			'online-coaching'  => 'emily',
			'saas-software'    => 'sarah',
			'software-license' => 'david',
		);

		foreach ( $sub_defs as $def ) {
			if ( ! isset( $plans[ $def['plan'] ] ) ) {
				continue;
			}
			foreach ( $plan_defs as $cat_slug => $cat_plans ) {
				if ( isset( $cat_plans[ $def['plan'] ] ) ) {
					$covered_cats[ $cat_slug ] = true;
				}
			}
		}

		foreach ( $selected_categories as $cat_slug ) {
			if ( ! empty( $covered_cats[ $cat_slug ] ) ) {
				continue;
			}

			$plan_slug = isset( $fallback_plan[ $cat_slug ] ) ? $fallback_plan[ $cat_slug ] : '';
			if ( '' === $plan_slug || ! isset( $plans[ $plan_slug ] ) ) {
				$plan_slug = self::first_imported_plan_slug_for_category( $cat_slug, $plans );
			}
			if ( '' === $plan_slug ) {
				continue;
			}

			$customer_key = isset( $fallback_customer[ $cat_slug ] ) ? $fallback_customer[ $cat_slug ] : 'john';
			$sub_defs[]   = array(
				'customer'   => $customer_key,
				'plan'       => $plan_slug,
				'status'     => 'active',
				'months_ago' => 1,
			);
		}

		return $sub_defs;
	}

	/**
	 * @param string              $category_slug Category slug.
	 * @param array<string,int>   $plans         Imported plan slug => ID.
	 * @return string
	 */
	protected static function first_imported_plan_slug_for_category( $category_slug, array $plans ) {
		$plan_defs = self::plan_definitions();
		if ( ! isset( $plan_defs[ $category_slug ] ) ) {
			return '';
		}

		foreach ( array_keys( $plan_defs[ $category_slug ] ) as $plan_slug ) {
			if ( isset( $plans[ $plan_slug ] ) ) {
				return $plan_slug;
			}
		}

		return '';
	}

	/**
	 * Normalize plan price to a monthly recurring value for MRR.
	 *
	 * @param float  $price    Plan price.
	 * @param string $interval Billing interval.
	 * @param int    $count    Interval count.
	 * @return float
	 */
	protected static function monthly_value( $price, $interval, $count ) {
		$count = max( 1, $count );
		switch ( $interval ) {
			case 'day':
				return round( $price * 30 / $count, 2 );
			case 'week':
				return round( $price * 4.33 / $count, 2 );
			case 'year':
				return round( $price / ( 12 * $count ), 2 );
			case 'lifetime':
				return 0.0;
			default:
				return round( $price / $count, 2 );
		}
	}

	/**
	 * Create paid history and open invoices for a subscription.
	 *
	 * @param LUCRSURE_Invoice_Repository $inv_repo Invoice repository.
	 * @param LUCRSURE_Plan_Repository    $plan_repo Plan repository.
	 * @param int                    $sub_id Subscription ID.
	 * @param int                    $customer_id Customer ID.
	 * @param int                    $plan_id Plan ID.
	 * @param string                 $currency Currency.
	 * @param string                 $status Subscription status.
	 * @param int                    $months_ago Months since start.
	 */
	protected static function seed_invoices_for_subscription( $inv_repo, $plan_repo, $sub_id, $customer_id, $plan_id, $currency, $status, $months_ago ) {
		$plan   = $plan_repo->find( $plan_id );
		$amount = lucrsure_plan_effective_price( $plan );
		$line   = wp_json_encode(
			array(
				array(
					'description' => $plan['name'],
					'quantity'    => 1,
					'amount'      => $amount,
				),
			)
		);

		$paid_cycles = max( 0, min( $months_ago, 3 ) );
		for ( $i = $paid_cycles; $i >= 1; $i-- ) {
			$paid_at = gmdate( 'Y-m-d H:i:s', strtotime( '-' . $i . ' months +5 days' ) );
			$due     = gmdate( 'Y-m-d H:i:s', strtotime( '-' . $i . ' months' ) );

			$inv_repo->insert(
				array(
					'invoice_number'  => $inv_repo->next_number(),
					'customer_id'     => $customer_id,
					'subscription_id' => $sub_id,
					'amount'          => $amount,
					'currency'        => $currency,
					'status'          => 'paid',
					'due_date'        => $due,
					'paid_at'         => $paid_at,
					'gateway'         => 'manual',
					'line_items'      => $line,
					'created_at'      => $due,
				)
			);
		}

		if ( in_array( $status, array( 'past_due', 'active', 'trialing' ), true ) ) {
			$due_status = 'past_due' === $status ? 'overdue' : 'unpaid';
			$due_date   = 'past_due' === $status
				? gmdate( 'Y-m-d H:i:s', strtotime( '-10 days' ) )
				: gmdate( 'Y-m-d H:i:s', strtotime( '+7 days' ) );

			$inv_repo->insert(
				array(
					'invoice_number'  => $inv_repo->next_number(),
					'customer_id'     => $customer_id,
					'subscription_id' => $sub_id,
					'amount'          => $amount,
					'currency'        => $currency,
					'status'          => $due_status,
					'due_date'        => $due_date,
					'paid_at'         => null,
					'gateway'         => 'manual',
					'line_items'      => $line,
					'created_at'      => current_time( 'mysql' ),
				)
			);
		}
	}
}
