<?php

/**
 * Media-library button + auto-generate-on-upload.
 *
 * @package BulkAltText
 */

declare(strict_types=1);

namespace BulkAltText\Media;

use BulkAltText\Ai\AiService;
use BulkAltText\Licensing\LicenseManager;
use WP_Post;

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

class MediaIntegration
{
    public function register(): void
    {
        add_filter('attachment_fields_to_edit', [$this, 'attachment_field'], 10, 2);
        add_action('add_attachment', [$this, 'maybe_auto_generate']);
        add_action('admin_enqueue_scripts', [$this, 'enqueue']);
    }

    /**
     * Inject an AI button next to the alt-text field in the media modal.
     *
     * @param array<string,mixed> $fields
     * @return array<string,mixed>
     */
    public function attachment_field(array $fields, WP_Post $post): array
    {
        if (strpos((string) $post->post_mime_type, 'image') !== 0) {
            return $fields;
        }

        // The AI button is a Pro feature — don't show it on the free plan.
        if (!LicenseManager::instance()->is_pro()) {
            return $fields;
        }

        $button = sprintf(
            '<button type="button" class="button batai-alt" data-attachment-id="%d">%s</button> <span class="batai-alt-status"></span>',
            (int) $post->ID,
            esc_html__('✨ Generate alt text with AI', 'bulk-alt-text-ai')
        );

        if (isset($fields['_wp_attachment_image_alt'])) {
            $fields['_wp_attachment_image_alt']['helps'] =
                ( $fields['_wp_attachment_image_alt']['helps'] ?? '' ) . '<br>' . $button;
        } else {
            $fields['batai_alt'] = [
                'label' => __('Alt text', 'bulk-alt-text-ai'),
                'input' => 'html',
                'html'  => $button,
            ];
        }

        return $fields;
    }

    /**
     * Automatically generate alt text when a new image is uploaded, if enabled.
     */
    public function maybe_auto_generate(int $attachmentId): void
    {
        $settings = self::settings();
        if (empty($settings['auto_on_upload'])) {
            return;
        }

        if (strpos((string) get_post_mime_type($attachmentId), 'image') !== 0) {
            return;
        }

        // Auto-generation uses the AI, which is Pro-only.
        if (is_wp_error(LicenseManager::instance()->can_generate())) {
            return;
        }

        // Don't clobber an alt text the uploader already typed.
        if (!$settings['overwrite'] && get_post_meta($attachmentId, AltWriter::ALT_META, true) !== '') {
            return;
        }

        $text = ( new AiService() )->alt_text(
            AltWriter::context($attachmentId),
            ['language' => $settings['language'], 'max_length' => $settings['max_length']]
        );

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

        AltWriter::apply($attachmentId, $text);
    }

    /**
     * Enqueue admin assets on the media + settings screens.
     */
    public function enqueue(string $hook): void
    {
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only screen routing.
        $page       = isset($_GET['page']) ? sanitize_key((string) wp_unslash($_GET['page'])) : '';
        $isSettings = $page === 'bulk-alt-text-ai';

        if ($hook !== 'upload.php' && $hook !== 'post.php' && !$isSettings) {
            return;
        }

        wp_enqueue_style(
            'batai-admin',
            BATAI_URL . 'assets/admin.css',
            [],
            BATAI_VERSION
        );

        wp_enqueue_script(
            'batai-admin',
            BATAI_URL . 'assets/admin.js',
            ['wp-api-fetch', 'wp-i18n'],
            BATAI_VERSION,
            true
        );

        if (function_exists('wp_set_script_translations')) {
            wp_set_script_translations('batai-admin', 'bulk-alt-text-ai');
        }

        $license = LicenseManager::instance();
        wp_localize_script('batai-admin', 'BATAI', [
            'root'     => esc_url_raw(rest_url('bulk-alt-text-ai/v1')),
            'nonce'    => wp_create_nonce('wp_rest'),
            'isPro'    => $license->is_pro(),
            'checkout' => $license->upgrade_url(),
            'i18n'     => [
                'generating'  => __('Generating…', 'bulk-alt-text-ai'),
                'error'       => __('Something went wrong.', 'bulk-alt-text-ai'),
                'upgrade'     => __('Upgrade to Pro', 'bulk-alt-text-ai'),
                'done'        => __('Done', 'bulk-alt-text-ai'),
                'confirm'     => __('Restore the original alt text for every image this plugin generated? This cannot be undone.', 'bulk-alt-text-ai'),
                'testing'     => __('Testing…', 'bulk-alt-text-ai'),
                'loading'     => __('Loading…', 'bulk-alt-text-ai'),
                'applying'    => __('Applying…', 'bulk-alt-text-ai'),
                'noSelection' => __('Select at least one image in the audit table first.', 'bulk-alt-text-ai'),
                'noText'      => __('Type the test text first.', 'bulk-alt-text-ai'),
                'selected'    => __('%d selected', 'bulk-alt-text-ai'),
                'appliedTo'   => __('Applied to %d image(s). ✓', 'bulk-alt-text-ai'),
                'aiReplied'   => __('AI replied in %dms:', 'bulk-alt-text-ai'),
                'sMissing'    => __('Missing alt', 'bulk-alt-text-ai'),
                'sOk'         => __('Has alt', 'bulk-alt-text-ai'),
                'sPlugin'     => __('Applied by plugin', 'bulk-alt-text-ai'),
                'noImages'    => __('No images match this filter. 🎉', 'bulk-alt-text-ai'),
            ],
        ]);
    }

    /**
     * @return array{language:string,max_length:int,auto_on_upload:bool,overwrite:bool}
     */
    public static function settings(): array
    {
        $opt = get_option('batai_settings', []);
        $opt = is_array($opt) ? $opt : [];

        return [
            'language'       => isset($opt['language']) ? sanitize_text_field((string) $opt['language']) : 'site',
            'max_length'     => isset($opt['max_length']) ? max(60, min(160, (int) $opt['max_length'])) : 125,
            'auto_on_upload' => !empty($opt['auto_on_upload']),
            'overwrite'      => !empty($opt['overwrite']),
        ];
    }
}
