<?php
declare(strict_types=1);
// ==================================================
// Nuclear Fancy Pants Edition™ — NUCLEAR+++
// File: modules/ai-gemini.php
// Last Edited: 2026-04-12
// Description: Gemini provider module — NUCLEAR+++
// ==================================================

namespace AutoMarketerAI\Modules;

use AutoMarketerAI\ModuleInterface;

if (!defined('ABSPATH')) {
    exit('No direct script access allowed.');
}

final class Gemini implements ModuleInterface
{
    private const PREFIX   = 'AIzaSy';
    private const MODAL_ID = 'gemini-activate-modal';

    // Ordered allowlist of Gemini text-generation models to surface in the UI.
    // Excludes embedding, vision-only, and AQA variants.
    private const MODEL_ALLOWLIST = [
        'gemini-2.5-pro'       => 'Gemini 2.5 Pro — Most capable',
        'gemini-2.5-flash'     => 'Gemini 2.5 Flash — Fast & efficient',
        'gemini-2.5-flash-lite' => 'Gemini 2.5 Flash Lite — Lightweight & fast',
    ];

    // Model name suffixes to exclude even if they pass prefix filter.
    private const EXCLUDE_SUFFIXES = [
        'embedding', 'embed', 'aqa', 'vision',
    ];

    public function get_id(): string
    {
        return 'ai-gemini';
    }

    public function get_name(): string
    {
        return 'Gemini';
    }

    public function get_description(): string
    {
        return 'Google\'s powerful multimodal AI. Excellent for reasoning, long context, coding, and general tasks.';
    }

    public function get_logo_url(): string
    {
        return '';
    }

    public function get_category(): string
    {
        return 'AI';
    }

    public function get_model_count(): int
    {
        return count(self::MODEL_ALLOWLIST);
    }

    public function get_available_models(): array
    {
        return self::MODEL_ALLOWLIST;
    }

    public function get_single_model_notice(): string
    {
        return '';
    }

    public function get_model_descriptions(): array
    {
        return [
            'gemini-2.5-pro'        => 'Most capable Gemini model. Best for complex reasoning, nuanced writing, and long-context tasks.',
            'gemini-2.5-flash'      => 'Fast and efficient with strong reasoning. Recommended for most content generation workloads.',
            'gemini-2.5-flash-lite' => 'Lightweight and cost-efficient. Great for high-volume, straightforward content tasks.',
        ];
    }

    // Fetch the live model list from Google and intersect with the allowlist.
    // Falls back to full allowlist on any error.
    public function fetch_live_models(string $key): array
    {
        $response = wp_remote_get(
            'https://generativelanguage.googleapis.com/v1beta/models?key=' . rawurlencode($key),
            ['timeout' => 10]
        );

        if (is_wp_error($response) || (int) wp_remote_retrieve_response_code($response) !== 200) {
            return self::MODEL_ALLOWLIST;
        }

        $body = json_decode(wp_remote_retrieve_body($response), true);
        if (!is_array($body) || empty($body['models'])) {
            return self::MODEL_ALLOWLIST;
        }

        // Build set of live model IDs — API returns 'models/gemini-1.5-pro', strip prefix.
        $live_ids = [];
        foreach ($body['models'] as $m) {
            if (!isset($m['name'])) {
                continue;
            }
            $id = str_replace('models/', '', (string) $m['name']);

            // Only include generateContent-capable models.
            $methods = $m['supportedGenerationMethods'] ?? [];
            if (!in_array('generateContent', $methods, true)) {
                continue;
            }

            // Exclude embedding, vision-only, AQA variants.
            foreach (self::EXCLUDE_SUFFIXES as $suffix) {
                if (str_contains(strtolower($id), $suffix)) {
                    continue 2;
                }
            }

            $live_ids[] = $id;
        }

        // Intersect allowlist with live IDs, preserving allowlist order.
        $result = [];
        foreach (self::MODEL_ALLOWLIST as $model_id => $label) {
            if (in_array($model_id, $live_ids, true)) {
                $result[$model_id] = $label;
            }
        }

        // If none matched (new key, older account), fall back to full allowlist.
        return !empty($result) ? $result : self::MODEL_ALLOWLIST;
    }

    public function validate_api_key(string $key): bool
    {
        if (!str_starts_with($key, 'AIza')) {
            return false;
        }

        $response = wp_remote_get(
            'https://generativelanguage.googleapis.com/v1beta/models?key=' . $key,
            ['timeout' => 10]
        );

        if (is_wp_error($response)) {
            return false;
        }

        return (int) wp_remote_retrieve_response_code($response) === 200;
    }

    public function generate_raw(string $prompt, string $api_key, string $model, int $max_tokens = 64): string
    {
        if ($prompt === '' || $api_key === '' || $model === '') {
            return '';
        }

        // Gemini uses a REST endpoint with the model in the URL and key as query param
        $url = 'https://generativelanguage.googleapis.com/v1beta/models/'
            . rawurlencode($model)
            . ':generateContent?key='
            . rawurlencode($api_key);

        $response = wp_remote_post($url, [
            'headers' => ['Content-Type' => 'application/json'],
            'body'    => (string) json_encode([
                'contents'         => [['parts' => [['text' => $prompt]]]],
                'generationConfig' => ['maxOutputTokens' => $max_tokens],
            ]),
            'timeout' => 15,
        ]);

        if (is_wp_error($response)) {
            return '';
        }

        $http_code = (int) wp_remote_retrieve_response_code($response);
        if ($http_code !== 200) {
            if ($http_code === 401 || $http_code === 429) {
                set_transient('amai_provider_credit_warning', $this->get_id(), HOUR_IN_SECONDS);
            }
            return '';
        }

        $body = json_decode(wp_remote_retrieve_body($response), true);
        return trim((string) ($body['candidates'][0]['content']['parts'][0]['text'] ?? ''));
    }

    public function register(): void
    {
        add_action('admin_footer', [$this, 'render_activation_popup']);
    }

    public function get_default_model(): string
    {
        return 'gemini-2.5-flash';
    }

    public function get_api_key_prefix(): string
    {
        return self::PREFIX;
    }

    public function render_activation_popup(): void
    {
        $nonce          = wp_create_nonce('amai_provider_actions');
        $active_modules = (array) get_option('amai_active_modules', []);
        $is_active      = in_array($this->get_id(), $active_modules);
        $saved_model    = $is_active ? get_option('amai_' . $this->get_id() . '_model', 'gemini-1.5-pro') : '';
        $prefix         = $this->get_api_key_prefix();
        ?>
        <script type="text/javascript">
            jQuery(document).ready(function($) {
                $(document).on('click', '[data-module-id="<?php echo esc_js($this->get_id()); ?>"] .amai-activate-btn', function(e) {
                    e.preventDefault();
                    e.stopPropagation();

                    const modalId = '<?php echo esc_js(self::MODAL_ID); ?>';
                    $('#' + modalId).remove();

                    const popupHtml = `
                        <div id="${modalId}" style="display:none; position:fixed; inset:0; width:100%; height:100%; background:rgba(0,0,0,0.65); z-index:99999; display:flex; align-items:center; justify-content:center;">
                            <div style="background:#ffffff; padding:28px; width:480px; max-width:92%; max-height:90vh; overflow-y:auto; box-shadow:0 20px 70px rgba(0,0,0,0.45); position:relative;">
                                <button id="${modalId}-close" style="position:absolute; top:12px; right:16px; background:none; border:none; font-size:32px; color:#555; cursor:pointer; line-height:1; padding:0;">×</button>
                                <h3 style="margin:0 0 24px; text-align:center; font-size:24px; color:#111; font-weight:600;">Activate <?php echo esc_html($this->get_name()); ?></h3>
                                <p style="margin-bottom:24px; text-align:center; color:#555; font-size:14px;">Google AI Studio API is free to start — generous credits for testing.</p>
                                <div id="${modalId}-error" style="display:none; margin:0 0 20px; padding:14px; background:#ffebee; border-left:5px solid #c62828; color:#b71c1c; font-size:14px; border-radius:4px;"></div>
                                <label for="${modalId}-key" style="display:block; margin-bottom:10px; font-weight:600; color:#222; font-size:15px;">Your Gemini API Key:</label>
                                <input type="text" id="${modalId}-key" placeholder="<?php echo esc_attr($prefix . '...'); ?>" style="width:100%; padding:12px; margin-bottom:20px; border:1px solid #ccc; font-size:15px; box-sizing:border-box;">
                                <label for="${modalId}-model" style="display:block; margin-bottom:10px; font-weight:600; color:#222; font-size:15px;">Preferred Model:</label>
                                <select id="${modalId}-model" style="width:100%; padding:12px; margin-bottom:24px; border:1px solid #ccc; font-size:15px; box-sizing:border-box;">
                                    <option value="">Select model</option>
                                    <?php
                                    foreach (self::MODEL_ALLOWLIST as $value => $label) {
                                        $selected = ($value === $saved_model) ? 'selected' : '';
                                        echo '<option value="' . esc_attr($value) . '" ' . $selected . '>' . esc_html($label) . '</option>';
                                    }
                                    ?>
                                </select>
                                <p style="margin-bottom:24px; text-align:center; color:#555; font-size:14px;">Don't have a key? <a href="https://aistudio.google.com/app/apikey" target="_blank" style="color:#2271b1; text-decoration:none;">Get one free in 1 minute</a>.</p>
                                <div style="text-align:center;">
                                    <button id="${modalId}-cancel" style="padding:12px 32px; margin-right:16px; background:#f5f5f5; border:1px solid #ccc; color:#333; font-size:15px; cursor:pointer; transition:background 0.2s;">Cancel</button>
                                    <button id="${modalId}-save" style="padding:12px 32px; background:#2271b1; color:white; border:none; font-size:15px; cursor:pointer; transition:background 0.2s;">Save & Activate</button>
                                </div>
                            </div>
                        </div>
                    `;

                    $('body').append(popupHtml);
                    const modal = $('#' + modalId);
                    modal.fadeIn(200);

                    <?php if ($is_active): ?>
                    modal.find('#' + modalId + '-save').text('Update & Save');
                    <?php endif; ?>

                    modal.find('#' + modalId + '-cancel').hover(function() { $(this).css('background', '#e0e0e0'); }, function() { $(this).css('background', '#f5f5f5'); });
                    modal.find('#' + modalId + '-save').hover(function() { $(this).css('background', '#1a5bb8'); }, function() { $(this).css('background', '#2271b1'); });

                    modal.find('#' + modalId + '-close, #' + modalId + '-cancel').on('click', function() {
                        modal.fadeOut(200, () => modal.remove());
                    });

                    modal.on('click', function(e) {
                        if (e.target === this) modal.fadeOut(200, () => modal.remove());
                    });

                    modal.find('#' + modalId + '-save').on('click', function() {
                        const apiKey = modal.find('#' + modalId + '-key').val().trim();
                        const model  = modal.find('#' + modalId + '-model').val() || 'gemini-1.5-pro';

                        if (!apiKey) {
                            modal.find('#' + modalId + '-error').text('Please enter your Gemini API Key.').show();
                            return;
                        }

                        modal.find('#' + modalId + '-error').hide();

                        $.post(ajaxurl, {
                            action:      'amai_activate_provider',
                            provider_id: '<?php echo esc_js($this->get_id()); ?>',
                            api_key:     apiKey,
                            model:       model,
                            _ajax_nonce: '<?php echo esc_js($nonce); ?>',
                        }, function(response) {
                            if (response.success) {
                                modal.fadeOut(200, () => { modal.remove(); location.reload(); });
                            } else {
                                modal.find('#' + modalId + '-error').text(response.data?.message || 'Activation failed. Please try again.').show();
                            }
                        }).fail(function() {
                            modal.find('#' + modalId + '-error').text('Connection error — please try again.').show();
                        });
                    });

                    modal.find('#' + modalId + '-key').on('input', function() {
                        modal.find('#' + modalId + '-error').hide();
                    });

                    modal.find('#' + modalId + '-key').focus();
                });
            });
        </script>
        <?php
    }
}