<?php
/**
 * Rank Booster Divi Support
 *
 * Handles the "Edit Draft" flow for Divi pages:
 *  - Stores AI draft in a meta key
 *  - Injects it into post_content when the Divi Visual Builder loads
 *  - Auto-marks the job as pushed_live when the user saves in Divi VB
 *
 * Divi stores content as shortcodes in post_content, so the main
 * optimization pipeline (extract → API → re-inject) works via the
 * existing Classic/Gutenberg flow. This class only handles the
 * editor injection and save detection.
 */

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

class Rank_Booster_Divi {

    /** Meta key for storing draft post_content (not yet live). */
    const META_DRAFT = '_rank_booster_divi_draft';

    /** Meta key: set when AI draft was loaded into the Divi VB. */
    const META_DRAFT_PENDING = '_rank_booster_divi_draft_pending';

    /**
     * Register hooks. Called from the bootstrap (class-rank-booster.php).
     */
    public static function init() {
        // When Divi Visual Builder loads (?et_fb=1), swap in draft content.
        // Use 'wp' action (fires after main query is set) — more reliable than the_post
        // because Divi VB may use get_post() which doesn't fire the_post.
        add_action( 'wp', array( __CLASS__, 'inject_draft_on_divi_vb' ) );

        // When user saves from Divi VB, auto-mark the job as pushed_live.
        add_action( 'save_post', array( __CLASS__, 'on_divi_save' ), 20, 1 );
    }

    /**
     * Swap post_content with AI draft when the Divi Visual Builder loads.
     *
     * Hooked to 'wp' action (after main query is set, before template rendering).
     * This modifies the global $post object and also updates the WP object cache
     * so get_post() returns the draft too.
     *
     * Behaviour:
     *  - If user saves in Divi VB → AI changes become the live version.
     *  - If user closes without saving → live post_content is untouched.
     *  - If user refreshes → original content loads (draft meta was deleted).
     */
    public static function inject_draft_on_divi_vb() {
        // Only act inside the Divi Visual Builder.
        if ( ! isset( $_GET['et_fb'] ) ) {
            return;
        }

        global $post;
        if ( ! $post || empty( $post->ID ) ) {
            self::log( 'inject skipped — no global $post available.' );
            return;
        }

        $draft = get_post_meta( $post->ID, self::META_DRAFT, true );
        self::log( 'post_id=' . $post->ID . ' | draft_meta_exists=' . ( ! empty( $draft ) ? 'YES (' . strlen( $draft ) . ' chars)' : 'NO' ) );

        if ( empty( $draft ) ) {
            return;
        }

        // 1. Modify the global $post object directly.
        $post->post_content = $draft;

        // 2. Also update the WP_Query main post object.
        global $wp_query;
        if ( $wp_query && ! empty( $wp_query->post ) ) {
            $wp_query->post->post_content = $draft;
        }

        // 3. Update the post cache so get_post() returns the draft too.
        wp_cache_set( $post->ID, $post, 'posts' );

        // 4. Delete immediately — one-shot injection.
        delete_post_meta( $post->ID, self::META_DRAFT );

        // 5. Mark that we injected a draft — persists so the save handler can detect it.
        update_post_meta( $post->ID, self::META_DRAFT_PENDING, '1' );

        self::log( '✅ draft injected into post_content for post ' . $post->ID . ' (' . strlen( $draft ) . ' chars).' );
    }

    /**
     * When the user saves from Divi VB after our draft was injected,
     * auto-mark the corresponding rank booster job as pushed_live.
     *
     * @param int $post_id
     */
    public static function on_divi_save( $post_id ) {
        // Skip autosaves and revisions.
        if ( wp_is_post_autosave( $post_id ) || wp_is_post_revision( $post_id ) ) {
            return;
        }

        // Check if we previously injected a draft into this post's Divi VB.
        $pending = get_post_meta( $post_id, self::META_DRAFT_PENDING, true );
        if ( empty( $pending ) ) {
            return;
        }

        // Clean up the flag.
        delete_post_meta( $post_id, self::META_DRAFT_PENDING );

        // Find the latest completed job for this post and mark it pushed_live.
        if ( class_exists( 'Rank_Booster_DB' ) ) {
            global $wpdb;
            $table = Rank_Booster_DB::table_name();
            $job   = $wpdb->get_row( $wpdb->prepare(
                "SELECT id FROM $table WHERE post_id = %d AND status = 'completed' ORDER BY updated_at DESC LIMIT 1",
                $post_id
            ) );

            if ( $job ) {
                Rank_Booster_DB::update_job( $job->id, array(
                    'status'         => 'pushed_live',
                    'pushed_live_at' => current_time( 'mysql' ),
                ) );
                Rank_Booster_DB::add_log_entry( $job->id, '🚀 Published from Divi Visual Builder.' );
            }
        }
    }

    /**
     * Write a debug log entry to the plugin's central log file (logs/rank-debug.log).
     * Same format as Rank_Processor::add_debug_log().
     * Used on the frontend where Rank_Processor is not loaded.
     *
     * @param string $message
     */
    private static function log( $message ) {
        if ( ! get_option( 'rank_debug_enabled', false ) ) {
            return;
        }
        $log_file = RANK_PLUGIN_DIR . 'logs/rank-debug.log';
        $timestamp = current_time( 'Y-m-d H:i:s' );
        $line = "[{$timestamp}] [info] [Divi] {$message}" . PHP_EOL;
        file_put_contents( $log_file, $line, FILE_APPEND | LOCK_EX );
    }
}
