<?php

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

// Require the base controller
require_once dirname(__FILE__) . '/BaseController.php';

/**
 * Class ContentCraftAI_ArticleGenerationController
 * 
 * Handles the generation of articles (single and bulk) for the Content Craft AI plugin.
 */
class ContentCraftAI_ArticleGenerationController extends ContentCraftAI_BaseController
{
    /**
     * Instance of this class.
     *
     * @var ContentCraftAI_ArticleGenerationController
     */
    private static $instance = null;

    /**
     * Get an instance of this class.
     *
     * @return ContentCraftAI_ArticleGenerationController
     */
    public static function get_instance()
    {
        if (null === self::$instance) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    /**
     * Constructor
     */
    private function __construct()
    {
        // Private constructor to prevent direct instantiation
    }

    /**
     * Generate a single article
     * 
     * @param array $params The article parameters
     * @return array The result of the generation
     */
    public function generate_single_article($params)
    {
        try {
            // Validate required parameters
            if (empty($params['articleTitle']) || empty($params['focusKeyword'])) {
                return [
                    'success' => false,
                    'message' => 'Article title and focus keyword are required',
                    'code' => 400
                ];
            }

            // Format data for validation and storage
            $article_data = [
                'title' => $params['articleTitle'],
                'focusKeyword' => $params['focusKeyword'],
                'wordCount' => $params['wordCount'] ?? 1000,
                'tagCount' => $params['tagCount'] ?? 5,
                'language' => $params['language'] ?? 'en',
                'aiModel' => $params['aiModel'] ?? 'gpt-4o-mini',
                'category' => $params['category'] ?? null,
                'imageService' => $params['imageService'] ?? 'pexels',
                'includeImages' => isset($params['includeImages']) ? $params['includeImages'] : true,
                'setFeaturedImage' => isset($params['setFeaturedImage']) ? $params['setFeaturedImage'] : true,
                'imageKeywords' => $params['imageKeywords'] ?? '',
                'postStatus' => $params['postStatus'] ?? 'draft',
            ];

            // Validate article parameters against plan limitations
            $validation_result = $this->validate_article_parameters($article_data);
            if (!$validation_result['success']) {
                return [
                    'success' => false,
                    'message' => $validation_result['message'],
                    'errors' => $validation_result['errors'] ?? [],
                    'code' => $validation_result['code'] ?? 403
                ];
            }

            // Generate a unique queue ID
            // @phpcs:ignore WordPress.WP.AlternativeFunctions.rand_mt_rand -- Using mt_rand for unique ID generation in environments where wp_rand may not be available
            $queue_id = 'queue_' . uniqid(mt_rand(), true);

            // Check if the article is scheduled for future generation
            $is_scheduled = !empty($params['scheduleDate']);
            $scheduled_time = null;

            // Get manager instances
            $article_manager = ContentCraftAI_ArticleGenerationManager::get_instance();

            if ($is_scheduled) {
                $scheduled_manager = ContentCraftAI_ScheduledArticleManager::get_instance();

                // Convert the ISO date from frontend to MySQL datetime
                $scheduled_time = gmdate('Y-m-d H:i:s', strtotime($params['scheduleDate']));
                $article_data['scheduleDateTime'] = $scheduled_time;

                // Store the scheduled article in database
                $result = $scheduled_manager->add_scheduled_generation(
                    $queue_id,
                    $article_data['title'],
                    $scheduled_time,
                    $article_data,
                    1 // Admin user ID (default)
                );

                if ($result) {
                    return [
                        'success' => true,
                        'message' => 'Article scheduled successfully',
                        'data' => [
                            'queueId' => $queue_id,
                            'title' => $article_data['title'],
                            'scheduled' => true,
                            'scheduledTime' => $scheduled_time
                        ]
                    ];
                } else {
                    return [
                        'success' => false,
                        'message' => 'Failed to schedule article',
                        'code' => 500
                    ];
                }
            } else {
                // Get the post creation manager to prepare API data with internal links
                require_once CONTENT_CRAFT_AI_PLUGIN_PATH . 'app/controllers/article-generator/PostCreationManager.php';
                $post_creation_manager = ContentCraftAI_PostCreationManager::get_instance();

                // Prepare API data with internal links
                $article_data = $post_creation_manager->prepare_api_data($article_data);

                // Call the API to generate article
                $api_response = content_craft_ai_api_generate_article($article_data);

                // Process API response
                if ($api_response && isset($api_response['success']) && $api_response['success']) {
                    // Only store in database if the API call was successful
                    $db_result = $article_manager->add_generation($queue_id, $article_data);

                    if (!$db_result) {
                        return [
                            'success' => false,
                            'message' => 'Failed to store article generation data',
                            'code' => 500
                        ];
                    }

                    // Store the external API queue ID in the parameters
                    if (isset($api_response['data']['queueId'])) {
                        $article_data['apiQueueId'] = $api_response['data']['queueId'];
                    }

                    // Update the record to "processing" status
                    $article_manager->update_generation_status($queue_id, 'processing');

                    // Update the parameters in the database
                    global $wpdb;
                    $wpdb->update(
                        $wpdb->prefix . 'content_craft_ai_generations',
                        ['parameters' => json_encode($article_data)],
                        ['queue_id' => $queue_id],
                        ['%s'], // parameters format
                        ['%s']  // queue_id format
                    );

                    return [
                        'success' => true,
                        'message' => 'Article generation started',
                        'data' => [
                            'queueId' => $queue_id,
                            'title' => $article_data['title'],
                            'apiQueueId' => $api_response['data']['queueId'] ?? null
                        ]
                    ];
                } else {
                    // API call failed
                    // Check for HTTP status code first, then fallback to API error code
                    $error_code = isset($api_response['code']) && is_numeric($api_response['code'])
                        ? (int)$api_response['code']  // This is the HTTP status code
                        : (isset($api_response['errorCode']) ? $api_response['errorCode'] : 500); // This is the API error code string

                    $error_message = $api_response['message'] ?? 'Unknown error';

                    // Don't store anything for 403 errors (permission/auth issues)
                    if ($error_code == 403) {
                        return [
                            'success' => false,
                            'message' => 'Failed to start article generation: ' . $error_message,
                            'code' => $error_code
                        ];
                    } else {
                        // For other errors, store in database with "failed" status
                        $db_result = $article_manager->add_generation($queue_id, $article_data);

                        if ($db_result) {
                            // Update the status to failed
                            $article_manager->update_generation_status($queue_id, 'failed');

                            // Store error details in the parameters
                            $article_data['error'] = $error_message;
                            $article_data['errorCode'] = $error_code;

                            global $wpdb;
                            $wpdb->update(
                                $wpdb->prefix . 'content_craft_ai_generations',
                                ['parameters' => json_encode($article_data)],
                                ['queue_id' => $queue_id],
                                ['%s'], // parameters format
                                ['%s']  // queue_id format
                            );
                        }

                        return [
                            'success' => false,
                            'message' => 'Failed to start article generation: ' . $error_message,
                            'code' => $error_code
                        ];
                    }
                }
            }
        } catch (Exception $e) {
            // error_log('Error generating article: ' . $e->getMessage());
            return [
                'success' => false,
                'message' => 'Error generating article: ' . $e->getMessage(),
                'code' => 500
            ];
        }
    }

    /**
     * Generate multiple articles in bulk
     * 
     * @param array $params Parameters for bulk article generation
     * @return array Response data
     */
    public function generate_bulk_articles($params)
    {
        try {
            // Check if we have articles in the request
            if (!isset($params['articles']) || !is_array($params['articles'])) {
                return [
                    'success' => false,
                    'message' => 'No articles provided for bulk generation',
                    'code' => 400
                ];
            }

            $articles = $params['articles'];

            // Validate all articles against plan limitations
            $validation = $this->validate_bulk_article_parameters($articles);

            // If validation failed, return the error
            if (!isset($validation['valid']) || $validation['valid'] === false) {
                // Return the complete validation error response
                return [
                    'success' => false,
                    'message' => $validation['message'] ?? 'Some articles failed validation',
                    'failedArticles' => $validation['failedArticles'] ?? [],
                    'results' => $validation['data']['results'] ?? [],
                    'code' => $validation['code'] ?? 403
                ];
            }

            // Process each article
            $article_manager = ContentCraftAI_ArticleGenerationManager::get_instance();
            $scheduled_manager = ContentCraftAI_ScheduledArticleManager::get_instance();
            $queue_ids = [];
            $scheduled_articles = [];

            foreach ($articles as $article) {
                // Format article data
                $formatted_article = [
                    'title' => $article['title'] ?? $article['articleTitle'] ?? '',
                    'wordCount' => $article['wordCount'] ?? 1000,
                    'focusKeyword' => $article['focusKeyword'] ?? '',
                    'tagCount' => $article['tagCount'] ?? 5,
                    'aiModel' => $article['aiModel'] ?? 'gpt-4o-mini',
                    'imageService' => $article['imageService'] ?? 'pexels',
                    'includeImages' => $article['includeImages'] ?? true,
                    'setFeaturedImage' => $article['setFeaturedImage'] ?? true,
                    'imageKeywords' => $article['imageKeywords'] ?? '',
                    'postStatus' => $article['postStatus'] ?? 'draft',
                    'language' => $article['language'] ?? 'en',
                    'scheduleDate' => isset($article['scheduleDate']) ? $article['scheduleDate'] : null,
                ];

                // Generate a unique queue ID
                $queue_id = 'queue_' . uniqid(mt_rand(), true);

                // Check if article should be scheduled
                $is_scheduled = isset($article['scheduleDate']) && !empty($article['scheduleDate']);
                $schedule_date = null;

                if ($is_scheduled) {
                    // Convert the ISO date from frontend to MySQL datetime
                    $schedule_date = gmdate('Y-m-d H:i:s', strtotime($article['scheduleDate']));
                    $formatted_article['scheduleDateTime'] = $schedule_date;

                    // Store the scheduled article in database
                    $result = $scheduled_manager->add_scheduled_generation(
                        $queue_id,
                        $formatted_article['title'],
                        $schedule_date,
                        $formatted_article,
                        1 // Admin user ID (default)
                    );

                    if ($result) {
                        $queue_ids[] = $queue_id;

                        // Add to scheduled articles list
                        $scheduled_articles[] = [
                            'queueId' => $queue_id,
                            'title' => $formatted_article['title'],
                            'scheduleDate' => $schedule_date
                        ];
                    }
                } else {
                    // Get the post creation manager to prepare API data with internal links
                    require_once CONTENT_CRAFT_AI_PLUGIN_PATH . 'app/controllers/article-generator/PostCreationManager.php';
                    $post_creation_manager = ContentCraftAI_PostCreationManager::get_instance();

                    // Prepare API data with internal links
                    $formatted_article = $post_creation_manager->prepare_api_data($formatted_article);

                    // Call the API to generate article
                    $api_response = content_craft_ai_api_generate_article($formatted_article);

                    // Process API response
                    if ($api_response && isset($api_response['success']) && $api_response['success']) {
                        // Only store in database if the API call was successful
                        $db_result = $article_manager->add_generation($queue_id, $formatted_article);

                        if ($db_result) {
                            $queue_ids[] = $queue_id;

                            // Store the external API queue ID in the parameters
                            if (isset($api_response['data']['queueId'])) {
                                $formatted_article['apiQueueId'] = $api_response['data']['queueId'];
                            }

                            // Update the record to "processing" status
                            $article_manager->update_generation_status($queue_id, 'processing');

                            // Update the parameters in the database
                            global $wpdb;
                            $wpdb->update(
                                $wpdb->prefix . 'content_craft_ai_generations',
                                ['parameters' => json_encode($formatted_article)],
                                ['queue_id' => $queue_id],
                                ['%s'], // parameters format
                                ['%s']  // queue_id format
                            );
                        }
                    } else {
                        // API call failed - don't count this as a success
                        // We'll just skip it
                        continue;
                    }
                }
            }

            // Check if any articles were queued
            if (empty($queue_ids)) {
                return [
                    'success' => false,
                    'message' => 'Failed to queue any articles for generation',
                    'code' => 500
                ];
            }

            // Return success response with queue IDs
            $response = [
                'success' => true,
                'message' => count($queue_ids) . ' articles queued for generation',
                'data' => [
                    'articles' => array_map(function ($id) {
                        return ['queueId' => $id];
                    }, $queue_ids),
                    'hasScheduledArticles' => !empty($scheduled_articles),
                    'scheduledArticles' => $scheduled_articles
                ]
            ];

            return $response;
        } catch (Exception $e) {
            return [
                'success' => false,
                'message' => 'Error generating bulk articles: ' . $e->getMessage(),
                'code' => 500
            ];
        }
    }

    /**
     * Validate a single article's parameters against plan limitations
     * 
     * @param array $params Article parameters to validate
     * @return array Validation result
     */
    private function validate_article_parameters($params)
    {
        try {
            // Call the API validation function
            return content_craft_ai_api_validate_article($params);
        } catch (Exception $e) {
            return [
                'success' => false,
                'message' => 'Error validating article parameters: ' . $e->getMessage(),
                'code' => 500
            ];
        }
    }

    /**
     * Validate bulk article parameters
     * 
     * @param array $articles Array of article parameters
     * @return array Validation result
     */
    private function validate_bulk_article_parameters($articles)
    {
        if (!function_exists('content_craft_ai_api_validate_article')) {
            require_once CONTENT_CRAFT_AI_PLUGIN_PATH . 'app/api/article-generator/single-article.php';
        }

        // Format articles for validation
        $formatted_articles = [];
        foreach ($articles as $article) {
            // Format article data for the API
            $formatted_article = [
                'title' => $article['title'] ?? $article['articleTitle'] ?? 'Untitled article',
                'wordCount' => $article['wordCount'] ?? 1000,
                'focusKeyword' => $article['focusKeyword'] ?? '',
                'tagCount' => $article['tagCount'] ?? 5,
                'aiModel' => $article['aiModel'] ?? 'gpt-4o-mini',
                'imageService' => $article['imageService'] ?? 'pexels',
                'includeImages' => $article['includeImages'] ?? true,
                'setFeaturedImage' => $article['setFeaturedImage'] ?? true,
                'imageKeywords' => $article['imageKeywords'] ?? '',
                'postStatus' => $article['postStatus'] ?? 'draft',
                'language' => $article['language'] ?? 'en',
            ];

            $formatted_articles[] = $formatted_article;
        }

        // Call the API validation function with bulk=true
        $validation_result = content_craft_ai_api_validate_article($formatted_articles, true);

        // Check if validation was successful
        if (isset($validation_result['success']) && $validation_result['success'] === true) {
            return [
                'valid' => true,
                'message' => 'All articles are valid',
                'data' => $validation_result
            ];
        }

        // If validation failed, format the errors
        $formatted_errors = $this->format_validation_errors($validation_result);

        // Return the formatted error response, ensuring we include the original validation results
        return [
            'valid' => false,
            'message' => $formatted_errors['message'] ?? 'Some articles failed validation',
            'failedArticles' => $formatted_errors['failedArticles'] ?? [],
            'code' => $formatted_errors['code'] ?? 403,
            'data' => $validation_result  // Include the complete validation result
        ];
    }

    /**
     * Format validation errors for API response
     * 
     * @param array $validation_result Validation result from API
     * @return array Formatted error response
     */
    private function format_validation_errors($validation_result)
    {
        // If we have results array, process it
        if (isset($validation_result['results']) && is_array($validation_result['results'])) {
            $results = $validation_result['results'];
            $failed_articles = [];

            foreach ($results as $result) {
                // Skip valid articles
                if (isset($result['valid']) && $result['valid'] === true) {
                    continue;
                }

                $article_title = $result['article'] ?? 'Unknown article';
                $errors = $result['errors'] ?? [];

                // Format error messages for this article
                $error_messages = [];
                foreach ($errors as $error) {
                    $error_messages[] = $error['message'] ?? 'Unknown error';
                }

                // Join error messages with a period and space
                $error_message = implode('. ', $error_messages);

                $failed_articles[] = [
                    'title' => $article_title,
                    'error' => $error_message,
                ];
            }

            // Return formatted error response
            return [
                'success' => false,
                'message' => $validation_result['message'] ?? 'Articles failed validation',
                'failedArticles' => $failed_articles,
                'code' => $validation_result['code'] ?? 403,
            ];
        }
        // If we have errors array but no results (single article case)
        else if (isset($validation_result['errors']) && is_array($validation_result['errors'])) {
            $errors = $validation_result['errors'];
            $error_message = $this->format_error_message($errors);

            return [
                'success' => false,
                'message' => $validation_result['message'] ?? 'Article failed validation',
                'errors' => $errors,
                'error_message' => $error_message,
                'code' => $validation_result['code'] ?? 403,
            ];
        }
        // If we have neither results nor errors array, but have a message
        else if (isset($validation_result['message'])) {
            return [
                'success' => false,
                'message' => $validation_result['message'],
                'code' => $validation_result['code'] ?? 403,
            ];
        }
        // Fallback for unknown error format
        else {
            return [
                'success' => false,
                'message' => 'Unknown validation error occurred',
                'code' => 403,
            ];
        }
    }

    /**
     * Format error messages from validation errors
     * 
     * @param array $errors Array of error objects
     * @return string Formatted error message
     */
    private function format_error_message($errors)
    {
        if (empty($errors)) {
            return 'Unknown validation error';
        }

        $messages = [];
        foreach ($errors as $error) {
            if (isset($error['param']) && isset($error['message'])) {
                $messages[] = $error['message'];
            }
        }

        return implode('. ', $messages);
    }
}
