<?php
if (!defined('ABSPATH')) exit;

/**
 * Creates the consultation-backed operating manifest used by every VMO subsystem.
 */
class VMO_Business_Manifest_Generator {
    const VERSION = 'vmo_business_manifest_v1';

    public function generate_manifest($user_id, $session_id, $consultation_data = array(), $business_package = array(), $website_result = array(), $research_results = array()) {
        $user_id = (int) $user_id;
        $session_id = sanitize_text_field((string) $session_id);
        $consultation_data = is_array($consultation_data) ? $consultation_data : array();
        $business_package = is_array($business_package) ? $business_package : array();
        $website_result = is_array($website_result) ? $website_result : array();
        $research_results = is_array($research_results) && !empty($research_results)
            ? $research_results
            : (is_array($consultation_data['research_results'] ?? null) ? $consultation_data['research_results'] : array());

        $user_type = $this->normalize_user_type($this->first_value(array(
            $consultation_data['user_type'] ?? '',
            $consultation_data['onboarding_type'] ?? '',
            $consultation_data['hosting_path'] ?? '',
            $consultation_data['provisioning_path'] ?? '',
            $consultation_data['email_roles_meta']['user_type'] ?? '',
        ), ''), $consultation_data);

        $business_profile = $this->build_business_profile($user_id, $session_id, $user_type, $consultation_data, $business_package);
        $target_audience = $this->build_target_audience($consultation_data, $business_package, $research_results);
        $offer_structure = $this->build_offer_structure($consultation_data, $business_package);
        $revenue_model = $this->build_revenue_model($consultation_data, $offer_structure);
        $email_system = $this->build_email_system($user_type, $consultation_data);
        $phone_system = $this->build_phone_system($consultation_data);
        $ecommerce_config = $this->build_ecommerce_config($consultation_data, $offer_structure, $revenue_model);
        $website_structure = $this->build_website_structure($consultation_data, $business_package, $website_result, $email_system, $ecommerce_config);
        $kpi_targets = $this->build_kpi_targets($business_profile, $target_audience, $revenue_model, $website_structure, $consultation_data);
        $marketing_strategy = $this->build_marketing_strategy($consultation_data, $business_package, $research_results, $target_audience);
        $seo_strategy = $this->build_seo_strategy($consultation_data, $business_package, $research_results);
        $automation_rules = $this->build_automation_rules($kpi_targets, $marketing_strategy, $seo_strategy, $email_system, $website_structure, $revenue_model);
        $documents_required = $this->build_documents_required($consultation_data, $business_profile, $revenue_model, $ecommerce_config);

        return array(
            'version' => self::VERSION,
            'manifest_id' => 'vmo_manifest_' . md5($user_id . '|' . $session_id . '|' . wp_json_encode($business_profile)),
            'source_of_truth' => 'class-vmo-enhanced-business-wizard.php',
            'prompt_source' => 'class-vmo-elite-consultation-prompts.php',
            'generated_at' => current_time('mysql'),
            'updated_at' => current_time('mysql'),
            'user_id' => $user_id,
            'session_id' => $session_id,
            'user_type' => $user_type,
            'user_type_notes' => array(
                'vultr_aliases' => array('vultr', 'quicklaunch', 'managed_vultr_cloudflare_mailcow'),
                'typo_normalized' => 'vulture is normalized to vultr',
                'wordpress_aliases' => array('wordpress', 'existing_wordpress', 'external_domain'),
            ),
            'business_profile' => $business_profile,
            'target_audience' => $target_audience,
            'revenue_model' => $revenue_model,
            'offer_structure' => $offer_structure,
            'kpi_targets' => $kpi_targets,
            'marketing_strategy' => $marketing_strategy,
            'seo_strategy' => $seo_strategy,
            'email_system' => $email_system,
            'phone_system' => $phone_system,
            'website_structure' => $website_structure,
            'ecommerce_config' => $ecommerce_config,
            'crm' => $this->build_crm_contract($consultation_data, $target_audience, $email_system, $phone_system),
            'payments' => $this->build_payments_contract($revenue_model, $ecommerce_config),
            'automation_rules' => $automation_rules,
            'documents_required' => $documents_required,
            'dashboard' => $this->build_dashboard_contract($kpi_targets, $automation_rules, $documents_required),
            'consultation_phase_outputs' => $this->build_phase_outputs($consultation_data, $research_results, $website_structure, $automation_rules, $documents_required),
            'research_results' => $this->normalize_research_results($research_results),
            'readiness' => $this->build_readiness($email_system, $phone_system, $website_structure, $ecommerce_config, $documents_required),
            'contracts' => array(
                'website_runtime' => 'standalone_html_css_js_no_wordpress_runtime_dependency',
                'email_interface' => 'vmo_email_dashboard',
                'phone_interface' => 'vmo_phone_dashboard',
                'payment_interface' => 'vmo_pay_stripe_connect',
                'consultation_release_gate' => 'all_required_subsystems_ready_or_explicitly_human_action_required',
            ),
        );
    }

    public function persist_manifest($user_id, $session_id, $manifest) {
        $user_id = (int) $user_id;
        $session_id = sanitize_text_field((string) $session_id);
        $manifest = is_array($manifest) ? $manifest : array();

        if ($user_id <= 0 || $session_id === '' || empty($manifest)) {
            return false;
        }

        update_user_meta($user_id, 'vmo_business_manifest', $manifest);
        update_user_meta($user_id, 'vmo_business_manifest_' . $session_id, $manifest);
        update_user_meta($user_id, 'vmo_business_manifest_updated_at', current_time('mysql'));

        if (!empty($manifest['research_results'])) {
            update_user_meta($user_id, 'vmo_research_results', $manifest['research_results']);
            update_user_meta($user_id, 'vmo_research_results_' . $session_id, $manifest['research_results']);
        }

        if (!empty($manifest['documents_required'])) {
            update_user_meta($user_id, 'vmo_documents_required', $manifest['documents_required']);
            update_user_meta($user_id, 'vmo_documents_required_' . $session_id, $manifest['documents_required']);
        }

        if (!empty($manifest['kpi_targets'])) {
            update_user_meta($user_id, 'vmo_kpi_targets', $manifest['kpi_targets']);
            update_user_meta($user_id, 'vmo_kpi_targets_' . $session_id, $manifest['kpi_targets']);
        }

        do_action('vmo_business_manifest_persisted', $user_id, $session_id, $manifest);
        return true;
    }

    private function build_business_profile($user_id, $session_id, $user_type, $consultation_data, $business_package) {
        $profile = is_array($consultation_data['business_profile'] ?? null) ? $consultation_data['business_profile'] : array();
        $extracted = is_array($consultation_data['extracted_information'] ?? null) ? $consultation_data['extracted_information'] : array();
        $targets = is_array($profile['targets'] ?? null) ? $profile['targets'] : array();
        $operations = is_array($profile['operations'] ?? null) ? $profile['operations'] : array();

        return array(
            'user_id' => (int) $user_id,
            'session_id' => (string) $session_id,
            'user_type' => $user_type,
            'business_name' => $this->clean_text($this->first_value(array(
                $consultation_data['business_name'] ?? '',
                $profile['business_name'] ?? '',
                $profile['name'] ?? '',
                $extracted['businessName'] ?? '',
                $business_package['business_name'] ?? '',
            ), '')),
            'industry' => $this->clean_text($this->first_value(array(
                $consultation_data['industry'] ?? '',
                $profile['industry'] ?? '',
                $extracted['industry'] ?? '',
            ), '')),
            'business_type' => $this->clean_text($this->first_value(array(
                $consultation_data['business_type'] ?? '',
                $profile['business_type'] ?? '',
                $business_package['business_type'] ?? '',
            ), '')),
            'location' => $this->clean_text($this->first_value(array(
                $consultation_data['location'] ?? '',
                $profile['location'] ?? '',
                $extracted['location'] ?? '',
                $consultation_data['contact_info']['address'] ?? '',
            ), '')),
            'mission' => $this->clean_text($this->first_value(array(
                $profile['mission'] ?? '',
                $consultation_data['mission'] ?? '',
                $business_package['business_strategy']['mission'] ?? '',
            ), '')),
            'goals' => $this->normalize_list($this->first_value(array(
                $targets['long_term'] ?? array(),
                $consultation_data['goals'] ?? array(),
                $consultation_data['business_goals'] ?? array(),
                $extracted['businessGoals'] ?? array(),
            ), array())),
            'north_star_metric' => $this->clean_text($this->first_value(array(
                $targets['north_star_metric'] ?? '',
                $consultation_data['north_star_metric'] ?? '',
            ), '')),
            'emotional_goals' => $this->normalize_list($this->first_value(array(
                $targets['emotional'] ?? array(),
                $consultation_data['emotional_goals'] ?? array(),
                $extracted['emotionalGoals'] ?? array(),
            ), array())),
            'lifestyle_goals' => $this->normalize_list($this->first_value(array(
                $targets['lifestyle'] ?? array(),
                $consultation_data['lifestyle_goals'] ?? array(),
                $extracted['lifestyleGoals'] ?? array(),
            ), array())),
            'scaling_goals' => $this->normalize_list($this->first_value(array(
                $operations['team_structure']['scale_intent'] ?? array(),
                $targets['scaling'] ?? array(),
                $consultation_data['scaling_goals'] ?? array(),
                $extracted['scalingGoals'] ?? array(),
            ), array())),
            'operations' => array(
                'fulfillment_model' => $this->clean_text($operations['fulfillment_model'] ?? ($consultation_data['fulfillment_model'] ?? '')),
                'team_structure' => is_array($operations['team_structure'] ?? null) ? $operations['team_structure'] : array(),
                'human_only_tasks' => $this->normalize_list($consultation_data['human_only_tasks'] ?? array('Identity verification', 'Contract signatures', 'Final legal approvals')),
            ),
        );
    }

    private function build_target_audience($consultation_data, $business_package, $research_results) {
        $profile = is_array($consultation_data['business_profile']['audience'] ?? null) ? $consultation_data['business_profile']['audience'] : array();
        $extracted = is_array($consultation_data['extracted_information'] ?? null) ? $consultation_data['extracted_information'] : array();

        return array(
            'primary_segments' => $this->normalize_list($this->first_value(array(
                $profile['primary_segments'] ?? array(),
                $consultation_data['target_audience'] ?? array(),
                $extracted['targetAudience'] ?? array(),
                $business_package['target_audience'] ?? array(),
            ), array())),
            'pain_points' => $this->normalize_list($this->first_value(array(
                $profile['pain_points'] ?? array(),
                $consultation_data['customer_pain_points'] ?? array(),
                $research_results['customer_pain_points'] ?? array(),
            ), array())),
            'buying_triggers' => $this->normalize_list($this->first_value(array(
                $profile['buying_triggers'] ?? array(),
                $research_results['buying_triggers'] ?? array(),
                $business_package['marketing_strategy']['buying_triggers'] ?? array(),
            ), array())),
            'acquisition_channels' => $this->normalize_list($this->first_value(array(
                $profile['acquisition_channels'] ?? array(),
                $research_results['recommended_channels'] ?? array(),
                $business_package['marketing_strategy']['channels'] ?? array(),
            ), array('Search', 'Website forms', 'Email', 'Phone'))),
        );
    }

    private function build_offer_structure($consultation_data, $business_package) {
        $offers_profile = is_array($consultation_data['offers_profile'] ?? null) ? $consultation_data['offers_profile'] : array();
        $ecommerce = is_array($consultation_data['ecommerce'] ?? null) ? $consultation_data['ecommerce'] : array();
        $extracted = is_array($consultation_data['extracted_information'] ?? null) ? $consultation_data['extracted_information'] : array();
        $extracted_ecommerce = is_array($extracted['ecommerce'] ?? null) ? $extracted['ecommerce'] : array();
        $ecommerce = array_replace_recursive($ecommerce, $extracted_ecommerce);

        $services = $this->normalize_list($this->first_value(array(
            $consultation_data['services'] ?? array(),
            $consultation_data['offerings'] ?? array(),
            $extracted['offerings'] ?? array(),
            $business_package['offerings'] ?? array(),
        ), array()));

        $products = is_array($ecommerce['products'] ?? null) ? $ecommerce['products'] : array();
        if (empty($products) && is_array($extracted['products_inventory'] ?? null)) {
            $products = $extracted['products_inventory'];
        }
        if (empty($products) && is_array($consultation_data['products_inventory'] ?? null)) {
            $products = $consultation_data['products_inventory'];
        }
        $donation_funds = is_array($ecommerce['donation_funds'] ?? null) ? $ecommerce['donation_funds'] : array();

        return array(
            'services' => $services,
            'products' => $this->sanitize_product_list($products),
            'donation_funds' => $this->sanitize_product_list($donation_funds),
            'packages' => is_array($offers_profile['items'] ?? null) ? $offers_profile['items'] : array(),
            'pricing_notes' => $this->clean_text($offers_profile['pricing_notes'] ?? ($consultation_data['pricing_notes'] ?? '')),
            'requires_owner_confirmation' => empty($services) && empty($products) && empty($donation_funds),
        );
    }

    private function build_revenue_model($consultation_data, $offer_structure) {
        $ecommerce = is_array($consultation_data['ecommerce'] ?? null) ? $consultation_data['ecommerce'] : array();
        $collection_mode = $this->clean_key($ecommerce['collection_mode'] ?? '');

        if ($collection_mode === 'donations' || !empty($offer_structure['donation_funds'])) {
            $primary = 'donations';
            $payment_flow = 'donation_flow';
        } elseif (!empty($offer_structure['products']) || !empty($ecommerce['intends_to_sell']) || !empty($ecommerce['sell_on_website'])) {
            $primary = 'product_sales';
            $payment_flow = 'checkout';
        } else {
            $primary = 'service_revenue';
            $payment_flow = 'invoice_or_booking_deposit';
        }

        return array(
            'primary_model' => $primary,
            'payment_flow' => $payment_flow,
            'vmo_pay_mode' => $payment_flow,
            'requires_vmo_pay' => $primary !== 'informational',
            'subscription_or_recurring' => !empty($ecommerce['recurring_payments']) || !empty($consultation_data['recurring_revenue']),
            'revenue_streams' => array_values(array_filter(array(
                !empty($offer_structure['services']) ? 'services' : '',
                !empty($offer_structure['products']) ? 'products' : '',
                !empty($offer_structure['donation_funds']) ? 'donations' : '',
            ))),
        );
    }

    private function build_email_system($user_type, $consultation_data) {
        $email_roles = is_array($consultation_data['email_roles'] ?? null) ? $consultation_data['email_roles'] : array();
        $meta = is_array($consultation_data['email_roles_meta'] ?? null) ? $consultation_data['email_roles_meta'] : array();
        $mode = $this->normalize_provisioning_mode($meta['provisioning_mode'] ?? ($consultation_data['provisioning_mode'] ?? ''));

        if ($mode === 'collect') {
            $mode = ($user_type === 'vultr') ? 'auto' : 'existing_mailbox';
        }

        $provider = 'vmo_email';
        if ($mode === 'auto') {
            $provider = 'mailcow_cloudflare';
        } elseif ($mode === 'zoho') {
            $provider = 'zoho_mail';
        } elseif ($mode === 'manual_dns') {
            $provider = 'external_dns_mail_provider';
        } elseif ($mode === 'existing_mailbox') {
            $provider = 'existing_mailbox';
        }

        return array(
            'user_interface' => 'vmo_email_dashboard',
            'provider_is_infrastructure_only' => true,
            'provisioning_mode' => $mode,
            'provider' => $provider,
            'managed_path' => $user_type === 'vultr' ? 'vultr_cloudflare_mailcow' : 'wordpress_existing_domain',
            'roles' => $this->normalize_email_roles($email_roles),
            'required_roles' => $this->normalize_list($meta['required_roles'] ?? array('info', 'support')),
            'ai_auto_reply_enabled' => !empty($meta['ai_auto_reply_enabled']),
            'routing_contract' => array(
                'forms_submit_to_crm' => true,
                'forms_notify_vmo_inbox' => true,
                'sender_identities_synced' => true,
                'external_webmail_is_not_primary_interface' => true,
            ),
            'status' => $this->clean_key($meta['provisioning_status'] ?? ($mode === 'existing_mailbox' ? 'pending_connection' : 'pending')),
        );
    }

    private function build_phone_system($consultation_data) {
        $phone = is_array($consultation_data['phone_system'] ?? null) ? $consultation_data['phone_system'] : array();
        $contact = is_array($consultation_data['contact_info'] ?? null) ? $consultation_data['contact_info'] : array();

        return array(
            'interface' => 'vmo_phone_dashboard',
            'provider' => 'twilio_infrastructure',
            'business_number' => $this->clean_text($phone['business_number'] ?? ($contact['phone'] ?? '')),
            'extensions' => is_array($phone['extensions'] ?? null) ? $phone['extensions'] : array(),
            'call_routing' => is_array($phone['call_routing'] ?? null) ? $phone['call_routing'] : array('default' => 'vmo_ai_receptionist_then_owner'),
            'sms_enabled' => !empty($phone['sms_enabled']),
            'status' => $this->clean_key($phone['status'] ?? 'pending'),
            'human_action_required' => $this->normalize_list($phone['human_action_required'] ?? array('A2P/identity verification when required')),
        );
    }

    private function build_website_structure($consultation_data, $business_package, $website_result, $email_system, $ecommerce_config) {
        $website_plan = is_array($consultation_data['website_plan'] ?? null) ? $consultation_data['website_plan'] : array();
        $pages = array();

        foreach (array($website_plan['pages'] ?? array(), $business_package['website_architecture']['pages'] ?? array(), $website_result['pages_created'] ?? array()) as $candidate_pages) {
            if (!is_array($candidate_pages)) {
                continue;
            }
            foreach ($candidate_pages as $key => $page) {
                $title = is_array($page) ? ($page['title'] ?? $page['name'] ?? $key) : $page;
                $slug = sanitize_title(is_string($key) ? $key : $title);
                if ($slug === '') {
                    continue;
                }
                $pages[$slug] = array(
                    'slug' => $slug,
                    'title' => $this->clean_text($title),
                    'purpose' => is_array($page) ? $this->clean_text($page['purpose'] ?? '') : '',
                );
            }
        }

        if (!$pages) {
            $pages = array(
                'home' => array('slug' => 'home', 'title' => 'Home', 'purpose' => 'Primary business landing experience'),
                'about' => array('slug' => 'about', 'title' => 'About', 'purpose' => 'Trust, story, and authority'),
                'services' => array('slug' => 'services', 'title' => 'Services', 'purpose' => 'Offer explanation and conversion'),
                'contact' => array('slug' => 'contact', 'title' => 'Contact', 'purpose' => 'Lead capture and customer communication'),
            );
        }

        if (!empty($ecommerce_config['enabled']) && empty($pages['shop']) && (($ecommerce_config['collection_mode'] ?? '') !== 'donations')) {
            $pages['shop'] = array('slug' => 'shop', 'title' => 'Shop', 'purpose' => 'Product browsing and checkout');
        }
        if (($ecommerce_config['collection_mode'] ?? '') === 'donations' && empty($pages['donate'])) {
            $pages['donate'] = array('slug' => 'donate', 'title' => 'Donate', 'purpose' => 'Donation collection');
        }

        $default_role = $this->first_email_address($email_system['roles'] ?? array());
        $forms = array(
            array(
                'form_type' => 'contact',
                'email_role' => $default_role,
                'crm_pipeline' => 'website_leads',
                'expected_pages' => array('home', 'contact'),
            ),
        );
        if ($this->page_exists($pages, array('booking', 'appointments', 'schedule'))) {
            $forms[] = array(
                'form_type' => 'booking',
                'email_role' => $this->first_email_address($email_system['roles'] ?? array(), array('bookings', 'sales', 'info')),
                'crm_pipeline' => 'appointments',
                'expected_pages' => array('booking', 'appointments', 'schedule'),
            );
        }

        return array(
            'role' => 'business_operating_interface_public_runtime',
            'runtime_contract' => 'standalone_html_css_js',
            'source_manifest' => 'vmo_business_manifest',
            'pages' => array_values($pages),
            'form_mappings' => $forms,
            'kpi_tracking_events' => array('page_view', 'cta_click', 'form_submit', 'phone_click', 'email_click', 'product_view', 'checkout_start', 'purchase'),
            'preview_ready' => !empty($website_result['preview_ready']),
            'media_complete' => !empty($website_result['media_complete']),
            'publish_ready' => !empty($website_result['publish_ready']),
        );
    }

    private function build_ecommerce_config($consultation_data, $offer_structure, $revenue_model) {
        $ecommerce = is_array($consultation_data['ecommerce'] ?? null) ? $consultation_data['ecommerce'] : array();
        $extracted = is_array($consultation_data['extracted_information'] ?? null) ? $consultation_data['extracted_information'] : array();
        $extracted_ecommerce = is_array($extracted['ecommerce'] ?? null) ? $extracted['ecommerce'] : array();
        $ecommerce = array_replace_recursive($ecommerce, $extracted_ecommerce);
        $products = $this->sanitize_product_list($offer_structure['products'] ?? array());
        $donation_funds = $this->sanitize_product_list($offer_structure['donation_funds'] ?? array());
        $demo_products = array();
        $catalog_items = $products;
        if (is_array($extracted['services_inventory'] ?? null)) {
            $catalog_items = array_merge($catalog_items, $this->sanitize_product_list($extracted['services_inventory']));
        }
        if (is_array($consultation_data['services_inventory'] ?? null)) {
            $catalog_items = array_merge($catalog_items, $this->sanitize_product_list($consultation_data['services_inventory']));
        }
        $catalog_readiness = $this->build_catalog_readiness($consultation_data, $catalog_items, $donation_funds, $ecommerce, $revenue_model);

        foreach ($products as $product) {
            if (!empty($product['demo_data']) || !empty($product['is_demo']) || in_array($this->clean_key($product['slug'] ?? $product['name'] ?? ''), array('starter-package', 'growth-package', 'premium-package'), true)) {
                $demo_products[] = $product['name'] ?? '';
            }
        }

        return array(
            'enabled' => !empty($products) || !empty($donation_funds) || (($revenue_model['primary_model'] ?? '') !== 'service_revenue'),
            'collection_mode' => ($revenue_model['primary_model'] ?? '') === 'donations' ? 'donations' : (!empty($products) ? 'products' : 'services'),
            'products' => $products,
            'donation_funds' => $donation_funds,
            'checkout_provider' => 'vmo_pay_stripe_connect',
            'invoice_provider' => 'vmo_pay_invoices',
            'demo_data_allowed' => false,
            'demo_products_present' => !empty($demo_products),
            'demo_product_names' => array_values(array_filter($demo_products)),
            'catalog_readiness' => $catalog_readiness,
            'catalog_required_questions' => $catalog_readiness['required_questions'],
            'missing_catalog_details' => $catalog_readiness['missing_details'],
            'requires_owner_catalog_confirmation' => !in_array($catalog_readiness['status'], array('ready', 'not_required'), true),
        );
    }

    private function build_catalog_readiness($consultation_data, $catalog_items, $donation_funds, $ecommerce, $revenue_model) {
        $extracted = is_array($consultation_data['extracted_information'] ?? null) ? $consultation_data['extracted_information'] : array();
        $collection_mode = $this->clean_key($ecommerce['collection_mode'] ?? '');
        $required = !empty($catalog_items)
            || ($collection_mode === 'products')
            || ($collection_mode === 'services')
            || (!empty($ecommerce['intends_to_sell']) && empty($donation_funds))
            || (!empty($ecommerce['sell_on_website']) && empty($donation_funds))
            || (($revenue_model['primary_model'] ?? '') === 'product_sales');

        if ($collection_mode === 'donations' || !empty($donation_funds)) {
            $required = false;
        }

        $deferred = !empty($extracted['product_catalog_deferred'])
            || !empty($ecommerce['catalog_deferred'])
            || !empty($consultation_data['approvals']['product_catalog_deferred']);

        $missing_details = array();
        foreach ((array) $catalog_items as $index => $product) {
            if (!is_array($product)) {
                continue;
            }
            $label = $this->clean_text($product['name'] ?? ('Product ' . ($index + 1)));
            if ($label === '') {
                $label = 'Product ' . ($index + 1);
                $missing_details[] = $label . ': name';
            }
            if ($this->clean_text($product['description'] ?? ($product['summary'] ?? '')) === '') {
                $missing_details[] = $label . ': description';
            }
            $price = $product['price'] ?? ($product['price_text'] ?? ($product['pricing'] ?? ''));
            if (!$this->catalog_value_present($price) && empty($product['quote_based']) && empty($product['price_pending'])) {
                $missing_details[] = $label . ': price/currency';
            }
            $has_media = $this->catalog_value_present($product['main_image'] ?? '')
                || $this->catalog_value_present($product['image'] ?? '')
                || !empty($product['images'])
                || !empty($product['gallery_images'])
                || !empty($product['videos'])
                || $this->catalog_value_present($product['media_status'] ?? '');
            if (!$has_media) {
                $missing_details[] = $label . ': images/videos or AI-media preference';
            }
            $variants_confirmed = !empty($product['variants'])
                || isset($product['has_variants'])
                || !empty($product['variants_confirmed'])
                || !empty($product['no_variants'])
                || !empty($product['options_confirmed']);
            if (!$variants_confirmed) {
                $missing_details[] = $label . ': variations/options confirmation';
            }
            $content_packet = is_array($product['content_packet'] ?? null) ? $product['content_packet'] : (is_array($product['product_content_packet'] ?? null) ? $product['product_content_packet'] : array());
            $media_packet = is_array($product['media_packet'] ?? null) ? $product['media_packet'] : (is_array($product['product_media_packet'] ?? null) ? $product['product_media_packet'] : array());
            if ($content_packet && empty($content_packet['product_schema'])) {
                $missing_details[] = $label . ': Product schema / Offer schema';
            }
            if ($content_packet && (empty($content_packet['seo_title']) || empty($content_packet['meta_description']))) {
                $missing_details[] = $label . ': SEO title/meta description';
            }
            if ($content_packet && empty($content_packet['media_alt_text'])) {
                $missing_details[] = $label . ': alt text for product media';
            }
            if ($media_packet && (empty($media_packet['product_card_image']) || empty($media_packet['product_hero_image']) || empty($media_packet['gallery_images']) || empty($media_packet['detail_images']) || empty($media_packet['product_lifestyle_image']) || empty($media_packet['mobile_fallback_image']))) {
                $missing_details[] = $label . ': complete product media packet';
            }
        }

        if ($required && empty($catalog_items)) {
            $missing_details[] = 'At least one product/service name, description, price, media preference, variation status, and fulfillment method';
        }

        $required_questions = array();
        if ($required && !$deferred && !empty($missing_details)) {
            $required_questions[] = 'Please list each product/service with title, short description, long description, story, benefits, specifications, relevant materials/ingredients/dimensions/compatibility/care/usage details, variants/options, fulfillment notes, SEO title/meta description, Product/Offer schema inputs, alt text needs, FAQ, and upsell/cross-sell context.';
            $required_questions[] = 'Please provide product card, hero, gallery, detail, lifestyle, mobile fallback, and video/poster media where available, or approve AI Media Director generation before ecommerce preview.';
            $required_questions[] = 'If product details are not ready, confirm that the catalog should stay as a draft and be completed later.';
        }

        $status = 'not_required';
        if ($required && $deferred) {
            $status = 'deferred';
        } elseif ($required && empty($missing_details)) {
            $status = 'ready';
        } elseif ($required) {
            $status = 'blocked';
        }

        return array(
            'status' => $status,
            'required' => (bool) $required,
            'deferred' => (bool) $deferred,
            'items_count' => count((array) $catalog_items),
            'products_count' => count((array) $catalog_items),
            'missing_details' => array_values(array_unique($missing_details)),
            'required_questions' => $required_questions,
            'product_content_packet_required' => (bool) $required,
            'product_media_packet_required' => (bool) $required,
            'packet_policy' => 'complete_product_content_packet_and_product_media_packet_before_ecommerce_preview',
        );
    }

    private function catalog_value_present($value) {
        if (is_array($value)) {
            return !empty($value);
        }
        if (is_numeric($value)) {
            return true;
        }
        return trim((string) $value) !== '';
    }

    private function build_kpi_targets($business_profile, $target_audience, $revenue_model, $website_structure, $consultation_data) {
        $raw_targets = is_array($consultation_data['kpi_targets'] ?? null) ? $consultation_data['kpi_targets'] : array();
        $north_star = $business_profile['north_star_metric'] ?: 'qualified_leads';
        $primary_model = $revenue_model['primary_model'] ?? 'service_revenue';

        $targets = array(
            'qualified_leads_monthly' => array('label' => 'Qualified Leads Monthly', 'category' => 'crm', 'current' => 0, 'target' => 25, 'unit' => 'leads', 'recommendation' => 'Use the consultation-generated website forms, lead discovery, and VMO Email follow-up campaigns.'),
            'website_visitors_monthly' => array('label' => 'Website Visitors Monthly', 'category' => 'traffic', 'current' => 0, 'target' => 1000, 'unit' => 'visitors', 'recommendation' => 'Publish the SEO plan and run weekly content improvements from the manifest.'),
            'conversion_rate' => array('label' => 'Website Conversion Rate', 'category' => 'conversion', 'current' => 0, 'target' => 3, 'unit' => 'percent', 'recommendation' => 'Review hero offer, CTA placement, trust proof, and form friction when conversion is below target.'),
            'phone_calls_monthly' => array('label' => 'Phone Calls Monthly', 'category' => 'phone', 'current' => 0, 'target' => 20, 'unit' => 'calls', 'recommendation' => 'Keep VMO Phone routing and missed-call follow-up active.'),
            'email_followups_weekly' => array('label' => 'Email Follow-ups Weekly', 'category' => 'email', 'current' => 0, 'target' => 25, 'unit' => 'emails', 'recommendation' => 'Use VMO Email sequences for new leads, stale leads, and post-form follow-up.'),
        );

        if ($primary_model === 'product_sales') {
            $targets['orders_monthly'] = array('label' => 'Orders Monthly', 'category' => 'commerce', 'current' => 0, 'target' => 20, 'unit' => 'orders', 'recommendation' => 'Connect product pages, checkout events, abandoned checkout follow-up, and product email campaigns.');
            $targets['revenue_monthly'] = array('label' => 'Monthly Revenue', 'category' => 'commerce', 'current' => 0, 'target' => 5000, 'unit' => 'currency', 'recommendation' => 'Use VMO Pay checkout and product promotion automations.');
        } elseif ($primary_model === 'donations') {
            $targets['donations_monthly'] = array('label' => 'Donations Monthly', 'category' => 'payments', 'current' => 0, 'target' => 50, 'unit' => 'donations', 'recommendation' => 'Use donation-specific pages, email appeals, and follow-up sequences.');
        } else {
            $targets['booked_consultations_monthly'] = array('label' => 'Booked Consultations Monthly', 'category' => 'sales', 'current' => 0, 'target' => 15, 'unit' => 'bookings', 'recommendation' => 'Route booking forms to VMO Email, VMO CRM, and calendar follow-up.');
        }

        foreach ($raw_targets as $metric => $target) {
            if (is_array($target)) {
                $key = $this->clean_key($metric);
                $targets[$key] = array_merge($targets[$key] ?? array(), $target);
            }
        }

        foreach ($targets as $metric => $target) {
            $current = (float) ($target['current'] ?? 0);
            $target_value = (float) ($target['target'] ?? 0);
            $targets[$metric]['metric'] = $metric;
            $targets[$metric]['gap'] = max(0, $target_value - $current);
            $targets[$metric]['north_star'] = ($metric === $this->clean_key($north_star) || strpos($metric, $this->clean_key($north_star)) !== false);
        }

        return $targets;
    }

    private function build_marketing_strategy($consultation_data, $business_package, $research_results, $target_audience) {
        $marketing = is_array($business_package['marketing_strategy'] ?? null) ? $business_package['marketing_strategy'] : array();
        return array(
            'positioning' => $this->clean_text($marketing['positioning'] ?? ($consultation_data['positioning'] ?? '')),
            'channels' => $this->normalize_list($marketing['channels'] ?? ($target_audience['acquisition_channels'] ?? array())),
            'campaigns' => is_array($marketing['campaigns'] ?? null) ? $marketing['campaigns'] : array(),
            'lead_magnets' => $this->normalize_list($marketing['lead_magnets'] ?? ($research_results['lead_magnets'] ?? array())),
            'email_campaigns_required' => true,
            'vmo_crm_followup_required' => true,
        );
    }

    private function build_seo_strategy($consultation_data, $business_package, $research_results) {
        $seo = is_array($business_package['seo_strategy'] ?? null) ? $business_package['seo_strategy'] : array();
        return array(
            'primary_keywords' => $this->normalize_list($seo['primary_keywords'] ?? ($research_results['seo_keywords'] ?? array())),
            'local_seo_required' => !empty($consultation_data['location']),
            'content_plan' => is_array($seo['content_plan'] ?? null) ? $seo['content_plan'] : array(),
            'technical_requirements' => array('titles', 'meta_descriptions', 'schema_json_ld', 'open_graph', 'image_alt_text', 'sitemap_ready'),
            'automation_enabled' => true,
        );
    }

    private function build_automation_rules($kpi_targets, $marketing_strategy, $seo_strategy, $email_system, $website_structure, $revenue_model) {
        return array(
            array(
                'rule_id' => 'lead_gap_email_campaign',
                'status' => 'active_after_launch',
                'when' => 'qualified_leads_monthly.current < qualified_leads_monthly.target',
                'trigger_metric' => 'qualified_leads_monthly',
                'action' => 'create_or_refresh_vmo_email_campaign',
                'owner' => 'vmo_ai',
                'approval_required' => true,
                'uses' => array('vmo_email_dashboard', 'vmo_crm', 'lead_discovery'),
            ),
            array(
                'rule_id' => 'traffic_gap_seo_content',
                'status' => 'active_after_launch',
                'when' => 'website_visitors_monthly.current < website_visitors_monthly.target',
                'trigger_metric' => 'website_visitors_monthly',
                'action' => 'generate_seo_content_recommendations',
                'owner' => 'vmo_ai',
                'approval_required' => true,
                'uses' => array('seo_strategy', 'website_structure', 'reports'),
            ),
            array(
                'rule_id' => 'conversion_gap_website_recommendation',
                'status' => 'active_after_launch',
                'when' => 'conversion_rate.current < conversion_rate.target',
                'trigger_metric' => 'conversion_rate',
                'action' => 'suggest_website_cta_offer_or_form_change',
                'owner' => 'vmo_ai',
                'approval_required' => true,
                'uses' => array('website_structure', 'analytics', 'kpi_dashboard'),
            ),
            array(
                'rule_id' => 'missed_call_followup',
                'status' => 'active_after_phone_ready',
                'when' => 'missed_calls_today > 0',
                'trigger_metric' => 'missed_calls_today',
                'action' => 'create_phone_and_email_followup_task',
                'owner' => 'vmo_ai',
                'approval_required' => false,
                'uses' => array('vmo_phone_dashboard', 'vmo_email_dashboard', 'today_actions'),
            ),
            array(
                'rule_id' => 'payment_gap_revenue_followup',
                'status' => 'active_after_vmo_pay_ready',
                'when' => 'revenue_or_donations_below_target',
                'trigger_metric' => ($revenue_model['primary_model'] ?? '') === 'donations' ? 'donations_monthly' : 'revenue_monthly',
                'action' => 'recommend_offer_payment_or_followup_improvement',
                'owner' => 'vmo_ai',
                'approval_required' => true,
                'uses' => array('vmo_pay', 'cfo', 'reports'),
            ),
        );
    }

    private function build_documents_required($consultation_data, $business_profile, $revenue_model, $ecommerce_config) {
        $required = array(
            array('type' => 'business_plan', 'title' => 'Business Plan', 'category' => 'Planning', 'required' => true),
            array('type' => 'brand_strategy', 'title' => 'Brand Strategy', 'category' => 'Brand', 'required' => true),
            array('type' => 'marketing_plan', 'title' => 'Marketing Plan', 'category' => 'Marketing', 'required' => true),
            array('type' => 'seo_plan', 'title' => 'SEO Plan', 'category' => 'SEO', 'required' => true),
            array('type' => 'operations_roadmap', 'title' => 'Operations Roadmap', 'category' => 'Operations', 'required' => true),
            array('type' => 'launch_checklist', 'title' => 'Launch Checklist', 'category' => 'Launch', 'required' => true),
            array('type' => 'kpi_plan', 'title' => 'KPI Plan', 'category' => 'Dashboard', 'required' => true),
            array('type' => 'privacy_policy', 'title' => 'Privacy Policy', 'category' => 'Legal', 'required' => true),
            array('type' => 'terms_of_service', 'title' => 'Terms of Service', 'category' => 'Legal', 'required' => true),
        );

        if (($revenue_model['primary_model'] ?? '') === 'product_sales') {
            $required[] = array('type' => 'refund_policy', 'title' => 'Refund Policy', 'category' => 'Legal', 'required' => true);
            $required[] = array('type' => 'shipping_policy', 'title' => 'Shipping Policy', 'category' => 'Legal', 'required' => !empty($ecommerce_config['products']));
        }
        if (($revenue_model['primary_model'] ?? '') === 'donations') {
            $required[] = array('type' => 'donation_policy', 'title' => 'Donation Policy', 'category' => 'Legal', 'required' => true);
        }

        return $required;
    }

    private function build_crm_contract($consultation_data, $target_audience, $email_system, $phone_system) {
        return array(
            'enabled' => true,
            'lead_sources' => array('website_forms', 'phone_calls', 'email_replies', 'ai_lead_discovery'),
            'segments' => $target_audience['primary_segments'] ?? array(),
            'email_roles' => $email_system['roles'] ?? array(),
            'phone_routing' => $phone_system['call_routing'] ?? array(),
            'default_pipeline' => 'consultation_generated_business_pipeline',
        );
    }

    private function build_payments_contract($revenue_model, $ecommerce_config) {
        return array(
            'provider' => 'vmo_pay_stripe_connect',
            'required' => !empty($revenue_model['requires_vmo_pay']),
            'mode' => $revenue_model['payment_flow'] ?? 'invoice_or_booking_deposit',
            'products_or_funds' => ($ecommerce_config['collection_mode'] ?? '') === 'donations'
                ? ($ecommerce_config['donation_funds'] ?? array())
                : ($ecommerce_config['products'] ?? array()),
            'human_action_required' => array('Stripe Express identity verification when required by Stripe'),
        );
    }

    private function build_dashboard_contract($kpi_targets, $automation_rules, $documents_required) {
        return array(
            'enabled' => true,
            'primary_views' => array('overview', 'today', 'reports', 'strategic_dashboard', 'cfo', 'crm', 'email', 'phone', 'payments', 'documents', 'website_health'),
            'kpi_targets' => $kpi_targets,
            'automation_rule_count' => count($automation_rules),
            'documents_required_count' => count($documents_required),
            'show_current_target_gap_recommendation' => true,
        );
    }

    private function build_phase_outputs($consultation_data, $research_results, $website_structure, $automation_rules, $documents_required) {
        $flow = is_array($consultation_data['consultation_flow'] ?? null) ? $consultation_data['consultation_flow'] : array();
        $phase_status = array();
        if (!empty($flow['phases']) && is_array($flow['phases'])) {
            foreach ($flow['phases'] as $index => $phase) {
                if (!is_array($phase)) {
                    continue;
                }
                $phase_status['phase_' . ((int) $index + 1)] = array(
                    'key' => sanitize_key((string) ($phase['key'] ?? ('phase_' . ((int) $index + 1)))),
                    'name' => $this->clean_text($phase['name'] ?? ''),
                    'status' => $this->clean_key($phase['status'] ?? 'pending'),
                );
            }
        }

        return array(
            'phase_1_foundations' => array('output' => 'business_profile', 'status' => $phase_status['phase_1']['status'] ?? 'captured'),
            'phase_2_blueprint' => array('output' => 'approved_business_blueprint', 'status' => !empty($consultation_data['phase_flags']['phase2_confirmed']) ? 'approved' : ($phase_status['phase_2']['status'] ?? 'pending')),
            'phase_3_research' => array('output' => 'vmo_research_results', 'status' => !empty($research_results) ? 'completed' : ($phase_status['phase_3']['status'] ?? 'pending')),
            'phase_4_recommendations' => array('output' => 'approved_recommendations', 'status' => !empty($consultation_data['approvals']['recommendations']['accepted']) ? 'approved' : ($phase_status['phase_4']['status'] ?? 'pending')),
            'phase_5_website' => array('output' => 'website_structure', 'status' => !empty($website_structure['pages']) ? 'planned' : ($phase_status['phase_5']['status'] ?? 'pending')),
            'phase_6_systems' => array('output' => 'email_phone_payments_crm_systems', 'status' => $phase_status['phase_6']['status'] ?? 'pending'),
            'phase_7_roadmap' => array('output' => 'automation_rules_and_operations_roadmap', 'status' => !empty($automation_rules) ? 'planned' : ($phase_status['phase_7']['status'] ?? 'pending')),
            'phase_8_launch' => array('output' => 'documents_kpis_launch_readiness', 'status' => !empty($documents_required) ? 'ready_for_gate' : ($phase_status['phase_8']['status'] ?? 'pending')),
        );
    }

    private function normalize_research_results($research_results) {
        if (!is_array($research_results)) {
            return array();
        }

        return array(
            'summary' => $this->clean_text($research_results['research_summary'] ?? ($research_results['analysis'] ?? '')),
            'key_findings' => is_array($research_results['key_findings'] ?? null) ? $research_results['key_findings'] : array(),
            'recommended_actions' => is_array($research_results['recommended_actions'] ?? null) ? $research_results['recommended_actions'] : array(),
            'raw' => $research_results,
        );
    }

    private function build_readiness($email_system, $phone_system, $website_structure, $ecommerce_config, $documents_required) {
        return array(
            'email_ready' => in_array($email_system['status'] ?? '', array('completed', 'ready', 'verified'), true) || !empty($email_system['roles']),
            'phone_ready' => in_array($phone_system['status'] ?? '', array('completed', 'ready', 'active'), true) || !empty($phone_system['business_number']),
            'website_preview_ready' => !empty($website_structure['preview_ready']),
            'website_media_complete' => !empty($website_structure['media_complete']),
            'payments_configured' => empty($ecommerce_config['enabled']) || !empty($ecommerce_config['products']) || (($ecommerce_config['collection_mode'] ?? '') === 'donations'),
            'documents_defined' => !empty($documents_required),
            'manual_human_actions' => array_values(array_filter(array_merge(
                $phone_system['human_action_required'] ?? array(),
                !empty($ecommerce_config['enabled']) ? array('Complete Stripe Express verification when required') : array()
            ))),
        );
    }

    private function normalize_user_type($value, $consultation_data = array()) {
        $signal = strtolower(trim((string) $value . ' ' . wp_json_encode($consultation_data)));
        if (strpos($signal, 'vulture') !== false || strpos($signal, 'vultr') !== false || strpos($signal, 'quicklaunch') !== false || strpos($signal, 'mailcow') !== false || strpos($signal, 'cloudflare') !== false) {
            return 'vultr';
        }
        if (strpos($signal, 'wordpress') !== false || strpos($signal, 'existing') !== false || strpos($signal, 'external_domain') !== false) {
            return 'wordpress';
        }
        return 'wordpress';
    }

    private function normalize_provisioning_mode($mode) {
        $mode = $this->clean_key($mode);
        if (in_array($mode, array('auto', 'manual_dns', 'zoho', 'existing_mailbox'), true)) {
            return $mode;
        }
        if (in_array($mode, array('mailcow', 'cloudflare', 'vultr'), true)) {
            return 'auto';
        }
        if (in_array($mode, array('existing', 'user_provided', 'external'), true)) {
            return 'existing_mailbox';
        }
        return 'collect';
    }

    private function normalize_email_roles($roles) {
        $out = array();
        foreach ((array) $roles as $role => $value) {
            if (is_array($value)) {
                $address = sanitize_email((string) ($value['address'] ?? $value['email'] ?? ''));
                $label = $this->clean_text($value['role'] ?? $value['label'] ?? $role);
            } else {
                $address = sanitize_email((string) $value);
                $label = $this->clean_text($role);
            }
            if ($address === '' && is_string($role) && is_email($role)) {
                $address = sanitize_email($role);
            }
            if ($address === '') {
                continue;
            }
            $out[] = array(
                'role' => $label !== '' && !is_numeric($label) ? $label : sanitize_key(strtok($address, '@')),
                'address' => $address,
                'vmo_sender_identity' => true,
                'vmo_inbox_enabled' => true,
            );
        }
        return $out;
    }

    private function sanitize_product_list($items) {
        $out = array();
        foreach ((array) $items as $item) {
            if (!is_array($item)) {
                $name = $this->clean_text($item);
                if ($name !== '') {
                    $out[] = array('name' => $name, 'slug' => sanitize_title($name));
                }
                continue;
            }
            $name = $this->clean_text($item['name'] ?? ($item['title'] ?? ''));
            if ($name === '') {
                continue;
            }
            $item['name'] = $name;
            $item['slug'] = sanitize_title($item['slug'] ?? $name);
            $out[] = $item;
        }
        return $out;
    }

    private function normalize_list($value) {
        $items = array();
        if (is_array($value)) {
            array_walk_recursive($value, function($item) use (&$items) {
                if (is_scalar($item)) {
                    $items[] = (string) $item;
                }
            });
        } elseif (is_string($value)) {
            $items = preg_split('/[\r\n,;]+/', $value);
        } elseif (is_scalar($value)) {
            $items = array((string) $value);
        }

        $out = array();
        $seen = array();
        foreach ($items as $item) {
            $text = $this->clean_text($item);
            if ($text === '') {
                continue;
            }
            $key = strtolower($text);
            if (isset($seen[$key])) {
                continue;
            }
            $seen[$key] = true;
            $out[] = $text;
        }
        return $out;
    }

    private function first_value($values, $default = '') {
        foreach ((array) $values as $value) {
            if (is_array($value) && !empty($value)) {
                return $value;
            }
            if (is_scalar($value) && trim((string) $value) !== '') {
                return $value;
            }
        }
        return $default;
    }

    private function first_email_address($roles, $preferred = array()) {
        $roles = is_array($roles) ? $roles : array();
        foreach ($preferred as $preferred_role) {
            foreach ($roles as $role) {
                if (!is_array($role)) {
                    continue;
                }
                if (strpos($this->clean_key($role['role'] ?? ''), $this->clean_key($preferred_role)) !== false && !empty($role['address'])) {
                    return $role['address'];
                }
            }
        }
        foreach ($roles as $role) {
            if (is_array($role) && !empty($role['address'])) {
                return $role['address'];
            }
        }
        return '';
    }

    private function page_exists($pages, $keys) {
        foreach ($keys as $key) {
            if (isset($pages[$key])) {
                return true;
            }
        }
        return false;
    }

    private function clean_text($value) {
        if (is_array($value)) {
            $value = implode(', ', $this->normalize_list($value));
        }
        return sanitize_text_field((string) $value);
    }

    private function clean_key($value) {
        return sanitize_key(str_replace('-', '_', strtolower(trim((string) $value))));
    }
}