<?php
// includes/save-generated-page.php
if (!defined('ABSPATH')) exit;

if (!function_exists('vmo_generated_page_standalone_blockers')) {
    function vmo_generated_page_standalone_blockers($html) {
        $html = (string) $html;
        $blockers = array();
        $patterns = array(
            '/admin-ajax\.php/i' => 'admin-ajax.php dependency',
            '/\/wp-admin\//i' => 'wp-admin dependency',
            '/wp-login\.php/i' => 'wp-login dependency',
            '/\/wp-json\//i' => 'wp-json dependency',
            '/wp-content\/plugins/i' => 'plugin asset dependency',
            '/wp-content\/themes/i' => 'theme asset dependency',
            '/wp-includes/i' => 'WordPress core asset dependency',
            '/window\.wp\b|wp\.apiFetch/i' => 'WordPress JavaScript dependency',
            '/<\?php/i' => 'PHP code in public markup',
        );
        foreach ($patterns as $pattern => $label) {
            if (preg_match($pattern, $html)) {
                $blockers[] = $label;
            }
        }
        if (preg_match_all('/(^|[\s>])\[(?!generated_image|generated_video)([a-z][a-z0-9_:-]*)(?:\s+[^\]]*)?\](?:\s*\[\/\2\])?/i', $html, $shortcode_matches, PREG_SET_ORDER)) {
            foreach ($shortcode_matches as $shortcode_match) {
                $shortcode_name = strtolower((string) ($shortcode_match[2] ?? ''));
                if ($shortcode_name !== '' && strpos($shortcode_name, 'data-') !== 0 && strpos($shortcode_name, 'aria-') !== 0) {
                    $blockers[] = 'shortcode dependency: [' . $shortcode_name . ']';
                    break;
                }
            }
        }
        return array_values(array_unique($blockers));
    }
}

if (!function_exists('vmo_generated_page_completion_blockers')) {
    function vmo_generated_page_completion_blockers($html) {
        $html = (string) $html;
        $blockers = array();
        $patterns = array(
            '/data-vmo-internal-fallback|vmo-internal-fallback|vmo-fallback-page|data-vmo-preview-blocked/i' => 'internal fallback draft',
            '/data-vmo-generate\s*=|\[(generated_image):/i' => 'unresolved generated image',
            '/data-vmo-sora\s*=|\[(generated_video):/i' => 'unresolved generated video',
            '/vmo-media-placeholder/i' => 'unresolved media placeholder',
            '/AI\s+(?:Image|Video)\s+Generating|A professional (?:image|video) will appear here/i' => 'visible media placeholder copy',
        );

        foreach ($patterns as $pattern => $label) {
            if (preg_match($pattern, $html)) {
                $blockers[] = $label;
            }
        }

        return array_values(array_unique($blockers));
    }
}

if (!function_exists('vmo_strip_editor_only_media_overlays')) {
    function vmo_strip_editor_only_media_overlays($html) {
        $html = (string) $html;
        if ($html === '') {
            return '';
        }

        $html = preg_replace('/<button\b[^>]*(?:data-replace-media|data-vmo-editor-only=["\']media-replace-overlay["\']|class=["\'][^"\']*(?:vmo-replace-overlay|vmo-replace-btn|vmo-replace-media-btn|replace-image-btn|replace-video-btn)[^"\']*["\'])[^>]*>[\s\S]*?<\/button>/i', '', $html);
        $html = preg_replace('/\sdata-vmo-has-button=("[^"]*"|\'[^\']*\'|[^\s>]+)/i', '', $html);
        $html = preg_replace('/\sdata-vmo-editor-only=("[^"]*"|\'[^\']*\'|[^\s>]+)/i', '', $html);
        return is_string($html) ? $html : '';
    }
}

/**
 * AJAX: Save generated HTML as WordPress page or post
 */
add_action('wp_ajax_vmo_save_generated_page', function () {
    // Accept both admin and builder nonces; return non-fatal JSON on failure
    $admin_nonce   = isset($_POST['nonce']) ? $_POST['nonce'] : '';
    $builder_nonce = isset($_POST['security']) ? $_POST['security'] : '';
    if (!(($admin_nonce && wp_verify_nonce($admin_nonce, 'vmo_admin_nonce')) || ($builder_nonce && wp_verify_nonce($builder_nonce, 'vmo_builder_nonce')))) {
        wp_send_json_error(['message' => 'Security check failed', 'status' => 'invalid_nonce']);
        return;
    }

    $title      = sanitize_text_field($_POST['title'] ?? '');
    $content    = wp_unslash($_POST['content'] ?? ''); // Do not sanitize — allow full HTML
    if (function_exists('vmo_strip_editor_only_media_overlays')) {
        $content = vmo_strip_editor_only_media_overlays($content);
    }
    $type       = sanitize_key($_POST['type'] ?? 'page');
    $status     = sanitize_key($_POST['status'] ?? 'draft');
    $slug       = sanitize_title($_POST['slug'] ?? '');
    $page_id    = isset($_POST['page_id']) ? intval($_POST['page_id']) : 0; // if provided, update existing
    $project_id = isset($_POST['project_id']) ? intval($_POST['project_id']) : 0; // link project -> live page

    if (!$title || !$content) {
        wp_send_json_error(['message' => 'Missing title or content.']);
        wp_die();
    }

    // Validate post type and status
    $allowed_types = ['page', 'post'];
    $allowed_statuses = ['draft', 'publish', 'private'];

    if (!in_array($type, $allowed_types, true)) {
        $type = 'page';
    }
    if (!in_array($status, $allowed_statuses, true)) {
        $status = 'draft';
    }

    $is_demo_showcase = is_string($content)
        && (
            strpos($content, 'id="vmo-demo-showcase"') !== false
            || strpos($content, "id='vmo-demo-showcase'") !== false
            || strpos($content, 'showcase-placeholder') !== false
        );

    if ($status === 'publish' && $is_demo_showcase) {
        wp_send_json_error([
            'message' => 'The demo website placeholder cannot be published. Generate or restore a real website first.',
            'code' => 'placeholder_not_publishable'
        ]);
        wp_die();
    }

    $standalone_blockers = vmo_generated_page_standalone_blockers($content);
    if ($status === 'publish' && !empty($standalone_blockers)) {
        wp_send_json_error([
            'message' => 'This site cannot be published as complete because it still depends on WordPress runtime pieces: ' . implode(', ', $standalone_blockers),
            'code' => 'standalone_dependency_blocked',
            'standalone_blockers' => $standalone_blockers,
        ]);
        wp_die();
    }

    $completion_blockers = vmo_generated_page_completion_blockers($content);
    if ($status === 'publish' && !empty($completion_blockers)) {
        wp_send_json_error([
            'message' => 'This site cannot be published because the canonical preview gate is still locked: ' . implode(', ', $completion_blockers),
            'code' => 'preview_gate_blocked',
            'completion_blockers' => $completion_blockers,
        ], 409);
        wp_die();
    }

    if ($status === 'publish') {
        $source_project = $project_id > 0 ? get_post($project_id) : null;
        if (!$source_project || $source_project->post_type !== 'vmo_project') {
            wp_send_json_error([
                'message' => 'This site cannot be published without a canonical VMO project source. Regenerate or reload the project through the VMO canonical website pipeline first.',
                'code' => 'canonical_project_required',
            ], 409);
            wp_die();
        }

        $project_preview_ready = get_post_meta($project_id, 'vmo_preview_ready', true) === 'yes';
        $project_media_complete = get_post_meta($project_id, 'vmo_media_complete', true) === 'yes';
        if (!$project_preview_ready || !$project_media_complete) {
            wp_send_json_error([
                'message' => 'This project cannot be published until final QA and required media are complete.',
                'code' => 'project_preview_gate_locked',
                'preview_ready' => $project_preview_ready,
                'media_complete' => $project_media_complete,
            ], 409);
            wp_die();
        }
    }

    // If the generator returned a full HTML document, split it so we store only the <body>
    // in post_content and persist head/footer assets in post meta for reliable frontend loading.
    $split = null;
    if (function_exists('vmo_split_html_document')) {
        $split = vmo_split_html_document($content);
        if (!empty($split['is_full_document'])) {
            $content = (string) ($split['body'] ?? $content);
        }
    }

    // Temporarily disable content sanitization
    remove_filter('content_save_pre', 'wp_filter_post_kses');
    remove_filter('content_filtered_save_pre', 'wp_filter_post_kses');

    $post_data = [
        'post_title'   => $title,
        'post_content' => $content,
        'post_status'  => $status,
        'post_type'    => $type
    ];

    // Allow caller to explicitly set the page URL extension (slug)
    if (!empty($slug)) {
        $post_data['post_name'] = $slug;
    }

    if ($page_id) {
        // Snapshot rollback: store previous content
        $prev = get_post($page_id);
        if ($prev && !is_wp_error($prev)) {
            $snapshots = get_post_meta($page_id, 'vmo_live_snapshots', true);
            if (!is_array($snapshots)) $snapshots = [];

            $prev_head   = get_post_meta($page_id, 'vmo_generated_head_html', true);
            $prev_footer = get_post_meta($page_id, 'vmo_generated_footer_html', true);
            $snapshots[] = [
                'timestamp' => current_time('mysql'),
                'user_id'   => get_current_user_id(),
                'content'   => $prev->post_content,
                'title'     => $prev->post_title,
                'slug'      => $prev->post_name,
                'head'      => is_string($prev_head) ? $prev_head : '',
                'footer'    => is_string($prev_footer) ? $prev_footer : '',
            ];
            if (count($snapshots) > 10) { $snapshots = array_slice($snapshots, -10); }
            update_post_meta($page_id, 'vmo_live_snapshots', $snapshots);
        }
        $post_data['ID'] = $page_id;
        $id = wp_update_post($post_data, true);
    } else {
        $id = wp_insert_post($post_data, true);
    }

    if (is_wp_error($id)) {
        error_log('[VMO] Failed to insert post: ' . $id->get_error_message());
        wp_send_json_error(['message' => 'Failed to save post.']);
        wp_die();
    }

    // Persist extracted head/footer assets for the VMO template runtime.
    if (is_array($split) && !empty($split['is_full_document'])) {
        update_post_meta($id, 'vmo_generated_head_html', (string) ($split['head'] ?? ''));
        update_post_meta($id, 'vmo_generated_footer_html', (string) ($split['footer'] ?? ''));
    } else {
        // If not a full doc, keep prior assets unless explicitly overwritten.
        // (Prevents losing previously extracted assets during small updates.)
        if (!isset($_POST['vmo_clear_generated_assets'])) {
            // no-op
        }
    }

    // === Set the custom template for perfect WYSIWYG ===
    update_post_meta($id, '_wp_page_template', 'vmo-fullwidth-template.php');
    update_post_meta($id, 'vmo_editing_surface', 'vmo_internal_builder_template');
    update_post_meta($id, 'vmo_wordpress_editor_usage', 'disabled_for_generated_sites');
    update_post_meta($id, 'vmo_runtime_output', 'standalone_html_css_js');
    update_post_meta($id, 'vmo_standalone_portable', empty($standalone_blockers) ? 'yes' : 'no');
    update_post_meta($id, 'vmo_completion_gate_clear', empty($completion_blockers) ? 'yes' : 'no');

    // Link live page to the corresponding project for future updates
    if ($project_id) {
        update_post_meta($project_id, 'vmo_live_page_id', $id);
    }

    // Flag effects requirement (for frontend enqueues)
    $needs_effects = (strpos($content, 'data-parallax') !== false) || (strpos($content, 'data-aos') !== false);
    if ($needs_effects) update_post_meta($id, 'vmo_effects_required', 1);

    // Ping sitemaps
    if (!function_exists('vmo_ping_sitemaps')) {
        function vmo_ping_sitemaps() {
            $home = home_url('/');
            $sitemap = trailingslashit($home) . 'sitemap.xml';
            $endpoints = [
                'https://www.google.com/ping?sitemap=' . rawurlencode($sitemap),
                'https://www.bing.com/ping?sitemap=' . rawurlencode($sitemap),
            ];
            foreach ($endpoints as $url) { wp_remote_get($url, ['timeout' => 3]); }
        }
    }
    vmo_ping_sitemaps();

    // Derive default Open Graph / Twitter metadata if not provided by SEO agent
    $og_title = get_post_meta($id, 'vmo_seo_title', true) ?: $title;
    $og_desc  = get_post_meta($id, 'vmo_seo_description', true) ?: wp_strip_all_tags(wp_trim_words($content, 40));
    update_post_meta($id, 'vmo_og_title', $og_title);
    update_post_meta($id, 'vmo_og_description', $og_desc);
    update_post_meta($id, 'vmo_twitter_title', $og_title);
    update_post_meta($id, 'vmo_twitter_description', $og_desc);

    // ✅ SERVER-SIDE TOKEN DEDUCTION: Charge for publishing (prevents free publishes)
    if ($status === 'publish' && function_exists('vmo_deduct_tokens')) {
        $user_id = get_current_user_id();
        $current_plan = '';
        if (class_exists('VMO_Tokens')) {
            $tokens_instance = VMO_Tokens::get_instance();
            $current_plan = $tokens_instance->get_user_plan($user_id);
        }
        // Mirror the frontend cost logic
        $publish_cost = 625; // default (unpaid users)
        if (in_array($current_plan, ['starter', 'pro', 'elite'])) {
            $publish_cost = 500;
        } elseif ($current_plan === 'topup') {
            $publish_cost = 550;
        }
        vmo_deduct_tokens($user_id, $publish_cost, 'publish', 'Website page published: ' . $title);
    }

    wp_send_json_success([
        'message' => 'Page saved successfully.',
        'id' => $id,
        'link' => get_permalink($id),
        'standalone_portable' => empty($standalone_blockers),
        'standalone_blockers' => $standalone_blockers,
    ]);
    wp_die();
});


/**
 * AJAX: Save page temporarily as draft for in-browser preview
 */
add_action('wp_ajax_vmo_preview_in_browser', function () {
    // Accept both admin and builder nonces; return non-fatal JSON on failure
    $admin_nonce   = isset($_POST['nonce']) ? $_POST['nonce'] : '';
    $builder_nonce = isset($_POST['security']) ? $_POST['security'] : '';
    if (!(($admin_nonce && wp_verify_nonce($admin_nonce, 'vmo_admin_nonce')) || ($builder_nonce && wp_verify_nonce($builder_nonce, 'vmo_builder_nonce')))) {
        wp_send_json_error(['message' => 'Security check failed', 'status' => 'invalid_nonce']);
        return;
    }

    $content = wp_unslash($_POST['content'] ?? '');
    if (function_exists('vmo_strip_editor_only_media_overlays')) {
        $content = vmo_strip_editor_only_media_overlays($content);
    }
    // Same split logic for previews (keeps head/footer working on preview pages too)
    $split = null;
    if (function_exists('vmo_split_html_document')) {
        $split = vmo_split_html_document($content);
        if (!empty($split['is_full_document'])) {
            $content = (string) ($split['body'] ?? $content);
        }
    }

    $preview_completion_blockers = vmo_generated_page_completion_blockers($content);
    if (!empty($preview_completion_blockers)) {
        wp_send_json_error(array(
            'message' => 'Preview is locked until final QA passes and required media is complete: ' . implode(', ', $preview_completion_blockers),
            'preview_ready' => false,
            'media_complete' => false,
            'completion_blockers' => $preview_completion_blockers,
        ), 409);
        return;
    }

    $source_post_id = absint($_POST['post_id'] ?? $_POST['project_id'] ?? 0);
    if ($source_post_id > 0 && get_post_type($source_post_id) === 'vmo_project') {
        $project_preview_ready = get_post_meta($source_post_id, 'vmo_preview_ready', true) === 'yes';
        $project_media_complete = get_post_meta($source_post_id, 'vmo_media_complete', true) === 'yes';
        if (!$project_preview_ready || !$project_media_complete) {
            wp_send_json_error(array(
                'message' => 'Preview is locked until final QA passes and required media is complete.',
                'preview_ready' => $project_preview_ready,
                'media_complete' => $project_media_complete,
            ), 409);
            return;
        }
    }

    $title = 'VMO Preview - ' . current_time('mysql');

    $post_id = wp_insert_post([
        'post_title'     => sanitize_text_field($title),
        'post_content'   => $content,
        'post_status'    => 'draft',
        'post_type'      => 'page',
        'page_template'  => 'vmo-fullwidth-template.php'
    ]);

    if (is_wp_error($post_id) || !$post_id) {
        wp_send_json_error(['message' => 'Preview failed to create draft.']);
    }

    // Tag for cleanup so stale preview drafts can be deleted later
    update_post_meta($post_id, '_vmo_preview_draft', 1);
    update_post_meta($post_id, '_vmo_preview_created_at', current_time('mysql'));

    // Ensure the VMO template is actually applied (WordPress uses post meta for page templates)
    update_post_meta($post_id, '_wp_page_template', 'vmo-fullwidth-template.php');

    if (is_array($split) && !empty($split['is_full_document'])) {
        update_post_meta($post_id, 'vmo_generated_head_html', (string) ($split['head'] ?? ''));
        update_post_meta($post_id, 'vmo_generated_footer_html', (string) ($split['footer'] ?? ''));
    }

    if (function_exists('get_preview_post_link')) {
        $link = get_preview_post_link($post_id);
    } else {
        $link = add_query_arg([
            'preview' => 'true',
            'p' => $post_id,
        ], get_permalink($post_id));
    }

    if (!$link) {
        $link = get_permalink($post_id);
    }

    wp_send_json_success(['link' => $link]);
    wp_die();
});

/**
 * AJAX: Roll back a live page to the previous snapshot
 * mode=check -> returns available count
 * mode=apply -> applies last snapshot and returns updated content
 */
add_action('wp_ajax_vmo_rollback_live_page', function () {
    // Accept both admin and builder nonces; return non-fatal JSON on failure
    $admin_nonce   = isset($_POST['nonce']) ? $_POST['nonce'] : '';
    $builder_nonce = isset($_POST['security']) ? $_POST['security'] : '';
    if (!(($admin_nonce && wp_verify_nonce($admin_nonce, 'vmo_admin_nonce')) || ($builder_nonce && wp_verify_nonce($builder_nonce, 'vmo_builder_nonce')))) {
        wp_send_json_error(['message' => 'Security check failed', 'status' => 'invalid_nonce']);
        return;
    }
    $page_id = isset($_POST['page_id']) ? intval($_POST['page_id']) : 0;
    $mode    = sanitize_key($_POST['mode'] ?? 'apply');
    if (!$page_id) wp_send_json_error(['message' => 'Missing page_id']);
    if (!current_user_can('edit_post', $page_id)) wp_send_json_error(['message' => 'Not allowed']);

    $snaps = get_post_meta($page_id, 'vmo_live_snapshots', true);
    if (!is_array($snaps)) $snaps = [];
    $available = count($snaps);
    if ($mode === 'check') {
        wp_send_json_success(['available' => $available]);
    }
    if ($available < 1) wp_send_json_error(['message' => 'No snapshots']);

    // Apply last snapshot (LIFO)
    $last = array_pop($snaps);
    if (!$last || empty($last['content'])) wp_send_json_error(['message' => 'Invalid snapshot']);

    // Update the page with snapshot content/title
    $post_data = [
        'ID'           => $page_id,
        'post_content' => $last['content'],
    ];
    if (!empty($last['title'])) $post_data['post_title'] = $last['title'];
    if (!empty($last['slug'])) $post_data['post_name'] = sanitize_title($last['slug']);
    $res = wp_update_post($post_data, true);
    if (is_wp_error($res)) wp_send_json_error(['message' => 'Rollback failed: ' . $res->get_error_message()]);

    // Restore head/footer assets if present in snapshot
    if (array_key_exists('head', $last)) {
        update_post_meta($page_id, 'vmo_generated_head_html', (string) ($last['head'] ?? ''));
    }
    if (array_key_exists('footer', $last)) {
        update_post_meta($page_id, 'vmo_generated_footer_html', (string) ($last['footer'] ?? ''));
    }
    // Keep the VMO template applied
    update_post_meta($page_id, '_wp_page_template', 'vmo-fullwidth-template.php');

    // Save truncated snapshots back
    update_post_meta($page_id, 'vmo_live_snapshots', $snaps);

    // Recalculate effects flag
    $content = get_post_field('post_content', $page_id);
    $needs_effects = (strpos($content, 'data-parallax') !== false) || (strpos($content, 'data-aos') !== false);
    if ($needs_effects) update_post_meta($page_id, 'vmo_effects_required', 1); else delete_post_meta($page_id, 'vmo_effects_required');

    wp_send_json_success([
        'id'      => $page_id,
        'content' => $content
    ]);
});

/**
 * WP-Cron: Purge stale VMO preview drafts older than 24 hours.
 * Runs twice daily via wp_cron.
 */
add_action('vmo_cleanup_preview_drafts', function () {
    global $wpdb;

    $cutoff = gmdate('Y-m-d H:i:s', time() - DAY_IN_SECONDS);

    $stale_ids = $wpdb->get_col($wpdb->prepare(
        "SELECT p.ID FROM {$wpdb->posts} p
         INNER JOIN {$wpdb->postmeta} pm1 ON p.ID = pm1.post_id AND pm1.meta_key = '_vmo_preview_draft' AND pm1.meta_value = '1'
         INNER JOIN {$wpdb->postmeta} pm2 ON p.ID = pm2.post_id AND pm2.meta_key = '_vmo_preview_created_at'
         WHERE pm2.meta_value < %s
         LIMIT 50",
        $cutoff
    ));

    foreach ($stale_ids as $post_id) {
        wp_delete_post((int) $post_id, true); // force delete, skip trash
    }

    if (!empty($stale_ids)) {
        error_log('[VMO] Cleaned up ' . count($stale_ids) . ' stale preview drafts.');
    }
});

// Schedule the cron event on plugin load if not already scheduled.
if (!wp_next_scheduled('vmo_cleanup_preview_drafts')) {
    wp_schedule_event(time(), 'twicedaily', 'vmo_cleanup_preview_drafts');
}