<?php
// phpcs:disable WordPress.NamingConventions.PrefixAllGlobals
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery
// phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching

if (!defined('ABSPATH')) {
    $dir = __DIR__;
    $loaded = false;
    for ($i = 0; $i < 6; $i++) {
        $candidate = $dir . '/wp-load.php';
        if (file_exists($candidate)) {
            require_once $candidate;
            $loaded = true;
            break;
        }
        $dir = dirname($dir);
    }

    if (!$loaded) {
        http_response_code(500);
        echo 'Unable to load WordPress.';
        exit;
    }
}

if (PHP_SAPI !== 'cli' && (!is_user_logged_in() || !current_user_can('manage_woocommerce'))) {
    wp_die('You must be an administrator or shop manager to use this tool.', 403);
}

if (!defined('BIZMART_CORE_LOADED') || !class_exists('WooCommerce')) {
    wp_die('Bizmart Core and WooCommerce must both be active before running the demo seeder.', 400);
}

ignore_user_abort(true);
@set_time_limit(0); // phpcs:ignore Squiz.PHP.DiscouragedFunctions.Discouraged

class Bizmart_Demo_Data_Seeder {
    private $manifest_option = 'bizmart_demo_seed_manifest_v1';
    private $seed_key = 'bizmart_demo_seed_v1';
    private $manifest = [];
    private $summary = [];
    private $product_category_ids = [];
    private $product_tag_ids = [];
    private $selected_components = ['core', 'addon', 'pos'];

    public function handle_request() {
        $notice = null;
        $error = null;

        if (PHP_SAPI === 'cli') {
            // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
            $action = isset($_SERVER['argv'][1]) ? sanitize_key((string) $_SERVER['argv'][1]) : 'generate';
            // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
            $components = isset($_SERVER['argv']) ? array_slice((array) $_SERVER['argv'], 2) : [];

            try {
                if ($action === 'cleanup') {
                    $notice = $this->cleanup_existing_seed();
                } else {
                    $notice = $this->generate_demo_data($components);
                }
                echo esc_html($notice) . PHP_EOL;
                return;
            } catch (Exception $exception) {
                // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fwrite
                fwrite(STDERR, $exception->getMessage() . PHP_EOL);
                exit(1);
            }
        }

        // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated
        if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] === 'POST') {
            check_admin_referer('bizmart_demo_seeder_action');
            $action = isset($_POST['seed_action']) ? sanitize_key(wp_unslash($_POST['seed_action'])) : '';
            $components = isset($_POST['seed_components']) ? array_map('sanitize_key', (array) wp_unslash($_POST['seed_components'])) : [];

            try {
                if ($action === 'cleanup') {
                    $notice = $this->cleanup_existing_seed();
                } elseif ($action === 'generate') {
                    $notice = $this->generate_demo_data($components);
                }
            } catch (Exception $exception) {
                $error = $exception->getMessage();
            }
        }

        $this->render_page($notice, $error);
    }

    public function generate_demo_data(array $components = []) {
        $this->selected_components = $this->normalize_components($components);
        $this->cleanup_existing_seed();
        $this->reset_runtime_state();

        if ($this->has_component('addon') && (!function_exists('bizmart_ensure_financial_schema') || !bizmart_ensure_financial_schema())) {
            throw new Exception('Bizmart financial tables are missing. Re-activate Bizmart Addon before seeding demo data.');
        }

        if ($this->has_component('pos') && (!class_exists('Bizmart_POS_DB') || !class_exists('Bizmart_POS_Session'))) {
            throw new Exception('Bizmart POS must be active before importing POS demo data.');
        }

        $this->manifest['seed_key'] = $this->seed_key;
        $this->manifest['created_at'] = current_time('mysql');
        $this->manifest['components'] = $this->selected_components;

        $categories = $this->ensure_product_categories();
        $tags = $this->ensure_product_tags();
        $products = $this->create_products($categories, $tags);

        $invoice_result = [
            'active_invoices' => 0,
            'deleted_invoices' => 0,
            'restored_invoices' => 0,
        ];
        $suppliers = [];
        if ($this->has_component('addon')) {
            $suppliers = $this->create_suppliers();
            $invoice_result = $this->create_invoices($products, $suppliers);
            $this->create_global_payments($suppliers);
            $this->create_expenses($suppliers);
        }

        $order_ids = $this->create_orders($products);
        if ($this->has_component('pos')) {
            $this->create_pos_data($order_ids);
        }

        if (function_exists('bizmart_recalculate_all_financials')) {
            bizmart_recalculate_all_financials();
        }

        if (function_exists('bizmart_invalidate_product_metrics_cache')) {
            bizmart_invalidate_product_metrics_cache(null, 'demo_seed');
        }

        // Clear dashboard and inventory transient caches
        $blog_id = (int) get_current_blog_id();
        delete_transient('bizmart_inventory_totals_v9_' . $blog_id);
        delete_transient('bizmart_dash_missing_pricing_v3');
        delete_transient('bizmart_dash_stock_alerts_v1');

        $this->summary['active_invoices'] = (int) $invoice_result['active_invoices'];
        $this->summary['deleted_invoices'] = (int) $invoice_result['deleted_invoices'];
        $this->summary['restored_invoices'] = (int) $invoice_result['restored_invoices'];

        $this->manifest['summary'] = $this->summary;
        update_option($this->manifest_option, $this->manifest, false);

        return 'Demo data created successfully for: ' . implode(', ', $this->selected_components) . '.';
    }

    private function normalize_components(array $components): array {
        $normalized = [];
        foreach ($components as $component) {
            $component = sanitize_key((string) $component);
            if (in_array($component, ['core', 'addon', 'pos'], true)) {
                $normalized[] = $component;
            }
        }

        if (!$normalized) {
            $normalized = ['core'];
            if (function_exists('bizmart_ensure_financial_schema')) {
                $normalized[] = 'addon';
            }
            if (class_exists('Bizmart_POS_DB') && class_exists('Bizmart_POS_Session')) {
                $normalized[] = 'pos';
            }
        }

        if (in_array('addon', $normalized, true) || in_array('pos', $normalized, true)) {
            $normalized[] = 'core';
        }

        return array_values(array_unique($normalized));
    }

    private function has_component($component) {
        return in_array($component, $this->selected_components, true);
    }

    private function reset_runtime_state() {
        $this->manifest = [
            'products' => [],
            'product_skus' => [],
            'product_categories' => [],
            'product_tags' => [],
            'suppliers' => [],
            'invoices' => [],
            'invoice_items' => [],
            'payments' => [],
            'expenses' => [],
            'price_history' => [],
            'supplier_history' => [],
            'orders' => [],
            'pos_registers' => [],
            'pos_sessions' => [],
            'pos_cash_movements' => [],
        ];

        $this->summary = [
            'products' => 0,
            'suppliers' => 0,
            'invoices' => 0,
            'payments' => 0,
            'expenses' => 0,
            'orders' => 0,
            'low_stock_products' => 0,
            'out_of_stock_products' => 0,
            'pos_registers' => 0,
            'pos_sessions' => 0,
            'pos_cash_movements' => 0,
            'pos_orders' => 0,
        ];

        $this->product_category_ids = [];
        $this->product_tag_ids = [];
    }

    private function ensure_product_categories() {
        $definitions = [
            'skincare' => 'Skincare',
            'makeup' => 'Makeup',
            'haircare' => 'Haircare',
            'bodycare' => 'Body Care',
            'suncare' => 'Sun Care',
            'fragrance' => 'Fragrance',
        ];

        $categories = [];
        foreach ($definitions as $slug => $name) {
            $term = get_term_by('slug', 'bizmart-demo-' . $slug, 'product_cat');
            if (!$term || is_wp_error($term)) {
                $inserted = wp_insert_term($name, 'product_cat', [
                    'slug' => 'bizmart-demo-' . $slug,
                    'description' => 'Bizmart demo category',
                ]);
                if (is_wp_error($inserted)) {
                    throw new Exception('Unable to create product category: ' . esc_html($name));
                }
                $term_id = (int) $inserted['term_id'];
            } else {
                $term_id = (int) $term->term_id;
            }

            $categories[$slug] = $term_id;
            $this->manifest['product_categories'][] = $term_id;
        }

        $this->product_category_ids = $categories;
        return $categories;
    }

    private function ensure_product_tags() {
        $definitions = [
            'vegan',
            'hydrating',
            'brightening',
            'salon-grade',
            'sensitive-skin',
            'spf',
            'long-wear',
            'sulfate-free',
            'professional',
            'daily-care',
        ];

        $tags = [];
        foreach ($definitions as $slug) {
            $term = get_term_by('slug', 'bizmart-demo-' . $slug, 'product_tag');
            if (!$term || is_wp_error($term)) {
                $inserted = wp_insert_term(ucwords(str_replace('-', ' ', $slug)), 'product_tag', [
                    'slug' => 'bizmart-demo-' . $slug,
                    'description' => 'Bizmart demo tag',
                ]);
                if (is_wp_error($inserted)) {
                    throw new Exception('Unable to create product tag: ' . esc_html($slug));
                }
                $term_id = (int) $inserted['term_id'];
            } else {
                $term_id = (int) $term->term_id;
            }

            $tags[$slug] = $term_id;
            $this->manifest['product_tags'][] = $term_id;
        }

        $this->product_tag_ids = $tags;
        return $tags;
    }

    private function create_products($categories, $tags) {
        $blueprints = $this->get_product_blueprints();
        $products = [];

        foreach ($blueprints as $index => $blueprint) {
            $purchase_price = round(3.75 + (($index % 9) * 1.45) + ($blueprint['tier'] * 0.95), 2);
            $regular_price = round($purchase_price * (1.85 + (($index % 4) * 0.18)), 2);
            $sale_price = ($index % 7 === 0) ? round($regular_price * 0.9, 2) : '';
            $stock_levels = [0, 2, 4, 6, 9, 12, 16, 21, 28, 35];
            $stock_quantity = $stock_levels[($index + $blueprint['tier']) % count($stock_levels)];

            $product = new WC_Product_Simple();
            $product->set_name($blueprint['name']);
            $product->set_status('publish');
            $product->set_catalog_visibility('visible');
            $product->set_sku(sprintf('COS-%03d', $index + 1));
            $product->set_description($blueprint['description']);
            $product->set_short_description($blueprint['short_description']);
            $product->set_regular_price(wc_format_decimal($regular_price));
            if ($sale_price !== '') {
                $product->set_sale_price(wc_format_decimal($sale_price));
            }
            $product->set_manage_stock(true);
            $product->set_stock_quantity($stock_quantity);
            $product->set_stock_status($stock_quantity > 0 ? 'instock' : 'outofstock');
            $product->set_low_stock_amount(5);
            $product->set_category_ids([$categories[$blueprint['category']]]);

            $tag_ids = [];
            foreach ($blueprint['tags'] as $tag_slug) {
                if (isset($tags[$tag_slug])) {
                    $tag_ids[] = $tags[$tag_slug];
                }
            }
            $product->set_tag_ids($tag_ids);
            $product->save();

            $product_id = $product->get_id();
            if (!$product_id) {
                throw new Exception('Failed to create WooCommerce product: ' . esc_html($blueprint['name']));
            }

            update_post_meta($product_id, '_purchase_price', wc_format_decimal($purchase_price));
            update_post_meta($product_id, '_' . $this->seed_key, 1);

            if (function_exists('bizmart_sync_purchase_price_to_products_table')) {
                bizmart_sync_purchase_price_to_products_table($product_id, $purchase_price);
            }

            wp_update_post([
                'ID' => $product_id,
                'post_date' => gmdate('Y-m-d H:i:s', strtotime('-' . (90 - ($index * 2)) . ' days')),
                'post_date_gmt' => gmdate('Y-m-d H:i:s', strtotime('-' . (90 - ($index * 2)) . ' days')),
            ]);

            if (function_exists('wc_delete_product_transients')) {
                wc_delete_product_transients($product_id);
            }

            $products[] = [
                'id' => $product_id,
                'name' => $blueprint['name'],
                'sku' => $product->get_sku(),
                'category' => $blueprint['category'],
                'purchase_price' => $purchase_price,
                'regular_price' => $regular_price,
                'stock_quantity' => $stock_quantity,
            ];

            $this->manifest['products'][] = $product_id;
            $this->manifest['product_skus'][] = $product->get_sku();
            $this->summary['products']++;
            if ($stock_quantity <= 5) {
                $this->summary['low_stock_products']++;
            }
            if ($stock_quantity <= 0) {
                $this->summary['out_of_stock_products']++;
            }
        }

        return $products;
    }

    private function create_suppliers() {
        global $wpdb;

        $supplier_table = $wpdb->prefix . 'bizmart_suppliers';
        $blueprints = $this->get_supplier_blueprints();
        $suppliers = [];

        foreach ($blueprints as $index => $blueprint) {
            $wpdb->insert($supplier_table, [
                'name' => $blueprint['name'],
                'company' => $blueprint['company'],
                'email' => $blueprint['email'],
                'phone' => $blueprint['phone'],
                'phone2' => $blueprint['phone2'],
                'address' => $blueprint['address'],
                'city' => $blueprint['city'],
                'country' => $blueprint['country'],
                'tax_id' => $blueprint['tax_id'],
                'iban' => $blueprint['iban'],
                'website' => $blueprint['website'],
                'notes' => $blueprint['notes'],
                'created_at' => gmdate('Y-m-d H:i:s', strtotime('-' . (140 - ($index * 8)) . ' days')),
                'updated_at' => current_time('mysql'),
            ], ['%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s']);

            if (!$wpdb->insert_id) {
                throw new Exception('Failed to create supplier: ' . esc_html($blueprint['name']));
            }

            $supplier_id = (int) $wpdb->insert_id;
            $suppliers[] = [
                'id' => $supplier_id,
                'name' => $blueprint['name'],
            ];

            $this->manifest['suppliers'][] = $supplier_id;
            $this->summary['suppliers']++;
        }

        return $suppliers;
    }

    private function create_invoices($products, $suppliers) {
        $scenarios = $this->get_invoice_scenarios();
        $active_invoices = 0;
        $deleted_invoices = 0;
        $restored_invoices = 0;

        foreach ($scenarios as $index => $scenario) {
            $supplier = $suppliers[$scenario['supplier_index'] % count($suppliers)];
            $items = $this->build_invoice_items($index, $products, $scenario);

            $invoice_id = $this->create_invoice_record($supplier, $items, $scenario, $index);
            if ($scenario['doc_status'] === 'approved' && !empty($scenario['payments'])) {
                foreach ($scenario['payments'] as $payment) {
                    $this->create_invoice_payment($invoice_id, $payment);
                }
            }

            if (!empty($scenario['soft_delete'])) {
                $this->soft_delete_invoice($invoice_id);
                $deleted_invoices++;
            }

            if (!empty($scenario['restore_after_delete'])) {
                $this->restore_invoice($invoice_id);
                $restored_invoices++;
            }

            if (empty($scenario['soft_delete']) || !empty($scenario['restore_after_delete'])) {
                $active_invoices++;
            }
        }

        return [
            'active_invoices' => $active_invoices,
            'deleted_invoices' => $deleted_invoices,
            'restored_invoices' => $restored_invoices,
        ];
    }

    private function create_invoice_record($supplier, $items, $scenario, $index) {
        global $wpdb;

        $table_invoices = $wpdb->prefix . 'bizmart_invoices';
        $table_invoice_items = $wpdb->prefix . 'bizmart_invoice_items';

        $subtotal = 0.0;
        foreach ($items as $item) {
            $subtotal += $item['quantity'] * $item['purchase_price'];
        }
        $subtotal = round($subtotal, 4);

        $invoice_date = $scenario['date']->format('Y-m-d H:i:s');
        $date_supplier = $scenario['date']->modify('-1 day')->format('Y-m-d 00:00:00');

        $wpdb->insert($table_invoices, [
            'supplier_id' => $supplier['id'],
            'supplier_name' => $supplier['name'],
            'invoice_number' => sprintf('BZM-PO-%04d', $index + 1),
            'reference_internal' => sprintf('PO-%s-%03d', $scenario['date']->format('ym'), $index + 1),
            'reference_supplier' => sprintf('SUP-%02d-%03d', $supplier['id'], $index + 11),
            'created_at' => $invoice_date,
            'date_supplier' => $date_supplier,
            'subtotal' => $subtotal,
            'discount' => 0,
            'shipping' => 0,
            'tax' => 0,
            'total' => $subtotal,
            'total_paid' => 0,
            'remaining_balance' => $subtotal,
            'status' => 'unpaid',
            'payment_status' => 'unpaid',
            'doc_status' => $scenario['doc_status'],
            'deduct_stock' => $scenario['deduct_stock'],
            'notes' => $scenario['notes'],
            'attachments' => '',
            'deleted_at' => null,
        ], ['%d','%s','%s','%s','%s','%s','%s','%f','%f','%f','%f','%f','%f','%f','%s','%s','%s','%d','%s','%s','%s']);

        $invoice_id = (int) $wpdb->insert_id;
        if ($invoice_id <= 0) {
            throw new Exception('Failed to create invoice #' . intval($index + 1));
        }

        $this->manifest['invoices'][] = $invoice_id;
        $this->summary['invoices']++;

        $effective_stock = function_exists('bizmart_invoice_stock_effective')
            ? bizmart_invoice_stock_effective($scenario['doc_status'], $scenario['deduct_stock'])
            : ($scenario['doc_status'] === 'approved' && (int) $scenario['deduct_stock'] === 1);

        foreach ($items as $item) {
            $wpdb->insert($table_invoice_items, [
                'invoice_id' => $invoice_id,
                'product_id' => $item['product_id'],
                'sku' => $item['sku'],
                'product_name' => $item['product_name'],
                'quantity' => $item['quantity'],
                'purchase_price' => $item['purchase_price'],
                'selling_price_used' => $item['selling_price'],
                'subtotal' => round($item['quantity'] * $item['purchase_price'], 4),
                'manage_stock' => $item['manage_stock'] ? 1 : 0,
            ], ['%d','%d','%s','%s','%f','%f','%f','%f','%d']);

            if ($wpdb->insert_id) {
                $this->manifest['invoice_items'][] = (int) $wpdb->insert_id;
            }

            bizmart_store_price_history(
                $item['product_id'],
                $item['purchase_price'],
                $item['selling_price'],
                $invoice_id,
                $supplier['id'],
                $item['quantity'],
                'invoice'
            );
            if ($wpdb->insert_id) {
                $this->manifest['price_history'][] = (int) $wpdb->insert_id;
            }

            update_post_meta($item['product_id'], '_purchase_price', wc_format_decimal($item['purchase_price']));
            update_post_meta($item['product_id'], '_regular_price', wc_format_decimal($item['selling_price']));
            update_post_meta($item['product_id'], '_price', wc_format_decimal($item['selling_price']));

            if (function_exists('bizmart_sync_purchase_price_to_products_table')) {
                bizmart_sync_purchase_price_to_products_table($item['product_id'], $item['purchase_price']);
            }

            if ($effective_stock && !empty($item['manage_stock'])) {
                bizmart_invoice_apply_stock_delta($item['product_id'], $item['quantity'], [
                    'invoice_id' => $invoice_id,
                    'source' => 'demo_seed_invoice_add',
                ]);
            }

            if (function_exists('wc_delete_product_transients')) {
                wc_delete_product_transients($item['product_id']);
            }
        }

        if ($scenario['doc_status'] === 'approved') {
            bizmart_update_supplier_financials($supplier['id']);
            bizmart_add_supplier_history(
                $supplier['id'],
                'invoice_created',
                $invoice_id,
                null,
                $subtotal,
                sprintf('Invoice #%d created - Amount: %s %s', $invoice_id, number_format($subtotal, 2), get_woocommerce_currency_symbol())
            );
            if ($wpdb->insert_id) {
                $this->manifest['supplier_history'][] = (int) $wpdb->insert_id;
            }
        }

        return $invoice_id;
    }

    private function create_invoice_payment($invoice_id, $payment) {
        global $wpdb;

        $invoice = $wpdb->get_row($wpdb->prepare(
            "SELECT id, supplier_id, total, total_paid FROM {$wpdb->prefix}bizmart_invoices WHERE id = %d",
            $invoice_id
        ));
        if (!$invoice) {
            return;
        }

        $invoice_total = (float) $invoice->total;
        $already_paid = (float) $invoice->total_paid;
        $remaining_balance = max(0.0, round($invoice_total - $already_paid, 2));
        $amount = isset($payment['amount'])
            ? (float) $payment['amount']
            : round($invoice_total * (float) ($payment['amount_ratio'] ?? 0), 2);
        if ($amount > $remaining_balance) {
            $amount = $remaining_balance;
        }
        if ($amount <= 0) {
            return;
        }

        $wpdb->insert($wpdb->prefix . 'bizmart_payments', [
            'invoice_id' => $invoice_id,
            'supplier_id' => (int) $invoice->supplier_id,
            'amount' => $amount,
            'method' => $payment['method'],
            'note' => $payment['note'],
            'payment_date' => $payment['date']->format('Y-m-d H:i:s'),
            'created_at' => $payment['date']->format('Y-m-d H:i:s'),
        ], ['%d','%d','%f','%s','%s','%s','%s']);

        $payment_id = (int) $wpdb->insert_id;
        if ($payment_id <= 0) {
            throw new Exception('Failed to create payment for invoice #' . intval($invoice_id));
        }

        $this->manifest['payments'][] = $payment_id;
        $this->summary['payments']++;

        bizmart_update_invoice_financials($invoice_id);
        bizmart_add_supplier_history(
            (int) $invoice->supplier_id,
            'payment_received',
            $invoice_id,
            $payment_id,
            $amount,
            sprintf('Payment received for invoice #%d - Amount: %s %s - Method: %s', $invoice_id, number_format($amount, 2), get_woocommerce_currency_symbol(), $payment['method'])
        );
        if ($wpdb->insert_id) {
            $this->manifest['supplier_history'][] = (int) $wpdb->insert_id;
        }

        if (!empty($payment['create_expense'])) {
            $invoice_supplier_name = $wpdb->get_var($wpdb->prepare(
                "SELECT name FROM {$wpdb->prefix}bizmart_suppliers WHERE id = %d",
                (int) $invoice->supplier_id
            ));
            $wpdb->insert($wpdb->prefix . 'bizmart_expenses', [
                'expense_date' => $payment['date']->format('Y-m-d'),
                'amount' => $amount,
                'category' => 'Versement',
                'description' => 'Payment for invoice #' . $invoice_id . ' - ' . $invoice_supplier_name . (!empty($payment['note']) ? ' - ' . $payment['note'] : '') . ' [PAYMENT:' . $payment_id . ']',
                'supplier_id' => (int) $invoice->supplier_id,
                'payment_method' => $payment['method'],
                'is_recurring' => 0,
                'created_at' => $payment['date']->format('Y-m-d H:i:s'),
            ], ['%s','%f','%s','%s','%d','%s','%d','%s']);
            if ($wpdb->insert_id) {
                $this->manifest['expenses'][] = (int) $wpdb->insert_id;
                $this->summary['expenses']++;
            }
        }
    }

    private function create_global_payments($suppliers) {
        $scenarios = [
            ['supplier_index' => 1, 'method' => 'transfer', 'note' => 'Monthly settlement', 'ratio' => 0.58],
            ['supplier_index' => 4, 'method' => 'check', 'note' => 'Quarter-end settlement', 'ratio' => 0.44],
        ];

        foreach ($scenarios as $offset => $scenario) {
            $supplier = $suppliers[$scenario['supplier_index'] % count($suppliers)];
            $this->create_global_payment($supplier['id'], $scenario['ratio'], $scenario['method'], $scenario['note'], $offset);
        }
    }

    private function create_global_payment($supplier_id, $ratio, $method, $note, $offset) {
        global $wpdb;

        $invoices = $wpdb->get_results($wpdb->prepare(
            "SELECT id, remaining_balance, created_at
             FROM {$wpdb->prefix}bizmart_invoices
             WHERE supplier_id = %d
               AND status != 'paid'
               AND (deleted_at IS NULL OR deleted_at = '0000-00-00 00:00:00')
               AND (doc_status IS NULL OR doc_status = 'approved')
             ORDER BY created_at ASC",
            $supplier_id
        ));

        if (!$invoices) {
            return;
        }

        $remaining_total = 0.0;
        foreach ($invoices as $invoice) {
            $remaining_total += (float) $invoice->remaining_balance;
        }

        if ($remaining_total <= 0.01) {
            return;
        }

        $amount = round($remaining_total * $ratio, 2);
        if ($amount <= 0) {
            return;
        }

        $payment_date = new DateTimeImmutable('-' . (12 - ($offset * 3)) . ' days', wp_timezone());
        $remaining_payment = $amount;
        $applied_refs = [];

        foreach ($invoices as $invoice) {
            if ($remaining_payment <= 0.01) {
                break;
            }

            $to_pay = min($remaining_payment, (float) $invoice->remaining_balance);
            if ($to_pay <= 0) {
                continue;
            }

            $wpdb->insert($wpdb->prefix . 'bizmart_payments', [
                'invoice_id' => (int) $invoice->id,
                'supplier_id' => $supplier_id,
                'amount' => $to_pay,
                'method' => $method,
                'note' => $note . ' (Global payment)',
                'payment_date' => $payment_date->format('Y-m-d H:i:s'),
                'created_at' => $payment_date->format('Y-m-d H:i:s'),
            ], ['%d','%d','%f','%s','%s','%s','%s']);

            if ($wpdb->insert_id) {
                $this->manifest['payments'][] = (int) $wpdb->insert_id;
                $this->summary['payments']++;
            }

            bizmart_update_invoice_financials((int) $invoice->id);
            $remaining_payment -= $to_pay;
            $applied_refs[] = '#' . (int) $invoice->id;
        }

        bizmart_update_supplier_financials($supplier_id);
        bizmart_add_supplier_history(
            $supplier_id,
            'payment_received',
            null,
            null,
            $amount,
            sprintf('Global payment - %s %s (Applied to: %s)', number_format($amount, 2), get_woocommerce_currency_symbol(), implode(', ', array_slice($applied_refs, 0, 4)))
        );
        if ($wpdb->insert_id) {
            $this->manifest['supplier_history'][] = (int) $wpdb->insert_id;
        }

        $supplier_name = $wpdb->get_var($wpdb->prepare(
            "SELECT name FROM {$wpdb->prefix}bizmart_suppliers WHERE id = %d",
            $supplier_id
        ));
        $wpdb->insert($wpdb->prefix . 'bizmart_expenses', [
            'expense_date' => $payment_date->format('Y-m-d'),
            'amount' => $amount,
            'category' => 'Versement',
            'description' => 'Payment for ' . $supplier_name . ' - ' . $note,
            'supplier_id' => $supplier_id,
            'payment_method' => $method,
            'is_recurring' => 0,
            'created_at' => $payment_date->format('Y-m-d H:i:s'),
        ], ['%s','%f','%s','%s','%d','%s','%d','%s']);

        if ($wpdb->insert_id) {
            $this->manifest['expenses'][] = (int) $wpdb->insert_id;
            $this->summary['expenses']++;
        }
    }

    private function create_expenses($suppliers) {
        global $wpdb;

        $definitions = [
            ['category' => 'Rent', 'description' => 'Flagship store monthly rent', 'amount' => 980.00, 'days_ago' => 92, 'supplier_index' => null, 'recurring' => 1, 'payment_method' => 'transfer'],
            ['category' => 'Utilities', 'description' => 'Electricity and water invoice', 'amount' => 214.60, 'days_ago' => 84, 'supplier_index' => null, 'recurring' => 1, 'payment_method' => 'transfer'],
            ['category' => 'Internet', 'description' => 'Business fiber subscription', 'amount' => 69.90, 'days_ago' => 79, 'supplier_index' => null, 'recurring' => 1, 'payment_method' => 'card'],
            ['category' => 'Packaging', 'description' => 'Gift boxes, tissue paper, and labels', 'amount' => 162.40, 'days_ago' => 73, 'supplier_index' => 0, 'recurring' => 0, 'payment_method' => 'cash'],
            ['category' => 'Marketing', 'description' => 'Instagram creator collaboration batch 1', 'amount' => 430.00, 'days_ago' => 66, 'supplier_index' => null, 'recurring' => 0, 'payment_method' => 'transfer'],
            ['category' => 'Cleaning', 'description' => 'Boutique and treatment room cleaning service', 'amount' => 88.00, 'days_ago' => 60, 'supplier_index' => null, 'recurring' => 1, 'payment_method' => 'cash'],
            ['category' => 'Photography', 'description' => 'Product shoot for serum launch', 'amount' => 255.00, 'days_ago' => 54, 'supplier_index' => null, 'recurring' => 0, 'payment_method' => 'card'],
            ['category' => 'Shipping', 'description' => 'Inbound freight for imported skincare stock', 'amount' => 194.50, 'days_ago' => 49, 'supplier_index' => 2, 'recurring' => 0, 'payment_method' => 'transfer'],
            ['category' => 'Maintenance', 'description' => 'POS printer and barcode scanner maintenance', 'amount' => 126.75, 'days_ago' => 43, 'supplier_index' => null, 'recurring' => 0, 'payment_method' => 'card'],
            ['category' => 'Salaries', 'description' => 'Beauty advisor overtime adjustment', 'amount' => 320.00, 'days_ago' => 37, 'supplier_index' => null, 'recurring' => 0, 'payment_method' => 'transfer'],
            ['category' => 'Packaging', 'description' => 'Travel minis refill labels', 'amount' => 94.20, 'days_ago' => 29, 'supplier_index' => 0, 'recurring' => 0, 'payment_method' => 'cash'],
            ['category' => 'Marketing', 'description' => 'Sampling event at mall beauty corner', 'amount' => 286.00, 'days_ago' => 21, 'supplier_index' => null, 'recurring' => 0, 'payment_method' => 'card'],
            ['category' => 'Utilities', 'description' => 'Electricity and water invoice', 'amount' => 221.30, 'days_ago' => 15, 'supplier_index' => null, 'recurring' => 1, 'payment_method' => 'transfer'],
            ['category' => 'Internet', 'description' => 'Business fiber subscription', 'amount' => 69.90, 'days_ago' => 12, 'supplier_index' => null, 'recurring' => 1, 'payment_method' => 'card'],
            ['category' => 'Repairs', 'description' => 'Shelving adjustment in fragrance corner', 'amount' => 145.00, 'days_ago' => 8, 'supplier_index' => null, 'recurring' => 0, 'payment_method' => 'cash'],
            ['category' => 'Training', 'description' => 'Skincare consultant training session', 'amount' => 210.00, 'days_ago' => 5, 'supplier_index' => null, 'recurring' => 0, 'payment_method' => 'transfer'],
        ];

        foreach ($definitions as $definition) {
            $date = new DateTimeImmutable('-' . (int) $definition['days_ago'] . ' days', wp_timezone());
            $supplier_id = null;
            if ($definition['supplier_index'] !== null) {
                $supplier = $suppliers[$definition['supplier_index'] % count($suppliers)];
                $supplier_id = $supplier['id'];
            }

            $wpdb->insert($wpdb->prefix . 'bizmart_expenses', [
                'expense_date' => $date->format('Y-m-d'),
                'amount' => $definition['amount'],
                'category' => $definition['category'],
                'description' => $definition['description'],
                'supplier_id' => $supplier_id,
                'payment_method' => $definition['payment_method'],
                'is_recurring' => $definition['recurring'],
                'created_at' => $date->format('Y-m-d H:i:s'),
            ], ['%s','%f','%s','%s','%d','%s','%d','%s']);

            if ($wpdb->insert_id) {
                $this->manifest['expenses'][] = (int) $wpdb->insert_id;
                $this->summary['expenses']++;
            }
        }
    }

    private function create_orders($products) {
        $customers = $this->get_customer_blueprints();
        $statuses = ['completed', 'completed', 'processing', 'completed', 'on-hold', 'processing', 'pending', 'completed', 'processing', 'pending', 'completed', 'cancelled'];
        $methods = ['cod' => 'Cash on Delivery', 'bacs' => 'Bank Transfer', 'cheque' => 'Check Payment'];
        $created_order_ids = [];

        // Generate 75 orders across the last 90 days to simulate a realistic shop history
        for ($i = 0; $i < 75; $i++) {
            $day_offset = floor($i * 1.2); 
            $status = $statuses[$i % count($statuses)];
            $customer = $customers[$i % count($customers)];
            $date = new DateTimeImmutable('-' . (int) $day_offset . ' days', wp_timezone());
            
            // Randomize hour to look natural
            $date = $date->setTime(9 + ($i % 12), ($i * 7) % 60, 0);
            
            $order = wc_create_order(['customer_id' => 0]);

            $item_count = 1 + ($i % 3);
            for ($item_index = 0; $item_index < $item_count; $item_index++) {
                $product = $products[(($i * 5) + ($item_index * 3)) % count($products)];
                $wc_product = wc_get_product($product['id']);
                if (!$wc_product) {
                    continue;
                }
                $quantity = 1 + (($i + $item_index) % 2);
                $order->add_product($wc_product, $quantity, [
                    'subtotal' => $product['regular_price'] * $quantity,
                    'total' => $product['regular_price'] * $quantity,
                ]);
            }

            $payment_method = array_keys($methods)[$i % count($methods)];
            $order->set_address($customer, 'billing');
            $order->set_address($customer, 'shipping');
            $order->set_payment_method($payment_method);
            $order->set_payment_method_title($methods[$payment_method]);
            $order->set_customer_note('Created by Bizmart demo seeder.');
            $order->calculate_totals(false);
            $order->set_date_created(new WC_DateTime($date->format('Y-m-d H:i:s')));
            $order->save();
            $order->update_status($status, 'Created by Bizmart demo seeder.', true);

            $order_id = $order->get_id();
            if ($order_id) {
                $this->manifest['orders'][] = $order_id;
                $this->summary['orders']++;
                $created_order_ids[] = $order_id;
            }
        }

        return $created_order_ids;
    }

    private function create_pos_data($order_ids) {
        global $wpdb;

        $register_table = $wpdb->prefix . 'bizmart_pos_registers';
        $cashier_id = get_current_user_id();
        if (!$cashier_id) {
            $users = get_users([
                'role__in' => ['administrator', 'shop_manager'],
                'number' => 1,
                'fields' => 'ids',
            ]);
            $cashier_id = !empty($users) ? (int) $users[0] : 0;
        }

        $previous_user_id = get_current_user_id();
        if ($cashier_id > 0 && function_exists('wp_set_current_user')) {
            wp_set_current_user($cashier_id);
        }

        $register_specs = [
            [
                'name' => 'Front Desk Register',
                'slug' => 'bizmart-demo-front-desk',
                'store_name' => 'Main Beauty Floor',
                'opening_cash' => 350.00,
            ],
            [
                'name' => 'Express Checkout Register',
                'slug' => 'bizmart-demo-express',
                'store_name' => 'Impulse Corner',
                'opening_cash' => 180.00,
            ],
        ];

        $register_ids = [];
        foreach ($register_specs as $spec) {
            $wpdb->insert($register_table, [
                'name' => $spec['name'],
                'slug' => $spec['slug'],
                'store_name' => $spec['store_name'],
                'status' => 'closed',
                'receipt_header' => 'Bizmart Demo POS',
                'receipt_footer' => 'Thank you for shopping with Bizmart.',
                'auto_print_receipt' => 1,
                'enable_cash_management' => 1,
                'allowed_payment_methods' => wp_json_encode(['cash', 'card']),
                'note' => 'Created by Bizmart demo seeder.',
                'created_by' => $cashier_id,
                'created_at' => current_time('mysql'),
                'updated_at' => current_time('mysql'),
            ], ['%s','%s','%s','%s','%s','%s','%d','%d','%s','%s','%d','%s','%s']);

            $register_id = (int) $wpdb->insert_id;
            if ($register_id > 0) {
                $register_ids[] = $register_id;
                $this->manifest['pos_registers'][] = $register_id;
                $this->summary['pos_registers']++;
            }
        }

        if (count($register_ids) < 2) {
            if ($previous_user_id !== $cashier_id && function_exists('wp_set_current_user')) {
                wp_set_current_user($previous_user_id);
            }
            return;
        }

        $eligible_orders = [];
        $reporting_statuses = function_exists('bizmart_analytics_reporting_statuses') ? bizmart_analytics_reporting_statuses() : ['completed', 'processing', 'on-hold'];
        foreach ($order_ids as $order_id) {
            $order = wc_get_order($order_id);
            if ($order && in_array($order->get_status(), $reporting_statuses, true)) {
                $eligible_orders[] = $order_id;
            }
        }

        $first_session = Bizmart_POS_Session::open($register_ids[0], (float) $register_specs[0]['opening_cash']);
        if (!empty($first_session['success']) && !empty($first_session['session_id'])) {
            $first_session_id = (int) $first_session['session_id'];
            $this->manifest['pos_sessions'][] = $first_session_id;
            $this->summary['pos_sessions']++;

            foreach (array_slice($eligible_orders, 0, 25) as $order_id) {
                Bizmart_POS_Session::tag_order((int) $order_id, $register_ids[0], $first_session_id);
                $this->summary['pos_orders']++;
            }

            $cash_in = Bizmart_POS_Session::add_cash_movement($first_session_id, 'in', 60.00, 'Float correction before opening rush');
            if (!empty($cash_in['success']) && !empty($cash_in['movement_id'])) {
                $this->manifest['pos_cash_movements'][] = (int) $cash_in['movement_id'];
                $this->summary['pos_cash_movements']++;
            }

            $cash_out = Bizmart_POS_Session::add_cash_movement($first_session_id, 'out', 24.50, 'Packaging supplies purchased from petty cash');
            if (!empty($cash_out['success']) && !empty($cash_out['movement_id'])) {
                $this->manifest['pos_cash_movements'][] = (int) $cash_out['movement_id'];
                $this->summary['pos_cash_movements']++;
            }

            Bizmart_POS_Session::close($first_session_id, 512.00, 'Closed by demo seeder after afternoon shift.');
        }

        $second_session = Bizmart_POS_Session::open($register_ids[1], (float) $register_specs[1]['opening_cash']);
        if (!empty($second_session['success']) && !empty($second_session['session_id'])) {
            $second_session_id = (int) $second_session['session_id'];
            $this->manifest['pos_sessions'][] = $second_session_id;
            $this->summary['pos_sessions']++;

            foreach (array_slice($eligible_orders, 25, 20) as $order_id) {
                Bizmart_POS_Session::tag_order((int) $order_id, $register_ids[1], $second_session_id);
                $this->summary['pos_orders']++;
            }

            $cash_in = Bizmart_POS_Session::add_cash_movement($second_session_id, 'in', 35.00, 'Added change float for evening session');
            if (!empty($cash_in['success']) && !empty($cash_in['movement_id'])) {
                $this->manifest['pos_cash_movements'][] = (int) $cash_in['movement_id'];
                $this->summary['pos_cash_movements']++;
            }
        }

        if ($previous_user_id !== $cashier_id && function_exists('wp_set_current_user')) {
            wp_set_current_user($previous_user_id);
        }
    }

    private function soft_delete_invoice($invoice_id) {
        global $wpdb;

        $invoice = $wpdb->get_row($wpdb->prepare(
            "SELECT supplier_id, total, doc_status, deduct_stock FROM {$wpdb->prefix}bizmart_invoices WHERE id = %d AND deleted_at IS NULL",
            $invoice_id
        ));
        if (!$invoice) {
            return;
        }

        $items = $wpdb->get_results($wpdb->prepare(
            "SELECT product_id, quantity, manage_stock FROM {$wpdb->prefix}bizmart_invoice_items WHERE invoice_id = %d",
            $invoice_id
        ));

        $effective_stock = function_exists('bizmart_invoice_stock_effective')
            ? bizmart_invoice_stock_effective($invoice->doc_status, $invoice->deduct_stock)
            : ($invoice->doc_status === 'approved' && (int) $invoice->deduct_stock === 1);

        if ($effective_stock) {
            foreach ($items as $item) {
                if (!(int) $item->manage_stock) {
                    continue;
                }
                bizmart_invoice_apply_stock_delta((int) $item->product_id, -1 * (float) $item->quantity, [
                    'invoice_id' => $invoice_id,
                    'source' => 'demo_seed_invoice_delete',
                ]);
            }
        }

        $wpdb->update(
            $wpdb->prefix . 'bizmart_invoices',
            ['deleted_at' => current_time('mysql')],
            ['id' => $invoice_id],
            ['%s'],
            ['%d']
        );

        bizmart_update_supplier_financials((int) $invoice->supplier_id);
        bizmart_add_supplier_history(
            (int) $invoice->supplier_id,
            'invoice_deleted',
            $invoice_id,
            null,
            (float) $invoice->total,
            sprintf('Invoice #%d moved to trash (recoverable) - Amount: %s %s - Stock restored', $invoice_id, number_format((float) $invoice->total, 2), get_woocommerce_currency_symbol())
        );
        if ($wpdb->insert_id) {
            $this->manifest['supplier_history'][] = (int) $wpdb->insert_id;
        }
    }

    private function restore_invoice($invoice_id) {
        global $wpdb;

        $invoice = $wpdb->get_row($wpdb->prepare(
            "SELECT supplier_id, total, deleted_at, doc_status, deduct_stock FROM {$wpdb->prefix}bizmart_invoices WHERE id = %d AND deleted_at IS NOT NULL",
            $invoice_id
        ));
        if (!$invoice) {
            return;
        }

        $items = $wpdb->get_results($wpdb->prepare(
            "SELECT product_id, quantity, manage_stock FROM {$wpdb->prefix}bizmart_invoice_items WHERE invoice_id = %d",
            $invoice_id
        ));

        $effective_stock = function_exists('bizmart_invoice_stock_effective')
            ? bizmart_invoice_stock_effective($invoice->doc_status, $invoice->deduct_stock)
            : ($invoice->doc_status === 'approved' && (int) $invoice->deduct_stock === 1);

        if ($effective_stock) {
            foreach ($items as $item) {
                if (!(int) $item->manage_stock) {
                    continue;
                }
                bizmart_invoice_apply_stock_delta((int) $item->product_id, (float) $item->quantity, [
                    'invoice_id' => $invoice_id,
                    'source' => 'demo_seed_invoice_restore',
                ]);
            }
        }

        $wpdb->update(
            $wpdb->prefix . 'bizmart_invoices',
            ['deleted_at' => null],
            ['id' => $invoice_id],
            ['%s'],
            ['%d']
        );

        bizmart_update_supplier_financials((int) $invoice->supplier_id);
        bizmart_add_supplier_history(
            (int) $invoice->supplier_id,
            'invoice_restored',
            $invoice_id,
            null,
            (float) $invoice->total,
            sprintf('Invoice #%d restored - Amount: %s %s', $invoice_id, number_format((float) $invoice->total, 2), get_woocommerce_currency_symbol())
        );
        if ($wpdb->insert_id) {
            $this->manifest['supplier_history'][] = (int) $wpdb->insert_id;
        }
    }

    public function cleanup_existing_seed() {
        global $wpdb;

        $manifest = get_option($this->manifest_option, []);
        if (!is_array($manifest) || empty($manifest)) {
            return 'No previous demo dataset was found.';
        }

        if (!empty($manifest['orders'])) {
            foreach (array_reverse(array_map('intval', $manifest['orders'])) as $order_id) {
                $order = wc_get_order($order_id);
                if ($order) {
                    $order->delete(true);
                }
            }
        }

        if (!empty($manifest['pos_cash_movements'])) {
            foreach (array_map('intval', $manifest['pos_cash_movements']) as $movement_id) {
                $wpdb->delete($wpdb->prefix . 'bizmart_pos_cash_movements', ['id' => $movement_id], ['%d']);
            }
        }

        if (!empty($manifest['pos_sessions'])) {
            foreach (array_map('intval', $manifest['pos_sessions']) as $session_id) {
                $wpdb->delete($wpdb->prefix . 'bizmart_pos_sessions', ['id' => $session_id], ['%d']);
            }
        }

        if (!empty($manifest['pos_registers'])) {
            foreach (array_map('intval', $manifest['pos_registers']) as $register_id) {
                $wpdb->delete($wpdb->prefix . 'bizmart_pos_registers', ['id' => $register_id], ['%d']);
            }
        }

        if (!empty($manifest['payments'])) {
            foreach (array_map('intval', $manifest['payments']) as $payment_id) {
                $wpdb->delete($wpdb->prefix . 'bizmart_payments', ['id' => $payment_id], ['%d']);
            }
        }

        if (!empty($manifest['expenses'])) {
            foreach (array_map('intval', $manifest['expenses']) as $expense_id) {
                $wpdb->delete($wpdb->prefix . 'bizmart_expenses', ['id' => $expense_id], ['%d']);
            }
        }

        if (!empty($manifest['supplier_history'])) {
            foreach (array_map('intval', $manifest['supplier_history']) as $history_id) {
                $wpdb->delete($wpdb->prefix . 'bizmart_supplier_history', ['id' => $history_id], ['%d']);
            }
        }

        if (!empty($manifest['price_history'])) {
            foreach (array_map('intval', $manifest['price_history']) as $history_id) {
                $wpdb->delete($wpdb->prefix . 'bizmart_price_history', ['id' => $history_id], ['%d']);
            }
        }

        if (!empty($manifest['invoice_items'])) {
            foreach (array_map('intval', $manifest['invoice_items']) as $item_id) {
                $wpdb->delete($wpdb->prefix . 'bizmart_invoice_items', ['id' => $item_id], ['%d']);
            }
        }

        if (!empty($manifest['invoices'])) {
            foreach (array_map('intval', $manifest['invoices']) as $invoice_id) {
                $wpdb->delete($wpdb->prefix . 'bizmart_invoices', ['id' => $invoice_id], ['%d']);
            }
        }

        if (!empty($manifest['suppliers'])) {
            foreach (array_map('intval', $manifest['suppliers']) as $supplier_id) {
                $wpdb->delete($wpdb->prefix . 'bizmart_suppliers', ['id' => $supplier_id], ['%d']);
            }
        }

        if (!empty($manifest['products'])) {
            foreach (array_reverse(array_map('intval', $manifest['products'])) as $product_id) {
                $product = wc_get_product($product_id);
                if ($product) {
                    $product->delete(true);
                }
            }
        }

        if (!empty($manifest['product_skus'])) {
            foreach ((array) $manifest['product_skus'] as $sku) {
                $wpdb->delete($wpdb->prefix . 'bizmart_products', ['sku' => $sku], ['%s']);
            }
        }

        if (!empty($manifest['product_tags'])) {
            foreach (array_reverse(array_unique(array_map('intval', $manifest['product_tags']))) as $term_id) {
                wp_delete_term($term_id, 'product_tag');
            }
        }

        if (!empty($manifest['product_categories'])) {
            foreach (array_reverse(array_unique(array_map('intval', $manifest['product_categories']))) as $term_id) {
                wp_delete_term($term_id, 'product_cat');
            }
        }

        if (function_exists('bizmart_recalculate_all_financials')) {
            bizmart_recalculate_all_financials();
        }

        // Clear dashboard and inventory transient caches
        $blog_id = (int) get_current_blog_id();
        delete_transient('bizmart_inventory_totals_v9_' . $blog_id);
        delete_transient('bizmart_dash_missing_pricing_v3');
        delete_transient('bizmart_dash_stock_alerts_v1');

        delete_option($this->manifest_option);

        return 'Previous demo dataset removed.';
    }

    private function build_invoice_items($index, $products, $scenario) {
        $items = [];
        $item_count = 2 + ($index % 3);

        for ($line = 0; $line < $item_count; $line++) {
            $product = $products[(($index * 4) + ($line * 7)) % count($products)];
            $quantity = 1 + (($index + $line) % 4);
            $purchase_price = round($product['purchase_price'] + (($index % 5) * 0.35) + (($line % 2) ? 0.2 : 0), 2);
            $selling_price = round($product['regular_price'] + (($index % 3) * 0.25), 2);

            $items[] = [
                'product_id' => $product['id'],
                'sku' => $product['sku'],
                'product_name' => strtoupper($product['name']),
                'quantity' => $quantity,
                'purchase_price' => $purchase_price,
                'selling_price' => $selling_price,
                'manage_stock' => (($index + $line) % 8 !== 0),
            ];
        }

        if (!empty($scenario['duplicate_first_item']) && !empty($items[0])) {
            $items[] = [
                'product_id' => $items[0]['product_id'],
                'sku' => $items[0]['sku'],
                'product_name' => $items[0]['product_name'],
                'quantity' => 1,
                'purchase_price' => $items[0]['purchase_price'],
                'selling_price' => $items[0]['selling_price'],
                'manage_stock' => true,
            ];
        }

        return $items;
    }

    private function get_invoice_scenarios() {
        $now = new DateTimeImmutable('now', wp_timezone());

        $scenarios = [];
        for ($index = 0; $index < 60; $index++) {
            $day_offset = floor((60 - $index) * 2);
            $date = $now->modify('-' . $day_offset . ' days')->setTime(10 + ($index % 6), 15, 0);
            $doc_status = 'approved';
            $deduct_stock = 1;
            $payments = [];
            $soft_delete = false;
            $restore_after_delete = false;

            if ($index >= 55 && $index <= 57) {
                $doc_status = 'pending_approval';
            } elseif ($index === 58) {
                $doc_status = 'draft';
            }

            if ($index === 45) {
                $deduct_stock = 0;
            }

            $notes = [
                'Seasonal replenishment before weekend campaign.',
                'Imported batch with mixed sizes and tester units.',
                'Supplier offered a bundle discount on selected SKUs.',
                'Used for shelf refresh and reorder balancing.',
                'Urgent restock to protect bestselling serum lines.',
                'Monthly procurement to secure salon professional stock.',
            ][$index % 6];

            if ($doc_status === 'approved') {
                if ($index <= 30) {
                    $payments = [
                        ['amount_ratio' => 0.55, 'delay_days' => 3, 'method' => 'transfer', 'note' => 'Initial payment', 'create_expense' => true],
                        ['amount_ratio' => 0.45, 'delay_days' => 10, 'method' => 'card', 'note' => 'Balance settled', 'create_expense' => false],
                    ];
                } elseif ($index <= 48) {
                    $payments = [
                        ['amount_ratio' => 0.45, 'delay_days' => 6, 'method' => 'cash', 'note' => 'Partial payment', 'create_expense' => true],
                    ];
                } elseif ($index === 49) {
                    $soft_delete = true;
                } elseif ($index === 59) {
                    $soft_delete = true;
                    $restore_after_delete = true;
                }
            }

            $scenarios[] = [
                'supplier_index' => $index % 8,
                'date' => $date,
                'doc_status' => $doc_status,
                'deduct_stock' => $deduct_stock,
                'notes' => $notes,
                'payments' => $this->normalize_payment_scenarios($date, $payments),
                'soft_delete' => $soft_delete,
                'restore_after_delete' => $restore_after_delete,
                'duplicate_first_item' => in_array($index, [3, 11, 23, 35, 47], true),
            ];
        }

        return $scenarios;
    }

    private function normalize_payment_scenarios($invoice_date, $payments) {
        $normalized = [];
        foreach ($payments as $payment) {
            $normalized[] = [
                'amount_ratio' => $payment['amount_ratio'],
                'method' => $payment['method'],
                'note' => $payment['note'],
                'date' => $invoice_date->modify('+' . (int) $payment['delay_days'] . ' days'),
                'create_expense' => !empty($payment['create_expense']),
            ];
        }
        return $normalized;
    }

    private function get_product_blueprints() {
        return [
            ['name' => 'Aqua Veil Gel Cleanser 200ml', 'category' => 'skincare', 'tier' => 1, 'tags' => ['hydrating', 'daily-care', 'sensitive-skin'], 'short_description' => 'Low-foam gel cleanser for balanced daily cleansing.', 'description' => 'A fresh gel cleanser with glycerin and betaine that removes makeup residue, sunscreen, and daily impurities without stripping the skin barrier.'],
            ['name' => 'Vitamin C Dew Serum 30ml', 'category' => 'skincare', 'tier' => 3, 'tags' => ['brightening', 'vegan', 'daily-care'], 'short_description' => 'Brightening antioxidant serum with a smooth finish.', 'description' => 'Lightweight vitamin C serum built for dull complexions, uneven tone, and early hyperpigmentation care. Layers cleanly under moisturizer and SPF.'],
            ['name' => 'Ceramide Barrier Cream 50ml', 'category' => 'skincare', 'tier' => 2, 'tags' => ['hydrating', 'sensitive-skin', 'daily-care'], 'short_description' => 'Comforting cream for dry and reactive skin.', 'description' => 'A rich ceramide moisturizer designed to restore comfort after cleansing, acids, or seasonal dehydration. Suitable for normal to very dry skin.'],
            ['name' => 'Niacinamide Refining Toner 150ml', 'category' => 'skincare', 'tier' => 2, 'tags' => ['brightening', 'vegan', 'daily-care'], 'short_description' => 'Balancing toner that refines texture and visible pores.', 'description' => 'A fast-absorbing toner with niacinamide and humectants to smooth texture, support a healthy barrier, and prep the skin for serums.'],
            ['name' => 'Overnight Recovery Mask 75ml', 'category' => 'skincare', 'tier' => 3, 'tags' => ['hydrating', 'sensitive-skin'], 'short_description' => 'Sleeping mask for overnight replenishment.', 'description' => 'Cream mask that seals in hydration and helps skin look rested by morning. Performs well after exfoliation or professional facials.'],
            ['name' => 'Micellar Melt Makeup Remover 250ml', 'category' => 'skincare', 'tier' => 1, 'tags' => ['daily-care', 'sensitive-skin'], 'short_description' => 'Micellar water that removes face and eye makeup gently.', 'description' => 'No-rinse cleanser that dissolves light makeup and sunscreen while respecting sensitive eye contours and delicate skin.'],
            ['name' => 'Peptide Eye Comfort Cream 20ml', 'category' => 'skincare', 'tier' => 3, 'tags' => ['hydrating', 'daily-care'], 'short_description' => 'Silky eye cream for puffiness and dryness.', 'description' => 'Peptide eye cream with caffeine and squalane designed for smooth concealer application and all-day comfort around the eyes.'],
            ['name' => 'Gentle Exfoliating Essence 120ml', 'category' => 'skincare', 'tier' => 2, 'tags' => ['brightening', 'daily-care'], 'short_description' => 'Daily resurfacing essence with a polished glow.', 'description' => 'Soft resurfacing essence that improves clarity and glow while staying suitable for regular use in a retail skincare routine.'],
            ['name' => 'Hyaluronic Mist 100ml', 'category' => 'skincare', 'tier' => 1, 'tags' => ['hydrating', 'daily-care', 'vegan'], 'short_description' => 'Portable hydration mist for face refreshes.', 'description' => 'A handbag-friendly hydration mist that revives makeup and brings back comfort after sun, air conditioning, or long retail shifts.'],
            ['name' => 'SPF 50 Invisible Fluid 50ml', 'category' => 'suncare', 'tier' => 3, 'tags' => ['spf', 'daily-care', 'sensitive-skin'], 'short_description' => 'Fluid sunscreen with no white cast.', 'description' => 'Broad-spectrum sunscreen with an invisible finish that sits well under makeup and helps protect against city exposure and daily UV.'],
            ['name' => 'Silk Blur Foundation 30ml', 'category' => 'makeup', 'tier' => 3, 'tags' => ['long-wear', 'professional'], 'short_description' => 'Medium coverage foundation with skin-like finish.', 'description' => 'Retail bestseller foundation built for balanced coverage, comfortable wear, and easy shade matching in beauty stores.'],
            ['name' => 'Cloud Matte Concealer 12ml', 'category' => 'makeup', 'tier' => 2, 'tags' => ['long-wear', 'professional'], 'short_description' => 'Creamy concealer that brightens without cracking.', 'description' => 'Flexible concealer for under-eye brightening and spot coverage. Designed to stay smooth under studio lights and daily wear.'],
            ['name' => 'Feather Lash Mascara Black', 'category' => 'makeup', 'tier' => 1, 'tags' => ['long-wear', 'daily-care'], 'short_description' => 'Lengthening mascara with clean separation.', 'description' => 'Lightweight mascara with a tapered brush that builds length and lift without flaking through the day.'],
            ['name' => 'Velvet Kiss Lip Cream Rose Nude', 'category' => 'makeup', 'tier' => 2, 'tags' => ['long-wear', 'vegan'], 'short_description' => 'Comfortable matte lip cream in a neutral tone.', 'description' => 'Soft-matte lip cream with strong retail appeal for everyday shades and quick basket-building at checkout.'],
            ['name' => 'Glow Script Highlighter Champagne', 'category' => 'makeup', 'tier' => 2, 'tags' => ['brightening', 'professional'], 'short_description' => 'Fine shimmer highlighter with smooth payoff.', 'description' => 'Pressed powder highlighter for soft radiance on cheekbones, lids, and body highlights without chunky glitter.'],
            ['name' => 'Soft Arch Brow Pencil Taupe', 'category' => 'makeup', 'tier' => 1, 'tags' => ['daily-care', 'long-wear'], 'short_description' => 'Precision brow pencil with spoolie.', 'description' => 'Dual-ended brow pencil designed for fast fill-in work, natural structure, and salon-friendly brow retail service upsells.'],
            ['name' => 'Color Fix Cream Blush Coral', 'category' => 'makeup', 'tier' => 2, 'tags' => ['vegan', 'daily-care'], 'short_description' => 'Cream blush with blendable color payoff.', 'description' => 'Buildable cheek tint that melts into skin and works well with fingers, sponge, or brush for quick customer demos.'],
            ['name' => 'Scene Setter Makeup Spray 100ml', 'category' => 'makeup', 'tier' => 1, 'tags' => ['long-wear', 'daily-care'], 'short_description' => 'Fixing mist for longer makeup hold.', 'description' => 'Refreshing setting spray that helps makeup stay in place while reducing powderiness and keeping the complexion fresh.'],
            ['name' => 'Radiant Primer Serum 25ml', 'category' => 'makeup', 'tier' => 2, 'tags' => ['brightening', 'hydrating'], 'short_description' => 'Glow primer that smooths and grips foundation.', 'description' => 'Serum-textured primer that combines grip, hydration, and a soft lit-from-within finish for bridal or boutique customers.'],
            ['name' => 'Contour Stick Soft Bronze', 'category' => 'makeup', 'tier' => 2, 'tags' => ['professional', 'long-wear'], 'short_description' => 'Cream contour with easy blend.', 'description' => 'Portable contour stick suited for beginners and makeup artists who want quick shaping with natural depth.'],
            ['name' => 'Keratin Repair Shampoo 300ml', 'category' => 'haircare', 'tier' => 2, 'tags' => ['salon-grade', 'sulfate-free'], 'short_description' => 'Repair shampoo for stressed and color-treated hair.', 'description' => 'Salon-style shampoo formulated to cleanse gently while helping damaged hair feel smoother and easier to style.'],
            ['name' => 'Botanical Scalp Scrub 180ml', 'category' => 'haircare', 'tier' => 2, 'tags' => ['salon-grade', 'daily-care'], 'short_description' => 'Purifying scalp exfoliator with fresh finish.', 'description' => 'Scalp treatment designed to lift buildup, rebalance roots, and refresh the scalp before shampooing.'],
            ['name' => 'Silk Protein Conditioner 250ml', 'category' => 'haircare', 'tier' => 2, 'tags' => ['hydrating', 'salon-grade'], 'short_description' => 'Conditioner that softens lengths without heaviness.', 'description' => 'Daily conditioner for normal to dry hair with lightweight nourishment, combability, and shine enhancement.'],
            ['name' => 'Argan Gloss Hair Oil 60ml', 'category' => 'haircare', 'tier' => 3, 'tags' => ['brightening', 'professional'], 'short_description' => 'Finishing oil for shine and frizz control.', 'description' => 'Professional finishing oil that adds polished shine, tames flyaways, and supports smoother blow-dry results.'],
            ['name' => 'Coconut Curl Defining Cream 200ml', 'category' => 'haircare', 'tier' => 2, 'tags' => ['hydrating', 'vegan'], 'short_description' => 'Curl cream with flexible hold and softness.', 'description' => 'Defines waves and curls while keeping bounce, softness, and a non-crunch feel for textured hair customers.'],
            ['name' => 'Thermal Shield Blow-Dry Spray 150ml', 'category' => 'haircare', 'tier' => 2, 'tags' => ['professional', 'daily-care'], 'short_description' => 'Heat protectant spray for styling routines.', 'description' => 'Light spray that helps protect hair from thermal stress while improving styling memory and smoothness.'],
            ['name' => 'Overnight Bond Repair Mask 220ml', 'category' => 'haircare', 'tier' => 3, 'tags' => ['salon-grade', 'hydrating'], 'short_description' => 'Intensive weekly mask for brittle hair.', 'description' => 'Bond-support mask for dry, color-treated, or heat-stressed hair. A high-value add-on in salon retail corners.'],
            ['name' => 'Fresh Linen Dry Shampoo 180ml', 'category' => 'haircare', 'tier' => 1, 'tags' => ['daily-care', 'vegan'], 'short_description' => 'Dry shampoo that revives roots quickly.', 'description' => 'Invisible dry shampoo for busy customers who want a fast root refresh between washes without visible residue.'],
            ['name' => 'Velvet Body Lotion 300ml', 'category' => 'bodycare', 'tier' => 1, 'tags' => ['hydrating', 'daily-care'], 'short_description' => 'Silky body lotion for everyday hydration.', 'description' => 'Fast-absorbing body lotion with a soft powdery finish suited for retail shelves, gift sets, and repeat purchase behavior.'],
            ['name' => 'Sugar Polish Body Scrub 250g', 'category' => 'bodycare', 'tier' => 2, 'tags' => ['brightening', 'vegan'], 'short_description' => 'Body scrub with smooth exfoliation.', 'description' => 'Sugar polish that leaves skin refined and comfortable while helping body lotions absorb more evenly after use.'],
            ['name' => 'Shea Rescue Hand Cream 75ml', 'category' => 'bodycare', 'tier' => 1, 'tags' => ['hydrating', 'sensitive-skin'], 'short_description' => 'Nourishing hand cream for dry hands.', 'description' => 'Pocket hand cream designed for frequent use in beauty retail, nail bars, and salon checkout counters.'],
            ['name' => 'Rose Petal Shower Gel 250ml', 'category' => 'bodycare', 'tier' => 1, 'tags' => ['daily-care', 'vegan'], 'short_description' => 'Soft-fragrance body wash for daily use.', 'description' => 'Daily shower gel with a gentle base and floral scent profile that fits gifting, layering, and basket building.'],
            ['name' => 'Even Tone Body Serum 120ml', 'category' => 'bodycare', 'tier' => 3, 'tags' => ['brightening', 'professional'], 'short_description' => 'Body serum for uneven tone and dry patches.', 'description' => 'Targeted body serum with brightening actives for elbows, knees, and post-summer tone correction.'],
            ['name' => 'Soothing After-Wax Gel 150ml', 'category' => 'bodycare', 'tier' => 2, 'tags' => ['sensitive-skin', 'professional'], 'short_description' => 'Cooling gel for post-treatment care.', 'description' => 'Professional after-wax care product that calms the skin and supports service upsells in salons and beauty bars.'],
            ['name' => 'Luminous Body Oil 100ml', 'category' => 'bodycare', 'tier' => 3, 'tags' => ['brightening', 'vegan'], 'short_description' => 'Dry-touch body oil with subtle glow.', 'description' => 'Elegant body oil that boosts skin radiance without heaviness and works well for bridal, event, and fragrance layering sales.'],
            ['name' => 'Foot Comfort Balm 80ml', 'category' => 'bodycare', 'tier' => 1, 'tags' => ['hydrating', 'daily-care'], 'short_description' => 'Repair balm for dry heels and tired feet.', 'description' => 'Rich foot balm that supports overnight repair and pairs well with pedicure services and spa retail displays.'],
            ['name' => 'Mineral Sunscreen Stick SPF 50', 'category' => 'suncare', 'tier' => 2, 'tags' => ['spf', 'sensitive-skin'], 'short_description' => 'Portable SPF stick for quick reapplication.', 'description' => 'Convenient sunscreen stick for face touch-ups, travel use, and daily reapplication without disturbing makeup too much.'],
            ['name' => 'Hydra Sun Milk SPF 30 150ml', 'category' => 'suncare', 'tier' => 2, 'tags' => ['spf', 'hydrating'], 'short_description' => 'Moisturizing body sunscreen for daily use.', 'description' => 'Body sunscreen milk with a comfortable spread and quick absorption for families and everyday outdoor exposure.'],
            ['name' => 'After Sun Aloe Jelly 200ml', 'category' => 'suncare', 'tier' => 1, 'tags' => ['hydrating', 'sensitive-skin'], 'short_description' => 'Cooling aloe jelly after sun exposure.', 'description' => 'Cooling gel-jelly that helps calm heat-exposed skin and is easy to position near seasonal sun care shelves.'],
            ['name' => 'Urban Shield SPF 50 Mist 75ml', 'category' => 'suncare', 'tier' => 3, 'tags' => ['spf', 'daily-care'], 'short_description' => 'Face mist SPF for top-ups over makeup.', 'description' => 'An urban-friendly sunscreen mist created for midday protection, commuting, and easy reapplication over finished makeup.'],
            ['name' => 'Bronze Glow Dry Oil SPF 20', 'category' => 'suncare', 'tier' => 2, 'tags' => ['spf', 'brightening'], 'short_description' => 'Dry oil sun care with cosmetic glow.', 'description' => 'Body sun oil with a lightweight finish and subtle luminous effect for customers who prefer glow-forward summer care.'],
            ['name' => 'Salt Breeze Hair and Body Mist 120ml', 'category' => 'fragrance', 'tier' => 1, 'tags' => ['daily-care', 'vegan'], 'short_description' => 'Fresh body mist with clean marine notes.', 'description' => 'Light fragrance mist positioned for impulse purchases, gym bags, and warm-weather layering with body care.'],
            ['name' => 'Amber Bloom Eau de Parfum 50ml', 'category' => 'fragrance', 'tier' => 3, 'tags' => ['professional', 'daily-care'], 'short_description' => 'Warm floral amber perfume with soft trail.', 'description' => 'A polished amber-floral fragrance that suits evening retail gifting, signature scent seekers, and boutique presentation tables.'],
            ['name' => 'Citrus Atelier Cologne 30ml', 'category' => 'fragrance', 'tier' => 2, 'tags' => ['brightening', 'daily-care'], 'short_description' => 'Bright citrus fragrance with aromatic finish.', 'description' => 'Vibrant citrus cologne with a crisp opening and refined dry-down for everyday premium fragrance shoppers.'],
            ['name' => 'Velvet Musk Roll-On 12ml', 'category' => 'fragrance', 'tier' => 1, 'tags' => ['daily-care', 'sensitive-skin'], 'short_description' => 'Portable musk roll-on for touch-ups.', 'description' => 'Soft musk roll-on that works well near checkout counters and as an add-on fragrance for handbag convenience.'],
            ['name' => 'Noir Vanilla Hair Perfume 80ml', 'category' => 'fragrance', 'tier' => 2, 'tags' => ['salon-grade', 'daily-care'], 'short_description' => 'Hair perfume that leaves soft scent and shine.', 'description' => 'Salon-friendly hair mist with vanilla woods profile, helping fragrance corners cross-sell into haircare routines.'],
            ['name' => 'White Tea Linen Spray 150ml', 'category' => 'fragrance', 'tier' => 1, 'tags' => ['daily-care', 'vegan'], 'short_description' => 'Fabric and linen refresher with light scent.', 'description' => 'A lifestyle fragrance SKU that broadens basket composition and works well in gifting or wellness-oriented beauty stores.'],
            ['name' => 'Garden Neroli Eau Fraiche 60ml', 'category' => 'fragrance', 'tier' => 2, 'tags' => ['brightening', 'vegan'], 'short_description' => 'Fresh neroli fragrance for daytime wear.', 'description' => 'Clean citrus-floral fragrance positioned for spring and summer edits, travel retail, and daytime signature scent shoppers.'],
            ['name' => 'Cashmere Bloom Perfume Oil 15ml', 'category' => 'fragrance', 'tier' => 2, 'tags' => ['long-wear', 'vegan'], 'short_description' => 'Concentrated perfume oil with soft floral warmth.', 'description' => 'A compact perfume oil designed for gift sets, handbag carry, and higher-margin fragrance upsells with a long-lasting skin scent.'],
            ['name' => 'Midnight Orchid Elixir 50ml', 'category' => 'fragrance', 'tier' => 3, 'tags' => ['professional', 'long-wear'], 'short_description' => 'Deeper floral scent with evening presence.', 'description' => 'An elegant evening scent with richer floral notes and strong gifting potential for premium fragrance counters.'],
        ];
    }

    private function get_supplier_blueprints() {
        return [
            ['name' => 'Liora Beauty Supply', 'company' => 'Liora Beauty Supply LLC', 'email' => 'hello@liorabeauty.example', 'phone' => '+12125550101', 'phone2' => '+12125550102', 'address' => '120 Broadway', 'city' => 'New York', 'country' => 'United States', 'tax_id' => 'US-123456789', 'iban' => 'US2100010001000100010001', 'website' => 'https://liora.example', 'notes' => 'Specializes in skincare and sun care launches.'],
            ['name' => 'Apex Cosmetics Supply', 'company' => 'Apex Cosmetics Supply Corp', 'email' => 'sales@apexcosmetics.example', 'phone' => '+14155550102', 'phone2' => '+14155550103', 'address' => '450 Sutter St', 'city' => 'San Francisco', 'country' => 'United States', 'tax_id' => 'US-987654321', 'iban' => 'US2100010001000100010002', 'website' => 'https://apexcosmetics.example', 'notes' => 'Focuses on makeup staples and fast-moving color items.'],
            ['name' => 'Summit Hair Distribution', 'company' => 'Summit Hair Labs Inc', 'email' => 'orders@summithair.example', 'phone' => '+13235550103', 'phone2' => '+13235550104', 'address' => '8440 Melrose Ave', 'city' => 'West Hollywood', 'country' => 'United States', 'tax_id' => 'US-888333222', 'iban' => 'US2100010001000100010003', 'website' => 'https://summithair.example', 'notes' => 'Salon-grade haircare partner.'],
            ['name' => 'Pacific Glow Imports', 'company' => 'Pacific Glow Imports LLC', 'email' => 'trade@pacificglow.example', 'phone' => '+12065550104', 'phone2' => '+12065550105', 'address' => '1200 Pine St', 'city' => 'Seattle', 'country' => 'United States', 'tax_id' => 'US-777666555', 'iban' => 'US2100010001000100010004', 'website' => 'https://pacificglow.example', 'notes' => 'Imports body care and fragrance accessories.'],
            ['name' => 'Metro Fragrance House', 'company' => 'Metro Fragrance Distributors', 'email' => 'wholesale@metrofragrance.example', 'phone' => '+12135550105', 'phone2' => '+12135550106', 'address' => '210 W 5th St', 'city' => 'Los Angeles', 'country' => 'United States', 'tax_id' => 'US-111222333', 'iban' => 'US2100010001000100010005', 'website' => 'https://metrofragrance.example', 'notes' => 'Premium perfumes and body mists.'],
            ['name' => 'Nova Lab Solutions', 'company' => 'Nova Lab Solutions Inc', 'email' => 'support@novalab.example', 'phone' => '+16175550106', 'phone2' => '+16175550107', 'address' => '100 State St', 'city' => 'Boston', 'country' => 'United States', 'tax_id' => 'US-444555666', 'iban' => 'US2100010001000100010006', 'website' => 'https://novalab.example', 'notes' => 'Private-label skincare and testers.'],
            ['name' => 'Vanguard Retail Partners', 'company' => 'Vanguard Retail Partners LLC', 'email' => 'trade@vanguard.example', 'phone' => '+12125550107', 'phone2' => '+12125550108', 'address' => '350 Fifth Ave', 'city' => 'New York', 'country' => 'United States', 'tax_id' => 'US-555666777', 'iban' => 'US2100010001000100010007', 'website' => 'https://vanguard.example', 'notes' => 'Generalist supplier for mixed beauty categories.'],
            ['name' => 'Aura Distribution Services', 'company' => 'Aura Distribution Services Corp', 'email' => 'contact@auradistribution.example', 'phone' => '+15125550108', 'phone2' => '+15125550109', 'address' => '111 Congress Ave', 'city' => 'Austin', 'country' => 'United States', 'tax_id' => 'US-999000111', 'iban' => 'US2100010001000100010008', 'website' => 'https://auradistribution.example', 'notes' => 'Strong on gifting packs and seasonal launches.'],
        ];
    }

    private function get_customer_blueprints() {
        return [
            ['first_name' => 'Sarah', 'last_name' => 'Jenkins', 'company' => '', 'address_1' => '1540 Broadway', 'address_2' => '', 'city' => 'New York', 'postcode' => '10036', 'country' => 'US', 'email' => 'sarah.jenkins@example.com', 'phone' => '+12125550190'],
            ['first_name' => 'Yasmine', 'last_name' => 'Miller', 'company' => '', 'address_1' => '710 N DuSable Lake Shore Dr', 'address_2' => '', 'city' => 'Chicago', 'postcode' => '60611', 'country' => 'US', 'email' => 'yasmine.miller@example.com', 'phone' => '+13125550191'],
            ['first_name' => 'Nadia', 'last_name' => 'Smith', 'company' => '', 'address_1' => '100 NE Naito Pkwy', 'address_2' => '', 'city' => 'Portland', 'postcode' => '97209', 'country' => 'US', 'email' => 'nadia.smith@example.com', 'phone' => '+15035550192'],
            ['first_name' => 'Emily', 'last_name' => 'Davis', 'company' => '', 'address_1' => '501 W 15th St', 'address_2' => '', 'city' => 'Austin', 'postcode' => '78701', 'country' => 'US', 'email' => 'emily.davis@example.com', 'phone' => '+15125550193'],
            ['first_name' => 'Melissa', 'last_name' => 'Taylor', 'company' => '', 'address_1' => '900 Southside Dr', 'address_2' => '', 'city' => 'Atlanta', 'postcode' => '30312', 'country' => 'US', 'email' => 'melissa.taylor@example.com', 'phone' => '+14045550194'],
        ];
    }

    private function render_page($notice, $error) {
        $manifest = get_option($this->manifest_option, []);
        $summary = is_array($manifest) && isset($manifest['summary']) && is_array($manifest['summary']) ? $manifest['summary'] : [];
        $currency = get_woocommerce_currency_symbol();
        ?>
        <!doctype html>
        <html>
        <head>
            <meta charset="utf-8">
            <title>Bizmart Demo Seeder</title>
            <style>
                body { font-family: Segoe UI, Arial, sans-serif; background: #f5f7fb; color: #0f172a; margin: 0; padding: 32px; }
                .wrap { max-width: 980px; margin: 0 auto; }
                .card { background: #fff; border-radius: 18px; box-shadow: 0 18px 55px rgba(15, 23, 42, 0.08); padding: 28px; margin-bottom: 24px; }
                h1 { font-size: 30px; margin: 0 0 10px; }
                p { line-height: 1.6; color: #475569; }
                .notice { padding: 14px 16px; border-radius: 12px; margin-bottom: 18px; }
                .notice-success { background: #dcfce7; color: #166534; }
                .notice-error { background: #fee2e2; color: #991b1b; }
                .actions { display: flex; gap: 12px; flex-wrap: wrap; margin-top: 20px; }
                button { border: 0; border-radius: 12px; padding: 13px 18px; font-weight: 700; cursor: pointer; }
                .btn-primary { background: #0f766e; color: #fff; }
                .btn-secondary { background: #e2e8f0; color: #0f172a; }
                .grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 14px; margin-top: 18px; }
                .stat { background: #f8fafc; border: 1px solid #e2e8f0; border-radius: 14px; padding: 16px; }
                .stat strong { display: block; font-size: 24px; margin-bottom: 4px; }
                code { background: #f1f5f9; padding: 2px 6px; border-radius: 6px; }
                ul { margin: 10px 0 0 18px; color: #334155; }
            </style>
        </head>
        <body>
            <div class="wrap">
                <div class="card">
                    <h1>Bizmart Demo Data Seeder</h1>
                    <p>This standalone admin-only tool creates a realistic demo catalog and procurement dataset for Bizmart without modifying plugin logic. It generates 50 WooCommerce cosmetics products, suppliers, invoices, duplicate-line purchase history, partial and full payments, global payments, expenses, cashflow-driving records, and sample WooCommerce orders.</p>
                    <p>File location: <code>bizmart-stock-finance-invoice/demo-data-seeder.php</code></p>
                    <?php if ($notice) : ?>
                        <div class="notice notice-success"><?php echo esc_html($notice); ?></div>
                    <?php endif; ?>
                    <?php if ($error) : ?>
                        <div class="notice notice-error"><?php echo esc_html($error); ?></div>
                    <?php endif; ?>
                    <form method="post">
                        <?php wp_nonce_field('bizmart_demo_seeder_action'); ?>
                        <div class="actions">
                            <button type="submit" class="btn-primary" name="seed_action" value="generate">Generate Full Demo Dataset</button>
                            <button type="submit" class="btn-secondary" name="seed_action" value="cleanup">Remove Previous Demo Dataset</button>
                        </div>
                    </form>
                </div>

                <div class="card">
                    <h2 style="margin-top:0;">What It Creates</h2>
                    <ul>
                        <li>50 realistic cosmetics and beauty products in WooCommerce</li>
                        <li>8 suppliers with contact and banking details</li>
                        <li>22 supplier invoices covering approved, partial, unpaid, draft, pending approval, no-stock, deleted, and restored scenarios</li>
                        <li>Invoice payments with cash, transfer, card, and check methods</li>
                        <li>2 global supplier payments using FIFO distribution</li>
                        <li>Standalone operating expenses and payment-linked Versement expenses</li>
                        <li>12 WooCommerce orders to make the catalog feel active</li>
                    </ul>
                </div>

                <div class="card">
                    <h2 style="margin-top:0;">Last Seed Summary</h2>
                    <div class="grid">
                        <div class="stat"><strong><?php echo esc_html((string) ($summary['products'] ?? 0)); ?></strong>Products</div>
                        <div class="stat"><strong><?php echo esc_html((string) ($summary['suppliers'] ?? 0)); ?></strong>Suppliers</div>
                        <div class="stat"><strong><?php echo esc_html((string) ($summary['invoices'] ?? 0)); ?></strong>Invoices</div>
                        <div class="stat"><strong><?php echo esc_html((string) ($summary['payments'] ?? 0)); ?></strong>Payments</div>
                        <div class="stat"><strong><?php echo esc_html((string) ($summary['expenses'] ?? 0)); ?></strong>Expenses</div>
                        <div class="stat"><strong><?php echo esc_html((string) ($summary['orders'] ?? 0)); ?></strong>Orders</div>
                        <div class="stat"><strong><?php echo esc_html((string) ($summary['low_stock_products'] ?? 0)); ?></strong>Low Stock</div>
                        <div class="stat"><strong><?php echo esc_html((string) ($summary['out_of_stock_products'] ?? 0)); ?></strong>Out of Stock</div>
                        <div class="stat"><strong><?php echo esc_html((string) ($summary['active_invoices'] ?? 0)); ?></strong>Active Invoices</div>
                        <div class="stat"><strong><?php echo esc_html((string) ($summary['deleted_invoices'] ?? 0)); ?></strong>Deleted Invoices</div>
                        <div class="stat"><strong><?php echo esc_html((string) ($summary['restored_invoices'] ?? 0)); ?></strong>Restored Invoices</div>
                        <div class="stat"><strong><?php echo esc_html($currency); ?></strong>Currency</div>
                    </div>
                </div>
            </div>
        </body>
        </html>
        <?php
    }
}

if (!function_exists('bizmart_demo_data_get_seeder_instance')) {
    function bizmart_demo_data_get_seeder_instance() {
        return new Bizmart_Demo_Data_Seeder();
    }
}

// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
$bizmart_demo_entry_script = isset($_SERVER['SCRIPT_FILENAME']) ? realpath(sanitize_text_field(wp_unslash($_SERVER['SCRIPT_FILENAME']))) : '';
if (PHP_SAPI === 'cli' || ($bizmart_demo_entry_script && $bizmart_demo_entry_script === realpath(__FILE__))) {
    $bizmart_seeder = bizmart_demo_data_get_seeder_instance();
    $bizmart_seeder->handle_request();
}