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

/**
 * Single gateway for VMO website generation.
 *
 * All public website creation paths should route here, then delegate to the
 * current premium consultation integration hub until the React-first agent
 * pipeline is fully split into dedicated services.
 */
class VMO_Canonical_Website_Pipeline {
    const PIPELINE_VERSION = 'v2.0-2026-04-30';

    private static $instance = null;

    public static function get_instance() {
        if (!self::$instance) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    private function prepare_long_running_runtime() {
        if (function_exists('set_time_limit')) {
            @set_time_limit(0);
        }
        if (function_exists('ignore_user_abort')) {
            @ignore_user_abort(true);
        }
        if (function_exists('ini_set')) {
            @ini_set('memory_limit', '512M');
        }
    }

    public function run_from_consultation($session_id) {
        $this->prepare_long_running_runtime();

        $session_id = sanitize_text_field((string) $session_id);
        if ($session_id === '') {
            return new WP_Error('vmo_missing_session', 'A consultation session is required for website generation.');
        }

        $integration = $this->get_integration_hub();
        if (is_wp_error($integration)) {
            return $integration;
        }

        $result = $integration->run_pipeline_sync($session_id);
        if (!is_array($result)) {
            return new WP_Error('vmo_canonical_generation_failed', 'The canonical website pipeline could not generate a website for this consultation.');
        }

        return $this->normalize_pipeline_result($result, 'consultation');
    }

    public function run_from_consultation_payload($session_id, array $consultation_data = array()) {
        $session_id = $this->ensure_consultation_record($session_id, $consultation_data, 'consultation_payload');
        if (is_wp_error($session_id)) {
            return $session_id;
        }

        return $this->run_from_consultation($session_id);
    }

    public function run_from_legacy_responses($responses, $session_id = '') {
        $responses = is_array($responses) ? $responses : array();
        $session_id = $this->ensure_consultation_record($session_id, array('responses' => $responses), 'legacy_responses');
        if (is_wp_error($session_id)) {
            return $session_id;
        }

        return $this->run_from_consultation($session_id);
    }

    public function run_from_builder_prompt($project_id, $prompt) {
        $project_id = absint($project_id);
        $prompt = sanitize_textarea_field((string) $prompt);

        if ($prompt === '') {
            return new WP_Error('vmo_missing_builder_prompt', 'A website generation prompt is required.');
        }

        if ($project_id > 0) {
            $post = get_post($project_id);
            if (!$post || $post->post_type !== 'vmo_project') {
                return new WP_Error('vmo_invalid_project', 'The selected website project could not be found.');
            }
            $current_user_id = get_current_user_id();
            if (!current_user_can('edit_post', $project_id) && (int) $post->post_author !== $current_user_id && !current_user_can('manage_options')) {
                return new WP_Error('vmo_project_forbidden', 'You do not have permission to generate this website project.');
            }
        }

        $session_id = $project_id > 0 ? (string) get_post_meta($project_id, 'vmo_session_id', true) : '';
        if ($session_id === '') {
            $session_id = 'vmo_builder_' . wp_generate_uuid4();
        }

        if (!function_exists('vmo_get_consultation_profile')) {
            $profile_file = plugin_dir_path(__FILE__) . 'consultation-profile.php';
            if (file_exists($profile_file)) {
                require_once $profile_file;
            }
        }

        $profile = function_exists('vmo_get_consultation_profile') ? vmo_get_consultation_profile(get_current_user_id()) : array();
        if (!is_array($profile)) {
            $profile = array();
        }

        $payload = array(
            'source' => 'builder_prompt',
            'project_id' => $project_id,
            'prompt' => $prompt,
            'responses' => array(
                'website_generation_prompt' => $prompt,
            ),
            'consultation_profile' => $profile,
            'extracted_information' => is_array($profile['extracted_information'] ?? null) ? $profile['extracted_information'] : array(),
        );

        $result = $this->run_from_consultation_payload($session_id, $payload);
        if (is_wp_error($result)) {
            return $result;
        }

        $result['canonical_source'] = 'builder_prompt';
        return $result;
    }

    public function run_regeneration($project_id, $scope) {
        $project_id = absint($project_id);
        if ($project_id <= 0) {
            return new WP_Error('vmo_regeneration_missing_project', 'A website project is required for canonical regeneration.');
        }

        $post = get_post($project_id);
        if (!$post || $post->post_type !== 'vmo_project') {
            return new WP_Error('vmo_regeneration_invalid_project', 'The selected website project could not be found.');
        }

        $current_user_id = get_current_user_id();
        if (!current_user_can('edit_post', $project_id) && (int) $post->post_author !== $current_user_id && !current_user_can('manage_options')) {
            return new WP_Error('vmo_regeneration_forbidden', 'You do not have permission to regenerate this website project.');
        }

        $scope = is_array($scope) ? $scope : array('scope' => $scope);
        $session_id = (string) get_post_meta($project_id, 'vmo_session_id', true);
        if ($session_id === '') {
            $session_id = 'vmo_regeneration_' . wp_generate_uuid4();
        }

        $pages_map = json_decode((string) get_post_meta($project_id, 'vmo_pages_map', true), true);
        if (!is_array($pages_map)) {
            $pages_map = array();
        }

        $payload = array(
            'source' => 'canonical_regeneration',
            'project_id' => $project_id,
            'prompt' => sanitize_textarea_field((string) ($scope['prompt'] ?? 'Regenerate this website through the canonical premium pipeline.')),
            'regeneration_scope' => $scope,
            'existing_project' => array(
                'post_id' => $project_id,
                'title' => $post->post_title,
                'content_sample' => substr(wp_strip_all_tags((string) $post->post_content), 0, 3000),
                'pages_map' => $pages_map,
            ),
        );

        $result = $this->run_from_consultation_payload($session_id, $payload);
        if (is_wp_error($result)) {
            return $result;
        }

        $result['canonical_source'] = 'canonical_regeneration';
        $result['regenerated_from_project_id'] = $project_id;
        return $result;
    }

    public function run_import_existing_page($page_id) {
        $page_id = absint($page_id);
        if ($page_id <= 0) {
            return new WP_Error('vmo_import_missing_page', 'An existing page is required for canonical import.');
        }

        $page = get_post($page_id);
        if (!$page || !in_array($page->post_type, array('page', 'post', 'vmo_project'), true)) {
            return new WP_Error('vmo_import_invalid_page', 'The selected page could not be imported.');
        }

        if (!current_user_can('edit_post', $page_id) && (int) $page->post_author !== get_current_user_id() && !current_user_can('manage_options')) {
            return new WP_Error('vmo_import_forbidden', 'You do not have permission to import this page.');
        }

        $session_id = 'vmo_import_' . $page_id . '_' . wp_generate_uuid4();
        $result = $this->run_from_consultation_payload($session_id, array(
            'source' => 'existing_page_import',
            'imported_page_id' => $page_id,
            'prompt' => 'Import and enhance this existing page through the v2.0 canonical website pipeline without copying unsafe scripts or public builder controls.',
            'existing_page' => array(
                'post_id' => $page_id,
                'title' => $page->post_title,
                'content' => $page->post_content,
                'url' => get_permalink($page_id),
            ),
        ));

        if (is_wp_error($result)) {
            return $result;
        }
        $result['canonical_source'] = 'existing_page_import';
        $result['imported_page_id'] = $page_id;
        return $result;
    }

    public function run_ecommerce_site_generation($project_id) {
        $project_id = absint($project_id);
        if ($project_id <= 0) {
            return new WP_Error('vmo_ecommerce_missing_project', 'A website project is required for ecommerce generation.');
        }

        return $this->run_regeneration($project_id, array(
            'scope' => 'ecommerce_site_generation',
            'prompt' => 'Generate or upgrade this project as a v2.0 ecommerce storytelling website with VMO Pay, product view tracking, checkout-start tracking, purchase/revenue reporting, shipping readiness for physical goods, and dashboard KPI wiring.',
            'ecommerce_required' => true,
        ));
    }

    public function run_quicklaunch_generation($quicklaunch_context) {
        $quicklaunch_context = is_array($quicklaunch_context) ? $quicklaunch_context : array('prompt' => (string) $quicklaunch_context);
        $session_id = sanitize_text_field((string) ($quicklaunch_context['session_id'] ?? $quicklaunch_context['quicklaunch_id'] ?? ''));
        if ($session_id === '') {
            $session_id = 'vmo_quicklaunch_' . wp_generate_uuid4();
        }

        $payload = array(
            'source' => 'quicklaunch_generation',
            'quicklaunch_context' => $quicklaunch_context,
            'prompt' => sanitize_textarea_field((string) ($quicklaunch_context['prompt'] ?? 'Create the QuickLaunch website through the v2.0 canonical premium website pipeline.')),
            'responses' => array(
                'business_name' => $quicklaunch_context['business_name'] ?? '',
                'industry' => $quicklaunch_context['industry'] ?? '',
                'website_generation_prompt' => $quicklaunch_context['prompt'] ?? '',
            ),
            'extracted_information' => is_array($quicklaunch_context['extracted_information'] ?? null) ? $quicklaunch_context['extracted_information'] : $quicklaunch_context,
        );

        $result = $this->run_from_consultation_payload($session_id, $payload);
        if (is_wp_error($result)) {
            return $result;
        }
        $result['canonical_source'] = 'quicklaunch_generation';
        return $result;
    }

    public function run_product_page_generation($product_id, $context) {
        $product_id = absint($product_id);
        $context = is_array($context) ? $context : array('prompt' => (string) $context);
        if ($product_id <= 0 && empty($context['product'])) {
            return new WP_Error('vmo_product_generation_missing_product', 'A product or product context is required for canonical product-page generation.');
        }

        $session_id = sanitize_text_field((string) ($context['session_id'] ?? ''));
        if ($session_id === '') {
            $session_id = 'vmo_product_' . ($product_id ?: 'context') . '_' . wp_generate_uuid4();
        }

        $payload = array(
            'source' => 'product_page_generation',
            'product_id' => $product_id,
            'product_page_context' => $context,
            'prompt' => sanitize_textarea_field((string) ($context['prompt'] ?? 'Generate a v2.0 product storytelling page with product media, quick-view/detail logic, checkout CTA, tracking hooks, SEO metadata, and dashboard wiring.')),
            'responses' => array(
                'website_generation_prompt' => $context['prompt'] ?? '',
                'business_name' => $context['business_name'] ?? '',
                'industry' => $context['industry'] ?? 'ecommerce',
            ),
            'ecommerce' => array(
                'intends_to_sell' => true,
                'products' => array_filter(array($context['product'] ?? array('id' => $product_id))),
            ),
        );

        $result = $this->run_from_consultation_payload($session_id, $payload);
        if (is_wp_error($result)) {
            return $result;
        }
        $result['canonical_source'] = 'product_page_generation';
        $result['product_id'] = $product_id;
        return $result;
    }

    public function model_for_agent($agent_key) {
        if (function_exists('vmo_get_website_agent_model')) {
            return vmo_get_website_agent_model($agent_key);
        }
        if (function_exists('vmo_get_model')) {
            return vmo_get_model('strategic');
        }
        return defined('VMO_MODEL_STRATEGIC') ? VMO_MODEL_STRATEGIC : 'gpt-5.5';
    }

    private function get_integration_hub() {
        if (!class_exists('VMO_Consultation_Website_Integration')) {
            return new WP_Error('vmo_missing_integration_hub', 'The consultation website integration hub is not loaded.');
        }

        if (method_exists('VMO_Consultation_Website_Integration', 'get_instance')) {
            return VMO_Consultation_Website_Integration::get_instance();
        }

        return new VMO_Consultation_Website_Integration();
    }

    private function ensure_consultation_record($session_id, array $payload, $source) {
        $session_id = sanitize_text_field((string) $session_id);
        if ($session_id === '') {
            $session_id = 'vmo_canonical_' . wp_generate_uuid4();
        }

        $canonical_context = $this->build_canonical_generation_context($payload, $source);
        $payload['canonical_generation_context'] = $canonical_context;

        if (!class_exists('VMO_Consultation_Database')) {
            return new WP_Error('vmo_missing_consultation_db', 'The consultation database layer is not loaded.');
        }

        $db = new VMO_Consultation_Database();
        $existing = $db->get_consultation_by_session($session_id);
        if ($existing) {
            $this->merge_existing_consultation_context($db, $existing, $payload, $source, $canonical_context);
            return $session_id;
        }

        $business_name = $this->extract_business_name($payload);
        $business_type = $this->extract_business_type($payload);

        $db->save_consultation(get_current_user_id(), $session_id, array(
            'phase' => 6,
            'phase_state' => array(
                'canonical_source' => $source,
                'canonical_generation_context' => $canonical_context,
            ),
            'business_name' => $business_name,
            'business_type' => $business_type,
            'consultation_data' => $payload,
            'client_data' => $payload,
            'conversation_log' => array(),
            'website_data' => array(
                'canonical_pipeline' => true,
                'pipeline_version' => self::PIPELINE_VERSION,
                'source' => $source,
                'canonical_generation_context' => $canonical_context,
                'selected_visual_preset' => $canonical_context['selected_visual_preset'] ?? '',
                'v2_agent_plan' => $canonical_context['v2_agent_plan'] ?? array(),
                'media_manifest_contract' => $canonical_context['media_manifest_contract'] ?? array(),
                'draft_assembled' => false,
                'media_complete' => false,
                'preview_ready' => false,
            ),
            'status' => 'in_progress',
        ));

        return $session_id;
    }

    private function build_canonical_generation_context(array $payload, $source) {
        if (function_exists('vmo_get_visual_preset_registry')) {
            $context = vmo_get_visual_preset_registry()->build_generation_context($payload, $source);
        } else {
            $context = array(
                'source' => sanitize_key((string) $source),
                'registry_version' => 'fallback',
                'selected_visual_preset' => 'cinematic_service_hero',
                'visual_preset_label' => 'Cinematic Service Hero',
                'required_premium_signals' => array('full-viewport hero', 'early trust proof', 'layered media', 'premium CTA cluster', 'scroll reveal'),
                'motion_requirements' => array('scroll reveal'),
                'media_requirements' => array('hero media'),
                'mobile_requirements' => array('mobile-first layout'),
            );
        }

        $context['agent_models'] = array(
            'master_orchestrator' => $this->model_for_agent('master_orchestrator'),
            'jerreme_handoff_normalizer' => $this->model_for_agent('jerreme_handoff_normalizer'),
            'website_strategy' => $this->model_for_agent('website_strategy'),
            'competitor_market_intelligence' => $this->model_for_agent('competitor_market_intelligence'),
            'visual_color_psychology' => $this->model_for_agent('visual_color_psychology'),
            'visual_experience_director' => $this->model_for_agent('visual_experience_director'),
            'hero_scene_director' => $this->model_for_agent('hero_scene_director'),
            'motion_experience_director' => $this->model_for_agent('motion_experience_director'),
            'media_director' => $this->model_for_agent('media_director'),
            'navigation_menu_director' => $this->model_for_agent('navigation_menu_director'),
            'fullscreen_minisite_experience' => $this->model_for_agent('fullscreen_minisite_experience'),
            'ecommerce_storytelling' => $this->model_for_agent('ecommerce_storytelling'),
            'food_restaurant_experience' => $this->model_for_agent('food_restaurant_experience'),
            'mobile_experience_director' => $this->model_for_agent('mobile_experience_director'),
            'wordpress_security_integrator' => $this->model_for_agent('wordpress_security_integrator'),
            'seo_content_intelligence' => $this->model_for_agent('seo_content_intelligence'),
            'website_kpi_wiring' => $this->model_for_agent('website_kpi_wiring'),
            'website_refinement_assistant' => $this->model_for_agent('website_refinement_assistant'),
            'final_qa_critic' => $this->model_for_agent('final_qa_critic'),
        );
        $context['pipeline_version'] = self::PIPELINE_VERSION;
        $context['preview_policy'] = 'block_until_media_complete_and_final_qa_passes';
        $context['component_state_policy'] = array(
            'source_of_truth' => 'react_style_component_state',
            'builder_shell' => 'wordpress_plugin_can_stage_and_export_only',
            'runtime_output' => 'standalone_html_css_js',
            'forbidden_runtime_dependencies' => array('shortcodes', 'wp-admin', 'admin-ajax.php', 'wp-json', 'wp-content/plugins', 'wp-content/themes', 'window.wp'),
            'builder_editing' => 'vmo_plugin_template_component_props_then_rendered_html',
            'wordpress_editor_usage' => 'disabled_for_generated_sites',
        );
        $context['standalone_runtime_contract'] = array(
            'required' => true,
            'artifact' => 'plain_html_css_js_with_resolved_assets',
            'wordpress_dependency_allowed' => false,
            'builder_role' => 'staging_generation_dashboard_only',
            'editing_surface' => 'vmo_internal_builder_and_template_only',
            'integration_policy' => 'use portable public endpoints, hosted checkout/payment links, mailto/tel/map links, and resolved media URLs instead of WordPress shortcodes or admin AJAX',
        );
        if (function_exists('vmo_build_website_v2_agent_plan')) {
            $context['v2_agent_plan'] = vmo_build_website_v2_agent_plan($payload, $context);
        }
        if (function_exists('vmo_get_website_media_manifest_service')) {
            $context['media_manifest_contract'] = vmo_get_website_media_manifest_service()->build_from_payload($payload, $context);
        }
        $context['created_at'] = current_time('mysql');

        return $context;
    }

    private function merge_existing_consultation_context($db, $existing, array $payload, $source, array $canonical_context) {
        $consultation_data = $this->decode_json_field($existing->consultation_data ?? '', array());
        $client_data = $this->decode_json_field($existing->client_data ?? '', array());
        $phase_state = $this->decode_json_field($existing->phase_state ?? '', array());
        $website_data = $this->decode_json_field($existing->website_data ?? '', array());

        $consultation_data = $this->merge_non_empty_arrays($consultation_data, $payload);
        $client_data = $this->merge_non_empty_arrays($client_data, $payload);

        $phase_state['canonical_source'] = $source;
        $phase_state['canonical_generation_context'] = $canonical_context;
        $phase_state['canonical_updated_at'] = current_time('mysql');

        $website_data['canonical_pipeline'] = true;
        $website_data['pipeline_version'] = self::PIPELINE_VERSION;
        $website_data['source'] = $source;
        $website_data['canonical_generation_context'] = $canonical_context;
        $website_data['selected_visual_preset'] = $canonical_context['selected_visual_preset'] ?? '';
        $website_data['v2_agent_plan'] = $canonical_context['v2_agent_plan'] ?? array();
        $website_data['media_manifest_contract'] = $canonical_context['media_manifest_contract'] ?? array();

        $db->save_consultation(get_current_user_id(), (string) $existing->session_id, array(
            'phase' => max(6, (int) ($existing->phase ?? 1)),
            'phase_state' => $phase_state,
            'business_name' => $existing->business_name ?: $this->extract_business_name($payload),
            'business_type' => $existing->business_type ?: $this->extract_business_type($payload),
            'consultation_data' => $consultation_data,
            'client_data' => $client_data,
            'website_data' => $website_data,
            'status' => 'in_progress',
        ));
    }

    private function decode_json_field($value, $fallback) {
        if (is_array($value)) {
            return $value;
        }
        $decoded = json_decode((string) $value, true);
        return is_array($decoded) ? $decoded : $fallback;
    }

    private function merge_non_empty_arrays(array $base, array $incoming) {
        foreach ($incoming as $key => $value) {
            if ($value === '' || $value === null || $value === array()) {
                continue;
            }
            if (is_array($value) && is_array($base[$key] ?? null)) {
                $base[$key] = $this->merge_non_empty_arrays($base[$key], $value);
            } else {
                $base[$key] = $value;
            }
        }
        return $base;
    }

    private function normalize_pipeline_result(array $result, $source) {
        $result['canonical_pipeline'] = true;
        $result['canonical_source'] = $source;
        $result['pipeline_version'] = self::PIPELINE_VERSION;

        if (!array_key_exists('media_complete', $result)) {
            $result['media_complete'] = false;
        }
        $result['media_complete'] = !empty($result['media_complete']);
        $result['preview_ready'] = array_key_exists('preview_ready', $result)
            ? (!empty($result['preview_ready']) && !empty($result['media_complete']))
            : false;
        if (empty($result['preview_ready'])) {
            $result['preview_url'] = '';
            $result['consultation_complete'] = false;
        }
        if (!array_key_exists('consultation_complete', $result)) {
            $result['consultation_complete'] = !empty($result['preview_ready']);
        }

        return $result;
    }

    private function extract_business_name(array $payload) {
        $paths = array(
            array('business_name'),
            array('businessName'),
            array('company_name'),
            array('extracted_information', 'businessName'),
            array('extracted_information', 'business_name'),
            array('responses', 'business_name'),
            array('responses', 'businessName'),
        );

        foreach ($paths as $path) {
            $value = $this->array_path($payload, $path);
            if (is_scalar($value) && trim((string) $value) !== '') {
                return sanitize_text_field((string) $value);
            }
        }

        return sanitize_text_field((string) get_bloginfo('name'));
    }

    private function extract_business_type(array $payload) {
        $paths = array(
            array('business_type'),
            array('businessType'),
            array('industry'),
            array('extracted_information', 'businessType'),
            array('extracted_information', 'industry'),
            array('responses', 'business_type'),
            array('responses', 'industry'),
        );

        foreach ($paths as $path) {
            $value = $this->array_path($payload, $path);
            if (is_scalar($value) && trim((string) $value) !== '') {
                return sanitize_text_field((string) $value);
            }
        }

        return '';
    }

    private function array_path(array $payload, array $path) {
        $current = $payload;
        foreach ($path as $segment) {
            if (!is_array($current) || !array_key_exists($segment, $current)) {
                return null;
            }
            $current = $current[$segment];
        }
        return $current;
    }
}

function vmo_get_canonical_website_pipeline() {
    return VMO_Canonical_Website_Pipeline::get_instance();
}