<?php
if ( ! defined( 'ABSPATH' ) ) exit; // Salir si se accede directamente

// Añadir acción AJAX para iniciar la generación
add_action('wp_ajax_easy_gpt_start_generation', 'easy_gpt_start_generation_handler');

function easy_gpt_start_generation_handler() {
    // Verificar el nonce para seguridad, sanitizando la entrada
    if (!isset($_POST['nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'])), 'save_bulk_generation_nonce')) {
        wp_send_json_error(['message' => 'Invalid nonce']);
        return;
    }

    // Sanitizar y validar las entradas
    $generation_id = isset($_POST['generation_id']) ? intval($_POST['generation_id']) : 0;
    $num_articles = isset($_POST['num_articles']) ? intval($_POST['num_articles']) : 1;

    // Obtener datos adicionales de la base de datos
    global $wpdb;
    $table_name = $wpdb->prefix . 'bulk_generations';

    // Preparar y ejecutar la consulta de manera segura
    $generation = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$table_name} WHERE id = %d", $generation_id));

    if ($generation) {
        $other_params = (array) $generation;
        easy_gpt_generate_articles($generation_id, $num_articles, $other_params);
        wp_send_json_success(['message' => 'Generation started.']);
    } else {
        wp_send_json_error(['message' => 'Generation not found.']);
    }
}

function easy_gpt_generate_articles($generation_id, $num_articles, $other_params) {
    // Sanitizar datos provenientes de la base de datos
    $prompt = isset($other_params['prompt']) ? sanitize_textarea_field($other_params['prompt']) : '';
    $keywords_str = isset($other_params['keywords']) ? sanitize_textarea_field($other_params['keywords']) : '';
    $titles_str = isset($other_params['specific_instructions_title']) ? sanitize_textarea_field($other_params['specific_instructions_title']) : '';
    $outlines_str = isset($other_params['specific_instructions_outline']) ? sanitize_textarea_field($other_params['specific_instructions_outline']) : '';
    $contents_str = isset($other_params['specific_instructions_content']) ? sanitize_textarea_field($other_params['specific_instructions_content']) : '';
    $excerpts_str = isset($other_params['specific_instructions_excerpt']) ? sanitize_textarea_field($other_params['specific_instructions_excerpt']) : '';

    $prompts_articles = array_map('sanitize_textarea_field', explode("\n", str_replace("\r", "", $prompt)));
    $keywords = array_map('sanitize_text_field', explode("\n", trim($keywords_str)));
    $titles = array_map('sanitize_textarea_field', explode("\n", trim($titles_str)));
    $outlines = array_map('sanitize_textarea_field', explode("\n", trim($outlines_str)));
    $contents = array_map('sanitize_textarea_field', explode("\n", trim($contents_str)));
    $excerpts = array_map('sanitize_textarea_field', explode("\n", trim($excerpts_str)));

    // Decodificar JSON de manera segura y sanitizar arrays
    $image_prompts = json_decode($other_params['image_prompts'], true);
    $use_same_image_prompts = json_decode($other_params['use_same_image_prompts'], true);

    $image_prompts = is_array($image_prompts) ? array_map('sanitize_text_field', $image_prompts) : [];
    $use_same_image_prompts = is_array($use_same_image_prompts) ? array_map('sanitize_text_field', $use_same_image_prompts) : [];

    // Procesar prompts de imágenes
    $article_image_prompts = [];

    foreach ($image_prompts as $index => $prompts) {
        if (!empty($use_same_image_prompts[$index])) {
            // Usar el mismo prompt para todos los artículos, sanitizar el array
            $processed_prompt = implode(", ", array_map('sanitize_text_field', (array)$prompts));
            $article_image_prompts[$index] = $processed_prompt;
        } else {
            // Asignar prompts individuales para cada artículo
            for ($i = 0; $i < $num_articles; $i++) {
                $article_image_prompts[$index][$i] = isset($prompts[$i]) ? sanitize_text_field($prompts[$i]) : 'No prompt defined';
            }
        }
    }

    // Inicializar variables de programación y sanitizar entradas
    $publish_action = isset($other_params['publish_action']) ? sanitize_text_field($other_params['publish_action']) : '';
    $scheduled_dates = [];

    if ($publish_action === 'schedule') {
        $frequency = isset($other_params['publish_frequency']) ? sanitize_text_field($other_params['publish_frequency']) : '';
        $start_date = isset($other_params['start_date']) ? sanitize_text_field($other_params['start_date']) : '';
        $start_time = isset($other_params['start_time']) ? sanitize_text_field($other_params['start_time']) : '';
        $articles_per_interval = isset($other_params['articles_per_interval']) ? intval($other_params['articles_per_interval']) : 1;

        // Calcular las fechas programadas
        $minutes_between_articles = isset($other_params['minutes_between_articles']) ? intval($other_params['minutes_between_articles']) : 0;

        $scheduled_dates = easy_gpt_calculate_scheduled_dates($start_date, $start_time, $frequency, $num_articles, $articles_per_interval, $minutes_between_articles);
    }

    for ($i = 0; $i < $num_articles; $i++) {
        // Aplicar instrucciones específicas
        $title_instruction = !empty($other_params['use_same_specific_title_instructions']) ? implode("\n", $titles) : ($titles[$i] ?? '');
        $outline_instruction = !empty($other_params['use_same_specific_outline_instructions']) ? implode("\n", $outlines) : ($outlines[$i] ?? '');
        $content_instruction = !empty($other_params['use_same_specific_content_instructions']) ? implode("\n", $contents) : ($contents[$i] ?? '');
        $excerpt_instruction = !empty($other_params['use_same_specific_excerpt_instructions']) ? implode("\n", $excerpts) : ($excerpts[$i] ?? '');
        
        $product_prices_str = isset($other_params['product_prices']) ? sanitize_textarea_field($other_params['product_prices']) : '';
        $product_prices = array_map('sanitize_text_field', explode("\n", trim($product_prices_str)));
        $product_price = !empty($other_params['use_same_product_price']) ? implode("\n", $product_prices) : ($product_prices[$i] ?? '');
        $product_price = floatval(str_replace(',', '.', $product_price));

        // Sanitizar instrucciones específicas
        $title_instruction = sanitize_textarea_field($title_instruction);
        $outline_instruction = sanitize_textarea_field($outline_instruction);
        $content_instruction = sanitize_textarea_field($content_instruction);
        $excerpt_instruction = sanitize_textarea_field($excerpt_instruction);

        // Preparar los prompts de imágenes para cada artículo
        $current_image_prompts = [];
        foreach ($article_image_prompts as $index => $prompt) {
            if (is_array($prompt)) {
                $current_image_prompts[] = isset($prompt[$i]) ? sanitize_text_field($prompt[$i]) : '';
            } else {
                $current_image_prompts[] = sanitize_text_field($prompt);
            }
        }

        // Preparar los parámetros del artículo
        $article_params = [
            'id' => intval($other_params['id']),
            'user_id' => intval($other_params['user_id']),
            'prompt' => isset($prompts_articles[$i]) ? sanitize_textarea_field($prompts_articles[$i]) : 'No prompt defined',
            'keywords' => isset($keywords[$i]) ? sanitize_text_field($keywords[$i]) : 'No keywords defined',
            'specific_instructions_title' => $title_instruction,
            'specific_instructions_outline' => $outline_instruction,
            'specific_instructions_content' => $content_instruction,
            'specific_instructions_excerpt' => $excerpt_instruction,
            'image_prompts' => $current_image_prompts,
            'date_created' => sanitize_text_field($other_params['date_created']),
            'status' => sanitize_text_field($other_params['status']),
            'num_articles' => intval($other_params['num_articles']),
            'articles_generated' => intval($other_params['articles_generated']),
            'total_cost' => floatval($other_params['total_cost']),
            'model' => sanitize_text_field($other_params['model']),
            'temperature' => floatval($other_params['temperature']),
            'language' => sanitize_text_field($other_params['language']),
            'min_words' => intval($other_params['min_words']),
            'max_words' => intval($other_params['max_words']),
            'num_subheadings' => intval($other_params['num_subheadings']),
            'subheading_types' => sanitize_text_field($other_params['subheading_types']),
            'format_article' => !empty($other_params['format_article']),
            'include_links' => !empty($other_params['include_links']),
            'include_bibliography' => !empty($other_params['include_bibliography']),
            'auto_categories' => !empty($other_params['auto_categories']),
            'auto_tags' => !empty($other_params['auto_tags']),
            'enable_seo' => !empty($other_params['enable_seo']),
            'writing_style' => sanitize_text_field($other_params['writing_style']),
            'writing_tone' => sanitize_text_field($other_params['writing_tone']),
            'include_excerpt' => !empty($other_params['include_excerpt']),
            'image_model' => sanitize_text_field($other_params['image_model']),
            'auto_images' => !empty($other_params['auto_images']),
            'num_images' => intval($other_params['num_images']),
            'image_size' => sanitize_text_field($other_params['image_size']),
            'image_quality' => sanitize_text_field($other_params['image_quality']),
            'image_style' => sanitize_text_field($other_params['image_style']),
            'set_featured_image' => !empty($other_params['set_featured_image']),
            'publish_action' => sanitize_text_field($other_params['publish_action']),
            'publish_frequency' => sanitize_text_field($other_params['publish_frequency']),
            'start_date' => sanitize_text_field($other_params['start_date']),
            'start_time' => sanitize_text_field($other_params['start_time']),
            'articles_per_interval' => intval($other_params['articles_per_interval']),
            'scheduled_publish_date' => ($publish_action === 'schedule' && isset($scheduled_dates[$i])) ? sanitize_text_field($scheduled_dates[$i]) : null,
            'content_type' => isset($other_params['content_type']) ? sanitize_text_field($other_params['content_type']) : 'article',
            'enable_product_prices' => isset($other_params['enable_product_prices']) ? intval($other_params['enable_product_prices']) : 0,
            'product_prices' => $product_price,
            'include_videos_bulk' => !empty($other_params['include_videos_bulk']),
            'video_position_bulk' => sanitize_text_field($other_params['video_position_bulk']),
            'video_paragraph_bulk' => intval($other_params['video_paragraph_bulk']),
			'include_citations_bulk' => !empty($other_params['include_citations_bulk']),
			'final_review_bulk' => !empty($other_params['final_review_bulk'])
        ];

        // Encolar la tarea de generación de artículo
        easy_gpt_enqueue_article_generation_tasks($generation_id, $article_params);
    }
}

function easy_gpt_calculate_scheduled_dates($start_date, $start_time, $frequency, $num_articles, $articles_per_interval, $minutes_between) {
    $dates = [];
    $interval_spec = '';

    switch ($frequency) {
        case 'daily':
            $interval_spec = 'P1D';
            break;
        case 'weekly':
            $interval_spec = 'P1W';
            break;
        case 'monthly':
            $interval_spec = 'P1M';
            break;
        default:
            $interval_spec = 'P1D';
            break;
    }

    try {
        $base_datetime = new DateTime($start_date . ' ' . $start_time);
    } catch (Exception $e) {
        $base_datetime = new DateTime();
    }

    $articles_scheduled = 0;

    while ($articles_scheduled < $num_articles) {
        // Clonar el objeto para evitar modificar la base directamente
        $current_datetime = clone $base_datetime;

        for ($i = 0; $i < $articles_per_interval && $articles_scheduled < $num_articles; $i++) {
            // Agregar minutos solo si es el segundo o posterior artículo del mismo intervalo
            if ($i > 0 && $minutes_between > 0) {
                $current_datetime->modify("+{$minutes_between} minutes");
            }

            $dates[] = $current_datetime->format('Y-m-d H:i:s');
            $articles_scheduled++;
        }

        // Pasar al siguiente intervalo (día/semana/mes)
        $base_datetime->add(new DateInterval($interval_spec));
    }

    return $dates;
}


function easy_gpt_enqueue_article_generation_tasks($generation_id, $article_params) {
    global $wpdb;
    $table_name = $wpdb->prefix . 'article_generation_tasks';

    // Obtener la fecha programada desde los parámetros
    $scheduled_datetime = isset($article_params['scheduled_publish_date']) ? sanitize_text_field($article_params['scheduled_publish_date']) : null;

    // Asegurar formato correcto si no viene en formato Y-m-d H:i:s
    if ($scheduled_datetime && strlen($scheduled_datetime) === 16) { // Si viene como Y-m-d H:i
        $scheduled_datetime .= ':00'; // Añadir segundos
    }

    $data = [
        'generation_id' => intval($generation_id),
        'article_params' => wp_json_encode($article_params),
        'status' => 'pending',
        'created_at' => current_time('mysql', 1),
        'scheduled_for' => $scheduled_datetime,
    ];

    $wpdb->insert($table_name, $data);
}

// Función para generar el artículo completo
function easy_gpt_generate_complete_article_bulk($article_params) {
    $total_cost = 0.0;

    // Generar el título del artículo
    $title_data = easy_gpt_generate_title_bulk($article_params);
    if (!$title_data) {
        return 'Error generating title';
    }
    $title = sanitize_text_field($title_data['text']);
    $total_cost += $title_data['total_cost'];

    // Generar el esquema del artículo
    $outline_data = easy_gpt_generate_outline($article_params, $title);
    if (!$outline_data) {
        return 'Error generating outline';
    }
    $outline = sanitize_textarea_field($outline_data['text']);
    $total_cost += $outline_data['total_cost'];

    // Generar el extracto
    $excerpt_data = easy_gpt_generate_excerpt($article_params, $title, $outline);
    if (!$excerpt_data) {
        return 'Error generating excerpt';
    }
    $excerpt = sanitize_textarea_field($excerpt_data['text']);
    $total_cost += $excerpt_data['total_cost'];

    // Generar datos SEO si está habilitado
    if (!empty($article_params['enable_seo'])) {
        $seo_data = easy_gpt_generate_seo($article_params, $title, $outline);
        if (!$seo_data) {
            return 'Error generating SEO data';
        }
        $seo_title = sanitize_text_field($seo_data['seo_title']);
        $seo_description = sanitize_textarea_field($seo_data['seo_description']);
        $total_cost += $seo_data['total_cost'];
    } else {
        $seo_title = '';
        $seo_description = '';
    }

    // Generar el contenido del artículo
    $article_content_data = easy_gpt_generate_article_content($article_params, $title, $outline);
    if (!$article_content_data) {
        return 'Error generating article content';
    }
    $article_content = wp_kses_post($article_content_data['text']);
    $total_cost += $article_content_data['total_cost'];

    // Guardar el artículo en WordPress
    $post_id = easy_gpt_save_article_to_wordpress($title, $article_content, $excerpt, $seo_title, $seo_description, $article_params);

    if (!$post_id) {
        return 'Error saving article to WordPress';
    }

    // Retornar éxito y costo total
    return [
        'message' => 'Article generated and saved successfully',
        'post_id' => intval($post_id),
        'total_cost' => floatval($total_cost)
    ];
}

// Función para generar el título
function easy_gpt_generate_title_bulk($article_params) {
    // Verificar si hay instrucciones específicas para el título
    if (!empty($article_params['specific_instructions_title'])) {
        return [
            'text' => sanitize_text_field($article_params['specific_instructions_title']),
            'total_cost' => 0.0
        ];
    }

    // Construir el prompt
    $prompt = sprintf(
        "Title Generation: Using the prompt '%s', keywords '%s', and specific instructions '%s', generate a title that fits the style '%s' and tone '%s' in '%s' language. Only return the title without enclosing it in quotes.",
        sanitize_text_field($article_params['prompt']),
        sanitize_text_field($article_params['keywords']),
        sanitize_text_field($article_params['specific_instructions_title']),
        sanitize_text_field($article_params['writing_style']),
        sanitize_text_field($article_params['writing_tone']),
        sanitize_text_field($article_params['language'])
    );

    // Parámetros de la API
    $api_key = sanitize_text_field(get_option('easy_gpt_options')['easy_gpt_api_key']);
    $model = sanitize_text_field($article_params['model']);
    $temperature = floatval($article_params['temperature']);

    // Llamada a la API
    $response = easy_gpt_call_openai_api_bulk($prompt, $model, $temperature, $api_key);

    if (isset($response['text']) && !empty($response['text'])) {
        return [
            'text' => sanitize_text_field($response['text']),
            'total_cost' => floatval($response['total_cost'])
        ];
    } else {
        return null; // Manejar error
    }
}

// Función para llamar a la API de OpenAI
function easy_gpt_call_openai_api_bulk($prompt, $model, $temperature, $api_key) {
    // Determinar el endpoint correcto basado en el modelo
    if (strpos($model, 'gpt-3.5-turbo') !== false || strpos($model, 'gpt-4') !== false) {
        $url = 'https://api.openai.com/v1/chat/completions';
        $post_data = [
            'model' => $model,
            'messages' => [
                ['role' => 'user', 'content' => $prompt]
            ],
            'temperature' => $temperature
        ];
    } else {
        $url = 'https://api.openai.com/v1/completions';
        $post_data = [
            'model' => $model,
            'prompt' => $prompt,
            'temperature' => $temperature
        ];
    }

    $response = wp_remote_post($url, [
        'headers' => [
            'Content-Type' => 'application/json',
            'Authorization' => 'Bearer ' . sanitize_text_field($api_key)
        ],
        'body' => wp_json_encode($post_data),
        'timeout' => 300
    ]);

    if (is_wp_error($response)) {
        // Manejar error
        return null;
    }

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

    if (isset($decoded_response['error'])) {
        // Manejar error
        return null;
    }

    // Procesar la respuesta y calcular el costo
    $text_response = isset($decoded_response['choices'][0]['message']['content']) ? $decoded_response['choices'][0]['message']['content'] : $decoded_response['choices'][0]['text'];

    $usage = $decoded_response['usage'] ?? [];
    $model_costs = get_option('easy_gpt_options')['model_costs'];
    $cost_model = $model_costs[$model] ?? ['input' => 0.0, 'output' => 0.0];

    $total_cost = easy_gpt_calculate_cost($usage, $cost_model);

    return [
        'text' => sanitize_text_field($text_response),
        'total_cost' => floatval($total_cost)
    ];
}

function easy_gpt_calculate_cost($usage, $cost_model) {
    $prompt_tokens = isset($usage['prompt_tokens']) ? intval($usage['prompt_tokens']) : 0;
    $completion_tokens = isset($usage['completion_tokens']) ? intval($usage['completion_tokens']) : 0;

    $input_cost = ($prompt_tokens / 1000) * floatval($cost_model['input']);
    $output_cost = ($completion_tokens / 1000) * floatval($cost_model['output']);

    return $input_cost + $output_cost;
}

function easy_gpt_save_article_to_wordpress($title, $content, $excerpt, $seo_title, $seo_description, $article_params) {
    // Lógica para guardar el artículo en WordPress, devolviendo el ID del post
    return 123; // Simula un ID de post creado
}
