<?php

namespace WPSN\Modules\AI\Admin;

use WPSN\Core\Branding;
use WPSN\Core\Logger;
use WPSN\Core\Settings;
use WPSN\Modules\AI\AICallRepository;
use WPSN\Modules\AI\AIInstaller;
use WPSN\Modules\AI\AISecretsRepository;
use WPSN\Modules\AI\AIUsageRepository;
use WPSN\Modules\AI\AICreditsRepository;
use WPSN\Modules\AI\SaaSAICreditsRepository;
use WPSN\Modules\AI\SaaSAICreditsClient;
use WPSN\Modules\ActivityLog\ActivityLogRepository;
use WPSN\Core\Capabilities;
use WPSN\Modules\SaaSSync\SaaSSyncService;

defined('ABSPATH') || exit;

final class AIAdmin
{
    private AISecretsRepository $secrets;
    private AIUsageRepository $usage;
    private AICallRepository $calls;
    private Logger $logger;
    private Settings $settings;

    public function __construct(AISecretsRepository $secrets, AIUsageRepository $usage, AICallRepository $calls, Logger $logger, Settings $settings)
    {
        $this->secrets = $secrets;
        $this->usage = $usage;
        $this->calls = $calls;
        $this->logger = $logger;
        $this->settings = $settings;
    }

    public function register(): void
    {
        add_action('admin_menu', [$this, 'addMenu']);

        add_action('admin_post_wpsn_ai_reset_usage', [$this, 'handleResetUsage']);
        add_action('admin_post_wpsn_ai_clear_logs', [$this, 'handleClearLogs']);

        // Credits wallet actions (admins only).
        add_action('admin_post_wpsn_ai_add_credits', [$this, 'handleAddCredits']);
        add_action('admin_post_wpsn_ai_set_credits', [$this, 'handleSetCredits']);
        add_action('admin_post_wpsn_ai_clear_credits_ledger', [$this, 'handleClearCreditsLedger']);

        // SaaS credits sync (admins only).
        add_action('admin_post_wpsn_ai_saas_sync_credits', [$this, 'handleSaasSyncCredits']);

        add_action('admin_notices', [$this, 'adminNotices']);

        // Ensure table exists.
        add_action('admin_init', [AIInstaller::class, 'maybeInstall'], 1);

        if ((bool) $this->settings->get('privacy.hide_ai_ui', false)) {
            // UI-only: do not expose AI pages/actions.
            return;
        }

    }

    public function addMenu(): void
    {
        // Respect per-user overrides.
        if (!Capabilities::canManageAIAdmin()) {
            return;
        }

        add_management_page(
            __('SEO AI', 'wp-seo-next'),
            __('SEO AI', 'wp-seo-next'),
            'read',
            'wpsn-seo-ai',
            [$this, 'renderPage']
        );
    }

    public function adminNotices(): void
    {
        if (empty($_GET['wpsn_notice'])) {
            return;
        }
        $notice = sanitize_key((string) wp_unslash($_GET['wpsn_notice']));
        $map = [
            'ai_usage_reset' => __('AI usage counters reset.', 'wp-seo-next'),
            'ai_logs_cleared' => __('AI logs cleared.', 'wp-seo-next'),
            'ai_overrides_cleared_all' => __('AI user overrides cleared.', 'wp-seo-next'),
            'ai_credits_added' => __('AI credits added.', 'wp-seo-next'),
            'ai_credits_set' => __('AI credits balance updated.', 'wp-seo-next'),
            'ai_credits_ledger_cleared' => __('AI credits ledger cleared.', 'wp-seo-next'),
            'ai_credits_invalid' => __('Please enter a valid credits amount.', 'wp-seo-next'),
            'ai_saas_credits_synced' => __('SaaS AI credits synced.', 'wp-seo-next'),
            'ai_saas_credits_failed' => __('Failed to sync SaaS AI credits.', 'wp-seo-next'),
        ];
        if (!isset($map[$notice])) {
            return;
        }

        $msg = $map[$notice];
        $class = ($notice === 'ai_credits_invalid' || $notice === 'ai_saas_credits_failed') ? 'notice-error' : 'notice-success';

        if ($notice === 'ai_saas_credits_failed' && !empty($_GET['wpsn_error'])) {
            $msg .= ' ' . sanitize_text_field((string) wp_unslash($_GET['wpsn_error']));
        }
        if ($notice === 'ai_overrides_cleared_all') {
            $users = isset($_GET['wpsn_ai_overrides_users']) ? (int) $_GET['wpsn_ai_overrides_users'] : 0;
            $use = isset($_GET['wpsn_ai_overrides_use']) ? (int) $_GET['wpsn_ai_overrides_use'] : 0;
            $manage = isset($_GET['wpsn_ai_overrides_manage']) ? (int) $_GET['wpsn_ai_overrides_manage'] : 0;
            $which = isset($_GET['wpsn_ai_overrides_which']) ? sanitize_key((string) wp_unslash($_GET['wpsn_ai_overrides_which'])) : 'both';
            if ($users > 0) {
                $msg .= ' ' . sprintf(
                    /* translators: 1: users affected, 2: cleared use, 3: cleared manage, 4: which */
                    __('(%1$d users; use: %2$d, manage: %3$d; mode: %4$s)', 'wp-seo-next'),
                    $users,
                    $use,
                    $manage,
                    $which
                );
            }
        }

        echo '<div class="notice ' . esc_attr($class) . ' is-dismissible"><p>' . esc_html($msg) . '</p></div>';
    }

    public function handleResetUsage(): void
    {
        if (!Capabilities::canManageAIAdmin()) {
            wp_die(esc_html__('You do not have permission to do this action.', 'wp-seo-next'));
        }
        if (!isset($_POST['wpsn_nonce']) || !wp_verify_nonce((string) wp_unslash($_POST['wpsn_nonce']), 'wpsn_ai_reset_usage')) {
            wp_die(esc_html__('Invalid nonce.', 'wp-seo-next'));
        }

        $this->usage->reset();

        wp_safe_redirect(admin_url('tools.php?page=wpsn-seo-ai&wpsn_notice=ai_usage_reset'));
        exit;
    }

    public function handleClearLogs(): void
    {
        if (!Capabilities::canManageAIAdmin()) {
            wp_die(esc_html__('You do not have permission to do this action.', 'wp-seo-next'));
        }
        if (!isset($_POST['wpsn_nonce']) || !wp_verify_nonce((string) wp_unslash($_POST['wpsn_nonce']), 'wpsn_ai_clear_logs')) {
            wp_die(esc_html__('Invalid nonce.', 'wp-seo-next'));
        }

        try {
            $this->calls->clear();
        } catch (\Throwable $e) {
            $this->logger->error('AI log clear failed: ' . $e->getMessage());
        }

        wp_safe_redirect(admin_url('tools.php?page=wpsn-seo-ai&wpsn_notice=ai_logs_cleared'));
        exit;
    }

    public function handleAddCredits(): void
    {
        if (!Capabilities::canManageAIAdmin() || !current_user_can('manage_options')) {
            wp_die(esc_html__('You do not have permission to do this action.', 'wp-seo-next'));
        }
        if (!isset($_POST['wpsn_nonce']) || !wp_verify_nonce((string) wp_unslash($_POST['wpsn_nonce']), 'wpsn_ai_add_credits')) {
            wp_die(esc_html__('Invalid nonce.', 'wp-seo-next'));
        }

        $amountRaw = isset($_POST['credits_amount']) ? (string) wp_unslash($_POST['credits_amount']) : '0';
        $amount = (float) str_replace(',', '.', trim($amountRaw));
        if ($amount <= 0.0) {
            wp_safe_redirect(admin_url('tools.php?page=wpsn-seo-ai&wpsn_notice=ai_credits_invalid'));
            exit;
        }

        $note = isset($_POST['credits_note']) ? sanitize_text_field((string) wp_unslash($_POST['credits_note'])) : '';

        $repo = new AICreditsRepository($this->settings);
        $newBal = $repo->add($amount, [
            'user_id' => (int) get_current_user_id(),
            'purpose' => 'admin_topup',
            'object_type' => 'system',
            'note' => $note !== '' ? $note : __('Manual top-up', 'wp-seo-next'),
            'meta' => [
                'source' => 'tools_seo_ai',
            ],
        ]);

        // Log the admin action (human-friendly).
        try {
            (new ActivityLogRepository())->insert(
                'ai_credits_add',
                sprintf(
                    /* translators: 1: credits added, 2: new balance */
                    __('AI credits: +%1$s (new balance: %2$s)', 'wp-seo-next'),
                    (string) $amount,
                    (string) $newBal
                ),
                [
                    'context' => 'ai',
                    'object_type' => 'system',
                    'meta' => [
                        'credits_added' => $amount,
                        'balance' => $newBal,
                        'note' => $note,
                    ],
                ]
            );
        } catch (\Throwable $e) {
            // Ignore.
        }

        wp_safe_redirect(admin_url('tools.php?page=wpsn-seo-ai&wpsn_notice=ai_credits_added'));
        exit;
    }

    public function handleSetCredits(): void
    {
        if (!Capabilities::canManageAIAdmin() || !current_user_can('manage_options')) {
            wp_die(esc_html__('You do not have permission to do this action.', 'wp-seo-next'));
        }
        if (!isset($_POST['wpsn_nonce']) || !wp_verify_nonce((string) wp_unslash($_POST['wpsn_nonce']), 'wpsn_ai_set_credits')) {
            wp_die(esc_html__('Invalid nonce.', 'wp-seo-next'));
        }

        $amountRaw = isset($_POST['credits_balance']) ? (string) wp_unslash($_POST['credits_balance']) : '0';
        $amount = (float) str_replace(',', '.', trim($amountRaw));
        if ($amount < 0.0) {
            $amount = 0.0;
        }

        $note = isset($_POST['credits_note']) ? sanitize_text_field((string) wp_unslash($_POST['credits_note'])) : '';

        $repo = new AICreditsRepository($this->settings);
        $old = $repo->getBalance();
        $new = $repo->setBalance($amount, [
            'user_id' => (int) get_current_user_id(),
            'purpose' => 'admin_set_balance',
            'object_type' => 'system',
            'note' => $note !== '' ? $note : __('Set balance', 'wp-seo-next'),
            'meta' => [
                'source' => 'tools_seo_ai',
                'old_balance' => $old,
            ],
        ]);

        try {
            (new ActivityLogRepository())->insert(
                'ai_credits_set',
                sprintf(
                    /* translators: 1: old balance, 2: new balance */
                    __('AI credits: set balance from %1$s to %2$s', 'wp-seo-next'),
                    (string) $old,
                    (string) $new
                ),
                [
                    'context' => 'ai',
                    'object_type' => 'system',
                    'meta' => [
                        'old_balance' => $old,
                        'new_balance' => $new,
                        'note' => $note,
                    ],
                ]
            );
        } catch (\Throwable $e) {
            // Ignore.
        }

        wp_safe_redirect(admin_url('tools.php?page=wpsn-seo-ai&wpsn_notice=ai_credits_set'));
        exit;
    }

    public function handleClearCreditsLedger(): void
    {
        if (!Capabilities::canManageAIAdmin() || !current_user_can('manage_options')) {
            wp_die(esc_html__('You do not have permission to do this action.', 'wp-seo-next'));
        }
        if (!isset($_POST['wpsn_nonce']) || !wp_verify_nonce((string) wp_unslash($_POST['wpsn_nonce']), 'wpsn_ai_clear_credits_ledger')) {
            wp_die(esc_html__('Invalid nonce.', 'wp-seo-next'));
        }

        $repo = new AICreditsRepository($this->settings);
        try {
            $repo->clearLedger();
        } catch (\Throwable $e) {
            // Ignore.
        }

        try {
            (new ActivityLogRepository())->insert(
                'ai_credits_ledger_clear',
                __('AI credits: ledger cleared', 'wp-seo-next'),
                [
                    'context' => 'ai',
                    'object_type' => 'system',
                ]
            );
        } catch (\Throwable $e) {
            // Ignore.
        }

        wp_safe_redirect(admin_url('tools.php?page=wpsn-seo-ai&wpsn_notice=ai_credits_ledger_cleared'));
        exit;
    }

    public function handleSaasSyncCredits(): void
    {
        if (!Capabilities::canManageAIAdmin()) {
            wp_die(esc_html__('You do not have permission to do this action.', 'wp-seo-next'));
        }

        check_admin_referer('wpsn_ai_saas_sync_credits');

        // If SaaS module is not enabled, just bail.
        if (!$this->settings->moduleEnabled('saas_sync', false) || !(bool) $this->settings->get('saas_sync.enabled', false)) {
            wp_safe_redirect(admin_url('tools.php?page=wpsn-seo-ai&wpsn_notice=ai_saas_credits_failed&wpsn_error=saas_disabled'));
            exit;
        }

        $saas = new SaaSSyncService($this->settings, $this->logger);
        if (!$saas->isActive() || !$saas->isTrusted()) {
            wp_safe_redirect(admin_url('tools.php?page=wpsn-seo-ai&wpsn_notice=ai_saas_credits_failed&wpsn_error=saas_not_ready'));
            exit;
        }

        $client = new SaaSAICreditsClient($saas, $this->logger, $this->settings);
        $res = $client->fetch();

        $repo = new SaaSAICreditsRepository();
        if (!empty($res['ok'])) {
            $repo->updateFromCreditsArray([
                'balance' => (float) ($res['balance'] ?? 0.0),
                'currency' => (string) ($res['currency'] ?? 'credits'),
            ]);

            wp_safe_redirect(admin_url('tools.php?page=wpsn-seo-ai&wpsn_notice=ai_saas_credits_synced'));
            exit;
        }

        $repo->setLastError((string) ($res['error'] ?? 'sync_failed'));
        wp_safe_redirect(admin_url('tools.php?page=wpsn-seo-ai&wpsn_notice=ai_saas_credits_failed&wpsn_error=' . rawurlencode((string) ($res['error'] ?? 'sync_failed'))));
        exit;
    }

    public function renderPage(): void
    {
        if (!Capabilities::canManageAIAdmin()) {
            wp_die(esc_html__('You do not have permission to access this page.', 'wp-seo-next'));
        }

        $usage = $this->usage->getToday();
        $hasKey = $this->secrets->hasOpenAIKey();
        $calls = $this->calls->recent(50);

        $creditsRepo = new AICreditsRepository($this->settings);
        $creditsBalance = $creditsRepo->getBalance();
        $creditsEnabled = $creditsRepo->isEnabled();
        $creditsMode = $creditsRepo->mode();
        $creditsLedger = $creditsRepo->recentLedger(50);

        $provider = (string) $this->settings->get('ai.external.provider', 'openai');
        $provider = $provider !== '' ? sanitize_key($provider) : 'openai';

        // SaaS credits cache.
        $saasCreditsRepo = new SaaSAICreditsRepository();
        $saasCredits = $saasCreditsRepo->get();
        $saasCreditsBalance = (float) ($saasCredits['balance'] ?? 0.0);
        $saasCreditsCurrency = (string) ($saasCredits['currency'] ?? 'credits');
        $saasCreditsUpdatedAt = (int) ($saasCredits['updated_at'] ?? 0);
        $saasCreditsError = (string) ($saasCredits['last_error'] ?? '');
        $saasCreditsUpdatedHuman = $saasCreditsUpdatedAt > 0 ? (gmdate('Y-m-d H:i:s', $saasCreditsUpdatedAt) . ' UTC') : __('Never', 'wp-seo-next');

        $saasEnabled = $this->settings->moduleEnabled('saas_sync', false) && (bool) $this->settings->get('saas_sync.enabled', false);
        $saasStatus = $saasEnabled ? 'unknown' : 'disabled';
        $saasTrusted = false;
        if ($saasEnabled) {
            try {
                $saasSvc = new SaaSSyncService($this->settings, $this->logger);
                $saasStatus = $saasSvc->status();
                $saasTrusted = $saasSvc->isTrusted();
            } catch (\Throwable $e) {
                $saasStatus = 'unknown';
            }
        }

        // Users with per-user overrides (use/manage).
        $overridesPerPage = 50;
        $overridesPageNum = isset($_GET['wpsn_ai_overrides_page']) ? (int) $_GET['wpsn_ai_overrides_page'] : 1;
        if ($overridesPageNum <= 0) {
            $overridesPageNum = 1;
        }
        $overridesSearch = isset($_GET['wpsn_ai_overrides_search']) ? trim((string) wp_unslash($_GET['wpsn_ai_overrides_search'])) : '';
        $overridesSearch = is_string($overridesSearch) ? $overridesSearch : '';
        $overridesOffset = ($overridesPageNum - 1) * $overridesPerPage;

        $qArgs = [
            'number' => $overridesPerPage,
            'offset' => $overridesOffset,
            'orderby' => 'ID',
            'order' => 'ASC',
            'count_total' => true,
            'fields' => 'all',
            'meta_query' => [
                'relation' => 'OR',
                [
                    'key' => \WPSN\Core\Capabilities::USERMETA_AI_USE_OVERRIDE,
                    'compare' => 'EXISTS',
                ],
                [
                    'key' => \WPSN\Core\Capabilities::USERMETA_AI_MANAGE_OVERRIDE,
                    'compare' => 'EXISTS',
                ],
            ],
        ];

        if ($overridesSearch !== '') {
            $qArgs['search'] = '*' . $overridesSearch . '*';
            $qArgs['search_columns'] = ['user_login', 'user_email', 'display_name'];
        }

        $uq = new \WP_User_Query($qArgs);
        $overrideUsers = $uq->get_results();
        $overrideTotal = (int) $uq->get_total();
        $overrideTotalPages = (int) ceil(max(1, $overrideTotal) / $overridesPerPage);
        if ($overrideTotalPages <= 0) {
            $overrideTotalPages = 1;
        }

        $settingsUrl = admin_url('admin.php?page=wp-seo-next');
        $settingsText = Branding::settingsLinkText($this->settings);

        $baseUrl = admin_url('tools.php?page=wpsn-seo-ai');
        $isAdmin = current_user_can('manage_options');

        ?>
        <div class="wrap">
            <h1><?php echo esc_html__('SEO AI', 'wp-seo-next'); ?></h1>

            <p class="description">
                <?php
                    echo esc_html__('Monitor AI usage, limits and recent generation calls.', 'wp-seo-next');
                ?>
                <br/>
                <?php
                    printf(
                        /* translators: %s Settings URL */
                        esc_html__('Configure AI in Settings: %s', 'wp-seo-next'),
                        sprintf('<a href="%s">%s</a>', esc_url($settingsUrl), esc_html($settingsText))
                    );
                ?>
            </p>

            <h2><?php echo esc_html__('Status', 'wp-seo-next'); ?></h2>
            <table class="widefat striped" style="max-width: 980px;">
                <tbody>
                    <tr>
                        <th style="width: 220px;"><?php echo esc_html__('External AI provider', 'wp-seo-next'); ?></th>
                        <td><code><?php echo esc_html($provider); ?></code></td>
                    </tr>
                    <tr>
                        <th style="width: 220px;"><?php echo esc_html__('OpenAI API key', 'wp-seo-next'); ?></th>
                        <td>
                            <?php
                                if ($provider === 'saas_proxy') {
                                    echo '<span style="opacity:.75">' . esc_html__('Not required in SaaS proxy mode.', 'wp-seo-next') . '</span>';
                                    if ($hasKey) {
                                        echo ' <span style="color:#0a7">(' . esc_html__('Key is set', 'wp-seo-next') . ')</span>';
                                    }
                                } else {
                                    echo $hasKey
                                        ? '<span style="color:#0a7">' . esc_html__('Configured', 'wp-seo-next') . '</span>'
                                        : '<span style="color:#a00">' . esc_html__('Not set', 'wp-seo-next') . '</span>';
                                }
                            ?>
                        </td>
                    </tr>

                    <tr>
                        <th><?php echo esc_html__('SaaS Sync status', 'wp-seo-next'); ?></th>
                        <td>
                            <?php
                                if (!$saasEnabled) {
                                    echo '<span style="opacity:.7">' . esc_html__('Disabled', 'wp-seo-next') . '</span>';
                                } else {
                                    $badge = $saasStatus;
                                    if ($saasTrusted) {
                                        $badge .= ' ✓';
                                    } else {
                                        $badge .= ' ⚠';
                                    }
                                    echo '<code>' . esc_html($badge) . '</code>';
                                }
                            ?>
                        </td>
                    </tr>

                    <tr>
                        <th><?php echo esc_html__('SaaS AI credits (cached)', 'wp-seo-next'); ?></th>
                        <td>
                            <strong><?php echo esc_html((string) $saasCreditsBalance); ?></strong>
                            <span style="opacity:.7">(<?php echo esc_html($saasCreditsCurrency); ?>)</span>
                            <div class="description" style="margin-top:4px;">
                                <?php
                                    printf(
                                        /* translators: 1: datetime */
                                        esc_html__('Last updated: %s', 'wp-seo-next'),
                                        '<code>' . esc_html($saasCreditsUpdatedHuman) . '</code>'
                                    );
                                ?>
                                <?php if ($saasCreditsError !== '') : ?>
                                    <br/>
                                    <span style="color:#a00;">⚠ <?php echo esc_html($saasCreditsError); ?></span>
                                <?php endif; ?>
                            </div>

                            <?php if ($isAdmin) : ?>
                                <form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>" style="margin-top:8px;">
                                    <input type="hidden" name="action" value="wpsn_ai_saas_sync_credits" />
                                    <?php wp_nonce_field('wpsn_ai_saas_sync_credits'); ?>
                                    <?php submit_button(__('Sync SaaS credits now', 'wp-seo-next'), 'secondary', 'submit', false); ?>
                                </form>
                            <?php endif; ?>
                        </td>
                    </tr>
                    <tr>
                        <th><?php echo esc_html__('Usage date (UTC)', 'wp-seo-next'); ?></th>
                        <td><?php echo esc_html((string) ($usage['date'] ?? '')); ?></td>
                    </tr>
                    <tr>
                        <th><?php echo esc_html__('Requests today', 'wp-seo-next'); ?></th>
                        <td><?php echo esc_html((string) (int) ($usage['requests'] ?? 0)); ?></td>
                    </tr>
                    <tr>
                        <th><?php echo esc_html__('Tokens today', 'wp-seo-next'); ?></th>
                        <td>
                            <?php
                                printf(
                                    '%s (in: %s, out: %s)',
                                    esc_html((string) (int) ($usage['tokens_total'] ?? 0)),
                                    esc_html((string) (int) ($usage['tokens_in'] ?? 0)),
                                    esc_html((string) (int) ($usage['tokens_out'] ?? 0))
                                );
                            ?>
                        </td>
                    </tr>
                    <tr>
                        <th><?php echo esc_html__('Estimated cost today', 'wp-seo-next'); ?></th>
                        <td><?php echo esc_html('$' . number_format((float) ($usage['cost_usd'] ?? 0.0), 4)); ?></td>
                    </tr>
                    <tr>
                        <th><?php echo esc_html__('Credits enforcement', 'wp-seo-next'); ?></th>
                        <td>
                            <?php
                                echo $creditsEnabled
                                    ? '<span style="color:#0a7">' . esc_html__('Enabled', 'wp-seo-next') . '</span>'
                                    : '<span style="opacity:.7">' . esc_html__('Disabled', 'wp-seo-next') . '</span>';

                                echo ' — ' . esc_html(sprintf(__('Mode: %s', 'wp-seo-next'), $creditsMode));
                            ?>
                        </td>
                    </tr>
                    <tr>
                        <th><?php echo esc_html__('Credits balance', 'wp-seo-next'); ?></th>
                        <td><strong><?php echo esc_html((string) $creditsBalance); ?></strong></td>
                    </tr>
                </tbody>
            </table>

            <div style="margin: 16px 0;">
                <form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>" style="display:inline-block; margin-right: 8px;">
                    <input type="hidden" name="action" value="wpsn_ai_reset_usage" />
                    <?php wp_nonce_field('wpsn_ai_reset_usage', 'wpsn_nonce'); ?>
                    <?php submit_button(__('Reset usage counters', 'wp-seo-next'), 'secondary', 'submit', false); ?>
                </form>

                <form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>" style="display:inline-block;">
                    <input type="hidden" name="action" value="wpsn_ai_clear_logs" />
                    <?php wp_nonce_field('wpsn_ai_clear_logs', 'wpsn_nonce'); ?>
                    <?php submit_button(__('Clear logs', 'wp-seo-next'), 'secondary', 'submit', false); ?>
                </form>
            </div>

            <h2><?php echo esc_html__('AI credits', 'wp-seo-next'); ?></h2>
            <p class="description" style="max-width: 980px;">
                <?php echo esc_html__('Optional: enforce a credits balance for external AI usage. When enabled, generation will stop when credits reach 0.', 'wp-seo-next'); ?>
                <br/>
                <?php echo esc_html__('Configure mode in Settings → AI (tokens-based is recommended).', 'wp-seo-next'); ?>
                <?php if (!$isAdmin) : ?>
                    <br/>
                    <strong><?php echo esc_html__('Only administrators can modify credits balance.', 'wp-seo-next'); ?></strong>
                <?php endif; ?>
            </p>

            <?php if ($isAdmin) : ?>
                <div style="display:flex; gap:16px; flex-wrap:wrap; align-items:flex-start; max-width: 980px;">
                    <form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>" style="background:#fff; border:1px solid #dcdcde; padding:12px; border-radius:6px; min-width: 320px;">
                        <h3 style="margin-top:0;"><?php echo esc_html__('Add credits', 'wp-seo-next'); ?></h3>
                        <input type="hidden" name="action" value="wpsn_ai_add_credits" />
                        <?php wp_nonce_field('wpsn_ai_add_credits', 'wpsn_nonce'); ?>
                        <p>
                            <label style="display:block; font-weight:600; margin-bottom:4px;">
                                <?php echo esc_html__('Credits amount', 'wp-seo-next'); ?>
                            </label>
                            <input type="number" step="0.000001" min="0" name="credits_amount" value="" style="width: 100%;" />
                        </p>
                        <p>
                            <label style="display:block; font-weight:600; margin-bottom:4px;">
                                <?php echo esc_html__('Note (optional)', 'wp-seo-next'); ?>
                            </label>
                            <input type="text" name="credits_note" value="" style="width: 100%;" />
                        </p>
                        <?php submit_button(__('Add credits', 'wp-seo-next'), 'primary', 'submit', false); ?>
                    </form>

                    <form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>" style="background:#fff; border:1px solid #dcdcde; padding:12px; border-radius:6px; min-width: 320px;">
                        <h3 style="margin-top:0;"><?php echo esc_html__('Set balance', 'wp-seo-next'); ?></h3>
                        <input type="hidden" name="action" value="wpsn_ai_set_credits" />
                        <?php wp_nonce_field('wpsn_ai_set_credits', 'wpsn_nonce'); ?>
                        <p>
                            <label style="display:block; font-weight:600; margin-bottom:4px;">
                                <?php echo esc_html__('New balance', 'wp-seo-next'); ?>
                            </label>
                            <input type="number" step="0.000001" min="0" name="credits_balance" value="<?php echo esc_attr((string) $creditsBalance); ?>" style="width: 100%;" />
                        </p>
                        <p>
                            <label style="display:block; font-weight:600; margin-bottom:4px;">
                                <?php echo esc_html__('Note (optional)', 'wp-seo-next'); ?>
                            </label>
                            <input type="text" name="credits_note" value="" style="width: 100%;" />
                        </p>
                        <?php submit_button(__('Update balance', 'wp-seo-next'), 'secondary', 'submit', false); ?>
                    </form>

                    <form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>" onsubmit="return confirm('<?php echo esc_js(__('Clear credits ledger? This does NOT change current balance.', 'wp-seo-next')); ?>');" style="background:#fff; border:1px solid #dcdcde; padding:12px; border-radius:6px; min-width: 320px;">
                        <h3 style="margin-top:0;"><?php echo esc_html__('Maintenance', 'wp-seo-next'); ?></h3>
                        <input type="hidden" name="action" value="wpsn_ai_clear_credits_ledger" />
                        <?php wp_nonce_field('wpsn_ai_clear_credits_ledger', 'wpsn_nonce'); ?>
                        <p class="description"><?php echo esc_html__('Use this only if you want to clear the audit history. Balance is kept.', 'wp-seo-next'); ?></p>
                        <?php submit_button(__('Clear ledger', 'wp-seo-next'), 'delete', 'submit', false); ?>
                    </form>
                </div>
            <?php endif; ?>

            <h3 style="margin-top: 14px;"><?php echo esc_html__('Recent credits ledger', 'wp-seo-next'); ?></h3>
            <table class="widefat striped" style="max-width: 980px;">
                <thead>
                    <tr>
                        <th style="width: 170px;"><?php echo esc_html__('Date (UTC)', 'wp-seo-next'); ?></th>
                        <th style="width: 120px;"><?php echo esc_html__('Delta', 'wp-seo-next'); ?></th>
                        <th style="width: 120px;"><?php echo esc_html__('Balance', 'wp-seo-next'); ?></th>
                        <th><?php echo esc_html__('Purpose', 'wp-seo-next'); ?></th>
                        <th style="width: 120px;"><?php echo esc_html__('Object', 'wp-seo-next'); ?></th>
                        <th style="width: 120px;"><?php echo esc_html__('Tokens', 'wp-seo-next'); ?></th>
                        <th style="width: 120px;"><?php echo esc_html__('Cost (USD)', 'wp-seo-next'); ?></th>
                    </tr>
                </thead>
                <tbody>
                    <?php if (empty($creditsLedger)) : ?>
                        <tr><td colspan="7" style="opacity:.7;"><?php echo esc_html__('No ledger entries yet.', 'wp-seo-next'); ?></td></tr>
                    <?php else : ?>
                        <?php foreach ($creditsLedger as $row) : ?>
                            <?php
                                $delta = isset($row['credits_delta']) ? (float) $row['credits_delta'] : 0.0;
                                $bal = isset($row['balance_after']) ? (float) $row['balance_after'] : 0.0;
                                $purpose = isset($row['purpose']) ? (string) $row['purpose'] : '';
                                $ot = isset($row['object_type']) ? (string) $row['object_type'] : '';
                                $oid = isset($row['object_id']) ? (int) $row['object_id'] : 0;
                                $tokens = isset($row['tokens_total']) ? (int) $row['tokens_total'] : 0;
                                $cost = isset($row['cost_usd']) ? (float) $row['cost_usd'] : 0.0;
                                $dt = isset($row['created_at']) ? (string) $row['created_at'] : '';

                                $deltaStr = ($delta > 0 ? '+' : '') . (string) $delta;
                                $objStr = $ot !== '' ? $ot : '—';
                                if ($oid > 0) {
                                    $objStr .= ':' . (string) $oid;
                                }
                            ?>
                            <tr>
                                <td><?php echo esc_html($dt); ?></td>
                                <td><code style="color:<?php echo $delta < 0 ? '#a00' : '#0a7'; ?>;"><?php echo esc_html($deltaStr); ?></code></td>
                                <td><strong><?php echo esc_html((string) $bal); ?></strong></td>
                                <td>
                                    <code><?php echo esc_html($purpose !== '' ? $purpose : '—'); ?></code>
                                    <?php if (!empty($row['note'])) : ?>
                                        <div style="opacity:.75;"><?php echo esc_html((string) $row['note']); ?></div>
                                    <?php endif; ?>
                                </td>
                                <td><?php echo esc_html($objStr); ?></td>
                                <td><?php echo esc_html((string) $tokens); ?></td>
                                <td><?php echo esc_html($cost > 0 ? '$' . number_format($cost, 4) : '—'); ?></td>
                            </tr>
                        <?php endforeach; ?>
                    <?php endif; ?>
                </tbody>
            </table>

            <hr style="margin: 18px 0;"/>

            <h2><?php echo esc_html__('Users with overrides', 'wp-seo-next'); ?></h2>
            <p class="description" style="max-width: 980px;">
                <?php echo esc_html__('These users have explicit per-user overrides (allow/deny) set for OpenAI usage and/or AI admin/tools access.', 'wp-seo-next'); ?>
                <?php if (!$isAdmin) : ?>
                    <br/>
                    <strong><?php echo esc_html__('Only administrators can clear overrides.', 'wp-seo-next'); ?></strong>
                <?php endif; ?>
            </p>

            <?php if ($isAdmin) : ?>
                <div style="margin: 10px 0; max-width: 980px; padding: 10px 12px; background: #fff; border: 1px solid #dcdcde; border-radius: 4px;">
                    <p style="margin:0 0 10px 0;">
                        <strong><?php echo esc_html__('Bulk action', 'wp-seo-next'); ?>:</strong>
                        <?php echo esc_html__('Clear all per-user AI overrides across the site (does not change role permissions).', 'wp-seo-next'); ?>
                    </p>
                    <form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>" onsubmit="return confirm(<?php echo wp_json_encode(__('Clear ALL per-user AI overrides? This cannot be undone.', 'wp-seo-next')); ?>);" style="margin:0;">
                        <input type="hidden" name="action" value="wpsn_clear_ai_overrides_all" />
                        <input type="hidden" name="which" value="both" />
                        <?php wp_nonce_field('wpsn_clear_ai_overrides_all'); ?>
                        <?php submit_button(__('Clear all overrides', 'wp-seo-next'), 'delete', 'submit', false); ?>
                    </form>
                </div>
            <?php endif; ?>

            <div style="display:flex; gap:10px; align-items:center; margin:10px 0; max-width: 980px;">
                <input type="text" class="regular-text" id="wpsn_ai_overrides_search" value="<?php echo esc_attr($overridesSearch); ?>" placeholder="<?php echo esc_attr__('Search users (login/email/name)…', 'wp-seo-next'); ?>" />
                <button type="button" class="button" id="wpsn_ai_overrides_search_btn"><?php echo esc_html__('Search', 'wp-seo-next'); ?></button>
                <?php if ($overridesSearch !== '') : ?>
                    <a class="button button-link-delete" href="<?php echo esc_url($baseUrl); ?>"><?php echo esc_html__('Clear', 'wp-seo-next'); ?></a>
                <?php endif; ?>
                <div style="margin-left:auto; opacity:.7;">
                    <?php
                        printf(
                            /* translators: %d total */
                            esc_html__('%d users with overrides', 'wp-seo-next'),
                            (int) $overrideTotal
                        );
                    ?>
                </div>
            </div>

            <script>
            (function(){
                var btn = document.getElementById('wpsn_ai_overrides_search_btn');
                var input = document.getElementById('wpsn_ai_overrides_search');
                if (!btn || !input) return;
                function go(){
                    var v = (input.value || '').trim();
                    var url = <?php echo wp_json_encode($baseUrl); ?>;
                    if (v) {
                        url += '&wpsn_ai_overrides_search=' + encodeURIComponent(v) + '&wpsn_ai_overrides_page=1';
                    } else {
                        url += '&wpsn_ai_overrides_page=1';
                    }
                    window.location = url;
                }
                btn.addEventListener('click', go);
                input.addEventListener('keydown', function(e){
                    if (e && e.key === 'Enter') {
                        e.preventDefault();
                        go();
                    }
                });
            })();
            </script>

            <table class="widefat striped" style="max-width: 980px;">
                <thead>
                    <tr>
                        <th><?php echo esc_html__('User', 'wp-seo-next'); ?></th>
                        <th style="width:180px;"><?php echo esc_html__('Roles', 'wp-seo-next'); ?></th>
                        <th style="width:140px;"><?php echo esc_html__('OpenAI use', 'wp-seo-next'); ?></th>
                        <th style="width:140px;"><?php echo esc_html__('AI manage', 'wp-seo-next'); ?></th>
                        <th style="width:260px;"><?php echo esc_html__('Actions', 'wp-seo-next'); ?></th>
                    </tr>
                </thead>
                <tbody>
                    <?php if (empty($overrideUsers)) : ?>
                        <tr>
                            <td colspan="5" style="text-align:center; opacity:.7; padding:14px;">
                                <?php echo esc_html__('No user overrides found.', 'wp-seo-next'); ?>
                            </td>
                        </tr>
                    <?php else : ?>
                        <?php foreach ($overrideUsers as $u) : ?>
                            <?php
                                if (!$u instanceof \WP_User) {
                                    continue;
                                }
                                $uid = (int) $u->ID;
                                $login = (string) ($u->user_login ?? '');
                                $name = (string) ($u->display_name ?? '');
                                $email = (string) ($u->user_email ?? '');
                                $rolesStr = '';
                                if (!empty($u->roles) && is_array($u->roles)) {
                                    $rolesStr = implode(', ', array_map('sanitize_key', $u->roles));
                                }
                                $useMode = \WPSN\Core\Capabilities::getUserAIUseOverride($uid);
                                $manageMode = \WPSN\Core\Capabilities::getUserAIManageOverride($uid);

                                $clearBase = admin_url('admin-post.php?action=wpsn_clear_ai_user_override&user_id=' . $uid);
                                $urlUse = wp_nonce_url(add_query_arg('which', 'use', $clearBase), 'wpsn_clear_ai_user_override');
                                $urlManage = wp_nonce_url(add_query_arg('which', 'manage', $clearBase), 'wpsn_clear_ai_user_override');
                                $urlBoth = wp_nonce_url(add_query_arg('which', 'both', $clearBase), 'wpsn_clear_ai_user_override');
                                $editUrl = get_edit_user_link($uid);

                                $fmtMode = static function (string $m): string {
                                    $m = sanitize_key($m);
                                    if ($m === 'allow') {
                                        return 'allow';
                                    }
                                    if ($m === 'deny') {
                                        return 'deny';
                                    }
                                    return 'inherit';
                                };
                            ?>
                            <tr>
                                <td>
                                    <strong><?php echo esc_html($login !== '' ? $login : ('user#' . $uid)); ?></strong>
                                    <?php if ($name !== '' && $name !== $login) : ?>
                                        <span style="opacity:.7;">— <?php echo esc_html($name); ?></span>
                                    <?php endif; ?>
                                    <?php if ($email !== '' && $isAdmin) : ?>
                                        <div style="opacity:.65;"><code><?php echo esc_html($email); ?></code></div>
                                    <?php endif; ?>
                                </td>
                                <td style="opacity:.85;"><?php echo esc_html($rolesStr); ?></td>
                                <td><code><?php echo esc_html($fmtMode($useMode)); ?></code></td>
                                <td><code><?php echo esc_html($fmtMode($manageMode)); ?></code></td>
                                <td>
                                    <?php if ($isAdmin) : ?>
                                        <a class="button button-small" href="<?php echo esc_url($urlUse); ?>"><?php echo esc_html__('Clear use', 'wp-seo-next'); ?></a>
                                        <a class="button button-small" href="<?php echo esc_url($urlManage); ?>"><?php echo esc_html__('Clear manage', 'wp-seo-next'); ?></a>
                                        <a class="button button-small" href="<?php echo esc_url($urlBoth); ?>"><?php echo esc_html__('Clear both', 'wp-seo-next'); ?></a>
                                    <?php else : ?>
                                        <span style="opacity:.65;">—</span>
                                    <?php endif; ?>
                                    <?php if (is_string($editUrl) && $editUrl !== '') : ?>
                                        <a class="button button-small" href="<?php echo esc_url($editUrl); ?>"><?php echo esc_html__('Edit user', 'wp-seo-next'); ?></a>
                                    <?php endif; ?>
                                </td>
                            </tr>
                        <?php endforeach; ?>
                    <?php endif; ?>
                </tbody>
            </table>

            <?php if ($overrideTotalPages > 1) : ?>
                <div style="margin-top:10px; max-width: 980px; display:flex; gap:8px; align-items:center;">
                    <?php
                        $prev = max(1, $overridesPageNum - 1);
                        $next = min($overrideTotalPages, $overridesPageNum + 1);
                        $prevUrl = add_query_arg([
                            'wpsn_ai_overrides_page' => $prev,
                            'wpsn_ai_overrides_search' => $overridesSearch,
                        ], $baseUrl);
                        $nextUrl = add_query_arg([
                            'wpsn_ai_overrides_page' => $next,
                            'wpsn_ai_overrides_search' => $overridesSearch,
                        ], $baseUrl);
                    ?>
                    <a class="button" href="<?php echo esc_url($prevUrl); ?>" <?php echo $overridesPageNum <= 1 ? 'style="pointer-events:none;opacity:.5;"' : ''; ?>><?php echo esc_html__('← Prev', 'wp-seo-next'); ?></a>
                    <span style="opacity:.7;">
                        <?php
                            printf(
                                /* translators: 1: page number, 2: total pages */
                                esc_html__('Page %1$d of %2$d', 'wp-seo-next'),
                                (int) $overridesPageNum,
                                (int) $overrideTotalPages
                            );
                        ?>
                    </span>
                    <a class="button" href="<?php echo esc_url($nextUrl); ?>" <?php echo $overridesPageNum >= $overrideTotalPages ? 'style="pointer-events:none;opacity:.5;"' : ''; ?>><?php echo esc_html__('Next →', 'wp-seo-next'); ?></a>
                </div>
            <?php endif; ?>

            <h2><?php echo esc_html__('Recent calls', 'wp-seo-next'); ?></h2>
            <table class="widefat striped" style="max-width: 1200px;">
                <thead>
                    <tr>
                        <th><?php echo esc_html__('Time (UTC)', 'wp-seo-next'); ?></th>
                        <th><?php echo esc_html__('Purpose', 'wp-seo-next'); ?></th>
                        <th><?php echo esc_html__('Prompt', 'wp-seo-next'); ?></th>
                        <th><?php echo esc_html__('Post ID', 'wp-seo-next'); ?></th>
                        <th><?php echo esc_html__('Model', 'wp-seo-next'); ?></th>
                        <th><?php echo esc_html__('Tokens', 'wp-seo-next'); ?></th>
                        <th><?php echo esc_html__('Cost', 'wp-seo-next'); ?></th>
                        <th><?php echo esc_html__('Latency', 'wp-seo-next'); ?></th>
                        <th><?php echo esc_html__('Status', 'wp-seo-next'); ?></th>
                        <th><?php echo esc_html__('Error', 'wp-seo-next'); ?></th>
                    </tr>
                </thead>
                <tbody>
                <?php if (!$calls) : ?>
                    <tr><td colspan="10"><?php echo esc_html__('No calls yet.', 'wp-seo-next'); ?></td></tr>
                <?php else : ?>
                    <?php foreach ($calls as $row) :
                        $ok = !empty($row['success']);
                        $err = isset($row['error_message']) ? (string) $row['error_message'] : '';
                        $pKey = isset($row['prompt_key']) ? (string) $row['prompt_key'] : '';
                        $pVer = isset($row['prompt_version']) ? (int) $row['prompt_version'] : 1;
                        $pLabel = $pKey !== '' ? ($pKey . ' (v' . $pVer . ')') : ('v' . $pVer);
                    ?>
                        <tr>
                            <td><?php echo esc_html((string) ($row['created_at'] ?? '')); ?></td>
                            <td><?php echo esc_html((string) ($row['purpose'] ?? '')); ?></td>
                            <td><?php echo esc_html($pLabel); ?></td>
                            <td><?php echo esc_html((string) ($row['post_id'] ?? '0')); ?></td>
                            <td><?php echo esc_html((string) ($row['model'] ?? '')); ?></td>
                            <td><?php echo esc_html((string) ($row['tokens_total'] ?? '0')); ?></td>
                            <td><?php echo esc_html('$' . number_format((float) ($row['cost_usd'] ?? 0.0), 4)); ?></td>
                            <td><?php echo esc_html((string) ($row['latency_ms'] ?? 0)) . 'ms'; ?></td>
                            <td><?php echo $ok ? '<span style="color:#0a7">OK</span>' : '<span style="color:#a00">Error</span>'; ?></td>
                            <td style="max-width: 380px; word-break: break-word;">
                                <?php echo esc_html($err); ?>
                            </td>
                        </tr>
                    <?php endforeach; ?>
                <?php endif; ?>
                </tbody>
            </table>
        </div>
        <?php
    }
}
