<?php
declare(strict_types=1);
// ==================================================
// Nuclear Fancy Pants Edition™ — NUCLEAR+++
// File: /home/ploi/automarketer-ai.com/public/wp-content/plugins/automarketer-ai/includes/class-unsplash.php
// Description: Unsplash API wrapper — keyword extraction, photo search, media library download - NUCLEAR+++
// Last Edited: 2026-04-12
// ==================================================
namespace AutoMarketerAI;
defined('ABSPATH') || exit;

final class Unsplash
{
    private const API_BASE = 'https://api.unsplash.com';
    private const STOPWORDS = [
        'a','an','the','and','or','but','in','on','at','to','for','of','with',
        'is','it','its','be','are','was','were','has','have','had','this','that',
        'we','our','your','their','they','you','i','my','me','us','he','she',
        'as','by','so','do','did','not','no','can','will','just','from','about',
        'into','than','then','when','there','what','which','who','how','all',
        'been','more','also','get','got','like','up','out','if','she','he',
    ];

    // Extract 2-3 keywords from post copy using the active AI provider.
    // Falls back to mechanical extraction if no provider is active or the call fails.
    public static function extractKeywordsAi(string $content): string
    {
        if (trim($content) === '') {
            return '';
        }

        // Resolve the active ai-* provider
        $active = (array) get_option('amai_active_modules', []);
        $provider_id = null;
        foreach ($active as $module_id) {
            if (is_string($module_id) && str_starts_with($module_id, 'ai-')) {
                $provider_id = $module_id;
                break;
            }
        }

        if ($provider_id === null) {
            return self::extractKeywords($content);
        }

        $module_file = AMAI_PLUGIN_DIR . '/modules/' . $provider_id . '.php';
        if (!is_file($module_file)) {
            return self::extractKeywords($content);
        }

        require_once $module_file;

        // Resolve class name — mirrors load_modules() logic in AdminPage
        // e.g. 'ai-claude' -> 'Claude', 'ai-openai' -> 'Openai', 'ai-gemini' -> 'Gemini'
        $basename  = substr($provider_id, 3); // strip 'ai-'
        $classname = 'AutoMarketerAI\\Modules\\' . ucfirst($basename);

        if (!class_exists($classname)) {
            return self::extractKeywords($content);
        }

        $api_key = KeyVault::decrypt((string) get_option('amai_api_key_' . $provider_id, ''));
        if ($api_key === '') {
            return self::extractKeywords($content);
        }

        $model = (string) get_option('amai_model_' . $provider_id, '');
        if ($model === '') {
            $provider_instance = new $classname();
            $model = $provider_instance->get_default_model();
        }

        $prompt = 'You are a stock photo search assistant. Given the following social media post, '
            . 'reply with exactly 2 to 3 keywords that would find a relevant, high-quality landscape '
            . 'photo on Unsplash. The keywords must be concrete and visual - things a photographer '
            . 'would actually shoot. Avoid abstract business jargon. Reply with only the keywords '
            . 'separated by spaces, nothing else.' . "\n\n"
            . 'Post: ' . $content;

        $provider = new $classname();
        $result   = $provider->generate_raw($prompt, $api_key, $model);

        if ($result === '') {
            return self::extractKeywords($content);
        }

        // Sanitize: keep only letters, numbers, spaces — strip any punctuation the model sneaks in
        $clean = preg_replace('/[^a-zA-Z0-9\s]/', ' ', $result);
        $clean = trim((string) preg_replace('/\s+/', ' ', (string) $clean));

        // Enforce max 3 words — truncate if model went over
        $words = explode(' ', $clean);
        $words = array_filter($words, fn(string $w): bool => $w !== '');
        $words = array_slice(array_values($words), 0, 3);

        $keywords = implode(' ', $words);
        return $keywords !== '' ? $keywords : self::extractKeywords($content);
    }

    // Mechanical fallback: extract 2-3 keywords from post copy by stopword filtering.
    // Used when no AI provider is active or the AI call fails.
    public static function extractKeywords(string $content): string
    {
        $content = strtolower($content);
        $content = preg_replace('/[^a-z\s]/', ' ', $content);
        $words   = preg_split('/\s+/', trim($content));
        $words   = array_filter($words, function (string $w): bool {
            return strlen($w) > 3 && !in_array($w, self::STOPWORDS, true);
        });
        $words = array_values($words);
        $top   = array_slice($words, 0, 3);
        return implode(' ', $top);
    }

    // Search Unsplash and return best result as [url, photographer, profile_url] or null.
    // Used by the scheduled post panel (auto-accepts first result).
    public static function search(string $query): ?array
    {
        $key = defined('UNSPLASH_ACCESS_KEY') ? UNSPLASH_ACCESS_KEY : '';
        if ($key === '' || $query === '') {
            return null;
        }
        $url      = self::API_BASE . '/search/photos?query=' . urlencode($query) . '&per_page=5&orientation=landscape';
        $response = wp_remote_get($url, [
            'headers' => [
                'Authorization'  => 'Client-ID ' . $key,
                'Accept-Version' => 'v1',
            ],
            'timeout' => 10,
        ]);
        if (is_wp_error($response)) {
            return null;
        }
        $code = wp_remote_retrieve_response_code($response);
        if ($code !== 200) {
            return null;
        }
        $body = json_decode(wp_remote_retrieve_body($response), true);
        if (empty($body['results'])) {
            return null;
        }
        $photo        = $body['results'][0];
        $img_url      = $photo['urls']['regular'] ?? '';
        $photographer = $photo['user']['name'] ?? '';
        $profile_url  = $photo['user']['links']['html'] ?? '';
        $download_url = $photo['links']['download_location'] ?? '';
        if ($img_url === '') {
            return null;
        }
        // Trigger Unsplash download tracking as required by API guidelines
        if ($download_url !== '') {
            wp_remote_get($download_url . '?client_id=' . $key, ['timeout' => 5, 'blocking' => false]);
        }
        return [
            'url'          => $img_url,
            'photographer' => $photographer,
            'profile_url'  => $profile_url,
        ];
    }

    // Search Unsplash and return multiple results for user selection.
    // Used by the manual compose page — returns up to $limit results.
    // Each result: [url, thumb, photographer, profile_url, download_location].
    // Does NOT trigger download tracking — tracking fires only when user accepts.
    public static function searchMultiple(string $query, int $limit = 6): array
    {
        $key = defined('UNSPLASH_ACCESS_KEY') ? UNSPLASH_ACCESS_KEY : '';
        if ($key === '' || $query === '') {
            return [];
        }
        $per_page = min(max($limit, 1), 30);
        $url      = self::API_BASE . '/search/photos?query=' . urlencode($query) . '&per_page=' . $per_page . '&orientation=landscape';
        $response = wp_remote_get($url, [
            'headers' => [
                'Authorization'  => 'Client-ID ' . $key,
                'Accept-Version' => 'v1',
            ],
            'timeout' => 10,
        ]);
        if (is_wp_error($response)) {
            return [];
        }
        $code = wp_remote_retrieve_response_code($response);
        if ($code !== 200) {
            return [];
        }
        $body = json_decode(wp_remote_retrieve_body($response), true);
        if (empty($body['results'])) {
            return [];
        }
        $results = [];
        foreach (array_slice($body['results'], 0, $limit) as $photo) {
            $img_url      = $photo['urls']['regular'] ?? '';
            $thumb_url    = $photo['urls']['small']   ?? '';
            $photographer = $photo['user']['name']          ?? '';
            $profile_url  = $photo['user']['links']['html'] ?? '';
            $download_loc = $photo['links']['download_location'] ?? '';
            if ($img_url === '') {
                continue;
            }
            $results[] = [
                'url'               => $img_url,
                'thumb'             => $thumb_url !== '' ? $thumb_url : $img_url,
                'photographer'      => $photographer,
                'profile_url'       => $profile_url,
                'download_location' => $download_loc,
            ];
        }
        return $results;
    }

    // Trigger Unsplash download tracking for a single photo.
    // Must be called when the user accepts/selects a photo from searchMultiple().
    public static function trackDownload(string $download_location): void
    {
        $key = defined('UNSPLASH_ACCESS_KEY') ? UNSPLASH_ACCESS_KEY : '';
        if ($key === '' || $download_location === '') {
            return;
        }
        wp_remote_get($download_location . '?client_id=' . $key, ['timeout' => 5, 'blocking' => false]);
    }

    // Download photo to WP media library, return attachment ID or 0 on failure
    public static function downloadToMedia(string $url, string $photographer, int $post_id, string $profile_url = ''): int
    {
        require_once ABSPATH . 'wp-admin/includes/file.php';
        require_once ABSPATH . 'wp-admin/includes/media.php';
        require_once ABSPATH . 'wp-admin/includes/image.php';
        $tmp = download_url($url, 15);
        if (is_wp_error($tmp)) {
            return 0;
        }
        $uploads   = wp_upload_dir();
        $filename  = 'amai-unsplash-' . $post_id . '-' . time() . '.jpg';
        $dest      = $uploads['basedir'] . '/' . $filename;
        $dest_url  = $uploads['baseurl'] . '/' . $filename;
        // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
        if (!@copy($tmp, $dest)) {
            @unlink($tmp);
            return 0;
        }
        @unlink($tmp);
        $wp_filetype = wp_check_filetype($filename, null);
        $attachment  = [
            'post_mime_type' => $wp_filetype['type'],
            'post_title'     => 'Photo by ' . $photographer . ' on Unsplash',
            'post_content'   => '',
            'post_status'    => 'inherit',
        ];
        $attachment_id = wp_insert_attachment($attachment, $dest, 0);
        if (is_wp_error($attachment_id) || $attachment_id === 0) {
            @unlink($dest);
            return 0;
        }
        $metadata = wp_generate_attachment_metadata($attachment_id, $dest);
        wp_update_attachment_metadata($attachment_id, $metadata);
        if (isset($profile_url) && is_string($profile_url) && $profile_url !== '') {
            update_post_meta($attachment_id, '_amai_unsplash_profile_url', $profile_url);
        }
        update_post_meta($attachment_id, '_amai_unsplash_source_url', $url);
        return (int) $attachment_id;
    }
}