<?php
namespace AIFI;

/**
 * Handles bulk AI image generation for multiple posts.
 *
 * @package AIFI
 */
class Bulk {
    /**
     * Settings instance.
     *
     * @var Settings
     */
    private $settings;

    /**
     * Generator instance.
     *
     * @var Generator
     */
    private $generator;

    /**
     * Parent menu slug.
     *
     * @var string
     */
    private $parent_slug = 'ai-featured-image-generator';

    /**
     * Initialize bulk generation.
     */
    public function __construct($settings, $generator) {
        $this->settings = $settings;
        $this->generator = $generator;

        add_action('rest_api_init', array($this, 'register_routes'));

        // Register bulk actions for enabled post types
        $post_types = $this->settings->get_enabled_post_types();
        foreach ($post_types as $post_type) {
            add_filter("bulk_actions-edit-{$post_type}", array($this, 'register_bulk_action'));
            add_filter("handle_bulk_actions-edit-{$post_type}", array($this, 'handle_bulk_action'), 10, 3);
        }
    }

    /**
     * Check if user has premium license.
     *
     * @return bool
     */
    private function is_premium_user() {
        return function_exists('afig_fs') && afig_fs()->can_use_premium_code();
    }

    /**
     * Maximum bulk batches for free users.
     */
    const FREE_BATCH_LIMIT = 50;

    /**
     * Maximum posts per batch for free users.
     */
    const FREE_POST_LIMIT = 5;

    /**
     * Register bulk action on post list pages.
     *
     * @param array $actions Existing bulk actions.
     * @return array
     */
    public function register_bulk_action($actions) {
        $actions['aifi_bulk_generate'] = __('Generate AI Featured Images', 'ai-featured-image-generator');
        return $actions;
    }

    /**
     * Handle bulk action from post list.
     *
     * @param string $redirect_url Redirect URL.
     * @param string $action       Action name.
     * @param array  $post_ids     Selected post IDs.
     * @return string
     */
    public function handle_bulk_action($redirect_url, $action, $post_ids) {
        if ($action !== 'aifi_bulk_generate') {
            return $redirect_url;
        }

        $ids = implode(',', array_map('absint', $post_ids));
        $nonce = wp_create_nonce('aifi_bulk_generate');
        return admin_url('admin.php?page=' . $this->parent_slug . '&tab=bulk&action=generate&post_ids=' . $ids . '&_wpnonce=' . $nonce);
    }

    /**
     * Register REST API routes.
     */
    public function register_routes() {
        register_rest_route('aifi/v1', '/bulk-generate', array(
            'methods'             => 'POST',
            'callback'            => array($this, 'bulk_generate_image'),
            'permission_callback' => array($this, 'check_bulk_permission'),
            'args'                => array(
                'post_id' => array(
                    'required'          => true,
                    'type'              => 'integer',
                    'sanitize_callback' => 'absint',
                ),
                'overwrite' => array(
                    'required'          => false,
                    'type'              => 'boolean',
                    'default'           => false,
                    'sanitize_callback' => 'rest_sanitize_boolean',
                ),
                'generate_prompt' => array(
                    'required'          => false,
                    'type'              => 'boolean',
                    'default'           => false,
                    'sanitize_callback' => 'rest_sanitize_boolean',
                ),
            ),
        ));

        register_rest_route('aifi/v1', '/bulk-posts', array(
            'methods'             => 'GET',
            'callback'            => array($this, 'get_bulk_posts'),
            'permission_callback' => array($this, 'check_bulk_permission_read'),
            'args'                => array(
                'post_type' => array(
                    'required'          => false,
                    'type'              => 'string',
                    'default'           => 'post',
                    'sanitize_callback' => 'sanitize_text_field',
                ),
                'post_status' => array(
                    'required'          => false,
                    'type'              => 'string',
                    'default'           => 'publish',
                    'sanitize_callback' => 'sanitize_text_field',
                ),
                'has_thumbnail' => array(
                    'required'          => false,
                    'type'              => 'string',
                    'default'           => 'any',
                    'sanitize_callback' => 'sanitize_text_field',
                ),
                'date_from' => array(
                    'required'          => false,
                    'type'              => 'string',
                    'sanitize_callback' => 'sanitize_text_field',
                ),
                'date_to' => array(
                    'required'          => false,
                    'type'              => 'string',
                    'sanitize_callback' => 'sanitize_text_field',
                ),
                'per_page' => array(
                    'required'          => false,
                    'type'              => 'integer',
                    'default'           => 50,
                    'sanitize_callback' => 'absint',
                ),
                'page' => array(
                    'required'          => false,
                    'type'              => 'integer',
                    'default'           => 1,
                    'sanitize_callback' => 'absint',
                ),
            ),
        ));
    }

    /**
     * Permission check for bulk generate endpoint.
     *
     * @param \WP_REST_Request $request Request object.
     * @return bool|\WP_Error
     */
    public function check_bulk_permission($request) {
        // Check batch limit for free users
        if (!$this->is_premium_user()) {
            $usage = $this->get_bulk_usage();
            if ($usage >= self::FREE_BATCH_LIMIT) {
                return new \WP_Error(
                    'batch_limit_reached',
                    __('You have reached your free bulk generation limit (50 images). Upgrade to Pro for unlimited bulk generation.', 'ai-featured-image-generator'),
                    array('status' => 403)
                );
            }
        }

        $post_id = absint($request['post_id']);

        if (!current_user_can('edit_post', $post_id)) {
            return new \WP_Error(
                'rest_forbidden',
                __('Sorry, you are not allowed to edit this post.', 'ai-featured-image-generator'),
                array('status' => rest_authorization_required_code())
            );
        }

        $post = get_post($post_id);
        if (!$post) {
            return new \WP_Error(
                'rest_invalid_post',
                __('Invalid post.', 'ai-featured-image-generator'),
                array('status' => 404)
            );
        }

        $enabled_post_types = $this->settings->get_enabled_post_types();
        if (!in_array($post->post_type, $enabled_post_types, true)) {
            return new \WP_Error(
                'rest_post_type_not_enabled',
                __('AI image generation is not enabled for this post type.', 'ai-featured-image-generator'),
                array('status' => 403)
            );
        }

        return true;
    }

    /**
     * Permission check for bulk posts listing endpoint.
     *
     * @param \WP_REST_Request $request Request object.
     * @return bool|\WP_Error
     */
    public function check_bulk_permission_read($request) {
        if (!current_user_can('edit_posts')) {
            return new \WP_Error(
                'rest_forbidden',
                __('Sorry, you are not allowed to view posts.', 'ai-featured-image-generator'),
                array('status' => rest_authorization_required_code())
            );
        }

        return true;
    }

    /**
     * Generate image for a single post (bulk endpoint).
     *
     * @param \WP_REST_Request $request Request object.
     * @return \WP_REST_Response|\WP_Error
     */
    public function bulk_generate_image($request) {
        $post_id         = $request['post_id'];
        $overwrite       = $request['overwrite'];
        $generate_prompt = $request['generate_prompt'];

        $post = get_post($post_id);
        if (!$post) {
            return new \WP_Error('invalid_post', __('Post not found.', 'ai-featured-image-generator'), array('status' => 404));
        }

        // Skip if post already has a featured image and overwrite is off
        if (!$overwrite && has_post_thumbnail($post_id)) {
            return rest_ensure_response(array(
                'success'    => true,
                'skipped'    => true,
                'post_id'    => $post_id,
                'post_title' => $post->post_title,
                'reason'     => __('Post already has a featured image.', 'ai-featured-image-generator'),
            ));
        }

        // Check API key
        $settings_data = $this->settings->get_settings();
        $provider      = isset($settings_data['ai_provider']) ? $settings_data['ai_provider'] : 'openai';

        if ($provider === 'gemini' && !$this->is_premium_user()) {
            $provider = 'openai';
        }

        $api_key_fields = array(
            'openai'    => 'openai_api_key',
            'gemini'    => 'gemini_api_key',
            'stability' => 'stability_api_key',
            'grok'      => 'grok_api_key',
        );
        $api_key_field = isset($api_key_fields[$provider]) ? $api_key_fields[$provider] : 'openai_api_key';

        // Legacy fallback for OpenAI
        if ($provider === 'openai' && empty($settings_data['openai_api_key']) && !empty($settings_data['api_key'])) {
            $api_key_field = 'api_key';
        }

        $provider_labels = array(
            'openai'    => 'OpenAI',
            'gemini'    => 'Google Gemini',
            'stability' => 'Stability AI',
            'grok'      => 'Grok (xAI)',
        );

        if (empty($settings_data[$api_key_field])) {
            return new \WP_Error(
                'no_api_key',
                sprintf(
                    __('API key not configured for %s.', 'ai-featured-image-generator'),
                    isset($provider_labels[$provider]) ? $provider_labels[$provider] : $provider
                ),
                array('status' => 400)
            );
        }

        // Optionally generate a content-based prompt before creating the image
        $prompt = '';
        if ($generate_prompt) {
            $prompt_result = $this->generator->generate_prompt_from_content($post_id);
            if (is_wp_error($prompt_result)) {
                // Log the failure but do not abort — fall back to title-only generation
                error_log('AIFI: Prompt generation failed for post ' . $post_id . ': ' . $prompt_result->get_error_message());
            } else {
                $prompt = $prompt_result;
                update_post_meta($post_id, '_aifi_custom_prompt', $prompt);
            }
        }

        // Generate image using existing generator (pass post title for filename)
        $result = $this->generator->generate_image($post_id, $prompt, '', $post->post_title, '', null);

        if (is_wp_error($result)) {
            return $result;
        }

        // Increment batch usage for free users
        if (!$this->is_premium_user()) {
            $this->increment_bulk_usage();
        }

        return rest_ensure_response(array(
            'success'       => true,
            'skipped'       => false,
            'post_id'       => $post_id,
            'post_title'    => $post->post_title,
            'attachment_id' => $result,
            'url'           => wp_get_attachment_url($result),
        ));
    }

    /**
     * Get posts for bulk generation page.
     *
     * @param \WP_REST_Request $request Request object.
     * @return \WP_REST_Response
     */
    public function get_bulk_posts($request) {
        $is_premium    = $this->is_premium_user();
        $post_type     = $is_premium ? $request['post_type'] : 'post';
        $post_status   = $request['post_status'];
        $has_thumbnail = $is_premium ? $request['has_thumbnail'] : 'any';
        $date_from     = $is_premium ? $request['date_from'] : '';
        $date_to       = $is_premium ? $request['date_to'] : '';
        $per_page      = min(100, max(1, $request['per_page']));
        $page          = max(1, $request['page']);

        // Validate post type is enabled
        $enabled_post_types = $this->settings->get_enabled_post_types();
        if (!in_array($post_type, $enabled_post_types, true)) {
            return new \WP_Error(
                'invalid_post_type',
                __('This post type is not enabled for AI image generation.', 'ai-featured-image-generator'),
                array('status' => 400)
            );
        }

        // Validate and set post status
        $allowed_statuses = array('publish', 'draft');
        if ($post_status === 'any') {
            $query_status = $allowed_statuses;
        } elseif (in_array($post_status, $allowed_statuses, true)) {
            $query_status = $post_status;
        } else {
            $query_status = 'publish';
        }

        $args = array(
            'post_type'      => $post_type,
            'post_status'    => $query_status,
            'posts_per_page' => $per_page,
            'paged'          => $page,
            'orderby'        => 'date',
            'order'          => 'DESC',
        );

        // Filter by thumbnail status
        if ($has_thumbnail === 'no') {
            $args['meta_query'] = array(
                array(
                    'key'     => '_thumbnail_id',
                    'compare' => 'NOT EXISTS',
                ),
            );
        } elseif ($has_thumbnail === 'yes') {
            $args['meta_query'] = array(
                array(
                    'key'     => '_thumbnail_id',
                    'compare' => 'EXISTS',
                ),
            );
        }

        // Date range
        if (!empty($date_from) || !empty($date_to)) {
            $date_query = array();
            if (!empty($date_from)) {
                $date_query['after'] = $date_from;
            }
            if (!empty($date_to)) {
                $date_query['before'] = $date_to;
                $date_query['inclusive'] = true;
            }
            $args['date_query'] = array($date_query);
        }

        $query = new \WP_Query($args);
        $posts = array();

        foreach ($query->posts as $post) {
            $has_thumb    = has_post_thumbnail($post->ID);
            $thumb_url    = $has_thumb ? get_the_post_thumbnail_url($post->ID, 'thumbnail') : '';

            $posts[] = array(
                'id'            => $post->ID,
                'title'         => $post->post_title,
                'has_thumbnail' => $has_thumb,
                'thumbnail_url' => $thumb_url,
                'edit_url'      => get_edit_post_link($post->ID, 'raw'),
                'date'          => get_the_date('Y-m-d', $post),
            );
        }

        return rest_ensure_response(array(
            'posts'       => $posts,
            'total'       => (int) $query->found_posts,
            'total_pages' => (int) $query->max_num_pages,
            'page'        => $page,
        ));
    }

    /**
     * Get the number of bulk batches used by free users.
     *
     * @return int
     */
    public function get_bulk_usage() {
        return (int) get_option('aifi_bulk_usage_count', 0);
    }

    /**
     * Increment the bulk usage counter.
     */
    private function increment_bulk_usage() {
        $count = $this->get_bulk_usage();
        update_option('aifi_bulk_usage_count', $count + 1);
    }
}
