<?php
/**
 * Settings page renderer and form handler.
 *
 * @package SkyEmagSync
 */

namespace SkyEmagSync\Admin;

use SkyEmagSync\Options;
use SkyEmagSync\Plugin;
use SkyEmagSync\PostMeta;
use SkyEmagSync\Sync\Runner;
use SkyEmagSync\Sync\Bootstrap;
use SkyEmagSync\Api\EmagClient;

defined( 'ABSPATH' ) || exit;

class SettingsPage {

    const NONCE_ACTION       = 'skyemag_save_settings';
    const NONCE_FIELD        = 'skyemag_settings_nonce';
    const SYNC_ACTION        = 'skyemag_manual_sync';
    const SYNC_NONCE         = 'skyemag_manual_sync_nonce';
    const BOOTSTRAP_ACTION   = 'skyemag_run_bootstrap';
    const BOOTSTRAP_NONCE    = 'skyemag_bootstrap_nonce';
    const PING_AJAX          = 'skyemag_ping';
    const CAT_IMPORT_AJAX    = 'skyemag_import_categories';
    const CAT_PROGRESS_AJAX  = 'skyemag_cat_import_progress';
    const CAT_DETAIL_AJAX    = 'skyemag_cat_detail_batch';
    const BB_TRACK_AJAX      = 'skyemag_bb_track';
    const DETECT_SOURCES_AJAX = 'skyemag_detect_field_sources';
    const BS_IMPORT_AJAX     = 'skyemag_run_bootstrap_ajax';
    const BS_PROGRESS_AJAX   = 'skyemag_bootstrap_progress';
    // Async sync (3.8.0): start enqueues batches via Dispatcher; progress
    // returns ProgressStore state; cancel halts mid-sync.
    const SYNC_START_AJAX    = 'skyemag_sync_start';
    const SYNC_PROGRESS_AJAX = 'skyemag_sync_progress';
    const SYNC_CANCEL_AJAX   = 'skyemag_sync_cancel';

    public function register(): void {
        add_action( 'admin_init', [ $this, 'handle_form' ] );
        add_action( 'admin_init', [ $this, 'handle_manual_sync' ] );
        add_action( 'admin_init', [ $this, 'handle_bootstrap' ] );

        // All AJAX endpoints exposed by the Settings page are registered on
        // every install. None of them depend on a license check — each one
        // either runs standalone (ping, bootstrap import, Brand/EAN source
        // detection) or self-guards on the presence of its supporting class
        // (CategoryImporter, BuyButtonTracker). Where that supporting class
        // is part of the Premium add-on and is therefore physically absent
        // from the Free build via the Freemius @fs_premium_only directive,
        // the handler returns a structured 404 — not a license error. This
        // keeps the contract with the WP.org Plugin Directory: there is no
        // locked-but-functional code path, only handlers whose dependency
        // is either present or not present.
        add_action( 'wp_ajax_' . self::PING_AJAX, [ $this, 'ajax_ping' ] );
        add_action( 'wp_ajax_' . self::BS_IMPORT_AJAX, [ $this, 'ajax_run_bootstrap' ] );
        add_action( 'wp_ajax_' . self::BS_PROGRESS_AJAX, [ $this, 'ajax_bootstrap_progress' ] );
        add_action( 'wp_ajax_' . self::DETECT_SOURCES_AJAX, [ $this, 'ajax_detect_sources' ] );
        add_action( 'wp_ajax_' . self::CAT_IMPORT_AJAX, [ $this, 'ajax_import_categories' ] );
        add_action( 'wp_ajax_' . self::CAT_PROGRESS_AJAX, [ $this, 'ajax_cat_import_progress' ] );
        add_action( 'wp_ajax_' . self::CAT_DETAIL_AJAX, [ $this, 'ajax_cat_detail_batch' ] );
        add_action( 'wp_ajax_' . self::BB_TRACK_AJAX, [ $this, 'ajax_bb_track' ] );

        // 3.8.0 async sync endpoints — three separate handlers so the JS
        // can start, poll, and cancel a sync without keeping the browser
        // connection open during the work itself.
        add_action( 'wp_ajax_' . self::SYNC_START_AJAX, [ $this, 'ajax_sync_start' ] );
        add_action( 'wp_ajax_' . self::SYNC_PROGRESS_AJAX, [ $this, 'ajax_sync_progress' ] );
        add_action( 'wp_ajax_' . self::SYNC_CANCEL_AJAX, [ $this, 'ajax_sync_cancel' ] );
    }

    // ── Form handlers ─────────────────────────────────────────────────────

    public function handle_form(): void {
        if ( ! isset( $_POST[ self::NONCE_FIELD ] ) ) {
            return;
        }
        check_admin_referer( self::NONCE_ACTION, self::NONCE_FIELD );
        if ( ! current_user_can( Menu::CAPABILITY ) ) {
            wp_die( esc_html__( 'Unauthorized.', 'skyservers-product-sync-for-emag' ) );
        }

        $errors = Options::save_settings( $_POST );
        if ( $errors ) {
            foreach ( $errors as $error_msg ) {
                self::queue_notice( 'error', (string) $error_msg );
            }
            $query = [ 'skyemag_notice' => 'error' ];
        } else {
            $query = [ 'skyemag_notice' => 'saved' ];
        }

        wp_safe_redirect( add_query_arg( $query, admin_url( 'admin.php?page=' . Menu::SETTINGS_SLUG ) ) );
        exit;
    }

    public function handle_manual_sync(): void {
        if ( ! isset( $_POST[ self::SYNC_NONCE ] ) ) {
            return;
        }
        check_admin_referer( self::SYNC_ACTION, self::SYNC_NONCE );
        if ( ! current_user_can( Menu::CAPABILITY ) ) {
            wp_die( esc_html__( 'Unauthorized.', 'skyservers-product-sync-for-emag' ) );
        }

        $result = Runner::run_sync( 'manual' );
        wp_safe_redirect( add_query_arg( [
            'skyemag_notice'  => $result['success'] ? 'synced' : 'sync_error',
            'skyemag_synced'  => $result['synced'],
            'skyemag_failed'  => $result['failed'],
            'skyemag_skipped' => $result['skipped'],
        ], admin_url( 'admin.php?page=' . Menu::SETTINGS_SLUG ) ) );
        exit;
    }

    public function handle_bootstrap(): void {
        if ( ! isset( $_POST[ self::BOOTSTRAP_NONCE ] ) ) {
            return;
        }
        check_admin_referer( self::BOOTSTRAP_ACTION, self::BOOTSTRAP_NONCE );
        if ( ! current_user_can( Menu::CAPABILITY ) ) {
            wp_die( esc_html__( 'Unauthorized.', 'skyservers-product-sync-for-emag' ) );
        }

        $result = Bootstrap::run();
        if ( ! $result['success'] && ! empty( $result['errors'] ) ) {
            self::queue_notice( 'error', __( 'Import failed: ', 'skyservers-product-sync-for-emag' )
                . implode( '; ', array_map( 'sanitize_text_field', (array) $result['errors'] ) ) );
        }
        wp_safe_redirect( add_query_arg( [
            'skyemag_notice'       => $result['success'] ? 'bootstrap_ok' : 'bootstrap_error',
            'skyemag_bs_matched'   => (int) $result['matched'],
            'skyemag_bs_unmatched' => (int) $result['unmatched'],
        ], admin_url( 'admin.php?page=' . Menu::SETTINGS_SLUG ) ) );
        exit;
    }

    public function ajax_ping(): void {
        check_ajax_referer( self::PING_AJAX, 'nonce' );
        if ( ! current_user_can( Menu::CAPABILITY ) ) {
            wp_send_json_error( [ 'message' => 'Unauthorized.' ], 403 );
        }

        // Allow testing with unsaved credentials from the form.
        $username = isset( $_POST['username'] )
            ? sanitize_text_field( wp_unslash( $_POST['username'] ) )
            : '';
        $password = isset( $_POST['password'] )
            ? sanitize_text_field( wp_unslash( $_POST['password'] ) )
            : '';

        if ( $username && $password ) {
            // Use the credentials sent from the form (not yet saved).
            $client = new EmagClient( $username, $password );
        } else {
            // Fall back to saved credentials.
            $client = new EmagClient();
        }

        $response = $client->ping();

        // Always include raw response for debugging auth issues
        $debug_info = [
            'http_code' => $response['http_code'] ?? 0,
            'error'     => $response['error']     ?? '',
            'raw'       => $response['raw']        ?? null,
            'data'      => $response['data']       ?? null,
        ];

        if ( $response['success'] ) {
            wp_send_json_success( [
                'message'    => sprintf(
                    /* translators: %1$d: number */
                    __( 'Connection OK (%d ms)', 'skyservers-product-sync-for-emag' ),
                    $response['data']['latency_ms'] ?? 0
                ),
                'debug' => $debug_info,
            ] );
        } else {
            wp_send_json_error( [
                'message' => $response['error'],
                'debug'   => $debug_info,
            ] );
        }
    }

    /**
     * AJAX: Start category import (runs in the current request).
     * For large catalogues this can take a few minutes.
     */
    public function ajax_import_categories(): void {
        check_ajax_referer( self::CAT_IMPORT_AJAX, 'nonce' );
        if ( ! current_user_can( Menu::CAPABILITY ) ) {
            wp_send_json_error( [ 'message' => 'Unauthorized.' ], 403 );
        }
        if ( ! class_exists( \SkyEmagSync\Products\CategoryImporter::class ) ) {
            wp_send_json_error( [ 'message' => 'Category importer is not available on this install.' ], 404 );
        }

        // Increase time limit for large imports.
        if ( function_exists( 'set_time_limit' ) ) {
            set_time_limit( 600 ); // 10 minutes max.
        }

        $result = \SkyEmagSync\Products\CategoryImporter::run_full_import();

        if ( $result['success'] ) {
            wp_send_json_success( [
                'message'  => sprintf(
                    /* translators: %1$d: number, %2$d: number, %3$d: number */
                    __( 'Import complete: %1$d categories, %2$d allowed, %3$d with details.', 'skyservers-product-sync-for-emag' ),
                    $result['imported'], $result['allowed'], $result['detailed']
                ),
                'stats' => $result,
            ] );
        } else {
            wp_send_json_error( [
                'message' => $result['error'],
                'stats'   => $result,
            ] );
        }
    }

    /**
     * AJAX: Poll category import progress.
     */
    public function ajax_cat_import_progress(): void {
        check_ajax_referer( self::CAT_PROGRESS_AJAX, 'nonce' );
        if ( ! current_user_can( Menu::CAPABILITY ) ) {
            wp_send_json_error( [ 'message' => 'Unauthorized.' ], 403 );
        }
        if ( ! class_exists( \SkyEmagSync\Products\CategoryImporter::class ) ) {
            wp_send_json_error( [ 'message' => 'Category importer is not available on this install.' ], 404 );
        }

        wp_send_json_success( \SkyEmagSync\Products\CategoryImporter::get_progress() );
    }

    /**
     * AJAX: Run one batch of detail imports (25 categories).
     * Called repeatedly from JS until done.
     */
    public function ajax_cat_detail_batch(): void {
        check_ajax_referer( self::CAT_DETAIL_AJAX, 'nonce' );
        if ( ! current_user_can( Menu::CAPABILITY ) ) {
            wp_send_json_error( [ 'message' => 'Unauthorized.' ], 403 );
        }
        if ( ! class_exists( \SkyEmagSync\Products\CategoryImporter::class ) ) {
            wp_send_json_error( [ 'message' => 'Category importer is not available on this install.' ], 404 );
        }

        $result = \SkyEmagSync\Products\CategoryImporter::run_detail_batch();

        wp_send_json_success( $result );
    }

    /**
     * AJAX: Run the eMAG offer bootstrap inside this request. Long-running;
     * the JS side polls ajax_bootstrap_progress() in parallel for the bar.
     * Mirror to ajax_import_categories.
     */
    public function ajax_run_bootstrap(): void {
        check_ajax_referer( self::BS_IMPORT_AJAX, 'nonce' );
        if ( ! current_user_can( Menu::CAPABILITY ) ) {
            wp_send_json_error( [ 'message' => 'Unauthorized.' ], 403 );
        }

        // Allow up to 10 minutes for large catalogues. Bootstrap pages
        // through up to 50 × 100 = 5000 offers, then loops them once.
        if ( function_exists( 'set_time_limit' ) ) {
            set_time_limit( 600 );
        }

        $result = \SkyEmagSync\Sync\Bootstrap::run();

        if ( ! empty( $result['success'] ) ) {
            wp_send_json_success( [
                'message' => sprintf(
                    /* translators: 1: matched, 2: unmatched, 3: skipped */
                    __( 'Import complete: %1$d matched, %2$d unmatched eMAG offers, %3$d unmapped WC products.', 'skyservers-product-sync-for-emag' ),
                    (int) ( $result['matched'] ?? 0 ),
                    (int) ( $result['unmatched'] ?? 0 ),
                    (int) ( $result['skipped'] ?? 0 )
                ),
                'stats' => $result,
            ] );
        }

        wp_send_json_error( [
            'message' => ! empty( $result['errors'] )
                ? implode( '; ', $result['errors'] )
                : __( 'Bootstrap failed without a specific error.', 'skyservers-product-sync-for-emag' ),
            'stats'   => $result,
        ] );
    }

    /**
     * AJAX: Poll the bootstrap progress transient. Mirror to
     * ajax_cat_import_progress.
     */
    public function ajax_bootstrap_progress(): void {
        check_ajax_referer( self::BS_PROGRESS_AJAX, 'nonce' );
        if ( ! current_user_can( Menu::CAPABILITY ) ) {
            wp_send_json_error( [ 'message' => 'Unauthorized.' ], 403 );
        }

        wp_send_json_success( \SkyEmagSync\Sync\Bootstrap::get_progress() );
    }

    // ── Render ────────────────────────────────────────────────────────────

    public static function render(): void {
        if ( ! current_user_can( Menu::CAPABILITY ) ) {
            return;
        }

        $creds           = Options::api_credentials();
        $bootstrap_done  = Options::is_bootstrap_done();
        $notices         = self::collect_notices();
        ?>
        <div class="wrap skyemag-settings">
            <?php
            if ( \SkyEmagSync\Options::setup_skipped()
                && ! \SkyEmagSync\Admin\SetupWizard::notice_dismissed_by_current_user() ) :
                $wizard_url = admin_url( 'admin.php?page=' . \SkyEmagSync\Admin\SetupWizard::PAGE_SLUG );
                ?>
                <div class="notice notice-info is-dismissible skyemag-skipped-notice"
                     data-skyemag-skipped-notice
                     style="margin-top:10px;">
                    <p>
                        <?php
                        echo wp_kses_post( sprintf(
                            /* translators: %s: link "Run setup wizard" */
                            esc_html__( 'Setup wizard was skipped. %s', 'skyservers-product-sync-for-emag' ),
                            '<a href="' . esc_url( $wizard_url ) . '" class="button button-primary" style="margin-left:8px;">' . esc_html__( 'Run setup wizard', 'skyservers-product-sync-for-emag' ) . '</a>'
                        ) );
                        ?>
                    </p>
                </div>
                <?php // Dismiss handler lives in assets/js/admin.js and reads ?>
                <?php // skyemagAdmin.wizardDismissNonce — no inline <script> needed. ?>
            <?php endif; ?>
            <h1><?php esc_html_e( 'SkyServers Sync — Settings', 'skyservers-product-sync-for-emag' ); ?></h1>

            <?php foreach ( $notices as $notice ) : ?>
                <div class="notice notice-<?php echo esc_attr( $notice['type'] ); ?> is-dismissible">
                    <p><?php echo wp_kses_post( $notice['message'] ); ?></p>
                </div>
            <?php endforeach; ?>

            <?php self::maybe_render_plan_status(); ?>

            <form method="post" action="">
                <?php wp_nonce_field( self::NONCE_ACTION, self::NONCE_FIELD ); ?>

                <!-- ── General ─────────────────────────────────────────── -->
                <h2 class="title"><?php esc_html_e( 'General', 'skyservers-product-sync-for-emag' ); ?></h2>
                <table class="form-table" role="presentation">
                    <tr>
                        <th scope="row"><?php esc_html_e( 'Enable Sync', 'skyservers-product-sync-for-emag' ); ?></th>
                        <td>
                            <label>
                                <input type="checkbox" name="master_enabled" value="1"
                                    <?php checked( Options::is_master_enabled() ); ?> />
                                <?php esc_html_e( 'Master switch – enable all synchronisation', 'skyservers-product-sync-for-emag' ); ?>
                            </label>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row">
                            <label for="skyemag_global_margin">
                                <?php esc_html_e( 'Global Margin (%)', 'skyservers-product-sync-for-emag' ); ?>
                            </label>
                        </th>
                        <td>
                            <input type="number" id="skyemag_global_margin" name="global_margin"
                                value="<?php echo esc_attr( Options::global_margin() ); ?>"
                                step="0.01" min="-50" max="300" class="small-text" />
                            <p class="description">
                                <?php esc_html_e( 'Fallback when no per-product margin is set. Range: -50% to 300%.', 'skyservers-product-sync-for-emag' ); ?>
                            </p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row">
                            <label for="skyemag_global_min_margin">
                                <?php esc_html_e( 'Global Min Margin (%)', 'skyservers-product-sync-for-emag' ); ?>
                            </label>
                        </th>
                        <td>
                            <?php
                            $stored_min = \SkyEmagSync\Options::get( \SkyEmagSync\Options::GLOBAL_MIN_MARGIN, '' );
                            ?>
                            <input type="number" id="skyemag_global_min_margin" name="global_min_margin"
                                value="<?php echo esc_attr( $stored_min ); ?>"
                                placeholder="<?php echo esc_attr( Options::global_margin() ); ?>"
                                step="0.01" min="-50" max="300" class="small-text" />
                            <p class="description">
                                <?php esc_html_e( 'Calculated price cannot go below: WC price ex. VAT × (1 + min margin / 100). If empty, mirrors Global Margin. Sync is blocked if calculated price falls below this threshold.', 'skyservers-product-sync-for-emag' ); ?>
                            </p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row">
                            <label for="skyemag_global_max_margin">
                                <?php esc_html_e( 'Global Max Margin (%)', 'skyservers-product-sync-for-emag' ); ?>
                            </label>
                        </th>
                        <td>
                            <?php
                            $stored_max = \SkyEmagSync\Options::get( \SkyEmagSync\Options::GLOBAL_MAX_MARGIN, '' );
                            ?>
                            <input type="number" id="skyemag_global_max_margin" name="global_max_margin"
                                value="<?php echo esc_attr( $stored_max ); ?>"
                                placeholder="<?php echo esc_attr( Options::global_margin() + 50 ); ?>"
                                step="0.01" min="-50" max="1000" class="small-text" />
                            <p class="description">
                                <?php esc_html_e( 'Sent to eMAG as the maximum allowed price: WC price ex. VAT × (1 + max margin / 100). If empty, defaults to Global Margin + 50%. Prevents sync from being blocked by eMAG max price threshold.', 'skyservers-product-sync-for-emag' ); ?>
                            </p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row">
                            <label for="skyemag_global_stock_percent">
                                <?php esc_html_e( 'Global Stock (%)', 'skyservers-product-sync-for-emag' ); ?>
                            </label>
                        </th>
                        <td>
                            <input type="number" id="skyemag_global_stock_percent" name="global_stock_percent"
                                value="<?php echo esc_attr( Options::global_stock_percent() ); ?>"
                                step="1" min="1" max="100" class="small-text" />
                            <span>%</span>
                            <p class="description">
                                <?php esc_html_e( 'Percentage of WooCommerce stock to send to eMAG. Rounded up (e.g. 28% of 10 = 3). Fallback when no per-product value is set.', 'skyservers-product-sync-for-emag' ); ?>
                            </p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row">
                            <label for="skyemag_min_wc_stock">
                                <?php esc_html_e( 'Minimum WC Stock', 'skyservers-product-sync-for-emag' ); ?>
                            </label>
                        </th>
                        <td>
                            <input type="number" id="skyemag_min_wc_stock" name="min_wc_stock"
                                value="<?php echo esc_attr( Options::min_wc_stock() ); ?>"
                                step="1" min="0" max="9999" class="small-text" />
                            <span><?php esc_html_e( 'units', 'skyservers-product-sync-for-emag' ); ?></span>
                            <p class="description">
                                <?php esc_html_e( 'If WooCommerce stock is at or below this value, the product will be sent to eMAG with stock 0 (out of stock). Use this to reserve a safety buffer. Example: set to 2 → if WC stock = 2 or less, eMAG shows out of stock. Default: 0 (disabled).', 'skyservers-product-sync-for-emag' ); ?>
                            </p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php esc_html_e( 'Price Rounding', 'skyservers-product-sync-for-emag' ); ?></th>
                        <td>
                            <?php foreach ( [
                                'none'      => __( 'No rounding (4 decimals)', 'skyservers-product-sync-for-emag' ),
                                '2decimals' => __( '2 decimal places', 'skyservers-product-sync-for-emag' ),
                                'end99'     => __( 'End in .99 (e.g. 12.37 → 12.99)', 'skyservers-product-sync-for-emag' ),
                            ] as $val => $label ) : ?>
                                <label style="display:block;margin-bottom:4px">
                                    <input type="radio" name="rounding_rule" value="<?php echo esc_attr( $val ); ?>"
                                        <?php checked( Options::rounding_rule(), $val ); ?> />
                                    <?php echo esc_html( $label ); ?>
                                </label>
                            <?php endforeach; ?>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php esc_html_e( 'Price source', 'skyservers-product-sync-for-emag' ); ?></th>
                        <td>
                            <label>
                                <input type="checkbox" name="use_regular_price" value="1"
                                    <?php checked( Options::use_regular_price() ); ?> />
                                <?php esc_html_e( 'Always send regular price to eMAG (ignore WooCommerce sales)', 'skyservers-product-sync-for-emag' ); ?>
                            </label>
                            <p class="description" style="margin-top:6px;">
                                <strong><?php esc_html_e( 'OFF (default):', 'skyservers-product-sync-for-emag' ); ?></strong>
                                <?php esc_html_e( 'eMAG receives the same price your WooCommerce customer pays right now — the sale price when a sale is running, the regular price otherwise. Each product is evaluated individually, so mixed catalogs (some on sale, some not) are mirrored exactly.', 'skyservers-product-sync-for-emag' ); ?>
                            </p>
                            <p class="description" style="margin-top:6px;">
                                <strong><?php esc_html_e( 'ON:', 'skyservers-product-sync-for-emag' ); ?></strong>
                                <?php esc_html_e( 'eMAG always receives the regular price, even for products with an active WooCommerce sale. Use this when you want WooCommerce promotions to stay on-site only and eMAG buyers to never see your discounts.', 'skyservers-product-sync-for-emag' ); ?>
                            </p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row">
                            <label for="skyemag_sync_schedule">
                                <?php esc_html_e( 'Sync Frequency', 'skyservers-product-sync-for-emag' ); ?>
                            </label>
                        </th>
                        <td>
                            <?php
                            $schedule_labels = [
                                '15min' => __( 'Every 15 minutes', 'skyservers-product-sync-for-emag' ),
                                '30min' => __( 'Every 30 minutes', 'skyservers-product-sync-for-emag' ),
                                '1h'    => __( 'Every hour', 'skyservers-product-sync-for-emag' ),
                                '3h'    => __( 'Every 3 hours', 'skyservers-product-sync-for-emag' ),
                                '6h'    => __( 'Every 6 hours', 'skyservers-product-sync-for-emag' ),
                                '12h'   => __( 'Every 12 hours', 'skyservers-product-sync-for-emag' ),
                                'daily' => __( 'Once daily', 'skyservers-product-sync-for-emag' ),
                            ];
                            ?>
                            <select id="skyemag_sync_schedule" name="sync_schedule">
                                <?php foreach ( $schedule_labels as $val => $label ) : ?>
                                    <option value="<?php echo esc_attr( $val ); ?>"
                                        <?php selected( Options::sync_schedule(), $val ); ?>>
                                        <?php echo esc_html( $label ); ?>
                                    </option>
                                <?php endforeach; ?>
                            </select>
                        </td>
                    </tr>
                </table>

                <!-- ── Sync Filters (free) ─────────────────────────────── -->
                <h2 class="title"><?php esc_html_e( 'Sync Filters', 'skyservers-product-sync-for-emag' ); ?></h2>
                <p class="description"><?php esc_html_e( 'Exclude products from every sync cycle when they match any of the rules below. Skipped products are recorded in the logs so you can audit the exclusions.', 'skyservers-product-sync-for-emag' ); ?></p>
                <table class="form-table" role="presentation">
                    <tr>
                        <th scope="row">
                            <label for="skyemag_sync_min_price_ex_vat"><?php esc_html_e( 'Minimum price (ex VAT)', 'skyservers-product-sync-for-emag' ); ?></label>
                        </th>
                        <td>
                            <input type="number" id="skyemag_sync_min_price_ex_vat" name="sync_min_price_ex_vat"
                                value="<?php echo esc_attr( (string) Options::sync_min_price_ex_vat() ); ?>"
                                step="0.01" min="0" class="small-text" />
                            <span>lei</span>
                            <p class="description"><?php esc_html_e( 'Skip products priced below this threshold. 0 = disabled.', 'skyservers-product-sync-for-emag' ); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row">
                            <label for="skyemag_sync_max_weight_kg"><?php esc_html_e( 'Maximum weight', 'skyservers-product-sync-for-emag' ); ?></label>
                        </th>
                        <td>
                            <input type="number" id="skyemag_sync_max_weight_kg" name="sync_max_weight_kg"
                                value="<?php echo esc_attr( (string) Options::sync_max_weight_kg() ); ?>"
                                step="0.01" min="0" class="small-text" />
                            <span>kg</span>
                            <p class="description"><?php esc_html_e( 'Skip products heavier than this (uses the weight from WooCommerce shipping data). 0 = disabled.', 'skyservers-product-sync-for-emag' ); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row">
                            <label for="skyemag_sync_skip_sku_pattern"><?php esc_html_e( 'Skip SKU pattern', 'skyservers-product-sync-for-emag' ); ?></label>
                        </th>
                        <td>
                            <input type="text" id="skyemag_sync_skip_sku_pattern" name="sync_skip_sku_pattern"
                                value="<?php echo esc_attr( Options::sync_skip_sku_pattern() ); ?>"
                                class="regular-text" placeholder="e.g. ^INT-|^SAMPLE-" />
                            <p class="description"><?php esc_html_e( 'PHP regex (without delimiters). Products whose SKU matches are skipped. Leave blank to disable.', 'skyservers-product-sync-for-emag' ); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php esc_html_e( 'Zero-stock handling', 'skyservers-product-sync-for-emag' ); ?></th>
                        <td>
                            <label>
                                <input type="checkbox" name="sync_skip_zero_stock" value="1"
                                    <?php checked( Options::sync_skip_zero_stock() ); ?> />
                                <?php esc_html_e( 'Skip products with 0 stock entirely (hard filter).', 'skyservers-product-sync-for-emag' ); ?>
                            </label>
                            <p class="description"><?php esc_html_e( 'Without this, the sync still runs but pushes stock = 0 to eMAG. The Min WC Stock buffer (Pro) is a softer alternative.', 'skyservers-product-sync-for-emag' ); ?></p>
                        </td>
                    </tr>
                </table>

                <!-- ── Publish Settings — only rendered on builds that ship
                     the publisher class. The Free WordPress.org build
                     strips ProductPublisher via the Freemius @fs_premium_only
                     directive, so the form is not surfaced there because
                     there is no consuming code path to act on the saved
                     values. -->
                <?php if ( class_exists( \SkyEmagSync\Products\ProductPublisher::class ) ) : ?>
                <h2 class="title"><?php esc_html_e( 'Publish Settings', 'skyservers-product-sync-for-emag' ); ?></h2>
                <p class="description"><?php esc_html_e( 'Defaults used when publishing new products to eMAG.', 'skyservers-product-sync-for-emag' ); ?></p>
                <table class="form-table" role="presentation">
                    <tr>
                        <th scope="row">
                            <label for="skyemag_publish_warranty"><?php esc_html_e( 'Warranty (months)', 'skyservers-product-sync-for-emag' ); ?></label>
                        </th>
                        <td>
                            <input type="number" id="skyemag_publish_warranty" name="publish_warranty"
                                value="<?php echo (int) Options::publish_warranty(); ?>"
                                min="0" max="120" step="1" class="small-text" />
                            <p class="description"><?php esc_html_e( 'Default: 12 months. Set 0 for no warranty (appropriate for food/coffee products).', 'skyservers-product-sync-for-emag' ); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row">
                            <label for="skyemag_publish_resupply"><?php esc_html_e( 'Resupply days', 'skyservers-product-sync-for-emag' ); ?></label>
                        </th>
                        <td>
                            <input type="number" id="skyemag_publish_resupply" name="publish_resupply_days"
                                value="<?php echo (int) Options::publish_resupply_days(); ?>"
                                min="0" max="365" step="1" class="small-text" />
                            <p class="description"><?php esc_html_e( 'supply_lead_time — days needed to restock. Default: 14.', 'skyservers-product-sync-for-emag' ); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row">
                            <?php esc_html_e( 'Send to eMAG Live', 'skyservers-product-sync-for-emag' ); ?>
                        </th>
                        <td>
                            <label>
                                <input type="checkbox" name="publish_live" value="1"
                                    <?php checked( Options::is_publish_live() ); ?> />
                                <?php esc_html_e( 'When ON, products are sent to eMAG for real. When OFF, Dry Run mode generates payloads without sending.', 'skyservers-product-sync-for-emag' ); ?>
                            </label>
                            <?php if ( Options::is_publish_live() ) : ?>
                                <p class="description" style="color:#dc3545;font-weight:600;">
                                    <?php esc_html_e( '⚠ LIVE mode is active — publishing will send products to eMAG!', 'skyservers-product-sync-for-emag' ); ?>
                                </p>
                            <?php endif; ?>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row">
                            <label for="skyemag_publish_id_offset"><?php esc_html_e( 'Publish ID offset', 'skyservers-product-sync-for-emag' ); ?></label>
                        </th>
                        <td>
                            <input type="number" id="skyemag_publish_id_offset" name="publish_id_offset"
                                value="<?php echo (int) Options::publish_id_offset(); ?>"
                                min="0" max="900000000" step="1" class="small-text" style="width:110px;" />
                            <p class="description"><?php esc_html_e( 'Added to the WooCommerce product ID to form the eMAG internal offer id when publishing new products. Set a value such as 1000000 if your eMAG account already contains offers created by another integration, so new publishes never collide with existing ids. Products already published or imported are not affected. Default: 0.', 'skyservers-product-sync-for-emag' ); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row">
                            <label for="skyemag_min_image_pixels"><?php esc_html_e( 'Minimum image size', 'skyservers-product-sync-for-emag' ); ?></label>
                        </th>
                        <td>
                            <input type="number" id="skyemag_min_image_pixels" name="min_image_pixels"
                                value="<?php echo (int) Options::min_image_pixels(); ?>"
                                min="0" max="5000" step="50" class="small-text" />
                            <span><?php esc_html_e( 'pixels (shorter edge)', 'skyservers-product-sync-for-emag' ); ?></span>
                            <p class="description"><?php esc_html_e( 'Marks a product as "Not Ready" when its featured image\'s shorter edge is below this value. 0 disables the check. Default: 600.', 'skyservers-product-sync-for-emag' ); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row">
                            <?php esc_html_e( 'Auto-sanitize characteristics', 'skyservers-product-sync-for-emag' ); ?>
                        </th>
                        <td>
                            <label>
                                <input type="checkbox" name="auto_sanitize_chars" value="1"
                                    <?php checked( Options::auto_sanitize_chars() ); ?> />
                                <?php esc_html_e( 'Clean characteristic values before sending to eMAG', 'skyservers-product-sync-for-emag' ); ?>
                            </label>
                            <p class="description">
                                <?php esc_html_e( 'Numeric fields extract the first number (e.g. "16 Pieces" → "16"). Text fields are trimmed and capped at 255 chars. Boolean fields normalize to Yes/No/N/A. All transformations are written to the activity log (action: sanitize). Turn OFF to send exactly what is in WooCommerce.', 'skyservers-product-sync-for-emag' ); ?>
                            </p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row">
                            <?php esc_html_e( 'Brand source', 'skyservers-product-sync-for-emag' ); ?>
                        </th>
                        <td>
                            <?php
                            $brand_sources = Options::brand_sources();
                            $brand_known   = [ 'pa_brand', 'pa_marca', '_brand', 'brand', '_manufacturer', 'pa_manufacturer' ];
                            for ( $i = 0; $i < 3; $i++ ) :
                                $val = $brand_sources[ $i ] ?? '';
                            ?>
                                <select name="brand_sources[]" class="skyemag-source-select skyemag-brand-source" style="width:320px;margin-bottom:4px;display:block;">
                                    <option value=""><?php echo esc_html( 0 === $i ? __( '— select brand source —', 'skyservers-product-sync-for-emag' ) : __( '— optional fallback —', 'skyservers-product-sync-for-emag' ) ); ?></option>
                                    <?php foreach ( $brand_known as $key ) : ?>
                                        <option value="<?php echo esc_attr( $key ); ?>" <?php selected( $val, $key ); ?>><?php echo esc_html( $key ); ?></option>
                                    <?php endforeach; ?>
                                    <?php if ( $val && ! in_array( $val, $brand_known, true ) ) : ?>
                                        <option value="<?php echo esc_attr( $val ); ?>" selected><?php echo esc_html( $val ); ?> (<?php esc_html_e( 'custom', 'skyservers-product-sync-for-emag' ); ?>)</option>
                                    <?php endif; ?>
                                </select>
                            <?php endfor; ?>
                            <p class="description">
                                <?php esc_html_e( 'Meta keys tried in order. First non-empty value wins. Works with taxonomy attributes (pa_brand) and post meta keys (_brand).', 'skyservers-product-sync-for-emag' ); ?>
                            </p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row">
                            <?php esc_html_e( 'EAN source', 'skyservers-product-sync-for-emag' ); ?>
                        </th>
                        <td>
                            <?php
                            $ean_sources = Options::ean_sources();
                            $ean_known   = [ '_global_unique_id', '_ean', '_barcode', '_gtin', 'hwp_product_gtin', '_alg_ean' ];
                            for ( $i = 0; $i < 3; $i++ ) :
                                $val = $ean_sources[ $i ] ?? '';
                            ?>
                                <select name="ean_sources[]" class="skyemag-source-select skyemag-ean-source" style="width:320px;margin-bottom:4px;display:block;">
                                    <option value=""><?php echo esc_html( 0 === $i ? __( '— select EAN source —', 'skyservers-product-sync-for-emag' ) : __( '— optional fallback —', 'skyservers-product-sync-for-emag' ) ); ?></option>
                                    <?php foreach ( $ean_known as $key ) : ?>
                                        <option value="<?php echo esc_attr( $key ); ?>" <?php selected( $val, $key ); ?>><?php echo esc_html( $key ); ?></option>
                                    <?php endforeach; ?>
                                    <?php if ( $val && ! in_array( $val, $ean_known, true ) ) : ?>
                                        <option value="<?php echo esc_attr( $val ); ?>" selected><?php echo esc_html( $val ); ?> (<?php esc_html_e( 'custom', 'skyservers-product-sync-for-emag' ); ?>)</option>
                                    <?php endif; ?>
                                </select>
                            <?php endfor; ?>
                            <p class="description">
                                <?php esc_html_e( 'Meta keys tried in order for EAN/GTIN. Default: _global_unique_id (WooCommerce 9.2+ built-in GTIN field).', 'skyservers-product-sync-for-emag' ); ?>
                            </p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"></th>
                        <td>
                            <button type="button" id="skyemag-detect-sources" class="button button-secondary">
                                <?php esc_html_e( 'Detect fields from products', 'skyservers-product-sync-for-emag' ); ?>
                            </button>
                            <span id="skyemag-detect-status" style="margin-left:8px;"></span>
                            <div id="skyemag-detect-results" style="display:none;margin-top:10px;"></div>
                        </td>
                    </tr>
                </table>
                <?php endif; ?>

                <!-- ── eMAG API ──────────────────────────────────────── -->
                <h2 class="title"><?php esc_html_e( 'eMAG API Credentials', 'skyservers-product-sync-for-emag' ); ?></h2>
                <table class="form-table" role="presentation">
                    <tr>
                        <th scope="row">
                            <label for="skyemag_api_username"><?php esc_html_e( 'Username eMAG', 'skyservers-product-sync-for-emag' ); ?></label>
                        </th>
                        <td>
                            <input type="text" id="skyemag_api_username" name="api_username"
                                value="<?php echo esc_attr( $creds['username'] ); ?>"
                                class="regular-text" autocomplete="off" />
                            <p class="description">
                                <?php esc_html_e( 'The username or email you use to log in on marketplace.emag.ro.', 'skyservers-product-sync-for-emag' ); ?>
                            </p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row">
                            <label for="skyemag_api_password"><?php esc_html_e( 'eMAG Account Password', 'skyservers-product-sync-for-emag' ); ?></label>
                        </th>
                        <td>
                            <input type="password" id="skyemag_api_password" name="api_password"
                                value="<?php echo esc_attr( $creds['password'] ); ?>"
                                class="regular-text" autocomplete="new-password" />
                            <p class="description">
                                <?php esc_html_e( 'The password you use to log in to marketplace.emag.ro — same as your username above. Not the API Code from Technical Details.', 'skyservers-product-sync-for-emag' ); ?>
                            </p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row">
                            <label for="skyemag_api_region"><?php esc_html_e( 'Region', 'skyservers-product-sync-for-emag' ); ?></label>
                        </th>
                        <td>
                            <select id="skyemag_api_region" name="api_region">
                                <option value="ro" <?php selected( $creds['region'], 'ro' ); ?>>Romania (RO)</option>
                                <option value="bg" <?php selected( $creds['region'], 'bg' ); ?>>Bulgaria (BG)</option>
                                <option value="hu" <?php selected( $creds['region'], 'hu' ); ?>>Hungary (HU)</option>
                            </select>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row">
                            <label for="skyemag_api_code"><?php esc_html_e( 'API Code (reference)', 'skyservers-product-sync-for-emag' ); ?></label>
                        </th>
                        <td>
                            <input type="text" id="skyemag_api_code" name="api_code"
                                value="<?php echo esc_attr( $creds['api_code'] ?? '' ); ?>"
                                class="regular-text" autocomplete="off" />
                            <p class="description">
                                <?php esc_html_e( 'Found in My Account → Profile → Technical Details → API Code. Stored for reference only — NOT used for authentication.', 'skyservers-product-sync-for-emag' ); ?>
                            </p>
                            <p style="margin-top:8px">
                                <button type="button" id="skyemag-test-connection" class="button button-secondary">
                                    <?php esc_html_e( 'Test Connection', 'skyservers-product-sync-for-emag' ); ?>
                                </button>
                                <span id="skyemag-ping-result" style="margin-left:10px;font-style:italic"></span>
                            </p>
                            <p class="description">
                                <?php
                                printf(
                                    /* translators: %s = link to Help page */
                                    esc_html__( 'Remember: your server IP must be whitelisted in your eMAG seller account before API calls will work. %s', 'skyservers-product-sync-for-emag' ),
                                    '<a href="' . esc_url( admin_url( 'admin.php?page=' . Menu::HELP_SLUG ) ) . '">' . esc_html__( 'See Help page for instructions and your server IP.', 'skyservers-product-sync-for-emag' ) . '</a>'
                                );
                                ?>
                            </p>
                        </td>
                    </tr>
                </table>

                <!-- ── Activity Logs ─────────────────────────────────── -->
                <h2 class="title"><?php esc_html_e( 'Activity Logs', 'skyservers-product-sync-for-emag' ); ?></h2>
                <table class="form-table" role="presentation">
                    <tr>
                        <th scope="row">
                            <label for="skyemag_log_retention_days">
                                <?php esc_html_e( 'Retention (days)', 'skyservers-product-sync-for-emag' ); ?>
                            </label>
                        </th>
                        <td>
                            <input type="number" id="skyemag_log_retention_days" name="log_retention_days"
                                value="<?php echo (int) Options::log_retention_days(); ?>"
                                min="<?php echo (int) Options::LOG_RETENTION_MIN; ?>"
                                max="<?php echo (int) Options::LOG_RETENTION_MAX; ?>"
                                step="1" class="small-text" />
                            <p class="description">
                                <?php
                                printf(
                                    /* translators: %1$d: min days, %2$d: max days */
                                    esc_html__( 'Logs older than this are deleted daily. Range: %1$d–%2$d days.', 'skyservers-product-sync-for-emag' ),
                                    (int) Options::LOG_RETENTION_MIN,
                                    (int) Options::LOG_RETENTION_MAX
                                );
                                ?>
                            </p>
                        </td>
                    </tr>
                </table>

                <!-- ── Data Management ───────────────────────────────── -->
                <h2 class="title"><?php esc_html_e( 'Data Management', 'skyservers-product-sync-for-emag' ); ?></h2>
                <table class="form-table" role="presentation">
                    <tr>
                        <th scope="row"><?php esc_html_e( 'Delete data on uninstall', 'skyservers-product-sync-for-emag' ); ?></th>
                        <td>
                            <label>
                                <input type="checkbox" name="delete_on_uninstall" value="yes"
                                    <?php checked( Options::delete_on_uninstall() ); ?> />
                                <?php esc_html_e( 'Remove all plugin options, product settings, logs and custom tables when this plugin is uninstalled.', 'skyservers-product-sync-for-emag' ); ?>
                            </label>
                            <p class="description" style="color:#d63638;">
                                <?php esc_html_e( 'Default: OFF. Keep disabled if you plan to upgrade from Free to Pro — otherwise you will lose all margins, mappings, and credentials on uninstall.', 'skyservers-product-sync-for-emag' ); ?>
                            </p>
                        </td>
                    </tr>
                </table>

                <?php submit_button( __( 'Save Settings', 'skyservers-product-sync-for-emag' ) ); ?>
            </form>

            <hr />

            <!-- ── eMAG Category Import — only rendered on builds that
                 ship the CategoryImporter class. The Free WordPress.org
                 build strips it via the Freemius @fs_premium_only
                 directive, so the section is not surfaced there because
                 there is no consuming code path to run. -->
            <?php if ( class_exists( \SkyEmagSync\Products\CategoryImporter::class ) ) : ?>
            <h2 class="title"><?php esc_html_e( 'eMAG Categories', 'skyservers-product-sync-for-emag' ); ?></h2>
            <?php
                $cat_counts = \SkyEmagSync\Products\CategoryImporter::get_counts();
                $cat_progress = \SkyEmagSync\Products\CategoryImporter::get_progress();
            ?>
            <table class="form-table" role="presentation">
                <tr>
                    <th scope="row"><?php esc_html_e( 'Local Cache', 'skyservers-product-sync-for-emag' ); ?></th>
                    <td>
                        <span id="skyemag-cat-total"><strong><?php echo esc_html( $cat_counts['total'] ); ?></strong></span>
                        <?php esc_html_e( 'categories imported', 'skyservers-product-sync-for-emag' ); ?> &nbsp;|&nbsp;
                        <span id="skyemag-cat-allowed"><strong><?php echo esc_html( $cat_counts['allowed'] ); ?></strong></span>
                        <?php esc_html_e( 'with access', 'skyservers-product-sync-for-emag' ); ?> &nbsp;|&nbsp;
                        <span id="skyemag-cat-detailed"><strong><?php echo esc_html( $cat_counts['detailed'] ); ?></strong></span>
                        <?php esc_html_e( 'with details', 'skyservers-product-sync-for-emag' ); ?>
                    </td>
                </tr>
                <tr>
                    <th scope="row"><?php esc_html_e( 'Import Categories', 'skyservers-product-sync-for-emag' ); ?></th>
                    <td>
                        <button type="button" id="skyemag-import-cats-btn" class="button button-primary">
                            <?php echo esc_html( $cat_counts['total'] > 0
                                ? __( 'Re-import Categories', 'skyservers-product-sync-for-emag' )
                                : __( 'Import Categories', 'skyservers-product-sync-for-emag' )
                            ); ?>
                        </button>
                        <span id="skyemag-cat-spinner" class="spinner" style="float:none;margin-top:0;visibility:hidden"></span>
                        <div id="skyemag-cat-progress" style="display:none; margin-top:10px; max-width:400px">
                            <div style="background:#e5e5e5; border-radius:3px; overflow:hidden; height:22px; position:relative">
                                <div id="skyemag-cat-bar" style="background:#2271b1; height:100%; width:0%; transition:width 0.3s; border-radius:3px;"></div>
                                <span id="skyemag-cat-bar-text" style="position:absolute; top:0; left:0; right:0; text-align:center; line-height:22px; font-size:12px; color:#1d2327; font-weight:500"></span>
                            </div>
                            <p id="skyemag-cat-status" class="description" style="margin-top:6px"></p>
                        </div>
                        <div id="skyemag-cat-result" style="display:none; margin-top:8px;"></div>
                        <div id="skyemag-cat-log" style="display:none; margin-top:10px; max-width:600px; max-height:200px; overflow-y:auto; background:#1d2327; color:#a7aaad; font-family:monospace; font-size:11px; padding:8px; border-radius:3px; white-space:pre-wrap;"></div>
                        <p class="description">
                            <?php esc_html_e( 'Downloads all eMAG categories with characteristics and family types. Required before publishing products.', 'skyservers-product-sync-for-emag' ); ?>
                        </p>
                    </td>
                </tr>
            </table>

            <hr />
            <?php endif; ?>

            <!-- ── eMAG Import & Manual Sync ─────────────────────────── -->
            <h2 class="title"><?php esc_html_e( 'eMAG Data Import', 'skyservers-product-sync-for-emag' ); ?></h2>
            <p>
                <?php if ( $bootstrap_done ) : ?>
                    <span class="skyemag-badge skyemag-badge--success"><?php esc_html_e( 'Import done', 'skyservers-product-sync-for-emag' ); ?></span>
                <?php else : ?>
                    <span class="skyemag-badge skyemag-badge--pending"><?php esc_html_e( 'Not imported yet', 'skyservers-product-sync-for-emag' ); ?></span>
                <?php endif; ?>
            </p>
            <p class="description">
                <?php esc_html_e( 'Reads all your existing offers from eMAG, matches them to WooCommerce products by SKU, and stores the eMAG offer ID, VAT rate, and price bounds per product. Run this once before your first sync, and again whenever you add new products to eMAG.', 'skyservers-product-sync-for-emag' ); ?>
            </p>

            <div style="display:inline-block;margin-right:12px;vertical-align:top;">
                <button type="button" id="skyemag-bs-import-btn" class="button button-primary">
                    <?php echo esc_html( $bootstrap_done
                        ? __( 'Re-import from eMAG', 'skyservers-product-sync-for-emag' )
                        : __( 'Import from eMAG', 'skyservers-product-sync-for-emag' )
                    ); ?>
                </button>
                <span id="skyemag-bs-spinner" class="spinner" style="float:none;margin-top:0;visibility:hidden"></span>

                <div id="skyemag-bs-progress" style="display:none; margin-top:10px; max-width:400px">
                    <div style="background:#e5e5e5; border-radius:3px; overflow:hidden; height:22px; position:relative">
                        <div id="skyemag-bs-bar" style="background:#2271b1; height:100%; width:0%; transition:width 0.3s; border-radius:3px;"></div>
                        <span id="skyemag-bs-bar-text" style="position:absolute; top:0; left:0; right:0; text-align:center; line-height:22px; font-size:12px; color:#1d2327; font-weight:500"></span>
                    </div>
                    <p id="skyemag-bs-status" class="description" style="margin-top:6px"></p>
                </div>

                <div id="skyemag-bs-result" style="display:none; margin-top:8px; max-width:600px;"></div>
                <div id="skyemag-bs-log" style="display:none; margin-top:10px; max-width:600px; max-height:200px; overflow-y:auto; background:#1d2327; color:#a7aaad; font-family:monospace; font-size:11px; padding:8px; border-radius:3px; white-space:pre-wrap;"></div>
            </div>

            <input type="hidden" id="skyemag-bs-import-nonce"
                value="<?php echo esc_attr( wp_create_nonce( self::BS_IMPORT_AJAX ) ); ?>" />
            <input type="hidden" id="skyemag-bs-progress-nonce"
                value="<?php echo esc_attr( wp_create_nonce( self::BS_PROGRESS_AJAX ) ); ?>" />

            <!-- Fallback POST form: hidden, but kept registered so users
                 without JS can still trigger the legacy blocking import. -->
            <noscript>
                <form method="post" action="" style="display:inline-block;margin-left:12px">
                    <?php wp_nonce_field( self::BOOTSTRAP_ACTION, self::BOOTSTRAP_NONCE ); ?>
                    <?php submit_button(
                        __( 'Import from eMAG (no JS)', 'skyservers-product-sync-for-emag' ),
                        'secondary',
                        'skyemag_bootstrap',
                        false
                    ); ?>
                </form>
            </noscript>

            <hr />

            <h2 class="title"><?php esc_html_e( 'Manual Sync', 'skyservers-product-sync-for-emag' ); ?></h2>
            <p class="description">
                <?php esc_html_e( 'Runs a full sync for all sync-enabled products. Runs asynchronously in the background — your browser is free to navigate while the work continues. Progress is shown live below.', 'skyservers-product-sync-for-emag' ); ?>
            </p>

            <button type="button" id="skyemag-sync-now-btn" class="button button-primary">
                <?php esc_html_e( 'Sync Now', 'skyservers-product-sync-for-emag' ); ?>
            </button>
            <span id="skyemag-sync-now-status" style="margin-left:10px; color:#646970;"></span>

            <input type="hidden" id="skyemag-sync-start-nonce"
                value="<?php echo esc_attr( wp_create_nonce( self::SYNC_START_AJAX ) ); ?>" />
            <input type="hidden" id="skyemag-sync-progress-nonce"
                value="<?php echo esc_attr( wp_create_nonce( self::SYNC_PROGRESS_AJAX ) ); ?>" />
            <input type="hidden" id="skyemag-sync-cancel-nonce"
                value="<?php echo esc_attr( wp_create_nonce( self::SYNC_CANCEL_AJAX ) ); ?>" />

            <!-- Progress UI — hidden until JS opens it on sync start or detects
                 an in-flight sync on page load. Structure mirrors the existing
                 Bootstrap import progress block. -->
            <div id="skyemag-sync-progress-wrap" style="display:none; margin-top:18px; max-width:760px;">
                <div style="background:#fff; border:1px solid #c3c4c7; border-radius:6px; padding:16px;">
                    <div style="display:flex; align-items:center; justify-content:space-between; gap:12px; margin-bottom:12px;">
                        <strong id="skyemag-sync-progress-title"><?php esc_html_e( 'Sync in progress', 'skyservers-product-sync-for-emag' ); ?></strong>
                        <div>
                            <span id="skyemag-sync-progress-eta" style="color:#646970; margin-right:12px;"></span>
                            <button type="button" id="skyemag-sync-cancel-btn" class="button button-secondary" style="color:#d63638;">
                                <?php esc_html_e( 'Cancel', 'skyservers-product-sync-for-emag' ); ?>
                            </button>
                        </div>
                    </div>
                    <div style="background:#e5e5e5; border-radius:3px; overflow:hidden; height:22px; position:relative;">
                        <div id="skyemag-sync-bar" style="background:#2271b1; height:100%; width:0%; transition:width 0.3s; border-radius:3px;"></div>
                        <span id="skyemag-sync-bar-text" style="position:absolute; top:0; left:0; right:0; text-align:center; line-height:22px; font-size:12px; color:#1d2327; font-weight:600;"></span>
                    </div>
                    <p id="skyemag-sync-counters" class="description" style="margin-top:8px;"></p>
                    <div id="skyemag-sync-log" style="margin-top:10px; max-height:160px; overflow-y:auto; background:#1d2327; color:#a7aaad; font-family:monospace; font-size:11px; padding:8px; border-radius:3px; white-space:pre-wrap;"></div>
                </div>
            </div>

            <!-- ── Buy Button Tracking — only rendered on builds that ship
                 the tracker class. The Free build strips BuyButtonTracker
                 via the Freemius @fs_premium_only directive, so the
                 "Track now" button is omitted because there is no
                 consuming code path to invoke. -->
            <?php if ( class_exists( \SkyEmagSync\Sync\BuyButtonTracker::class ) ) : ?>
            <h2 class="title"><?php esc_html_e( 'Buy Button Tracking', 'skyservers-product-sync-for-emag' ); ?></h2>
            <p class="description">
                <?php esc_html_e( 'Reads buy_button_rank, number_of_offers, and best_offer_price from eMAG for all mapped products. Runs automatically every 6 hours.', 'skyservers-product-sync-for-emag' ); ?>
            </p>
            <button type="button" id="skyemag-bb-track-btn" class="button button-secondary">
                <?php esc_html_e( 'Track Buy Button Now', 'skyservers-product-sync-for-emag' ); ?>
            </button>
            <span id="skyemag-bb-track-status" style="margin-left:8px;"></span>
            <?php endif; ?>

            <!-- Hidden nonces for AJAX -->
            <input type="hidden" id="skyemag-settings-nonce"
                value="<?php echo esc_attr( wp_create_nonce( 'skyemag_settings_nonce' ) ); ?>" />
            <input type="hidden" id="skyemag-ping-nonce"
                value="<?php echo esc_attr( wp_create_nonce( self::PING_AJAX ) ); ?>" />
            <?php if ( class_exists( \SkyEmagSync\Products\CategoryImporter::class ) ) : ?>
            <input type="hidden" id="skyemag-cat-import-nonce"
                value="<?php echo esc_attr( wp_create_nonce( self::CAT_IMPORT_AJAX ) ); ?>" />
            <input type="hidden" id="skyemag-cat-progress-nonce"
                value="<?php echo esc_attr( wp_create_nonce( self::CAT_PROGRESS_AJAX ) ); ?>" />
            <input type="hidden" id="skyemag-cat-detail-nonce"
                value="<?php echo esc_attr( wp_create_nonce( self::CAT_DETAIL_AJAX ) ); ?>" />
            <?php endif; ?>
        </div>
        <?php
    }

    // ── Notices ───────────────────────────────────────────────────────────

    private static function collect_notices(): array {
        $notices = self::consume_notice_queue();
        // phpcs:disable WordPress.Security.NonceVerification.Recommended -- read-only flash-notice flags carried in the redirect URL, no state mutation.
        $type    = isset( $_GET['skyemag_notice'] ) ? sanitize_key( wp_unslash( $_GET['skyemag_notice'] ) ) : '';

        switch ( $type ) {
            case 'saved':
                $notices[] = [ 'type' => 'success', 'message' => __( 'Settings saved.', 'skyservers-product-sync-for-emag' ) ];
                break;

            case 'error':
                // Detail messages already came in via the transient queue
                // (consumed above). Nothing to add here — the queue carries
                // the full per-field error list.
                break;

            case 'synced':
                $notices[] = [ 'type' => 'success', 'message' => sprintf(
                    /* translators: %1$d: number, %2$d: number, %3$d: number */
                    __( 'Sync complete: %1$d synced, %2$d skipped, %3$d failed.', 'skyservers-product-sync-for-emag' ),
                    isset( $_GET['skyemag_synced'] )  ? absint( wp_unslash( $_GET['skyemag_synced'] ) )  : 0,
                    isset( $_GET['skyemag_skipped'] ) ? absint( wp_unslash( $_GET['skyemag_skipped'] ) ) : 0,
                    isset( $_GET['skyemag_failed'] )  ? absint( wp_unslash( $_GET['skyemag_failed'] ) )  : 0
                ) ];
                break;

            case 'sync_error':
                $notices[] = [ 'type' => 'error', 'message' => __( 'Sync could not run. Check logs for details.', 'skyservers-product-sync-for-emag' ) ];
                break;

            case 'bootstrap_ok':
                $notices[] = [ 'type' => 'success', 'message' => sprintf(
                    /* translators: %1$d: number, %2$d: number */
                    __( 'Import complete: %1$d products mapped, %2$d eMAG offers had no matching WC SKU.', 'skyservers-product-sync-for-emag' ),
                    isset( $_GET['skyemag_bs_matched'] )   ? absint( wp_unslash( $_GET['skyemag_bs_matched'] ) )   : 0,
                    isset( $_GET['skyemag_bs_unmatched'] ) ? absint( wp_unslash( $_GET['skyemag_bs_unmatched'] ) ) : 0
                ) ];
                break;

            case 'bootstrap_error':
                // Detail messages came in via the transient queue (consumed
                // above) — no decoding needed here.
                break;
        }
        // phpcs:enable WordPress.Security.NonceVerification.Recommended

        return $notices;
    }

    /**
     * Queue an admin notice for the current user, to be rendered on the
     * next admin page load. Replaces the previous base64-in-querystring
     * mechanism — keeps the URL clean (passes Plugin Check guidelines on
     * obfuscated payloads) and survives multiple errors per save.
     *
     * Stored as a transient keyed by user id. 60-second TTL is plenty for
     * a wp_safe_redirect → next admin page render hop, while still being
     * short enough to garbage-collect itself if the redirect fails.
     */
    public static function queue_notice( string $type, string $message ): void {
        $user_id = get_current_user_id();
        if ( ! $user_id || '' === $message ) {
            return;
        }
        $key   = self::notice_queue_key( $user_id );
        $queue = get_transient( $key );
        if ( ! is_array( $queue ) ) {
            $queue = [];
        }
        $queue[] = [
            'type'    => 'error' === $type ? 'error' : 'success',
            'message' => sanitize_text_field( $message ),
        ];
        set_transient( $key, $queue, MINUTE_IN_SECONDS );
    }

    /**
     * Pop and return the queued notices for the current user. Idempotent
     * — repeated calls within the same request return the same set
     * (drained on first call) rather than reading stale data.
     */
    private static function consume_notice_queue(): array {
        $user_id = get_current_user_id();
        if ( ! $user_id ) {
            return [];
        }
        $key   = self::notice_queue_key( $user_id );
        $queue = get_transient( $key );
        if ( ! is_array( $queue ) || empty( $queue ) ) {
            return [];
        }
        delete_transient( $key );
        return $queue;
    }

    private static function notice_queue_key( int $user_id ): string {
        return 'skyemag_notices_' . $user_id;
    }

    // ── AJAX: Buy Button tracking ─────────────────────────────────────────

    public function ajax_bb_track(): void {
        check_ajax_referer( 'skyemag_settings_nonce', 'nonce' );
        if ( ! current_user_can( Menu::CAPABILITY ) ) {
            wp_send_json_error( [ 'message' => 'Unauthorized.' ], 403 );
        }
        if ( ! class_exists( \SkyEmagSync\Sync\BuyButtonTracker::class ) ) {
            wp_send_json_error( [ 'message' => 'Buy Button tracker is not available on this install.' ], 404 );
        }

        // Run in the background. With thousands of mapped offers the tracker
        // needs dozens of paginated eMAG calls and can exceed the web server
        // proxy timeout — the browser then reports "Request failed" even
        // though PHP keeps running and finishes the job. Scheduling a
        // single cron event (unique arg so it never collides with the
        // recurring 6h event) returns immediately instead.
        wp_schedule_single_event( time(), \SkyEmagSync\Sync\BuyButtonTracker::CRON_HOOK, [ 'manual' ] );
        if ( function_exists( 'spawn_cron' ) ) {
            spawn_cron();
        }

        wp_send_json_success( [
            'message' => __( 'Buy Button tracking started in the background. Check Activity Logs in a few minutes for the result.', 'skyservers-product-sync-for-emag' ),
        ] );
    }

    /**
     * AJAX: scan products for meta keys that look like Brand or EAN sources.
     */
    public function ajax_detect_sources(): void {
        check_ajax_referer( 'skyemag_settings_nonce', 'nonce' );
        if ( ! current_user_can( Menu::CAPABILITY ) ) {
            wp_send_json_error( [ 'message' => 'Unauthorized.' ], 403 );
        }

        global $wpdb;

        // Known EAN-like keys to check.
        $ean_candidates = [
            '_global_unique_id', '_ean', '_barcode', '_gtin',
            'hwp_product_gtin', '_alg_ean', 'hwp_var_gtin',
            '_wpm_gtin_code', '_wepos_barcode',
        ];

        // Known Brand-like keys to check.
        $brand_candidates = [
            'pa_brand', 'pa_marca', '_brand', 'brand',
            '_manufacturer', 'pa_manufacturer', '_wpmr_brand',
        ];

        $ean_results   = [];
        $brand_results = [];

        // Check meta keys: count products that have non-empty values.
        foreach ( $ean_candidates as $key ) {
            $count = (int) $wpdb->get_var( $wpdb->prepare(
                "SELECT COUNT(DISTINCT post_id) FROM {$wpdb->postmeta}
                 WHERE meta_key = %s AND meta_value != ''",
                $key
            ) );
            if ( $count > 0 ) {
                $sample = $wpdb->get_var( $wpdb->prepare(
                    "SELECT meta_value FROM {$wpdb->postmeta}
                     WHERE meta_key = %s AND meta_value != '' LIMIT 1",
                    $key
                ) );
                $ean_results[] = [
                    'key'    => $key,
                    'count'  => $count,
                    'sample' => mb_substr( (string) $sample, 0, 30 ),
                ];
            }
        }

        // Check brand: taxonomy attributes + meta keys.
        foreach ( $brand_candidates as $key ) {
            if ( 0 === strpos( $key, 'pa_' ) ) {
                // Taxonomy attribute — count terms assigned to products.
                $taxonomy = $key;
                $count = (int) $wpdb->get_var( $wpdb->prepare(
                    "SELECT COUNT(DISTINCT tr.object_id)
                     FROM {$wpdb->term_relationships} tr
                     INNER JOIN {$wpdb->term_taxonomy} tt ON tt.term_taxonomy_id = tr.term_taxonomy_id
                     WHERE tt.taxonomy = %s",
                    $taxonomy
                ) );
                if ( $count > 0 ) {
                    $sample = $wpdb->get_var( $wpdb->prepare(
                        "SELECT t.name FROM {$wpdb->terms} t
                         INNER JOIN {$wpdb->term_taxonomy} tt ON tt.term_id = t.term_id
                         WHERE tt.taxonomy = %s LIMIT 1",
                        $taxonomy
                    ) );
                    $brand_results[] = [
                        'key'    => $key,
                        'count'  => $count,
                        'sample' => mb_substr( (string) $sample, 0, 30 ),
                        'type'   => 'attribute',
                    ];
                }
            } else {
                $count = (int) $wpdb->get_var( $wpdb->prepare(
                    "SELECT COUNT(DISTINCT post_id) FROM {$wpdb->postmeta}
                     WHERE meta_key = %s AND meta_value != ''",
                    $key
                ) );
                if ( $count > 0 ) {
                    $sample = $wpdb->get_var( $wpdb->prepare(
                        "SELECT meta_value FROM {$wpdb->postmeta}
                         WHERE meta_key = %s AND meta_value != '' LIMIT 1",
                        $key
                    ) );
                    $brand_results[] = [
                        'key'    => $key,
                        'count'  => $count,
                        'sample' => mb_substr( (string) $sample, 0, 30 ),
                        'type'   => 'meta',
                    ];
                }
            }
        }

        wp_send_json_success( [
            'ean'   => $ean_results,
            'brand' => $brand_results,
        ] );
    }

    // ── Plan status / helpers ────────────────────────────────────────────

    /**
     * Premium Features showcase — only visible to non-paying installs.
     * Replaces the previous Free-plan cap banner with a feature-based
     * upsell that complies with WP.org Plugin Directory guidelines:
     * the panel describes Premium-exclusive features (which physically
     * do not ship in the Free build) instead of locking baseline
     * functionality behind a payment.
     */
    private static function maybe_render_plan_status(): void {
        if ( Plugin::is_premium() ) {
            return;
        }
        $upgrade = self::upgrade_url();
        ?>
        <div class="skyemag-premium-panel" style="background:#fff;border:1px solid #e2e4e7;border-radius:8px;padding:24px;margin:18px 0;">
            <div style="display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:12px;margin-bottom:16px;">
                <div>
                    <h2 style="margin:0 0 4px 0;font-size:18px;">
                        <?php esc_html_e( 'Get more from your eMAG integration', 'skyservers-product-sync-for-emag' ); ?>
                    </h2>
                    <p style="margin:0;color:#646970;">
                        <?php esc_html_e( 'Premium adds the features that turn your dashboard into a complete eMAG operations centre.', 'skyservers-product-sync-for-emag' ); ?>
                    </p>
                </div>
                <a href="<?php echo esc_url( $upgrade ); ?>" class="button button-primary button-hero" style="white-space:nowrap;">
                    <?php esc_html_e( 'Upgrade to Premium', 'skyservers-product-sync-for-emag' ); ?>
                </a>
            </div>
            <div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:12px;">
                <?php
                $cards = [
                    [ '📦', __( 'Publish products to eMAG', 'skyservers-product-sync-for-emag' ), __( 'Push WooCommerce products onto the marketplace with category, characteristic, and family mapping.', 'skyservers-product-sync-for-emag' ) ],
                    [ '📥', __( 'Order import (webhook-first)', 'skyservers-product-sync-for-emag' ), __( 'Incoming eMAG orders land in WooCommerce automatically. Manual import-by-id available for backfill.', 'skyservers-product-sync-for-emag' ) ],
                    [ '🚚', __( 'AWB shipping labels', 'skyservers-product-sync-for-emag' ), __( 'Issue and print AWBs (A4 / A5 / A6 / ZPL) directly from the WooCommerce order screen.', 'skyservers-product-sync-for-emag' ) ],
                    [ '🏆', __( 'Buy Button rank tracking', 'skyservers-product-sync-for-emag' ), __( 'Monitor positions 1-4 across your catalog with email alerts on rank drops and competitor undercuts.', 'skyservers-product-sync-for-emag' ) ],
                    [ '✉️', __( 'Email notifications', 'skyservers-product-sync-for-emag' ), __( 'Per-event alerts for sync errors, blocked products, new orders, cancellations, AWB issuance.', 'skyservers-product-sync-for-emag' ) ],
                ];
                foreach ( $cards as $card ) {
                    printf(
                        '<div style="background:#f6f7f7;border-radius:6px;padding:14px;"><div style="font-size:20px;margin-bottom:6px;">%s</div><div style="font-weight:600;margin-bottom:4px;">%s</div><div style="color:#646970;font-size:13px;line-height:1.4;">%s</div></div>',
                        esc_html( $card[0] ),
                        esc_html( $card[1] ),
                        esc_html( $card[2] )
                    );
                }
                ?>
            </div>
        </div>
        <?php
    }

    /**
     * Upgrade URL for the Freemius checkout flow.
     */
    private static function upgrade_url(): string {
        return Menu::upgrade_url();
    }

    // ── 3.8.0 Async sync AJAX endpoints ──────────────────────────────────

    /**
     * Start a full sync. Returns sync_id + total counts; the actual work
     * runs in background via Action Scheduler. Polled by JS for progress.
     */
    public function ajax_sync_start(): void {
        check_ajax_referer( self::SYNC_START_AJAX, 'nonce' );
        if ( ! current_user_can( Menu::CAPABILITY ) ) {
            wp_send_json_error( [ 'message' => 'Unauthorized.' ], 403 );
        }

        $result = \SkyEmagSync\Sync\Dispatcher::enqueue_full( 'manual' );

        if ( ! $result['success'] && ! empty( $result['already_running'] ) ) {
            // Surface existing sync's progress instead of a hard error so the
            // JS can resume polling without restarting.
            wp_send_json_success( [
                'sync_id'         => $result['sync_id'] ?? '',
                'already_running' => true,
            ] );
        }

        if ( ! $result['success'] ) {
            wp_send_json_error( [
                'message' => $result['errors'][0] ?? 'Sync could not be started.',
            ] );
        }

        wp_send_json_success( [
            'sync_id'        => $result['sync_id'],
            'total_products' => (int) $result['total_products'],
            'total_batches'  => (int) $result['total_batches'],
        ] );
    }

    /**
     * Return the current ProgressStore state + computed ETA. The JS poller
     * calls this every 1.5 s while a sync is in flight.
     */
    public function ajax_sync_progress(): void {
        check_ajax_referer( self::SYNC_PROGRESS_AJAX, 'nonce' );
        if ( ! current_user_can( Menu::CAPABILITY ) ) {
            wp_send_json_error( [ 'message' => 'Unauthorized.' ], 403 );
        }

        $state = \SkyEmagSync\Sync\ProgressStore::get();
        if ( null === $state ) {
            wp_send_json_success( [ 'state' => 'idle' ] );
        }

        $state['eta_seconds'] = \SkyEmagSync\Sync\ProgressStore::eta_seconds();
        wp_send_json_success( $state );
    }

    /**
     * Request cancellation of the in-flight sync. BatchProcessor checks the
     * cancel flag before each chunk and exits gracefully.
     */
    public function ajax_sync_cancel(): void {
        check_ajax_referer( self::SYNC_CANCEL_AJAX, 'nonce' );
        if ( ! current_user_can( Menu::CAPABILITY ) ) {
            wp_send_json_error( [ 'message' => 'Unauthorized.' ], 403 );
        }

        $sync_id = isset( $_POST['sync_id'] )
            ? sanitize_text_field( wp_unslash( $_POST['sync_id'] ) )
            : '';

        if ( '' === $sync_id ) {
            wp_send_json_error( [ 'message' => 'Missing sync_id.' ] );
        }

        \SkyEmagSync\Sync\ProgressStore::cancel( $sync_id );
        \SkyEmagSync\Sync\Runner::release_lock();

        wp_send_json_success( [ 'cancelled' => true, 'sync_id' => $sync_id ] );
    }
}
