<?php

/**
 * Admin menu (under Media): bulk generator, settings and license.
 *
 * @package BulkAltText
 */

declare(strict_types=1);

namespace BulkAltText\Admin;

use BulkAltText\Ai\AiService;
use BulkAltText\Licensing\LicenseManager;
use BulkAltText\Media\AltWriter;

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

class SettingsPage
{
    public function register(): void
    {
        add_action('admin_menu', [$this, 'add_menu']);
        add_action('admin_init', [$this, 'register_settings']);
    }

    public function add_menu(): void
    {
        add_media_page(
            __('Bulk Alt Text AI', 'bulk-alt-text-ai'),
            __('Bulk Alt Text AI', 'bulk-alt-text-ai'),
            'upload_files',
            'bulk-alt-text-ai',
            [$this, 'render']
        );
    }

    public function register_settings(): void
    {
        register_setting('batai_settings_group', 'batai_settings', [
            'type'              => 'array',
            'sanitize_callback' => [$this, 'sanitize_settings'],
            'default'           => [],
        ]);
    }

    /**
     * @param mixed $input
     * @return array<string,mixed>
     */
    public function sanitize_settings($input): array
    {
        $input = is_array($input) ? $input : [];

        $languages = ['site', 'auto', 'English', 'Portuguese', 'Spanish', 'French', 'German', 'Italian'];

        return [
            'language'       => in_array(($input['language'] ?? ''), $languages, true) ? $input['language'] : 'site',
            'max_length'     => max(60, min(160, (int) ($input['max_length'] ?? 125))),
            'auto_on_upload' => !empty($input['auto_on_upload']),
            'overwrite'      => !empty($input['overwrite']),
        ];
    }

    public function render(): void
    {
        if (!current_user_can('upload_files')) {
            return;
        }

        // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only tab routing.
        $tab = isset($_GET['tab']) ? sanitize_key((string) wp_unslash($_GET['tab'])) : 'bulk';
        ?>
        <div class="wrap batai-wrap">
            <h1><span class="dashicons dashicons-images-alt2"></span> <?php esc_html_e('Bulk Alt Text AI', 'bulk-alt-text-ai'); ?></h1>
            <?php $this->tabs($tab); ?>
            <div class="batai-panel">
                <?php
                switch ($tab) {
                    case 'scan':
                        $this->render_scan();
                        break;
                    case 'settings':
                        $this->render_settings();
                        break;
                    default:
                        $this->render_bulk();
                }
                ?>
            </div>
        </div>
        <?php
    }

    private function tabs(string $current): void
    {
        $tabs = [
            'bulk'     => __('Bulk generate', 'bulk-alt-text-ai'),
            'scan'     => __('Page scanner', 'bulk-alt-text-ai'),
            'settings' => __('Settings', 'bulk-alt-text-ai'),
        ];
        echo '<nav class="nav-tab-wrapper">';
        foreach ($tabs as $slug => $label) {
            printf(
                '<a href="%s" class="nav-tab %s">%s</a>',
                esc_url(admin_url('upload.php?page=bulk-alt-text-ai&tab=' . $slug)),
                $current === $slug ? 'nav-tab-active' : '',
                esc_html($label)
            );
        }
        echo '</nav>';
    }

    /**
     * Small "Pro" pill shown next to a locked feature's heading.
     */
    private function pro_tag(bool $isPro): void
    {
        if (!$isPro) {
            echo '<span class="batai-badge is-pro">Pro</span>';
        }
    }

    /**
     * Inline lock + upgrade button shown in place of a Pro-only control.
     */
    private function pro_lock(string $text): void
    {
        printf(
            '<p class="batai-prolock"><span class="dashicons dashicons-lock"></span> %s <a class="button button-primary button-small" href="%s">%s</a></p>',
            esc_html($text),
            esc_url(LicenseManager::instance()->upgrade_url()),
            esc_html__('Upgrade to Pro', 'bulk-alt-text-ai')
        );
    }

    private function render_bulk(): void
    {
        $license   = LicenseManager::instance();
        $isPro     = $license->is_pro();
        $aiReady   = AiService::is_available();
        $missing   = $this->count_missing();
        $total     = $this->count_total();
        $generated = AltWriter::generated_count();
        ?>
        <div class="batai-cards">
            <div class="batai-card">
                <span class="batai-card-label"><?php esc_html_e('Images total', 'bulk-alt-text-ai'); ?></span>
                <span class="batai-card-num"><?php echo esc_html(number_format_i18n($total)); ?></span>
            </div>
            <div class="batai-card">
                <span class="batai-card-label"><?php esc_html_e('Missing alt text', 'bulk-alt-text-ai'); ?></span>
                <span class="batai-card-num <?php echo $missing > 0 ? 'is-warn' : 'is-ok'; ?>"><?php echo esc_html(number_format_i18n($missing)); ?></span>
            </div>
            <div class="batai-card">
                <span class="batai-card-label"><?php esc_html_e('Generated by AI', 'bulk-alt-text-ai'); ?></span>
                <span class="batai-card-num"><?php echo esc_html(number_format_i18n($generated)); ?></span>
            </div>
        </div>

        <?php if (!$aiReady) : ?>
            <div class="notice notice-warning inline"><p>
                <?php esc_html_e('No AI connector is configured yet. Set up an AI provider under Settings → AI in WordPress. You can still use the audit and the manual test mode below.', 'bulk-alt-text-ai'); ?>
            </p></div>
        <?php endif; ?>

        <div class="batai-step">
            <h2><span class="batai-step-num">1</span> <?php esc_html_e('Test the AI connection', 'bulk-alt-text-ai'); ?> <?php $this->pro_tag($isPro); ?></h2>
            <p class="description"><?php esc_html_e('Sends a tiny “hi” prompt to your configured provider and shows the reply, so you know everything is wired up.', 'bulk-alt-text-ai'); ?></p>
            <?php if ($isPro) : ?>
                <p>
                    <button type="button" class="button" id="batai-test-conn"><?php esc_html_e('👋 Send a test “Hi” to the AI', 'bulk-alt-text-ai'); ?></button>
                    <span class="batai-test-result" aria-live="polite"></span>
                </p>
            <?php else : ?>
                <?php $this->pro_lock(__('Testing the AI connection is part of the Pro plan.', 'bulk-alt-text-ai')); ?>
            <?php endif; ?>
        </div>

        <div class="batai-step">
            <h2><span class="batai-step-num">2</span> <?php esc_html_e('Audit your images', 'bulk-alt-text-ai'); ?></h2>
            <p class="description"><?php esc_html_e('See exactly which images pass or fail the accessibility check (alt text present), then select the ones you want to fix — or select them all.', 'bulk-alt-text-ai'); ?></p>
            <p>
                <label for="batai-filter" class="screen-reader-text"><?php esc_html_e('Filter', 'bulk-alt-text-ai'); ?></label>
                <select id="batai-filter">
                    <option value="missing"><?php esc_html_e('Missing alt text (needs fixing)', 'bulk-alt-text-ai'); ?></option>
                    <option value="all"><?php esc_html_e('All images', 'bulk-alt-text-ai'); ?></option>
                    <option value="generated"><?php esc_html_e('Applied by this plugin', 'bulk-alt-text-ai'); ?></option>
                </select>
                <button type="button" class="button" id="batai-load"><?php esc_html_e('Load images', 'bulk-alt-text-ai'); ?></button>
            </p>
            <div id="batai-audit" hidden>
                <table class="widefat striped batai-table">
                    <thead>
                        <tr>
                            <td class="check-column"><input type="checkbox" id="batai-check-all" aria-label="<?php esc_attr_e('Select all', 'bulk-alt-text-ai'); ?>"></td>
                            <th><?php esc_html_e('Image', 'bulk-alt-text-ai'); ?></th>
                            <th><?php esc_html_e('File', 'bulk-alt-text-ai'); ?></th>
                            <th><?php esc_html_e('Alt text', 'bulk-alt-text-ai'); ?></th>
                            <th><?php esc_html_e('Status', 'bulk-alt-text-ai'); ?></th>
                        </tr>
                    </thead>
                    <tbody id="batai-rows"></tbody>
                </table>
                <p>
                    <button type="button" class="button" id="batai-more" hidden><?php esc_html_e('Load more', 'bulk-alt-text-ai'); ?></button>
                    <span class="batai-selcount" aria-live="polite"></span>
                </p>
            </div>
        </div>

        <div class="batai-step">
            <h2><span class="batai-step-num">3</span> <?php esc_html_e('Fix the alt text', 'bulk-alt-text-ai'); ?></h2>

            <h3><?php esc_html_e('Manual mode (no AI)', 'bulk-alt-text-ai'); ?> <span class="batai-badge is-gen"><?php esc_html_e('Free', 'bulk-alt-text-ai'); ?></span></h3>
            <p class="description"><?php esc_html_e('Applies the text below to every selected image — no AI involved. Free and unlimited.', 'bulk-alt-text-ai'); ?></p>
            <p>
                <label for="batai-manual-text" class="screen-reader-text"><?php esc_html_e('Text to apply', 'bulk-alt-text-ai'); ?></label>
                <input type="text" id="batai-manual-text" class="regular-text" placeholder="<?php esc_attr_e('e.g. Product photo on white background', 'bulk-alt-text-ai'); ?>">
                <button type="button" class="button" id="batai-manual-apply"><?php esc_html_e('Apply text to selected', 'bulk-alt-text-ai'); ?></button>
                <span class="batai-manual-status" aria-live="polite"></span>
            </p>

            <h3><?php esc_html_e('Generate with AI for the selected images', 'bulk-alt-text-ai'); ?> <?php $this->pro_tag($isPro); ?></h3>
            <p class="description"><?php esc_html_e('Let the AI write descriptive alt text for each image you selected in the audit above.', 'bulk-alt-text-ai'); ?></p>
            <?php if ($isPro) : ?>
                <p>
                    <button type="button" class="button button-primary" id="batai-ai-selected"><?php esc_html_e('✨ Generate for selected with AI', 'bulk-alt-text-ai'); ?></button>
                    <span class="batai-ai-selected-status" aria-live="polite"></span>
                </p>
            <?php else : ?>
                <?php $this->pro_lock(__('Letting the AI write your alt text is a Pro feature.', 'bulk-alt-text-ai')); ?>
            <?php endif; ?>

            <h3><?php esc_html_e('Run on the whole library', 'bulk-alt-text-ai'); ?> <span class="batai-badge is-pro">Pro</span></h3>
            <?php if (!$isPro) : ?>
                <div class="batai-locked">
                    <p><span class="dashicons dashicons-lock"></span>
                        <?php esc_html_e('Whole-library runs are a Pro feature. Upgrade to fill every missing alt text automatically — perfect for large or legacy media libraries.', 'bulk-alt-text-ai'); ?>
                    </p>
                    <a class="button button-primary button-hero" href="<?php echo esc_url($license->upgrade_url()); ?>">
                        <?php esc_html_e('Upgrade to Pro', 'bulk-alt-text-ai'); ?>
                    </a>
                </div>
            <?php else : ?>
                <div id="batai-bulk" data-missing="<?php echo esc_attr((string) $missing); ?>" data-total="<?php echo esc_attr((string) $total); ?>">
                    <table class="form-table" role="presentation">
                        <tr>
                            <th scope="row"><?php esc_html_e('Which images', 'bulk-alt-text-ai'); ?></th>
                            <td>
                                <label><input type="radio" name="batai-scope" value="missing" checked> <?php esc_html_e('Only images missing alt text', 'bulk-alt-text-ai'); ?></label><br>
                                <label><input type="radio" name="batai-scope" value="all"> <?php esc_html_e('All images (regenerate everything)', 'bulk-alt-text-ai'); ?></label>
                            </td>
                        </tr>
                        <tr>
                            <th scope="row"><?php esc_html_e('Uploaded between', 'bulk-alt-text-ai'); ?></th>
                            <td>
                                <input type="date" id="batai-date-from"> &ndash;
                                <input type="date" id="batai-date-to">
                                <p class="description"><?php esc_html_e('Optional. Leave empty to include every date.', 'bulk-alt-text-ai'); ?></p>
                            </td>
                        </tr>
                    </table>

                    <p>
                        <button type="button" class="button button-primary button-hero" id="batai-bulk-start"><?php esc_html_e('Start bulk generation', 'bulk-alt-text-ai'); ?></button>
                        <button type="button" class="button" id="batai-bulk-stop" hidden><?php esc_html_e('Stop', 'bulk-alt-text-ai'); ?></button>
                    </p>

                    <div class="batai-progress" hidden>
                        <div class="batai-progress-bar"><span></span></div>
                        <p class="batai-progress-label"></p>
                    </div>
                    <ul class="batai-log" aria-live="polite"></ul>
                </div>
            <?php endif; ?>
        </div>

        <?php if ($generated > 0) : ?>
                <hr>
                <h2><?php esc_html_e('Undo', 'bulk-alt-text-ai'); ?></h2>
                <p><?php printf(
                    /* translators: %s: number of images */
                    esc_html__('%s image(s) currently have an alt text applied by this plugin (AI or manual test).', 'bulk-alt-text-ai'),
                    '<strong>' . esc_html(number_format_i18n($generated)) . '</strong>'
                ); ?></p>
                <p>
                    <button type="button" class="button" id="batai-revert"><?php esc_html_e('Restore original alt text', 'bulk-alt-text-ai'); ?></button>
                    <span class="batai-revert-status"></span>
                </p>
        <?php endif; ?>
        <?php
    }

    private function render_scan(): void
    {
        $isPro = LicenseManager::instance()->is_pro();
        ?>
        <h2><?php esc_html_e('Page scanner — accessibility & SEO audit', 'bulk-alt-text-ai'); ?> <?php $this->pro_tag($isPro); ?></h2>
        <p class="description">
            <?php esc_html_e('Loads one of your pages right here and audits it in your browser: accessibility checks (WCAG) plus basic SEO signals. Read-only — nothing on your site changes unless you click a fix button.', 'bulk-alt-text-ai'); ?>
        </p>

        <?php if (!$isPro) : ?>
            <div class="batai-locked">
                <p><span class="dashicons dashicons-lock"></span>
                    <?php esc_html_e('The page scanner is a Pro feature. Upgrade to audit any page for accessibility (WCAG) and SEO issues, and fix image alt text in one click.', 'bulk-alt-text-ai'); ?>
                </p>
                <a class="button button-primary button-hero" href="<?php echo esc_url(LicenseManager::instance()->upgrade_url()); ?>">
                    <?php esc_html_e('Upgrade to Pro', 'bulk-alt-text-ai'); ?>
                </a>
            </div>
            <?php
            return;
        endif;

        $pages = get_posts([
            'post_type'      => ['page', 'post'],
            'post_status'    => 'publish',
            'posts_per_page' => 30,
            'orderby'        => 'date',
            'order'          => 'DESC',
        ]);

        $hasSeoPlugin = defined('WPSEO_VERSION') || defined('RANK_MATH_VERSION') || function_exists('aioseo');
        ?>
        <p>
            <label for="batai-scan-page" class="screen-reader-text"><?php esc_html_e('Page to scan', 'bulk-alt-text-ai'); ?></label>
            <select id="batai-scan-page">
                <option value="<?php echo esc_attr(home_url('/')); ?>"><?php esc_html_e('Homepage', 'bulk-alt-text-ai'); ?></option>
                <?php foreach ($pages as $p) : ?>
                    <option value="<?php echo esc_attr((string) get_permalink($p)); ?>">
                        <?php echo esc_html(get_the_title($p) . ' (' . $p->post_type . ')'); ?>
                    </option>
                <?php endforeach; ?>
            </select>
            <button type="button" class="button button-primary" id="batai-scan-start"><?php esc_html_e('🔍 Scan page', 'bulk-alt-text-ai'); ?></button>
            <span class="batai-scan-status" aria-live="polite"></span>
        </p>

        <div id="batai-scan-report" data-seo-plugin="<?php echo $hasSeoPlugin ? '1' : '0'; ?>" hidden>
            <div class="batai-scan-summary"></div>
            <div class="batai-scan-results"></div>
            <p class="description">
                <?php esc_html_e('Image alt text can be fixed right here with the AI buttons. Issues in your theme or page markup (headings, labels, link text…) are reported for you or your developer to fix — this plugin only ever writes image alt text into your media library.', 'bulk-alt-text-ai'); ?>
            </p>
        </div>

        <div id="batai-scan-frame-wrap" class="batai-scan-frame-wrap" hidden>
            <iframe id="batai-scan-frame" title="<?php esc_attr_e('Page being scanned', 'bulk-alt-text-ai'); ?>"></iframe>
        </div>
        <?php
    }

    private function render_settings(): void
    {
        $opt  = get_option('batai_settings', []);
        $opt  = is_array($opt) ? $opt : [];
        $lang = $opt['language'] ?? 'site';
        $len  = (int) ($opt['max_length'] ?? 125);
        $auto = !empty($opt['auto_on_upload']);
        $over = !empty($opt['overwrite']);

        $languages = [
            'site'       => __('Same as site language', 'bulk-alt-text-ai'),
            'auto'       => __('Auto-detect from context', 'bulk-alt-text-ai'),
            'English'    => 'English',
            'Portuguese' => 'Português',
            'Spanish'    => 'Español',
            'French'     => 'Français',
            'German'     => 'Deutsch',
            'Italian'    => 'Italiano',
        ];
        ?>
        <form method="post" action="options.php">
            <?php settings_fields('batai_settings_group'); ?>
            <table class="form-table" role="presentation">
                <tr>
                    <th scope="row"><label for="batai_language"><?php esc_html_e('Alt text language', 'bulk-alt-text-ai'); ?></label></th>
                    <td>
                        <select id="batai_language" name="batai_settings[language]">
                            <?php foreach ($languages as $value => $label) : ?>
                                <option value="<?php echo esc_attr($value); ?>" <?php selected($lang, $value); ?>><?php echo esc_html($label); ?></option>
                            <?php endforeach; ?>
                        </select>
                    </td>
                </tr>
                <tr>
                    <th scope="row"><label for="batai_max_length"><?php esc_html_e('Maximum length', 'bulk-alt-text-ai'); ?></label></th>
                    <td>
                        <input type="number" id="batai_max_length" name="batai_settings[max_length]" value="<?php echo esc_attr((string) $len); ?>" min="60" max="160" step="5" />
                        <p class="description"><?php esc_html_e('Characters. 125 is the accessibility sweet spot for screen readers.', 'bulk-alt-text-ai'); ?></p>
                    </td>
                </tr>
                <tr>
                    <th scope="row"><?php esc_html_e('Automation', 'bulk-alt-text-ai'); ?> <?php $this->pro_tag(LicenseManager::instance()->is_pro()); ?></th>
                    <td>
                        <label><input type="checkbox" name="batai_settings[auto_on_upload]" value="1" <?php checked($auto); ?>>
                            <?php esc_html_e('Automatically generate alt text when a new image is uploaded (Pro)', 'bulk-alt-text-ai'); ?></label>
                        <br>
                        <label><input type="checkbox" name="batai_settings[overwrite]" value="1" <?php checked($over); ?>>
                            <?php esc_html_e('Overwrite existing alt text (otherwise only fill in blanks)', 'bulk-alt-text-ai'); ?></label>
                    </td>
                </tr>
            </table>
            <?php submit_button(); ?>
        </form>
        <?php
    }

    private function count_missing(): int
    {
        $query = new \WP_Query([
            'post_type'      => 'attachment',
            'post_status'    => 'inherit',
            'post_mime_type' => 'image',
            'posts_per_page' => 1,
            'fields'         => 'ids',
            'meta_query'     => [ // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
                'relation' => 'OR',
                ['key' => AltWriter::ALT_META, 'compare' => 'NOT EXISTS'],
                ['key' => AltWriter::ALT_META, 'value' => '', 'compare' => '='],
            ],
        ]);

        return (int) $query->found_posts;
    }

    private function count_total(): int
    {
        $query = new \WP_Query([
            'post_type'      => 'attachment',
            'post_status'    => 'inherit',
            'post_mime_type' => 'image',
            'posts_per_page' => 1,
            'fields'         => 'ids',
        ]);

        return (int) $query->found_posts;
    }
}
