<?php

declare(strict_types=1);

namespace Numinix\SeekmodoWordPress\Admin;

use Numinix\SeekmodoWordPress\LocalIndex\Indexer;
use Numinix\SeekmodoWordPress\LocalIndex\IndexSettings;
use Numinix\SeekmodoWordPress\LocalIndex\LocalMerchandising;
use Numinix\SeekmodoWordPress\LocalIndex\Schema;
use Numinix\SeekmodoWordPress\LocalIndex\Stopwords;
use Numinix\SeekmodoWordPress\LocalIndex\VerticalConfig;

/**
 * Local Index admin UI under Settings → Seekmodo Search.
 */
final class LocalIndexAdmin
{
    public static function register(): void
    {
        if (!function_exists('add_action')) {
            return;
        }
        add_action('admin_init', [self::class, 'handlePost']);
        add_action('admin_notices', [self::class, 'maybeShowEmptyIndexNotice']);
    }

    public static function maybeShowEmptyIndexNotice(): void
    {
        if (!function_exists('current_user_can') || !current_user_can('manage_options')) {
            return;
        }
        if (!VerticalConfig::isEnabled() || VerticalConfig::mode() === VerticalConfig::MODE_OFF) {
            return;
        }
        if (!VerticalConfig::contentIndexEnabled() && !VerticalConfig::commerceIndexEnabled()) {
            return;
        }
        if (Schema::docCount() > 0) {
            return;
        }

        $settings_url = function_exists('admin_url')
            ? admin_url('options-general.php?page=' . SettingsPage::SLUG)
            : '';
        $cli = 'wp seekmodo local_index build';

        echo '<div class="notice notice-warning"><p>';
        echo '<strong>' . esc_html__('Seekmodo search index is empty.', 'seekmodo') . '</strong> ';
        echo esc_html__(
            'An automatic build is scheduled (usually within a few minutes). Search stays on WordPress defaults until indexing completes.',
            'seekmodo'
        );
        echo ' ';
        if ($settings_url !== '') {
            printf(
                '<a href="%s">%s</a>',
                esc_url($settings_url),
                esc_html__('Open Seekmodo settings', 'seekmodo')
            );
            echo ' &middot; ';
        }
        printf(
            '<code>%s</code>',
            esc_html($cli)
        );
        echo '</p></div>';
    }

    public static function handlePost(): void
    {
        if (!function_exists('current_user_can') || !current_user_can('manage_options')) {
            return;
        }
        if (!isset($_POST['seekmodo_local_index_action'])) {
            return;
        }
        check_admin_referer('seekmodo_local_index');

        $action = sanitize_key((string) $_POST['seekmodo_local_index_action']);
        switch ($action) {
            case 'build_full':
                Indexer::reindexFull();
                add_settings_error('seekmodo_local_index', 'built', __('Local index rebuild started.', 'seekmodo'), 'updated');
                break;
            case 'save_settings':
                self::saveSettings();
                add_settings_error('seekmodo_local_index', 'saved', __('Local index settings saved.', 'seekmodo'), 'updated');
                break;
            case 'add_stopword':
                $word = sanitize_text_field((string) ($_POST['stopword'] ?? ''));
                if ($word !== '') {
                    Stopwords::add($word);
                }
                break;
            case 'add_synonym':
                $term = sanitize_text_field((string) ($_POST['syn_term'] ?? ''));
                $syn = sanitize_text_field((string) ($_POST['syn_value'] ?? ''));
                if ($term !== '' && $syn !== '') {
                    LocalMerchandising::addSynonym($term, $syn);
                }
                break;
        }
    }

    public static function renderPanel(): void
    {
        if (!function_exists('current_user_can') || !current_user_can('manage_options')) {
            return;
        }
        $status = Indexer::status();
        settings_errors('seekmodo_local_index');
        ?>
        <h2><?php esc_html_e('Local Index (Enhanced Native)', 'seekmodo'); ?></h2>
        <p><?php esc_html_e('On-server inverted index for relevance-ranked search without a subscription.', 'seekmodo'); ?></p>
        <?php if ((int) $status['docs'] === 0 && VerticalConfig::isEnabled() && VerticalConfig::mode() !== VerticalConfig::MODE_OFF) : ?>
            <div class="notice notice-info inline" style="margin: 1em 0;">
                <p>
                    <?php esc_html_e('No documents indexed yet. The plugin builds the index automatically after activation (cron, usually within a few minutes). Use “Build index now” to run immediately, or:', 'seekmodo'); ?>
                    <code>wp seekmodo local_index build</code>
                </p>
            </div>
        <?php endif; ?>
        <table class="form-table">
            <tr>
                <th><?php esc_html_e('Status', 'seekmodo'); ?></th>
                <td>
                    <?php
                    printf(
                        /* translators: 1: doc count 2: row count */
                        esc_html__('Indexed documents: %1$d (%2$d term rows)', 'seekmodo'),
                        (int) $status['docs'],
                        (int) $status['rows']
                    );
                    ?>
                </td>
            </tr>
            <tr>
                <th><?php esc_html_e('Mode', 'seekmodo'); ?></th>
                <td>
                    <select name="seekmodo_local_index_mode">
                        <?php foreach ([VerticalConfig::MODE_FALLBACK, VerticalConfig::MODE_PRIMARY, VerticalConfig::MODE_OFF] as $mode) : ?>
                            <option value="<?php echo esc_attr($mode); ?>" <?php selected(VerticalConfig::mode(), $mode); ?>><?php echo esc_html($mode); ?></option>
                        <?php endforeach; ?>
                    </select>
                </td>
            </tr>
            <tr>
                <th><?php esc_html_e('Relevanssi compat', 'seekmodo'); ?></th>
                <td>
                    <label>
                        <input type="checkbox" name="seekmodo_relevanssi_compat_enabled" value="1" <?php checked(VerticalConfig::relevanssiCompatEnabled()); ?> />
                        <?php esc_html_e('Honor relevanssi flag and filter names', 'seekmodo'); ?>
                    </label>
                </td>
            </tr>
            <tr>
                <th><?php esc_html_e('Default operator', 'seekmodo'); ?></th>
                <td>
                    <select name="seekmodo_local_index_default_operator">
                        <option value="and" <?php selected(IndexSettings::defaultOperator(), 'and'); ?>>AND</option>
                        <option value="or" <?php selected(IndexSettings::defaultOperator(), 'or'); ?>>OR</option>
                    </select>
                </td>
            </tr>
            <tr>
                <th><?php esc_html_e('Partial matching', 'seekmodo'); ?></th>
                <td>
                    <label>
                        <input type="checkbox" name="seekmodo_local_index_partial_match" value="1" <?php checked(IndexSettings::partialMatchEnabled()); ?> />
                        <?php esc_html_e('Enable prefix/suffix matching', 'seekmodo'); ?>
                    </label>
                </td>
            </tr>
            <tr>
                <th><?php esc_html_e('OR fallback', 'seekmodo'); ?></th>
                <td>
                    <label>
                        <input type="checkbox" name="seekmodo_local_index_or_fallback" value="1" <?php checked(IndexSettings::orFallbackEnabled()); ?> />
                        <?php esc_html_e('Retry with OR when AND returns zero results', 'seekmodo'); ?>
                    </label>
                </td>
            </tr>
        </table>

        <p>
            <button type="submit" name="seekmodo_local_index_action" value="save_settings" class="button button-primary">
                <?php esc_html_e('Save local index settings', 'seekmodo'); ?>
            </button>
            <button type="submit" name="seekmodo_local_index_action" value="build_full" class="button">
                <?php esc_html_e('Build index now', 'seekmodo'); ?>
            </button>
        </p>

        <h3><?php esc_html_e('Add stopword', 'seekmodo'); ?></h3>
        <p>
            <input type="text" name="stopword" placeholder="<?php esc_attr_e('word', 'seekmodo'); ?>" />
            <button type="submit" name="seekmodo_local_index_action" value="add_stopword" class="button"><?php esc_html_e('Add', 'seekmodo'); ?></button>
        </p>

        <h3><?php esc_html_e('Add synonym', 'seekmodo'); ?></h3>
        <p>
            <input type="text" name="syn_term" placeholder="<?php esc_attr_e('term', 'seekmodo'); ?>" />
            <input type="text" name="syn_value" placeholder="<?php esc_attr_e('synonym', 'seekmodo'); ?>" />
            <button type="submit" name="seekmodo_local_index_action" value="add_synonym" class="button"><?php esc_html_e('Add', 'seekmodo'); ?></button>
        </p>
        <?php
        wp_nonce_field('seekmodo_local_index');
    }

    private static function saveSettings(): void
    {
        if (isset($_POST['seekmodo_local_index_mode'])) {
            update_option(VerticalConfig::OPT_MODE, sanitize_key((string) $_POST['seekmodo_local_index_mode']));
        }
        update_option(VerticalConfig::OPT_RELEVANSSI_COMPAT, isset($_POST['seekmodo_relevanssi_compat_enabled']) ? '1' : '0');
        if (isset($_POST['seekmodo_local_index_default_operator'])) {
            update_option(IndexSettings::OPT_DEFAULT_OPERATOR, sanitize_key((string) $_POST['seekmodo_local_index_default_operator']));
        }
        update_option(IndexSettings::OPT_PARTIAL_MATCH, isset($_POST['seekmodo_local_index_partial_match']) ? '1' : '0');
        update_option(IndexSettings::OPT_OR_FALLBACK, isset($_POST['seekmodo_local_index_or_fallback']) ? '1' : '0');

        if (Schema::docCount() === 0 && VerticalConfig::isEnabled() && VerticalConfig::mode() !== VerticalConfig::MODE_OFF) {
            Indexer::queueInitialFullBuild();
        }
    }
}
