<?php
/**
 * Rank Booster WPBakery (Visual Composer) Support
 *
 * WPBakery stores its content as shortcodes directly in post_content
 * (e.g. [vc_row][vc_column][vc_column_text]...[/vc_column_text]). That means
 * the generic Classic/Gutenberg pipeline already extracts, rewrites and
 * re-applies it correctly — exactly like Divi.
 *
 * This class therefore only handles the editor side of the "Edit Draft" flow:
 *  - Stores the AI draft in a meta key.
 *  - Swaps it into post_content when the WPBakery frontend editor loads.
 *  - Auto-marks the job pushed_live when the user saves from the editor.
 *
 * The LLM is told editor_type='wpbakery' so it preserves the [vc_*] shortcode
 * structure and only rewrites the human text between tags.
 */

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

class Rank_Booster_WPBakery {

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

    /** Meta key: set when an AI draft was loaded into the WPBakery editor. */
    const META_DRAFT_PENDING = '_rank_booster_wpbakery_draft_pending';

    public static function init() {
        // WPBakery frontend ("Frontend Editor") loads with ?vc_editable=true
        // or ?vc_action=vc_inline. Swap in the draft content there.
        add_action( 'wp', array( __CLASS__, 'inject_draft_on_frontend_editor' ) );

        // Auto-mark pushed_live when the user saves.
        add_action( 'save_post', array( __CLASS__, 'on_wpbakery_save' ), 20, 1 );
    }

    /**
     * Is the current request the WPBakery frontend editor?
     */
    private static function is_frontend_editor() {
        if ( isset( $_GET['vc_editable'] ) && $_GET['vc_editable'] === 'true' ) {
            return true;
        }
        if ( isset( $_GET['vc_action'] ) && $_GET['vc_action'] === 'vc_inline' ) {
            return true;
        }
        return false;
    }

    /**
     * Swap post_content with the AI draft when the WPBakery frontend editor loads.
     * One-shot: the draft meta is deleted after injection.
     */
    public static function inject_draft_on_frontend_editor() {
        if ( ! self::is_frontend_editor() ) {
            return;
        }

        global $post;
        if ( ! $post || empty( $post->ID ) ) {
            return;
        }

        $draft = get_post_meta( $post->ID, self::META_DRAFT, true );
        if ( empty( $draft ) ) {
            return;
        }

        $post->post_content = $draft;
        global $wp_query;
        if ( $wp_query && ! empty( $wp_query->post ) ) {
            $wp_query->post->post_content = $draft;
        }
        wp_cache_set( $post->ID, $post, 'posts' );

        delete_post_meta( $post->ID, self::META_DRAFT );
        update_post_meta( $post->ID, self::META_DRAFT_PENDING, '1' );
    }

    /**
     * Auto-mark the latest completed job pushed_live after a WPBakery save.
     */
    public static function on_wpbakery_save( $post_id ) {
        if ( wp_is_post_autosave( $post_id ) || wp_is_post_revision( $post_id ) ) {
            return;
        }
        $pending = get_post_meta( $post_id, self::META_DRAFT_PENDING, true );
        if ( empty( $pending ) ) {
            return;
        }
        delete_post_meta( $post_id, self::META_DRAFT_PENDING );

        if ( ! class_exists( 'Rank_Booster_DB' ) ) {
            return;
        }
        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 WPBakery editor.' );
        }
    }

    /**
     * Validate that WPBakery shortcode structure survived the API round-trip.
     *
     * @param string $original
     * @param string $returned
     * @return true|WP_Error
     */
    public static function validate_content( $original, $returned ) {
        $orig = preg_match_all( '/\[vc_/', $original );
        if ( $orig > 0 && preg_match_all( '/\[vc_/', $returned ) === 0 ) {
            return new WP_Error( 'shortcodes_lost', 'WPBakery shortcodes were stripped by the API. Draft stored but may break the builder.' );
        }
        return true;
    }
}
