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

function easy_gpt_bulk_generations_view_page() {
    global $wpdb;
    $table_name = $wpdb->prefix . 'bulk_generations';
    
    // Definiendo la paginación
    $per_page     = 20;  // Número de registros por página
    $current_page = isset( $_GET['paged'] ) ? max( 1, intval( $_GET['paged'] ) ) : 1;
    $offset       = ( $current_page - 1 ) * $per_page;
    
    // Obtenemos las generaciones por lote
    $bulk_generations = easy_gpt_get_bulk_generations( $per_page, $offset );
    
    // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- El nombre de la tabla es seguro y no puede ser parametrizado
    $total_query = "SELECT COUNT(1) FROM `{$table_name}`";
    $total       = $wpdb->get_var( $total_query );
    $total_pages = ceil( $total / $per_page );

    // Comienza a escribir el contenido de la página
    echo '<div class="wrap"><h1 class="wp-heading-inline">' . esc_html__('View Bulk Generations', 'easy-gpt-for-wp') . '</h1>';
    echo '<a href="' . esc_url(admin_url('admin.php?page=easy-gpt-bulk-generate-new')) . '">' . esc_html__('Add New Bulk Generation', 'easy-gpt-for-wp') . '</a>';
    echo '<form id="bulk-action-form" method="post" class="bulk-action-form">';
    echo '<input type="hidden" name="action" value="bulk_delete_generations">';
    echo '<table class="wp-list-table widefat fixed striped">';
    echo '<thead>';
    echo '<tr>';
    echo '<th scope="col" id="cb" class="manage-column column-cb check-column"><input type="checkbox" /></th>';  // Checkbox para seleccionar todos
    echo '<th scope="col" id="id" class="manage-column column-id">' . esc_html__('ID', 'easy-gpt-for-wp') . '</th>';
    echo '<th scope="col" id="date" class="manage-column column-date">' . esc_html__('Date', 'easy-gpt-for-wp') . '</th>';
    echo '<th scope="col" id="user" class="manage-column column-user">' . esc_html__('User', 'easy-gpt-for-wp') . '</th>';
    echo '<th scope="col" id="status" class="manage-column column-status">' . esc_html__('Status', 'easy-gpt-for-wp') . '</th>';
    echo '<th scope="col" id="articles" class="manage-column column-articles">' . esc_html__('Articles (Requested/Done)', 'easy-gpt-for-wp') . '</th>';
	echo '<th scope="col">' . esc_html__('Mode', 'easy-gpt-for-wp') . '</th>';
	echo '<th scope="col">' . esc_html__('Publishing', 'easy-gpt-for-wp') . '</th>';
    echo '<th scope="col" id="cost" class="manage-column column-cost">' . esc_html__('Cost', 'easy-gpt-for-wp') . '</th>';
    echo '<th scope="col" id="actions" class="manage-column column-actions">' . esc_html__('Actions', 'easy-gpt-for-wp') . '</th>';  // Columna para acciones
    echo '</tr>';
    echo '</thead>';
    echo '<tbody id="the-list">';

    if (!empty($bulk_generations)) {
        foreach ($bulk_generations as $generation) {
			echo '<tr>';
			echo '<td><input type="checkbox" name="generation[]" value="' . esc_attr($generation['id']) . '" /></td>';
			echo '<td><a href="#" class="generation-id-link" data-generation-id="' . esc_attr($generation['id']) . '">' . esc_html($generation['id']) . '</a></td>';
			echo '<td>' . esc_html( get_date_from_gmt( $generation['date_created'], 'Y-m-d H:i:s' ) ) . '</td>';
			echo '<td>' . esc_html(get_userdata($generation['user_id'])->display_name) . '</td>';
			echo '<td>' . esc_html($generation['status']) . '</td>';
			echo '<td>' . esc_html($generation['num_articles']) . '/' . esc_html($generation['articles_generated']) . '</td>';
			echo '<td>' . ($generation['just_in_time_generation'] ? 'Just-in-Time' : 'Pre-Generated') . '</td>';
			$publish_action = $generation['publish_action'] ?? 'save_draft';

			if ($publish_action === 'publish_immediately') {
				$publishing_label = 'Publish';
				$publishing_detail = '';
			} elseif ($publish_action === 'save_draft') {
				$publishing_label = 'Draft';
				$publishing_detail = '';
			} else { // schedule
				$publishing_label = 'Scheduled';
				$start_dt = trim(($generation['start_date'] ?? '') . ' ' . ($generation['start_time'] ?? ''));
				$freq = $generation['publish_frequency'] ?? 'daily';
				$api = intval($generation['articles_per_interval'] ?? 1);
				$mba = intval($generation['minutes_between_articles'] ?? 0);

				$publishing_detail = $start_dt
					? ('Starts: ' . esc_html($start_dt) . ' | ' . strtoupper($freq) . ' | ' . $api . '/interval' . ($mba ? (' | +' . $mba . 'm') : ''))
					: ('Frequency: ' . strtoupper($freq));
			}

			/* ---------------------------------------------------
			   ✅ Detectar overrides en tareas PENDING
			----------------------------------------------------*/

			$pending_rows = $wpdb->get_results(
				$wpdb->prepare(
					"SELECT article_params 
					 FROM {$wpdb->prefix}article_generation_tasks 
					 WHERE generation_id = %d AND status = 'pending'",
					$generation['id']
				),
				ARRAY_A
			);

			$cnt_publish = 0;
			$cnt_draft   = 0;
			$cnt_sched   = 0;

			if (is_array($pending_rows)) {
				foreach ($pending_rows as $row) {
					$p = json_decode($row['article_params'] ?? '', true);
					$a = is_array($p) ? ($p['publish_action'] ?? '') : '';

					if ($a === 'publish_immediately') {
						$cnt_publish++;
					} elseif ($a === 'schedule') {
						$cnt_sched++;
					} else {
						$cnt_draft++; // default o vacío
					}
				}
			}

			$default_action = $publish_action;

			$overrides = [];

			if ($default_action !== 'publish_immediately' && $cnt_publish > 0) {
				$overrides[] = $cnt_publish . ' publish';
			}

			if ($default_action !== 'save_draft' && $cnt_draft > 0) {
				$overrides[] = $cnt_draft . ' draft';
			}

			if ($default_action !== 'schedule' && $cnt_sched > 0) {
				$overrides[] = $cnt_sched . ' scheduled';
			}

			$overrides_text = !empty($overrides)
				? 'Overrides (pending): ' . implode(', ', $overrides)
				: '';

			// Ejemplo simple (sin CSS fancy):
			echo '<td><strong>' . esc_html($publishing_label) . '</strong>'
			   . ($publishing_detail ? '<br><small>' . wp_kses_post($publishing_detail) . '</small>' : '')
			   . ($overrides_text ? '<br><small style="opacity:.85;">' . esc_html($overrides_text) . '</small>' : '')
			   . '</td>';			
			echo '<td>$' . esc_html(number_format($generation['total_cost'], 2)) . '</td>';
			echo '<td>';

			if (!in_array($generation['status'], ['completed', 'failed', 'cancelled', 'complete with errors'])) {
				echo '<button type="button" class="button-cancel" onclick="cancelGeneration(' . esc_js($generation['id']) . ')">' . esc_html__('Cancel', 'easy-gpt-for-wp') . '</button>';

				if ($generation['status'] === 'paused') {
					echo '<button type="button" class="button-resume" onclick="resumeGeneration(' . esc_js($generation['id']) . ')">' . esc_html__('Resume', 'easy-gpt-for-wp') . '</button>';
				} else {
					echo '<button type="button" class="button-pause" onclick="pauseGeneration(' . esc_js($generation['id']) . ')">' . esc_html__('Pause', 'easy-gpt-for-wp') . '</button>';
				}
			}

			/** ✅ Edit solo si hay tasks pending */
			$pending_count = (int) $wpdb->get_var( $wpdb->prepare(
				"SELECT COUNT(*) FROM {$wpdb->prefix}article_generation_tasks WHERE generation_id = %d AND status = 'pending'",
				$generation['id']
			));
			if ( $pending_count > 0 && !in_array($generation['status'], ['completed', 'cancelled']) ) {
				echo '<button type="button" class="button button-secondary easy-gpt-edit-generation" data-generation-id="' . esc_attr($generation['id']) . '" style="margin-right:10px;">Edit</button>';
			}

			echo '<button type="button" class="button-view" onclick="viewGenerationDetails(' . esc_js($generation['id']) . ')">' . esc_html__('View', 'easy-gpt-for-wp') . '</button>';

			if (in_array($generation['status'], ['failed', 'complete with errors'])) {
				echo '<button type="button" class="button-retry-lot" onclick="retryGeneration(' . esc_js($generation['id']) . ')">' . esc_html__('Retry Failed', 'easy-gpt-for-wp') . '</button>';
			}

			echo '</td>';
			echo '</tr>';
            // Nuevo TR para detalles
            echo '<tr id="details-' . esc_attr($generation['id']) . '" class="generation-details-row" style="display: none;">';
            echo '<td colspan="10">' . esc_html__('Loading...', 'easy-gpt-for-wp') . '</td>';
            echo '</tr>';
        }
    } else {
        echo '<tr><td colspan="10">' . esc_html__('No bulk generations found.', 'easy-gpt-for-wp') . '</td></tr>';
    }
    echo '</tbody>';
    echo '</table>';
    
    $timestamp = wp_next_scheduled( 'easy_gpt_process_pending_generations' );
    if ( $timestamp ) {
        $next_schedule = wp_date( 'Y-m-d H:i:s', $timestamp );
        // translators: %s is the next scheduled execution time.
        echo '<div>' . sprintf( esc_html__( 'Next scheduled execution is set for: %s', 'easy-gpt-for-wp' ), esc_html( $next_schedule ) ) . '</div>';
    } else {
        echo '<div>' . esc_html__( "No events scheduled for 'easy_gpt_process_pending_generations'.", 'easy-gpt-for-wp' ) . '</div>';
    }
    
    echo '<div class="actions-panel">';
    echo '<input type="submit"  class="button action delete-selected" value="' . esc_attr__('Delete Selected', 'easy-gpt-for-wp') . '">';
    $pagination = paginate_links([
        'base' => add_query_arg('paged', '%#%'),
        'format' => '?paged=%#%',
        'current' => $current_page,
        'total' => $total_pages,
        'prev_text'    => esc_html__('&laquo; Prev', 'easy-gpt-for-wp'),
        'next_text'    => esc_html__('Next &raquo;', 'easy-gpt-for-wp'),
        'type' => 'plain', // Esto mantiene los enlaces como antes, sin <ul> <li>
    ]);
    echo '<div class="pagination-wrap">' . wp_kses_post($pagination) . '</div>';
    echo '</div>';
    echo '</form>';
	echo '
	<div id="easy-gpt-edit-modal" style="display:none;">
	  <form id="easy-gpt-edit-form">
		<input type="hidden" name="generation_id" id="easy_gpt_edit_generation_id" value="" />

		<p>
		  <label><strong>Action after generation</strong></label><br>
		  <select name="publish_action" id="easy_gpt_edit_publish_action">
			<option value="publish_immediately">Publish Immediately</option>
			<option value="save_draft">Save as Draft</option>
			<option value="schedule">Schedule for Later</option>
		  </select>
		</p>

		<div id="easy_gpt_edit_schedule_options" style="display:none; margin-top:10px;">
		  <p>
			<label><strong>Frequency</strong></label><br>
			<select name="publish_frequency" id="easy_gpt_edit_publish_frequency">
			  <option value="daily">Daily</option>
			  <option value="weekly">Weekly</option>
			  <option value="monthly">Monthly</option>
			</select>
		  </p>

		  <p>
			<label><strong>Start Date</strong></label><br>
			<input type="date" name="start_date" id="easy_gpt_edit_start_date" />
		  </p>

		  <p>
			<label><strong>Start Time</strong></label><br>
			<input type="time" name="start_time" id="easy_gpt_edit_start_time" />
		  </p>

		  <p>
			<label><strong>Articles per Interval</strong></label><br>
			<input type="number" min="1" name="articles_per_interval" id="easy_gpt_edit_articles_per_interval" value="1" />
		  </p>

		  <p>
			<label><strong>Minutes Between Articles (same interval)</strong></label><br>
			<input type="number" min="0" name="minutes_between_articles" id="easy_gpt_edit_minutes_between_articles" value="0" />
		  </p>
		</div>

		<p style="margin-top:12px;">
		  <em>This will only affect articles that are still pending.</em>
		</p>
	  </form>
	</div>
	';
    echo '</div>'; 

	echo '
	<div id="easy-gpt-edit-task-modal" style="display:none;">
	  <form id="easy-gpt-edit-task-form">
		<input type="hidden" id="easy_gpt_edit_task_id" value="" />

		<p>
		  <label><strong>Prompt</strong></label><br>
		  <textarea id="easy_gpt_edit_task_prompt" rows="3" style="width:100%;"></textarea>
		</p>

		<p>
		  <label><strong>Keywords</strong></label><br>
		  <input type="text" id="easy_gpt_edit_task_keywords" style="width:100%;" />
		</p>

		<p>
		  <label><strong>Publish plan</strong></label><br>
		  <select id="easy_gpt_edit_task_publish_action" style="width:100%;">
			<option value="publish_immediately">Publish Immediately</option>
			<option value="save_draft">Save as Draft</option>
			<option value="schedule">Schedule for Later</option>
		  </select>
		</p>

		<div id="easy_gpt_edit_task_schedule_wrap" style="display:none;">
		  <p>
			<label><strong>Scheduled for</strong></label><br>
			<input type="datetime-local" id="easy_gpt_edit_task_scheduled_for" style="width:100%;" />
			<small>Timezone: site timezone</small>
		  </p>
		</div>

		<p style="margin-top:12px;">
		  <em>Only pending tasks can be edited.</em>
		</p>
	  </form>
	</div>
	';

    wp_enqueue_script('bulk-generation-js', plugins_url('../js/easy-gpt-bulk-list.js', __FILE__), array('jquery'), false, true);
	
	wp_enqueue_script('jquery-ui-dialog');
	wp_enqueue_style('wp-jquery-ui-dialog');

	wp_enqueue_script(
		'easy-gpt-bulk-edit-js',
		plugins_url('../js/easy-gpt-bulk-edit.js', __FILE__),
		array('jquery', 'jquery-ui-dialog'),
		'1.0.0',
		true
	);

	wp_localize_script('easy-gpt-bulk-edit-js', 'easyGptBulkEdit', array(
		'ajaxUrl' => admin_url('admin-ajax.php'),
		'nonce'   => wp_create_nonce('easy_gpt_bulk_edit_nonce'),
	));
}

function easy_gpt_cancel_task() {
    global $wpdb;

    $task_id = isset($_POST['task_id']) ? absint($_POST['task_id']) : 0;
    if (!$task_id) {
        wp_send_json_error(['message' => 'Invalid Task ID.']);
        return;
    }

    // Obtener generation_id de la tarea
    $generation_id = (int) $wpdb->get_var(
        $wpdb->prepare(
            "SELECT generation_id FROM {$wpdb->prefix}article_generation_tasks WHERE id = %d",
            $task_id
        )
    );

    $result = $wpdb->update(
        $wpdb->prefix . 'article_generation_tasks',
        ['status' => 'cancelled'],
        ['id' => $task_id]
    );

    if ($result !== false) {
        // ✅ Recalcular estado del lote
        if ($generation_id) {
            easy_gpt_recalculate_bulk_generation_status($generation_id);
        }

        wp_send_json_success(['message' => 'Task cancelled successfully.']);
    } else {
        wp_send_json_error(['message' => 'Failed to cancel task.']);
    }
}

// Hook para la función AJAX de WordPress
add_action('wp_ajax_cancel_task', 'easy_gpt_cancel_task');

add_action('wp_ajax_get_generation_details', 'easy_gpt_get_generation_details');

function easy_gpt_get_generation_details() {
    global $wpdb;
    $generation_id = isset($_POST['generation_id']) ? intval($_POST['generation_id']) : 0;

    if (!$generation_id) {
        wp_send_json_error(['message' => 'Invalid Generation ID.']);
        return;
    }

    $table_name = $wpdb->prefix . 'article_generation_tasks';
    $tasks = $wpdb->get_results($wpdb->prepare(
        "SELECT * FROM $table_name WHERE generation_id = %d ORDER BY id DESC",
        $generation_id
    ));

    // Datos del lote
    $just_in_time = $wpdb->get_var( $wpdb->prepare(
        "SELECT just_in_time_generation FROM {$wpdb->prefix}bulk_generations WHERE id = %d",
        $generation_id
    ) );

    $gen_publish_action = $wpdb->get_var( $wpdb->prepare(
        "SELECT publish_action FROM {$wpdb->prefix}bulk_generations WHERE id = %d",
        $generation_id
    ) );

    // Mostrar columna scheduled cuando el lote es schedule (independiente de JIT)
    $show_scheduled_for = false;

	if (is_array($tasks)) {
		foreach ($tasks as $t) {
			$p = json_decode($t->article_params, true);
			$task_action = is_array($p) ? ($p['publish_action'] ?? '') : '';
			if ($task_action === 'schedule' || !empty($t->scheduled_for)) {
				$show_scheduled_for = true;
				break;
			}
		}
	}

    if ($tasks) {
        ob_start();
        echo '<table class="wp-list-table widefat fixed">';
        echo '<thead>';
        echo '<tr>';
        echo '<th>Prompt | Keywords</th>';
        echo '<th>Status</th>';
        echo '<th>Publish plan</th>';
        if ( $show_scheduled_for ) {
            echo '<th>Scheduled For</th>';
        }
        echo '<th>Cost</th><th>Error Message</th><th>Actions</th>';
        echo '</tr>';
        echo '</thead>';

        echo '<tbody>';

        foreach ($tasks as $task) {
            $params = json_decode($task->article_params, true);
            if (!is_array($params)) {
                $params = [];
            }

            $prompt   = isset($params['prompt']) ? $params['prompt'] : '';
            $keywords = isset($params['keywords']) ? $params['keywords'] : '';

            $error_message = !empty($task->error_message) ? esc_html($task->error_message) : esc_html__('No error', 'easy-gpt-for-wp');

            // Status display
            $status_display = $task->status;

            // Publish plan por tarea (prioriza params, fallback al lote)
            $task_publish_action = $params['publish_action'] ?? $gen_publish_action ?? 'save_draft';

            $plan_label = 'Draft';
            $plan_extra = '';

            if ($task_publish_action === 'publish_immediately') {
                $plan_label = 'Publish';
            } elseif ($task_publish_action === 'save_draft') {
                $plan_label = 'Draft';
			} elseif ($task_publish_action === 'schedule') {
				$plan_label = 'Scheduled';
				$plan_extra = ''; // la fecha solo se muestra en "Scheduled For"
			}

            echo '<tr id="task-row-' . esc_attr($task->id) . '">';
            echo '<td>' . esc_html($prompt . ' | ' . $keywords) . '</td>';
            echo '<td class="status-cell">' . esc_html($status_display) . '</td>';
            echo '<td>' . esc_html($plan_label . $plan_extra) . '</td>';

            if ( $show_scheduled_for ) {
                $scheduled_for = !empty($task->scheduled_for) ? esc_html($task->scheduled_for) : esc_html__('Not scheduled', 'easy-gpt-for-wp');
                echo '<td>' . $scheduled_for . '</td>';
            }

            echo '<td>$' . esc_html(number_format((float)$task->cost, 2)) . '</td>';
            echo '<td>' . $error_message . '</td>';

            echo '<td>';
            if ($task->status === 'pending') {
                echo '<button type="button" class="button-cancel" onclick="cancelTask(' . esc_js($task->id) . ')">Cancel</button>';
				echo '<button type="button" class="button button-secondary easy-gpt-edit-task"
            data-task-id="' . esc_attr($task->id) . '">Edit</button> ';
            }
            if ($task->status === 'failed') {
                echo '<button type="button" class="button-retry" onclick="retryTask(' . esc_js($task->id) . ')">Retry</button>';
            }
            echo '</td>';

            echo '</tr>';
        }

        echo '</tbody>';
        echo '</table>';

        $output = ob_get_clean();
        wp_send_json_success(['html' => $output]);
    } else {
        wp_send_json_error(['message' => 'No tasks found for this generation.']);
    }
}

function easy_gpt_get_bulk_generations( $per_page = 10, $offset = 0 ) {
    global $wpdb;
    $table_name = $wpdb->prefix . 'bulk_generations';

    // Validate inputs
    $per_page = absint( $per_page );
    $offset   = absint( $offset );

    // Prepare the query with placeholders for LIMIT and OFFSET
    $query = $wpdb->prepare(
        "SELECT * FROM `{$table_name}` ORDER BY date_created DESC LIMIT %d OFFSET %d",
        $per_page,
        $offset
    );

    // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- Table name is safe and cannot be parameterized
    $results = $wpdb->get_results( $query, ARRAY_A );

    return $results;
}

add_action('wp_ajax_cancel_bulk_generation', 'easy_gpt_cancel_bulk_generation');

function easy_gpt_cancel_bulk_generation() {
    global $wpdb;
    $generation_id = isset($_POST['generation_id']) ? intval($_POST['generation_id']) : 0;

    if ($generation_id) {
        // Comienza una transacción para asegurar la integridad de los datos
        $wpdb->query('START TRANSACTION');

        // Actualizar el estado en bulk_generations
        $updated = $wpdb->update(
            $wpdb->prefix . 'bulk_generations',
            ['status' => 'cancelled'],
            ['id' => $generation_id]
        );

        // Verificar si la actualización fue exitosa
        if ($updated === false) {
            $wpdb->query('ROLLBACK'); // Revertir la transacción si falla
            wp_send_json_error(['message' => 'Failed to update bulk generation status.']);
        }

        // Cancelar los registros asociados pendientes en article_generation_tasks
        $updated_tasks = $wpdb->update(
            $wpdb->prefix . 'article_generation_tasks',
            ['status' => 'cancelled'],
            ['generation_id' => $generation_id, 'status' => 'pending']
        );

        if ($updated_tasks === false) {
            $wpdb->query('ROLLBACK'); // Revertir la transacción si falla
            wp_send_json_error(['message' => 'Failed to update associated tasks.']);
        }

        // Si todo va bien, hacer commit de la transacción
        $wpdb->query('COMMIT');
        wp_send_json_success(['message' => 'Generation and associated tasks cancelled successfully.']);
    } else {
        wp_send_json_error(['message' => 'Invalid Generation ID.']);
    }
}

add_action('wp_ajax_bulk_delete_generations', 'easy_gpt_bulk_delete_generations');

function easy_gpt_bulk_delete_generations() {
    global $wpdb;
    if (!current_user_can('delete_posts')) {
        wp_send_json_error(['message' => 'Insufficient permissions']);
    }

    $generation_ids = isset($_POST['generation_ids']) ? array_map('intval', $_POST['generation_ids']) : array();
    if (empty($generation_ids)) {
        wp_send_json_error(['message' => 'No generations selected']);
    }

    foreach ($generation_ids as $generation_id) {
        // Aquí implementarías la lógica para borrar cada generación
        // Asegúrate de iniciar una transacción si estás haciendo múltiples borrados
        $wpdb->query('START TRANSACTION');

        $deleted_tasks = $wpdb->delete($wpdb->prefix . 'article_generation_tasks', ['generation_id' => $generation_id]);
        $deleted_generation = $wpdb->delete($wpdb->prefix . 'bulk_generations', ['id' => $generation_id]);

        if ($deleted_tasks !== false && $deleted_generation !== false) {
            $wpdb->query('COMMIT');
        } else {
            $wpdb->query('ROLLBACK');
            wp_send_json_error(['message' => 'Failed to delete generation or associated tasks.']);
            return; // Detener el procesamiento si hay un fallo
        }
    }

    wp_send_json_success(['message' => 'Selected generations deleted successfully.']);
}


function easy_gpt_enqueue_admin_scripts($hook_suffix) {
    if ($hook_suffix == 'easy-gpt_page_easy-gpt-bulk-generate-view') {
        wp_enqueue_style('bulk-list-css', plugins_url('../styles/bulk-list.css', __FILE__));
    }
}
add_action('admin_enqueue_scripts', 'easy_gpt_enqueue_admin_scripts');

// Cancelar todo el lote, incluso si ya está en proceso
add_action('wp_ajax_cancel_bulk_generation_force', 'easy_gpt_cancel_bulk_generation_force');

function easy_gpt_cancel_bulk_generation_force() {
    global $wpdb;

    $generation_id = isset($_POST['generation_id']) ? absint($_POST['generation_id']) : 0;
    if (!$generation_id) {
        wp_send_json_error(['message' => 'Invalid Generation ID.']);
    }

    $wpdb->query('START TRANSACTION');

    // ✅ Permitir cancelar aunque el lote esté processing
    $updated_gen = $wpdb->query(
        $wpdb->prepare(
            "UPDATE {$wpdb->prefix}bulk_generations
             SET status = 'cancelled'
             WHERE id = %d
             AND status NOT IN ('completed', 'cancelled')",
            $generation_id
        )
    );

    if ($updated_gen === false) {
        $wpdb->query('ROLLBACK');
        wp_send_json_error(['message' => 'Failed to cancel generation.']);
    }

    // ✅ Cancelar SOLO las pendientes (dejar processing terminar)
    $updated_tasks = $wpdb->query(
        $wpdb->prepare(
            "UPDATE {$wpdb->prefix}article_generation_tasks
             SET status = 'cancelled'
             WHERE generation_id = %d
             AND status = 'pending'",
            $generation_id
        )
    );

    if ($updated_tasks === false) {
        $wpdb->query('ROLLBACK');
        wp_send_json_error(['message' => 'Failed to cancel pending tasks.']);
    }

    $wpdb->query('COMMIT');

    // ✅ Recalcular por si ya no queda nada por hacer
    if (function_exists('easy_gpt_recalculate_bulk_generation_status')) {
        easy_gpt_recalculate_bulk_generation_status($generation_id);
    }

    wp_send_json_success(['message' => 'Generation cancelled (pending tasks only).']);
}


// Pausar un lote en cualquier momento
add_action('wp_ajax_pause_bulk_generation', 'easy_gpt_pause_bulk_generation');

function easy_gpt_pause_bulk_generation() {
    global $wpdb;
    $generation_id = isset($_POST['generation_id']) ? intval($_POST['generation_id']) : 0;

    if ($generation_id) {
        $updated = $wpdb->update(
            $wpdb->prefix . 'bulk_generations',
            ['status' => 'paused'],
            ['id' => $generation_id]
        );

        if ($updated !== false) {
            wp_send_json_success(['message' => 'Generation paused successfully.']);
        } else {
            wp_send_json_error(['message' => 'Failed to pause generation.']);
        }
    } else {
        wp_send_json_error(['message' => 'Invalid Generation ID.']);
    }
}

add_action('wp_ajax_resume_bulk_generation', 'easy_gpt_resume_bulk_generation');

function easy_gpt_resume_bulk_generation() {
    global $wpdb;
    $generation_id = isset($_POST['generation_id']) ? intval($_POST['generation_id']) : 0;

    if ($generation_id) {
        $updated = $wpdb->update(
            $wpdb->prefix . 'bulk_generations',
            ['status' => 'pending'], // Cambiar el estado a pending para que el cron lo procese
            ['id' => $generation_id]
        );

        if ($updated !== false) {
            wp_send_json_success(['message' => 'Generation resumed successfully.']);
        } else {
            wp_send_json_error(['message' => 'Failed to resume generation.']);
        }
    } else {
        wp_send_json_error(['message' => 'Invalid Generation ID.']);
    }
}

add_action('wp_ajax_retry_failed_task', 'easy_gpt_retry_failed_task');
function easy_gpt_retry_failed_task() {
    global $wpdb;

    $task_id = isset($_POST['task_id']) ? intval($_POST['task_id']) : 0;
    if (!$task_id) {
        wp_send_json_error(['message' => 'Invalid Task ID']);
        return;
    }

    // Obtener la generación asociada a la tarea
    $generation_id = $wpdb->get_var(
        $wpdb->prepare(
            "SELECT generation_id FROM {$wpdb->prefix}article_generation_tasks WHERE id = %d AND status = 'failed'",
            $task_id
        )
    );

    if (!$generation_id) {
        wp_send_json_error(['message' => 'Task not found or not failed']);
        return;
    }

    // Actualizar la tarea a pending
    $updated = $wpdb->update(
        $wpdb->prefix . 'article_generation_tasks',
        ['status' => 'pending'],
        ['id' => $task_id]
    );

    if ($updated === false) {
        wp_send_json_error(['message' => 'Failed to update task']);
        return;
    }

    // Poner la generación asociada en 'processing'
    $wpdb->update(
        $wpdb->prefix . 'bulk_generations',
        ['status' => 'processing'],
        ['id' => $generation_id]
    );

    wp_send_json_success(['message' => 'Task set to pending and generation set to processing']);
}


add_action('wp_ajax_retry_failed_generation', 'easy_gpt_retry_failed_generation');
function easy_gpt_retry_failed_generation() {
    global $wpdb;

    $generation_id = isset($_POST['generation_id']) ? intval($_POST['generation_id']) : 0;
    if (!$generation_id) {
        wp_send_json_error(['message' => 'Invalid Generation ID']);
        return;
    }

    // Poner en pending las tareas fallidas
    $tasks_updated = $wpdb->update(
        $wpdb->prefix . 'article_generation_tasks',
        ['status' => 'pending'],
        ['generation_id' => $generation_id, 'status' => 'failed']
    );

    // Obtener el nuevo número de tareas pendientes
    $pending_tasks = $wpdb->get_var(
        $wpdb->prepare(
            "SELECT COUNT(*) FROM {$wpdb->prefix}article_generation_tasks WHERE generation_id = %d AND status = 'pending'",
            $generation_id
        )
    );

    // Si hay tareas pendientes, poner el lote en 'processing'
    if ($pending_tasks > 0) {
        $wpdb->update(
            $wpdb->prefix . 'bulk_generations',
            ['status' => 'processing'],
            ['id' => $generation_id]
        );
    }

    wp_send_json_success(['message' => 'Failed tasks set to pending']);
}


add_action('wp_ajax_easy_gpt_get_bulk_generation_edit', 'easy_gpt_get_bulk_generation_edit');

function easy_gpt_get_bulk_generation_edit() {
    if ( ! current_user_can('manage_options') ) {
        wp_send_json_error(['message' => 'Insufficient permissions']);
    }

    $nonce = isset($_POST['nonce']) ? sanitize_text_field(wp_unslash($_POST['nonce'])) : '';
    if ( ! wp_verify_nonce($nonce, 'easy_gpt_bulk_edit_nonce') ) {
        wp_send_json_error(['message' => 'Invalid nonce']);
    }

    global $wpdb;
    $generation_id = isset($_POST['generation_id']) ? absint($_POST['generation_id']) : 0;
    if ( ! $generation_id ) {
        wp_send_json_error(['message' => 'Invalid Generation ID']);
    }

    $gen = $wpdb->get_row($wpdb->prepare(
        "SELECT publish_action, publish_frequency, start_date, start_time, articles_per_interval, minutes_between_articles, status
         FROM {$wpdb->prefix}bulk_generations WHERE id = %d",
        $generation_id
    ), ARRAY_A);

    if ( ! $gen ) {
        wp_send_json_error(['message' => 'Generation not found']);
    }

    $pending_count = (int) $wpdb->get_var($wpdb->prepare(
        "SELECT COUNT(*) FROM {$wpdb->prefix}article_generation_tasks WHERE generation_id = %d AND status = 'pending'",
        $generation_id
    ));

    wp_send_json_success([
        'generation' => $gen,
        'pending_count' => $pending_count,
    ]);
}

add_action('wp_ajax_easy_gpt_save_bulk_generation_edit', 'easy_gpt_save_bulk_generation_edit');


function easy_gpt_save_bulk_generation_edit() {
    if ( ! current_user_can('manage_options') ) {
        wp_send_json_error(['message' => 'Insufficient permissions']);
    }

    $nonce = isset($_POST['nonce']) ? sanitize_text_field(wp_unslash($_POST['nonce'])) : '';
    if ( ! wp_verify_nonce($nonce, 'easy_gpt_bulk_edit_nonce') ) {
        wp_send_json_error(['message' => 'Invalid nonce']);
    }

    global $wpdb;

    $generation_id = isset($_POST['generation_id']) ? absint($_POST['generation_id']) : 0;
    if ( ! $generation_id ) {
        wp_send_json_error(['message' => 'Invalid Generation ID']);
    }

    $publish_action = isset($_POST['publish_action']) ? sanitize_text_field(wp_unslash($_POST['publish_action'])) : 'save_draft';
    $publish_frequency = isset($_POST['publish_frequency']) ? sanitize_text_field(wp_unslash($_POST['publish_frequency'])) : 'daily';
    $start_date = isset($_POST['start_date']) ? sanitize_text_field(wp_unslash($_POST['start_date'])) : '';
    $start_time = isset($_POST['start_time']) ? sanitize_text_field(wp_unslash($_POST['start_time'])) : '';
    $articles_per_interval = isset($_POST['articles_per_interval']) ? max(1, absint($_POST['articles_per_interval'])) : 1;
    $minutes_between = isset($_POST['minutes_between_articles']) ? max(0, absint($_POST['minutes_between_articles'])) : 0;

    if ($publish_action === 'schedule' && (empty($start_date) || empty($start_time))) {
        wp_send_json_error(['message' => 'Start date/time required for schedule']);
    }

    // Contar tasks
    $total_tasks = (int) $wpdb->get_var($wpdb->prepare(
        "SELECT COUNT(*) FROM {$wpdb->prefix}article_generation_tasks WHERE generation_id = %d",
        $generation_id
    ));
    $pending_tasks = $wpdb->get_results($wpdb->prepare(
        "SELECT id, article_params FROM {$wpdb->prefix}article_generation_tasks
         WHERE generation_id = %d AND status = 'pending'
         ORDER BY id ASC",
        $generation_id
    ));
    $pending_count = is_array($pending_tasks) ? count($pending_tasks) : 0;
    $done_count = max(0, $total_tasks - $pending_count);

    if ($pending_count === 0) {
        wp_send_json_error(['message' => 'No pending tasks to update']);
    }

    // Actualizar bulk_generations
    $updated_gen = $wpdb->update(
        $wpdb->prefix . 'bulk_generations',
        [
            'publish_action' => $publish_action,
            'publish_frequency' => ($publish_action === 'schedule') ? $publish_frequency : '',
            'start_date' => ($publish_action === 'schedule') ? $start_date : '',
            'start_time' => ($publish_action === 'schedule') ? $start_time : '',
            'articles_per_interval' => ($publish_action === 'schedule') ? $articles_per_interval : 0,
            'minutes_between_articles' => ($publish_action === 'schedule') ? $minutes_between : 0,
        ],
        ['id' => $generation_id]
    );

    if ($updated_gen === false) {
        wp_send_json_error(['message' => 'Failed updating generation']);
    }

    // Preparar schedule dates (solo si schedule)
    $pending_dates = [];
    if ($publish_action === 'schedule') {
        $all_dates = easy_gpt_calculate_scheduled_dates(
            $start_date,
            $start_time,
            $publish_frequency,
            $total_tasks,              // generamos para todas
            $articles_per_interval,
            $minutes_between
        );
        // Cogemos solo las correspondientes a las pendientes, manteniendo offset de las ya ejecutadas
        $pending_dates = array_slice($all_dates, $done_count, $pending_count);
    }

    // Update tasks pending: scheduled_for + article_params JSON
    foreach ($pending_tasks as $idx => $task) {
        $task_id = (int) $task->id;

        $params = json_decode($task->article_params, true);
        if (!is_array($params)) $params = [];

        $scheduled_for = null;
        if ($publish_action === 'schedule') {
            $scheduled_for = $pending_dates[$idx] ?? null;
        }

        // Actualizar params (lo que usa tu worker)
        $params['publish_action'] = $publish_action;
        $params['publish_frequency'] = ($publish_action === 'schedule') ? $publish_frequency : '';
        $params['start_date'] = ($publish_action === 'schedule') ? $start_date : '';
        $params['start_time'] = ($publish_action === 'schedule') ? $start_time : '';
        $params['articles_per_interval'] = ($publish_action === 'schedule') ? $articles_per_interval : 0;
        $params['minutes_between_articles'] = ($publish_action === 'schedule') ? $minutes_between : 0;
        $params['scheduled_publish_date'] = $scheduled_for; // clave que ya usas

        $wpdb->update(
            $wpdb->prefix . 'article_generation_tasks',
            [
                'scheduled_for' => $scheduled_for,
                'article_params' => wp_json_encode($params),
            ],
            ['id' => $task_id]
        );
    }

    wp_send_json_success(['message' => 'Pending tasks updated']);
}

add_action('wp_ajax_easy_gpt_get_task_edit', 'easy_gpt_get_task_edit');

function easy_gpt_get_task_edit() {
    if ( ! current_user_can('manage_options') ) {
        wp_send_json_error(['message' => 'Insufficient permissions']);
    }

    $nonce = isset($_POST['nonce']) ? sanitize_text_field(wp_unslash($_POST['nonce'])) : '';
    if ( ! wp_verify_nonce($nonce, 'easy_gpt_bulk_edit_nonce') ) {
        wp_send_json_error(['message' => 'Invalid nonce']);
    }

    global $wpdb;
    $task_id = isset($_POST['task_id']) ? absint($_POST['task_id']) : 0;
    if ( ! $task_id ) {
        wp_send_json_error(['message' => 'Invalid Task ID']);
    }

    $task = $wpdb->get_row($wpdb->prepare(
        "SELECT id, status, scheduled_for, article_params
         FROM {$wpdb->prefix}article_generation_tasks
         WHERE id = %d",
        $task_id
    ), ARRAY_A);

    if ( ! $task ) {
        wp_send_json_error(['message' => 'Task not found']);
    }

    if ( $task['status'] !== 'pending' ) {
        wp_send_json_error(['message' => 'Only pending tasks can be edited']);
    }

    $params = json_decode($task['article_params'], true);
    if (!is_array($params)) $params = [];

    // Convertir scheduled_for a formato datetime-local (YYYY-MM-DDTHH:MM)
	$scheduled_for_local = '';
	if ( ! empty( $task['scheduled_for'] ) ) {
		try {
			$tz = wp_timezone(); // timezone del sitio
			$dt = DateTimeImmutable::createFromFormat('Y-m-d H:i:s', $task['scheduled_for'], $tz);
			if ( $dt instanceof DateTimeImmutable ) {
				// datetime-local necesita "T"
				$scheduled_for_local = $dt->format('Y-m-d\TH:i');
			}
		} catch (Exception $e) {
			$scheduled_for_local = '';
		}
	}

    wp_send_json_success([
        'task' => [
            'id' => (int)$task['id'],
            'prompt' => $params['prompt'] ?? '',
            'keywords' => $params['keywords'] ?? '',
            'publish_action' => $params['publish_action'] ?? '',
            'scheduled_for_local' => $scheduled_for_local,
        ]
    ]);
}

add_action('wp_ajax_easy_gpt_save_task_edit', 'easy_gpt_save_task_edit');

function easy_gpt_save_task_edit() {
    if ( ! current_user_can('manage_options') ) {
        wp_send_json_error(['message' => 'Insufficient permissions']);
    }

    $nonce = isset($_POST['nonce']) ? sanitize_text_field(wp_unslash($_POST['nonce'])) : '';
    if ( ! wp_verify_nonce($nonce, 'easy_gpt_bulk_edit_nonce') ) {
        wp_send_json_error(['message' => 'Invalid nonce']);
    }

    global $wpdb;

    $task_id = isset($_POST['task_id']) ? absint($_POST['task_id']) : 0;
    if ( ! $task_id ) {
        wp_send_json_error(['message' => 'Invalid Task ID']);
    }

    $row = $wpdb->get_row($wpdb->prepare(
        "SELECT id, status, generation_id, scheduled_for, article_params
         FROM {$wpdb->prefix}article_generation_tasks WHERE id = %d",
        $task_id
    ), ARRAY_A);

    if ( ! $row ) {
        wp_send_json_error(['message' => 'Task not found']);
    }

    if ( $row['status'] !== 'pending' ) {
        wp_send_json_error(['message' => 'Only pending tasks can be edited']);
    }

    $prompt = isset($_POST['prompt']) ? sanitize_textarea_field(wp_unslash($_POST['prompt'])) : '';
    $keywords = isset($_POST['keywords']) ? sanitize_text_field(wp_unslash($_POST['keywords'])) : '';
    $publish_action = isset($_POST['publish_action']) ? sanitize_text_field(wp_unslash($_POST['publish_action'])) : 'save_draft';

    $scheduled_for = null;

    // scheduled_for_local viene como "YYYY-MM-DDTHH:MM"
    $scheduled_for_local = isset($_POST['scheduled_for_local']) ? sanitize_text_field(wp_unslash($_POST['scheduled_for_local'])) : '';

    if ($publish_action === 'schedule') {
        if (empty($scheduled_for_local)) {
            wp_send_json_error(['message' => 'Scheduled datetime required']);
        }
        // convertir a "Y-m-d H:i:s"
        $scheduled_for_local = str_replace('T', ' ', $scheduled_for_local);
        if (strlen($scheduled_for_local) === 16) {
            $scheduled_for_local .= ':00';
        }
        $scheduled_for = $scheduled_for_local;
    }

    $params = json_decode($row['article_params'], true);
    if (!is_array($params)) $params = [];

    // Actualizar params
    $params['prompt'] = $prompt;
    $params['keywords'] = $keywords;
    $params['publish_action'] = $publish_action;
    $params['scheduled_publish_date'] = $scheduled_for; // tu clave existente

    $updated = $wpdb->update(
        $wpdb->prefix . 'article_generation_tasks',
        [
            'scheduled_for' => $scheduled_for,
            'article_params' => wp_json_encode($params),
        ],
        ['id' => $task_id]
    );

    if ($updated === false) {
        wp_send_json_error(['message' => 'Failed updating task']);
    }

    wp_send_json_success(['message' => 'Task updated']);
}

function easy_gpt_recalculate_bulk_generation_status( $generation_id ) {
    global $wpdb;

    $generation_id = absint($generation_id);
    if ( ! $generation_id ) return;

    $table_tasks = $wpdb->prefix . 'article_generation_tasks';
    $table_gen   = $wpdb->prefix . 'bulk_generations';

    // Conteos por estado
    $rows = $wpdb->get_results(
        $wpdb->prepare(
            "SELECT status, COUNT(*) AS c
             FROM {$table_tasks}
             WHERE generation_id = %d
             GROUP BY status",
            $generation_id
        ),
        ARRAY_A
    );

    $counts = [
        'pending'    => 0,
        'processing' => 0,
        'completed'  => 0,
        'failed'     => 0,
        'cancelled'  => 0,
    ];

    if (is_array($rows)) {
        foreach ($rows as $r) {
            $st = $r['status'] ?? '';
            if (isset($counts[$st])) {
                $counts[$st] = (int) $r['c'];
            }
        }
    }

    $total = array_sum($counts);

    // Si no hay tasks, no tocamos
    if ($total <= 0) return;

    // Respeta pausa si está paused (no lo cambies automáticamente)
    $current_status = $wpdb->get_var(
        $wpdb->prepare("SELECT status FROM {$table_gen} WHERE id = %d", $generation_id)
    );
    if ($current_status === 'paused') {
        return;
    }

    // Determinar estado nuevo
    if ($counts['processing'] > 0) {
        $new_status = 'processing';
    } elseif ($counts['pending'] > 0) {
        $new_status = 'pending';
    } else {
        // No hay pending ni processing: ya terminó "algo"
        if ($counts['failed'] > 0) {
            $new_status = 'complete with errors';
        } elseif ($counts['completed'] > 0) {
            // si hay completadas y el resto canceladas, sigue siendo "completed"
            $new_status = 'completed';
        } else {
            // todo cancelado
            $new_status = 'cancelled';
        }
    }

    // Update solo si cambia
    if ($new_status && $new_status !== $current_status) {
        $wpdb->update(
            $table_gen,
            ['status' => $new_status],
            ['id' => $generation_id]
        );
    }
}