<?php
/**
 * Post Scheduler Functionality
 *
 * This file contains all functions related to the post scheduling feature.
 *
 * @package Simple_Ai_Auto_Post
 * @since 1.2.0
 */

// If this file is called directly, abort.
if ( ! defined( 'WPINC' ) ) {
	die;
}

/**
 * Render the Post Scheduler tab.
 */
function saiap_render_scheduler_tab() {
    ?>
    <?php
    // Show Post Map CTA for licensed users with no post maps
    if ( function_exists( 'saiap_render_post_map_cta' ) ) {
        saiap_render_post_map_cta( 'scheduler' );
    }
    ?>
    <div class="saiap-scheduler-page">
        <div class="scheduler-grid">
            <?php for ( $i = 0; $i < 7; $i++ ) : ?>
                <?php
                $date = new DateTime( "+$i days", new DateTimeZone( 'UTC' ) );
                // Adjust to site's timezone for display
                $site_date = new DateTime( $date->format( 'Y-m-d' ), new DateTimeZone( wp_timezone_string() ) );
                ?>
                <div class="day-column">
                    <div class="day-header">
                        <div class="day-name"><?php echo esc_html( $site_date->format( 'l' ) ); ?></div>
                        <div class="day-date"><?php echo esc_html( $site_date->format( 'F j' ) ); ?></div>
                    </div>
                    <div class="prompt-card-wrapper" data-date="<?php echo esc_attr( $site_date->format( 'Y-m-d' ) ); ?>">
                        <!-- Prompts will be loaded here via JavaScript -->
                        <div class="prompt-card empty">
                            <div class="prompt-content">
                                <p><?php esc_html_e( 'No prompt scheduled.', 'clearpost-simple-ai-auto-post' ); ?></p>
                            </div>
                            <div class="prompt-actions">
                                <button class="button-secondary edit-prompt"><?php esc_html_e( 'Add', 'clearpost-simple-ai-auto-post' ); ?></button>
                            </div>
                        </div>
                    </div>
                </div>
            <?php endfor; ?>
        </div>

        <!-- Modal for editing/adding prompts -->
        <div id="saiap-scheduler-modal" class="saiap-modal" style="display: none;">
            <div class="saiap-modal-content">
                <h2 id="saiap-modal-title"><?php esc_html_e( 'Edit Prompt', 'clearpost-simple-ai-auto-post' ); ?></h2>
                <form id="saiap-scheduler-form">
                    <input type="hidden" id="saiap-modal-prompt-id" value="">
                    <input type="hidden" id="saiap-modal-date" value="">
                    <textarea id="saiap-modal-prompt-text" rows="5" placeholder="<?php esc_attr_e( 'Enter your post prompt here...', 'clearpost-simple-ai-auto-post' ); ?>"></textarea>
                    <div class="saiap-modal-actions">
                        <button type="button" class="button-secondary" id="saiap-modal-cancel"><?php esc_html_e( 'Cancel', 'clearpost-simple-ai-auto-post' ); ?></button>
                        <button type="submit" class="button-primary" id="saiap-modal-save"><?php esc_html_e( 'Save Prompt', 'clearpost-simple-ai-auto-post' ); ?></button>
                    </div>
                </form>
            </div>
        </div>
    </div>
    <div class="saiap-research-agent-card">
        <h3><?php esc_html_e( 'Research Agent', 'clearpost-simple-ai-auto-post' ); ?></h3>
        <p><?php esc_html_e( 'Let our AI research agent fill your content calendar with relevant post ideas.', 'clearpost-simple-ai-auto-post' ); ?></p>
        <textarea id="saiap-research-prompt" rows="3" placeholder="<?php esc_attr_e( 'e.g., "Find trending topics about AI in marketing"', 'clearpost-simple-ai-auto-post' ); ?>"></textarea>
        <div id="saiap-research-recos" class="saiap-research-recos" style="margin: 8px 0 12px; display: flex; gap: 8px; flex-wrap: wrap;"></div>
        <button id="saiap-fill-calendar-btn" class="button-primary"><?php esc_html_e( 'Fill Calendar', 'clearpost-simple-ai-auto-post' ); ?></button>
    </div>
    <div id="saiap-research-results" class="saiap-research-results-panel">
        <!-- Research results will be displayed here -->
    </div>
    <?php
}

/**
 * AJAX handler to fetch the scheduled prompts from the premium API.
 */
function saiap_ajax_get_schedule() {
    check_ajax_referer( 'saiap_scheduler_nonce', 'nonce' );

    if ( ! current_user_can( 'manage_options' ) ) {
        wp_send_json_error( 'Unauthorized' );
    }

    $license_key = get_option( 'saiap_license_key' );
    $domain = saiap_get_server_host();

    if ( empty( $license_key ) ) {
        wp_send_json_error( 'Missing license key.' );
    }

    $url = add_query_arg(
        array(
            'license_key' => $license_key,
            'domain'      => $domain,
        ),
        SAIAP_PREMIUM_API_URL . '/api/prompts/list'
    );

    $response = wp_remote_get( $url, array( 'timeout' => 15 ) );

    if ( is_wp_error( $response ) ) {
        wp_send_json_error( $response->get_error_message() );
    }

    $body = wp_remote_retrieve_body( $response );
    $data = json_decode( $body, true );

    if ( wp_remote_retrieve_response_code( $response ) !== 200 ) {
        wp_send_json_error( $data );
    }

    wp_send_json_success( $data['prompts'] );
}
add_action( 'wp_ajax_saiap_get_schedule', 'saiap_ajax_get_schedule' );

/**
 * AJAX handler to update a scheduled prompt.
 */
function saiap_ajax_update_prompt() {
    check_ajax_referer( 'saiap_scheduler_nonce', 'nonce' );

    if ( ! current_user_can( 'manage_options' ) ) {
        wp_send_json_error( 'Unauthorized' );
    }

    $prompt_id = isset( $_POST['prompt_id'] ) ? sanitize_text_field( wp_unslash( $_POST['prompt_id'] ) ) : '';
    $prompt_text = isset( $_POST['prompt_text'] ) ? sanitize_textarea_field( wp_unslash( $_POST['prompt_text'] ) ) : '';

    if ( empty( $prompt_id ) || empty( $prompt_text ) ) {
        wp_send_json_error( 'Missing prompt ID or text.' );
    }

    $license_key = get_option( 'saiap_license_key' );
    $domain = saiap_get_server_host();

    $url = SAIAP_PREMIUM_API_URL . '/api/prompts/update/' . $prompt_id;
    $response = wp_remote_request( $url, array(
        'method'  => 'PUT',
        'headers' => array( 'Content-Type' => 'application/json' ),
        'body'    => wp_json_encode( array(
            'license_key' => $license_key,
            'domain'      => $domain,
            'prompt'      => $prompt_text,
        ) ),
        'timeout' => 15,
    ) );

    if ( is_wp_error( $response ) ) {
        wp_send_json_error( $response->get_error_message() );
    }

    $body = wp_remote_retrieve_body( $response );
    $data = json_decode( $body, true );

    if ( wp_remote_retrieve_response_code( $response ) !== 200 ) {
        wp_send_json_error( $data );
    }

    if ( ! empty( $license_key ) && function_exists( 'saiap_premium_onboarding_mark_step_complete' ) ) {
        saiap_premium_onboarding_mark_step_complete( 4 );
    }

    wp_send_json_success( $data['prompt'] );
}
add_action( 'wp_ajax_saiap_update_prompt', 'saiap_ajax_update_prompt' );

/**
 * AJAX handler to regenerate a scheduled prompt.
 */
function saiap_ajax_regenerate_prompt() {
    check_ajax_referer( 'saiap_scheduler_nonce', 'nonce' );

    if ( ! current_user_can( 'manage_options' ) ) {
        wp_send_json_error( 'Unauthorized' );
    }

    $prompt_id = isset( $_POST['prompt_id'] ) ? sanitize_text_field( wp_unslash( $_POST['prompt_id'] ) ) : '';

    if ( empty( $prompt_id ) ) {
        wp_send_json_error( 'Missing prompt ID.' );
    }

    $license_key = get_option( 'saiap_license_key' );
    $domain = saiap_get_server_host();

    $url = SAIAP_PREMIUM_API_URL . '/api/prompts/regenerate/' . $prompt_id;
    $response = wp_remote_post( $url, array(
        'headers' => array( 'Content-Type' => 'application/json' ),
        'body'    => wp_json_encode( array(
            'license_key' => $license_key,
            'domain'      => $domain,
        ) ),
        'timeout' => 30, // Regeneration can take longer
    ) );

    if ( is_wp_error( $response ) ) {
        wp_send_json_error( $response->get_error_message() );
    }

    $body = wp_remote_retrieve_body( $response );
    $data = json_decode( $body, true );

    if ( wp_remote_retrieve_response_code( $response ) !== 200 ) {
        wp_send_json_error( $data );
    }

    wp_send_json_success( $data['prompt'] );
}
add_action( 'wp_ajax_saiap_regenerate_prompt', 'saiap_ajax_regenerate_prompt' );

/**
 * AJAX handler to create a new scheduled prompt.
 */
function saiap_ajax_create_prompt() {
    check_ajax_referer( 'saiap_scheduler_nonce', 'nonce' );

    if ( ! current_user_can( 'manage_options' ) ) {
        wp_send_json_error( 'Unauthorized' );
    }

    $prompt_text = isset( $_POST['prompt_text'] ) ? sanitize_textarea_field( wp_unslash( $_POST['prompt_text'] ) ) : '';
    $scheduled_date = isset( $_POST['scheduled_date'] ) ? sanitize_text_field( wp_unslash( $_POST['scheduled_date'] ) ) : '';

    if ( empty( $prompt_text ) || empty( $scheduled_date ) ) {
        wp_send_json_error( 'Missing prompt text or scheduled date.' );
    }

    $license_key = get_option( 'saiap_license_key' );
    $domain = saiap_get_server_host();

    // The API expects a full ISO 8601 timestamp. We'll append a time.
    // We'll use the site's timezone to interpret the date. If the chosen time for today
    // has already passed, schedule a few minutes in the future so it appears in the list window.
    $site_tz = new DateTimeZone( wp_timezone_string() );
    $scheduled_at_datetime = new DateTime( $scheduled_date . ' 10:00:00', $site_tz );
    $now_site = new DateTime( 'now', $site_tz );
    if ( $scheduled_at_datetime <= $now_site ) {
        $scheduled_at_datetime = ( clone $now_site )->modify( '+5 minutes' );
    }
    
    $url = SAIAP_PREMIUM_API_URL . '/api/prompts/generate';
    $response = wp_remote_post( $url, array(
        'headers' => array( 'Content-Type' => 'application/json' ),
        'body'    => wp_json_encode( array(
            'license_key'  => $license_key,
            'domain'       => $domain,
            'prompt'       => $prompt_text,
            'scheduled_at' => $scheduled_at_datetime->format( DateTime::ATOM ), // ISO8601 format
        ) ),
        'timeout' => 15,
    ) );

    if ( is_wp_error( $response ) ) {
        wp_send_json_error( $response->get_error_message() );
    }

    $body = wp_remote_retrieve_body( $response );
    $data = json_decode( $body, true );

    if ( ! in_array( wp_remote_retrieve_response_code( $response ), array( 200, 201 ), true ) ) {
        wp_send_json_error( $data );
    }

    if ( ! empty( $license_key ) && function_exists( 'saiap_premium_onboarding_mark_step_complete' ) ) {
        saiap_premium_onboarding_mark_step_complete( 4 );
    }

    wp_send_json_success( $data['prompt'] );
}
add_action( 'wp_ajax_saiap_create_prompt', 'saiap_ajax_create_prompt' );

/**
 * AJAX handler to generate research ideas.
 */
function saiap_ajax_generate_research() {
    check_ajax_referer( 'saiap_scheduler_nonce', 'nonce' );

    if ( ! current_user_can( 'manage_options' ) ) {
        wp_send_json_error( 'Unauthorized' );
    }

    $prompt = isset( $_POST['prompt'] ) ? sanitize_textarea_field( wp_unslash( $_POST['prompt'] ) ) : '';

    if ( empty( $prompt ) ) {
        wp_send_json_error( 'Missing research prompt.' );
    }

    $license_key = get_option( 'saiap_license_key' );
    $domain = saiap_get_server_host();
    $site_context_data = get_option( 'saiap_site_context_data' );

    $site_context_string = '';
    if ( is_array( $site_context_data ) && ! empty( $site_context_data ) ) {
        $context_parts = array();
        if ( ! empty( $site_context_data['summary'] ) ) {
            $context_parts[] = 'Summary: ' . $site_context_data['summary'];
        }
        if ( ! empty( $site_context_data['topics'] ) && is_array( $site_context_data['topics'] ) ) {
            $context_parts[] = 'Topics: ' . implode( ', ', $site_context_data['topics'] );
        }
        $site_context_string = implode( "\n", $context_parts );
    }

    $token_url = SAIAP_PREMIUM_API_URL . '/api/research/token';
    $token_resp = wp_remote_post( $token_url, array(
        'headers' => array( 'Content-Type' => 'application/json' ),
        'body'    => wp_json_encode( array(
            'license_key' => $license_key,
            'domain'      => $domain,
        ) ),
        'timeout' => 15,
    ) );

    if ( is_wp_error( $token_resp ) ) {
        wp_send_json_error( $token_resp->get_error_message() );
    }
    $token_body = json_decode( wp_remote_retrieve_body( $token_resp ), true );
    if ( wp_remote_retrieve_response_code( $token_resp ) !== 200 || empty( $token_body['token'] ) ) {
        wp_send_json_error( $token_body );
    }

    // Fallback path: use non-streaming one-shot call when streaming is unavailable or fails
    $url = SAIAP_PREMIUM_API_URL . '/api/research/generate';
    $response = wp_remote_post( $url, array(
        'headers' => array( 'Content-Type' => 'application/json', 'Authorization' => 'Bearer ' . $token_body['token'] ),
        'body'    => wp_json_encode( array(
            'license_key'  => $license_key,
            'domain'       => $domain,
            'prompt'       => $prompt,
            'siteContext'  => $site_context_string,
        ) ),
        'timeout' => 90, // Temporary bump
    ) );

    if ( is_wp_error( $response ) ) {
        wp_send_json_error( $response->get_error_message() );
    }

    $body = wp_remote_retrieve_body( $response );
    $data = json_decode( $body, true );

    if ( ! in_array( wp_remote_retrieve_response_code( $response ), array( 200, 201 ), true ) ) {
        wp_send_json_error( $data );
    }

    if ( ! empty( $license_key ) && function_exists( 'saiap_premium_onboarding_mark_step_complete' ) ) {
        saiap_premium_onboarding_mark_step_complete( 3 );
    }

    wp_send_json_success( $data['data'] );
}
add_action( 'wp_ajax_saiap_generate_research', 'saiap_ajax_generate_research' );

/**
 * AJAX handler to fetch research topic recommendations (3 max).
 * Tries premium ideas endpoint; falls back to local site context topics.
 */
function saiap_get_research_recommendations() {
    check_ajax_referer( 'saiap_scheduler_nonce', 'nonce' );

    if ( ! current_user_can( 'manage_options' ) ) {
        wp_send_json_error( 'Unauthorized' );
    }

    $license_key = get_option( 'saiap_license_key' );
    $domain      = saiap_get_server_host();

    $topics = array();

    if ( ! empty( $license_key ) ) {
        $url      = SAIAP_PREMIUM_API_URL . '/api/ideas/generate';
        $response = wp_remote_post( $url, array(
            'headers' => array( 'Content-Type' => 'application/json' ),
            'body'    => wp_json_encode( array(
                'license_key' => $license_key,
                'domain'      => $domain,
            ) ),
            'timeout' => 20,
        ) );

        if ( ! is_wp_error( $response ) && 200 === wp_remote_retrieve_response_code( $response ) ) {
            $body = json_decode( wp_remote_retrieve_body( $response ), true );
            if ( isset( $body['ideas'] ) && is_array( $body['ideas'] ) ) {
                foreach ( $body['ideas'] as $idea ) {
                    if ( isset( $idea['title'] ) && $idea['title'] ) {
                        $topics[] = sanitize_text_field( $idea['title'] );
                    }
                    if ( count( $topics ) >= 3 ) {
                        break;
                    }
                }
            }
        }
    }

    if ( empty( $topics ) ) {
        $site_context_data = get_option( 'saiap_site_context_data' );
        if ( is_array( $site_context_data ) && ! empty( $site_context_data['topics'] ) && is_array( $site_context_data['topics'] ) ) {
            $topics = array_slice( array_map( 'sanitize_text_field', $site_context_data['topics'] ), 0, 3 );
        }
    }

    if ( empty( $topics ) ) {
        wp_send_json_error( 'No recommendations available.' );
    }

    wp_send_json_success( array( 'topics' => array_values( $topics ) ) );
}
add_action( 'wp_ajax_saiap_get_research_recommendations', 'saiap_get_research_recommendations' );

/**
 * AJAX handler to fetch a short-lived research stream token for the browser.
 */
function saiap_ajax_get_stream_token() {
    check_ajax_referer( 'saiap_scheduler_nonce', 'nonce' );

    if ( ! current_user_can( 'manage_options' ) ) {
        wp_send_json_error( 'Unauthorized' );
    }

    $license_key = get_option( 'saiap_license_key' );
    $domain      = saiap_get_server_host();

    if ( empty( $license_key ) ) {
        wp_send_json_error( 'Missing license key.' );
    }

    $token_url = SAIAP_PREMIUM_API_URL . '/api/research/token';
    $token_resp = wp_remote_post( $token_url, array(
        'headers' => array( 'Content-Type' => 'application/json' ),
        'body'    => wp_json_encode( array(
            'license_key' => $license_key,
            'domain'      => $domain,
        ) ),
        'timeout' => 15,
    ) );

    if ( is_wp_error( $token_resp ) ) {
        wp_send_json_error( $token_resp->get_error_message() );
    }

    $code = wp_remote_retrieve_response_code( $token_resp );
    $body = json_decode( wp_remote_retrieve_body( $token_resp ), true );

    if ( 200 !== $code || empty( $body['token'] ) ) {
        wp_send_json_error( $body );
    }

    wp_send_json_success( array(
        'token'    => $body['token'],
        'domain'   => $domain,
        'base_url' => SAIAP_PREMIUM_API_URL,
    ) );
}
add_action( 'wp_ajax_saiap_get_stream_token', 'saiap_ajax_get_stream_token' );

/**
 * Schedule the daily cron job for generating posts.
 */
function saiap_schedule_daily_post_generation() {
    if ( ! wp_next_scheduled( 'saiap_generate_scheduled_post' ) ) {
        // Schedule to run daily
        wp_schedule_event( strtotime( '10:00:00' ), 'daily', 'saiap_generate_scheduled_post' );
    }
}
add_action( 'init', 'saiap_schedule_daily_post_generation' );

/**
 * The main function for the daily cron job.
 *
 * This function will be responsible for fetching due prompts
 * and creating posts from them.
 */
function saiap_do_generate_scheduled_post() {
    $license_key = get_option( 'saiap_license_key' );
    $domain = saiap_get_server_host();
    $run_id = wp_generate_uuid4();
    $start_time = microtime( true );

    // Report scheduler start to premium backend.
    saiap_report_scheduler_heartbeat( $domain, $license_key, array(
        'event'   => 'scheduler_started',
        'run_id'  => $run_id,
        'php_version' => PHP_VERSION,
        'wp_version'  => get_bloginfo( 'version' ),
        'memory_limit' => ini_get( 'memory_limit' ),
        'max_execution_time' => ini_get( 'max_execution_time' ),
    ) );

    // 1. Fetch today's scheduled prompts
    $url = add_query_arg(
        array(
            'license_key' => $license_key,
            'domain'      => $domain,
        ),
        SAIAP_PREMIUM_API_URL . '/api/prompts/list/today'
    );

    $response = wp_remote_get( $url, array( 'timeout' => 15 ) );

    if ( is_wp_error( $response ) ) {
        saiap_report_scheduler_heartbeat( $domain, $license_key, array(
            'event'   => 'scheduler_error',
            'run_id'  => $run_id,
            'error'   => 'fetch_failed',
            'message' => $response->get_error_message(),
            'duration_ms' => round( ( microtime( true ) - $start_time ) * 1000 ),
        ) );
        return;
    }

    $status_code = wp_remote_retrieve_response_code( $response );
    if ( 200 !== $status_code ) {
        saiap_report_scheduler_heartbeat( $domain, $license_key, array(
            'event'   => 'scheduler_error',
            'run_id'  => $run_id,
            'error'   => 'fetch_non_200',
            'status_code' => $status_code,
            'body'    => substr( wp_remote_retrieve_body( $response ), 0, 500 ),
            'duration_ms' => round( ( microtime( true ) - $start_time ) * 1000 ),
        ) );
        return;
    }

    $prompts = json_decode( wp_remote_retrieve_body( $response ), true );
    if ( empty( $prompts['prompts'] ) ) {
        saiap_report_scheduler_heartbeat( $domain, $license_key, array(
            'event'   => 'scheduler_completed',
            'run_id'  => $run_id,
            'prompts_found' => 0,
            'posts_generated' => 0,
            'posts_failed' => 0,
            'duration_ms' => round( ( microtime( true ) - $start_time ) * 1000 ),
        ) );
        return;
    }

    // Track results for heartbeat.
    $posts_generated = 0;
    $posts_failed = 0;
    $prompt_count = count( $prompts['prompts'] );

    // 2. Loop through prompts and generate posts
    foreach ( $prompts['prompts'] as $prompt ) {
        $status_to_set = 'completed';
        $wp_post_id    = null;
        try {
            // Use default provider and model settings for generation. Fall back
            // through saiap_get_model_for_provider() so a missing option (which
            // shouldn't happen post-activation but has been seen in the wild)
            // still sends a real model string to the backend.
            $provider = get_option( 'saiap_default_provider', 'openai' );
            $model    = saiap_get_model_for_provider( $provider );

            $args = array(
                'prompt'        => $prompt['prompt'],
                'provider'      => $provider,
                'model'         => $model,
                'post_type'     => get_option( 'saiap_post_type', 'post' ),
                'title'         => '', // Let the orchestrator generate it
                'custom_fields' => array(),
                'content_brief' => isset( $prompt['content_brief'] ) ? $prompt['content_brief'] : '',
            );

            $result = saiap_orchestrate_post_creation( $args );

            if ( is_wp_error( $result ) ) {
                $status_to_set = 'failed';
                /**
                 * Fires when scheduled post generation fails.
                 *
                 * @since 1.1.9
                 * @param array $prompt Prompt payload
                 * @param WP_Error $error Error object
                 */
                do_action( 'saiap_scheduler_post_generation_failed', $prompt, $result );
            } else {
                // Capture post ID for calendar sync
                if ( ! empty( $result['post_id'] ) ) {
                    $wp_post_id = absint( $result['post_id'] );
                }

                // Set status based on whether the post was published or is a draft
                if ( isset( $result['post_status'] ) && 'publish' === $result['post_status'] ) {
                    $status_to_set = 'published';
                } else {
                    $status_to_set = 'pending_review';
                }

                // On success, optionally notify via email (default: yes for new installs)
                $notify = get_option( 'saiap_notify_on_schedule', 'yes' );
                if ( 'yes' === $notify && ! empty( $result['post_id'] ) ) {
                    $post_id   = absint( $result['post_id'] );
                    $post      = get_post( $post_id );
                    $site_name = wp_specialchars_decode( get_bloginfo( 'name' ), ENT_QUOTES );
                    $edit_url  = get_edit_post_link( $post_id, '' );
                    if ( empty( $edit_url ) ) {
                        // Cron may lack a user context; fall back to admin edit URL which will prompt login if needed
                        $edit_url = admin_url( 'post.php?post=' . $post_id . '&action=edit' );
                    }

                    // Build recipients from option (CSV), sanitize, dedupe
                    $raw_recipients = get_option( 'saiap_notify_recipients', get_option( 'admin_email', '' ) );
                    $emails = array_filter( array_map( 'trim', explode( ',', (string) $raw_recipients ) ) );
                    $emails = array_unique( array_values( array_filter( $emails, 'is_email' ) ) );

                    if ( ! empty( $emails ) ) {
                        // Subject and body with i18n
                        $subject = sprintf(
                            /* translators: %s: post title */
                            __( 'ClearPost: New AI draft — %s', 'clearpost-simple-ai-auto-post' ),
                            $post ? $post->post_title : __( '(untitled)', 'clearpost-simple-ai-auto-post' )
                        );

                        // Created at in site timezone
                        $tz      = wp_timezone();
                        $created = new DateTime( 'now', $tz );
                        $created_str = $created->format( 'Y-m-d H:i' );

                        // Determine status label for email
                        $post_status_label = ( isset( $result['post_status'] ) && 'publish' === $result['post_status'] )
                            ? __( 'Published', 'clearpost-simple-ai-auto-post' )
                            : __( 'Draft', 'clearpost-simple-ai-auto-post' );

                        $body_lines = array(
                            /* translators: %s: site name */
                            sprintf( __( 'Site: %s', 'clearpost-simple-ai-auto-post' ), $site_name ),
                            /* translators: %s: post title */
                            sprintf( __( 'Title: %s', 'clearpost-simple-ai-auto-post' ), $post ? $post->post_title : '' ),
                            /* translators: %s: post status */
                            sprintf( __( 'Status: %s', 'clearpost-simple-ai-auto-post' ), $post_status_label ),
                            /* translators: %s: created date/time */
                            sprintf( __( 'Created: %s', 'clearpost-simple-ai-auto-post' ), $created_str ),
                            /* translators: %s: edit URL */
                            sprintf( __( 'Edit link: %s', 'clearpost-simple-ai-auto-post' ), $edit_url ),
                            '',
                            ( 'publish' === ( $result['post_status'] ?? '' ) )
                                ? __( 'This post was generated and published by ClearPost.', 'clearpost-simple-ai-auto-post' )
                                : __( 'This draft was generated by ClearPost. Review, edit, and publish when ready.', 'clearpost-simple-ai-auto-post' ),
                        );

                        $email_payload = array(
                            'recipients' => $emails,
                            'subject'    => $subject,
                            'body'       => implode( "\n", $body_lines ),
                            'headers'    => array( 'Content-Type: text/plain; charset=UTF-8' ),
                        );

                        /**
                         * Filter the scheduler notification email payload.
                         *
                         * @since 1.1.9
                         * @param array $email_payload { recipients, subject, body, headers }
                         * @param int $post_id Generated post ID
                         * @param array $prompt Prompt payload
                         */
                        $email_payload = apply_filters( 'saiap_scheduler_notification_email', $email_payload, $post_id, $prompt );

                        if ( ! empty( $email_payload['recipients'] ) && ! empty( $email_payload['subject'] ) && isset( $email_payload['body'] ) ) {
                            // Per-post notifications via wp_mail() are disabled by default. The
                            // backend now ships a Resend-backed digest path (one ranked email
                            // per site per day, authenticated, logged, much higher
                            // deliverability) — see wp-autopost-premium ResendService::
                            // sendPostReviewDigest. Two notification paths firing in parallel
                            // produces duplicate inbox noise, so we gate the legacy wp_mail()
                            // path behind an opt-in option that defaults to false. Anyone who
                            // has a working SMTP plugin and wants the per-post cadence back can
                            // run update_option('saiap_notify_via_wp_mail', true).
                            if ( get_option( 'saiap_notify_via_wp_mail', false ) ) {
                                // Send the email (one message, multiple recipients)
                                wp_mail( (array) $email_payload['recipients'], (string) $email_payload['subject'], (string) $email_payload['body'], (array) ( $email_payload['headers'] ?? array() ) );
                            }
                        }
                    }
                }

                /**
                 * Fires when a scheduled post was generated successfully.
                 *
                 * @since 1.1.9
                 * @param array $prompt Prompt payload
                 * @param array $result Result from orchestrator (post_id, edit_url)
                 */
                do_action( 'saiap_scheduler_post_generated', $prompt, $result );
            }

        } catch ( Exception $e ) {
            $status_to_set = 'failed';
            do_action( 'saiap_scheduler_post_generation_failed', $prompt, new WP_Error( 'scheduler_exception', $e->getMessage() ) );
        }

        // Track success/failure for heartbeat.
        if ( 'failed' === $status_to_set ) {
            $posts_failed++;
        } else {
            $posts_generated++;
        }

        // 3. Update the prompt status on the premium service
        $update_url = SAIAP_PREMIUM_API_URL . '/api/prompts/update/' . $prompt['id'] . '/status';
        $update_body = array(
            'license_key' => $license_key,
            'domain'      => $domain,
            'status'      => $status_to_set,
        );

        // Include WordPress post ID for calendar sync
        if ( $wp_post_id ) {
            $update_body['wp_post_id'] = $wp_post_id;
        }

        wp_remote_request( $update_url, array(
            'method'  => 'PUT',
            'headers' => array( 'Content-Type' => 'application/json' ),
            'body'    => wp_json_encode( $update_body ),
            'timeout' => 15,
        ) );
    }

    // Report scheduler completion to premium backend.
    saiap_report_scheduler_heartbeat( $domain, $license_key, array(
        'event'           => 'scheduler_completed',
        'run_id'          => $run_id,
        'prompts_found'   => $prompt_count,
        'posts_generated' => $posts_generated,
        'posts_failed'    => $posts_failed,
        'duration_ms'     => round( ( microtime( true ) - $start_time ) * 1000 ),
    ) );
}
add_action( 'saiap_generate_scheduled_post', 'saiap_do_generate_scheduled_post' );

/**
 * Report scheduler heartbeat to premium backend for diagnostics.
 *
 * Fire-and-forget - we don't wait for response or handle errors.
 *
 * @param string $domain      Site domain.
 * @param string $license_key License key.
 * @param array  $data        Heartbeat data.
 */
function saiap_report_scheduler_heartbeat( $domain, $license_key, $data ) {
    $url = SAIAP_PREMIUM_API_URL . '/api/scheduler/heartbeat';

    $payload = array_merge(
        array(
            'domain'      => $domain,
            'license_key' => $license_key,
            'timestamp'   => gmdate( 'c' ),
        ),
        $data
    );

    // Fire and forget - don't block on response.
    wp_remote_post(
        $url,
        array(
            'headers'  => array( 'Content-Type' => 'application/json' ),
            'body'     => wp_json_encode( $payload ),
            'timeout'  => 5,
            'blocking' => false,
        )
    );
}

/**
 * Sync calendar status when a ClearPost-generated post is manually published.
 *
 * This hooks into WordPress post status transitions to detect when a user
 * publishes a draft that was created by ClearPost. It then updates the
 * calendar item status from 'pending_review' to 'published'.
 *
 * @since 1.3.0
 * @param string  $new_status New post status.
 * @param string  $old_status Old post status.
 * @param WP_Post $post       Post object.
 */
function saiap_sync_calendar_on_publish( $new_status, $old_status, $post ) {
    // Only process draft → publish transitions
    if ( 'publish' !== $new_status || 'draft' !== $old_status ) {
        return;
    }

    // Only process posts generated by ClearPost
    $is_generated = get_post_meta( $post->ID, '_saiap_generated', true );
    if ( ! $is_generated ) {
        return;
    }

    // Need either a license key or an active trial to call the API
    $license_key = get_option( 'saiap_license_key' );
    $has_trial = function_exists( 'saiap_is_trial_active' ) && saiap_is_trial_active();

    if ( empty( $license_key ) && ! $has_trial ) {
        return;
    }

    $domain = saiap_get_server_host();

    // Call the premium service to update calendar status by wp_post_id
    $update_url = SAIAP_PREMIUM_API_URL . '/api/prompts/update-by-wp-post-id';

    // Build request body - only include license_key if not empty
    $request_body = array(
        'domain'     => $domain,
        'status'     => 'published',
        'wp_post_id' => $post->ID,
    );
    if ( ! empty( $license_key ) ) {
        $request_body['license_key'] = $license_key;
    }

    $response = wp_remote_request( $update_url, array(
        'method'  => 'PUT',
        'headers' => array( 'Content-Type' => 'application/json' ),
        'body'    => wp_json_encode( $request_body ),
        'timeout' => 15,
    ) );

    if ( is_wp_error( $response ) ) {
        // Fail silently - this is a non-critical sync
        return;
    }

    $body = json_decode( wp_remote_retrieve_body( $response ), true );
    if ( ! empty( $body['updated'] ) ) {
        /**
         * Fires when a ClearPost-generated post is manually published and calendar is synced.
         *
         * @since 1.3.0
         * @param int   $post_id Post ID that was published.
         * @param array $body    Response from calendar sync API.
         */
        do_action( 'saiap_calendar_synced_on_publish', $post->ID, $body );
    }
}
add_action( 'transition_post_status', 'saiap_sync_calendar_on_publish', 10, 3 );