<?php
declare(strict_types=1);
// ==================================================
// Nuclear Fancy Pants Edition™ -- NUCLEAR+++
// File: /home/ploi/automarketer-ai.com/public/wp-content/plugins/automarketer-ai/modules/img-flux.php
// Description: Flux (Black Forest Labs) image provider module -- NUCLEAR+++
// Last Edited: 2026-05-25
// ==================================================

namespace AutoMarketerAI\Modules;

use AutoMarketerAI\ImageProviderInterface;
use AutoMarketerAI\ImageProvider;

defined('ABSPATH') || exit;

final class ImgFlux implements ImageProviderInterface
{
    private const API_BASE     = 'https://api.bfl.ai/v1';
    private const DEFAULT_MODEL = 'flux-pro-1.1';

    // Endpoint slug per model ID.
    private const MODEL_ENDPOINTS = [
        'flux-pro-1.1'       => 'flux-pro-1.1',
        'flux-pro-1.1-ultra' => 'flux-pro-1.1-ultra',
        'flux-pro'           => 'flux-pro',
    ];

    // Per-model cost strings shown on the card chip.
    private const MODEL_COSTS = [
        'flux-pro-1.1'       => '$0.04 / image',
        'flux-pro-1.1-ultra' => '$0.06 / image',
        'flux-pro'           => '$0.05 / image',
    ];

    public function get_id(): string
    {
        return 'img-flux';
    }

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

    public function get_description(): string
    {
        return 'Black Forest Labs\' Flux produces high-quality, prompt-accurate marketing visuals with fast generation times.';
    }

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

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

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

    public function get_available_models(): array
    {
        return [
            'flux-pro-1.1'       => 'FLUX1.1 [pro] -- $0.04 / image',
            'flux-pro-1.1-ultra' => 'FLUX1.1 [pro] Ultra -- $0.06 / image',
            'flux-pro'           => 'FLUX.1 [pro] -- $0.05 / image',
        ];
    }

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

    public function validate_api_key(string $key): bool
    {
        if ($key === '') {
            return false;
        }

        // BFL keys are UUID-format -- validate by hitting the models list.
        $response = wp_remote_get(self::API_BASE . '/models', [
            'headers' => [
                'accept' => 'application/json',
                'x-key'  => $key,
            ],
            'timeout' => 10,
        ]);

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

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

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

    public function get_default_model(): string
    {
        return self::DEFAULT_MODEL;
    }

    public function render_activation_popup(): void
    {
        // Not used -- activation modal rendered by shared template.
    }

    public function register(): void
    {
        // No additional hooks needed.
    }

    public function generate_raw(string $prompt, string $api_key = '', string $model = ''): string
    {
        // Image providers do not implement generate_raw.
        return '';
    }

    // --------------------------------------------------
    // Generate an image using the BFL async polling API.
    // Submits a request, polls until Ready, downloads the
    // result URL to the WP media library.
    // Returns a local attachment URL on success, null on failure.
    // --------------------------------------------------
    public function generate_image(string $prompt, string $api_key): ?string
    {
        if ($prompt === '' || $api_key === '') {
            return null;
        }

        $active_model = (string) get_option('amai_model_img-flux', self::DEFAULT_MODEL);
        $endpoint     = self::MODEL_ENDPOINTS[$active_model] ?? self::MODEL_ENDPOINTS[self::DEFAULT_MODEL];
        $safe_prompt  = mb_substr($prompt, 0, 5000);

        $body = wp_json_encode([
            'prompt' => $safe_prompt,
            'width'  => 1024,
            'height' => 1024,
        ]);

        if ($body === false) {
            return null;
        }

        // Submit the generation request.
        $response = wp_remote_post(self::API_BASE . '/' . $endpoint, [
            'headers' => [
                'accept'       => 'application/json',
                'x-key'        => $api_key,
                'Content-Type' => 'application/json',
            ],
            'body'    => $body,
            'timeout' => 30,
        ]);

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

        $code = (int) wp_remote_retrieve_response_code($response);
        $json = json_decode(wp_remote_retrieve_body($response), true);

        if ($code !== 200 || !is_array($json) || empty($json['id']) || empty($json['polling_url'])) {
            return null;
        }

        $polling_url = (string) $json['polling_url'];

        // Poll until Ready or failed -- max 30 attempts at 2s intervals = 60s timeout.
        $max_attempts = 30;
        $image_url    = null;

        for ($i = 0; $i < $max_attempts; $i++) {
            sleep(2);

            $poll = wp_remote_get($polling_url, [
                'headers' => [
                    'accept' => 'application/json',
                    'x-key'  => $api_key,
                ],
                'timeout' => 15,
            ]);

            if (is_wp_error($poll)) {
                continue;
            }

            $poll_json = json_decode(wp_remote_retrieve_body($poll), true);

            if (!is_array($poll_json)) {
                continue;
            }

            $status = (string) ($poll_json['status'] ?? '');

            if ($status === 'Ready') {
                $url = $poll_json['result']['sample'] ?? '';
                if (is_string($url) && $url !== '') {
                    $image_url = $url;
                }
                break;
            }

            if ($status === 'Error' || $status === 'Failed') {
                break;
            }
        }

        if ($image_url === null) {
            return null;
        }

        return ImageProvider::downloadToMediaLibrary($image_url, 'amai-flux');
    }
}