<?php

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

$fmt_int = static function ($v) { return number_format_i18n((float) $v, 0); };
$badge   = static function ($txt, $bg, $fg, $title = '') {
    return '<span' . ($title ? ' title="' . esc_attr($title) . '" style="cursor:help;"' : '') . '><span style="display:inline-block;padding:1px 7px;border-radius:10px;font-size:11px;font-weight:600;background:' . $bg . ';color:' . $fg . ';">' . esc_html($txt) . '</span></span>';
};

$help = static function ($txt) {
    return ' <span class="aieo-pr-help" tabindex="0" role="img" aria-label="' . esc_attr($txt) . '">?<span class="aieo-pr-tip">' . esc_html($txt) . '</span></span>';
};
?>
<style>
.aieo-pr-kpis{display:flex;flex-wrap:wrap;gap:12px;}
.aieo-pr-kpi{flex:1 1 160px;background:#f8fafc;border:1px solid #e6e9ee;border-radius:8px;padding:12px 14px;}
.aieo-pr-kpi .n{font-size:22px;font-weight:700;color:#111827;line-height:1.1;}
.aieo-pr-kpi .l{font-size:11px;color:#6b7280;margin-top:3px;}
.aieo-pr-kpi .l .sub{display:inline-block;margin-top:4px;font-size:13px;font-weight:600;color:#6b7280;}
.aieo-pr-table{width:100%;border-collapse:collapse;font-size:13px;margin-top:8px;}
.aieo-pr-table th,.aieo-pr-table td{padding:7px 8px;border-bottom:1px solid #eef0f2;text-align:left;vertical-align:top;}
.aieo-pr-table th{font-size:11px;color:#6b7280;text-transform:uppercase;letter-spacing:.03em;}
.aieo-pr-table img{max-height:42px;max-width:42px;object-fit:contain;border-radius:4px;}
.aieo-pr-table tr.is-applied{background:#f0fdf4;}
.aieo-pr-table th.sortable{cursor:pointer;user-select:none;}
.aieo-pr-table th.sortable:hover{color:#111827;}
.aieo-pr-table th .arr{font-size:9px;margin-left:3px;color:#9ca3af;}
.aieo-pr-chip{display:inline-block;margin:1px 3px 1px 0;padding:1px 7px;border-radius:9px;font-size:11px;background:#fef3c7;color:#92400e;}
.aieo-pr-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(210px,1fr));gap:14px;}
.aieo-pr-grid label{display:block;font-size:12px;color:#374151;margin:0 0 3px;font-weight:600;}
.aieo-pr-grid input[type=number]{width:100px;}
#aieo-pr-status{font-size:12px;margin-left:10px;}
.aieo-pr-btn-sm{font-size:11px!important;height:auto!important;min-height:0!important;padding:2px 8px!important;line-height:1.7!important;}
.aieo-pr-toolbar{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;}
.aieo-pr-help{display:inline-flex;align-items:center;justify-content:center;width:15px;height:15px;border-radius:50%;background:#e5e7eb;color:#374151;font-size:10px;font-weight:700;cursor:help;position:relative;vertical-align:middle;}
.aieo-pr-help:hover,.aieo-pr-help:focus{background:#6366f1;color:#fff;outline:none;}
.aieo-pr-help .aieo-pr-tip{display:none;position:absolute;left:50%;bottom:150%;transform:translateX(-50%);width:250px;background:#111827;color:#f9fafb;font-size:12px;font-weight:400;line-height:1.5;padding:9px 11px;border-radius:7px;box-shadow:0 8px 28px rgba(0,0,0,.28);z-index:99999;white-space:normal;text-align:left;}
.aieo-pr-help:hover .aieo-pr-tip,.aieo-pr-help:focus .aieo-pr-tip{display:block;}
.aieo-pr-help .aieo-pr-tip::after{content:"";position:absolute;top:100%;left:50%;transform:translateX(-50%);border:6px solid transparent;border-top-color:#111827;}
</style>

<div class="aieo-dmm-section">

    <h2><?php esc_html_e('Stock Recovery — physical-demand vs eshop catalogue', 'ai-eshop-optimizer'); ?></h2>
    <p class="description">
        <?php esc_html_e('Products the ERP marks out-of-stock but the physical stores still sell — put them back in stock with your confidence thresholds. (SKUs not yet live in the eshop are in the “Missing Hot Sellers” tab.)', 'ai-eshop-optimizer'); ?>
        <?php if (!empty($data_asof)) : ?>
            <br><?php esc_html_e('Physical-store data valid through', 'ai-eshop-optimizer'); ?> <strong><?php echo esc_html($data_asof); ?></strong>.
        <?php endif; ?>
    </p>
    <p style="margin:0;">
        <button type="button" class="button button-primary js-pr-run" id="aieo-pr-run"><?php esc_html_e('Run detection now', 'ai-eshop-optimizer'); ?></button>
        <span id="aieo-pr-status"></span>
    </p>

    <?php if (!$have_tables) : ?>
        <div class="notice notice-warning"><p><?php esc_html_e('Tables not yet created. Reactivate the plugin, then click “Run detection now”.', 'ai-eshop-optimizer'); ?></p></div>
    <?php endif; ?>

    <?php ?>
    <?php $cstot = isset($cand_totals) && is_array($cand_totals) ? $cand_totals : array('count' => 0, 'count_recent' => 0, 'units' => 0, 'units_recent' => 0, 'turnover' => 0, 'turnover_recent' => 0, 'lost' => 0, 'lost_pess' => 0, 'lost_opt' => 0); ?>
    <?php $rec = isset($settings['recency_days']) ? (int) $settings['recency_days'] : 30; ?>
    <?php if ((int) $cstot['count'] > 0) : ?>
    <div class="aieo-dmm-card">
        <h3><?php esc_html_e('Out-of-stock products still selling in the stores', 'ai-eshop-optimizer'); ?></h3>
        <div class="aieo-pr-kpis" style="margin-top:10px;">
            <div class="aieo-pr-kpi" style="background:#fef2f2;border-color:#fecaca;">
                <div class="n"><?php echo esc_html(number_format_i18n((float) $cstot['turnover_recent'], 2)); ?> €</div>
                <div class="l">
                    <?php printf(esc_html__('In-store sales in the last %d days', 'ai-eshop-optimizer'), $rec); ?>
                    <br><span class="sub"><?php echo esc_html(number_format_i18n((float) $cstot['turnover'], 2)); ?> € <?php esc_html_e('total since they went out of stock', 'ai-eshop-optimizer'); ?></span>
                </div>
            </div>
            <div class="aieo-pr-kpi">
                <div class="n"><?php echo esc_html(number_format_i18n((int) $cstot['count_recent'])); ?></div>
                <div class="l">
                    <?php printf(esc_html__('Products sold in stores in the last %d days', 'ai-eshop-optimizer'), $rec); ?>
                    <br><span class="sub"><?php echo esc_html(number_format_i18n((int) $cstot['count'])); ?> <?php esc_html_e('total out of stock in the eshop, still selling', 'ai-eshop-optimizer'); ?></span>
                </div>
            </div>
            <div class="aieo-pr-kpi">
                <div class="n"><?php echo esc_html(number_format_i18n((float) $cstot['units_recent'], 0)); ?></div>
                <div class="l">
                    <?php printf(esc_html__('Units sold in stores in the last %d days', 'ai-eshop-optimizer'), $rec); ?>
                    <br><span class="sub"><?php echo esc_html(number_format_i18n((float) $cstot['units'], 0)); ?> <?php esc_html_e('total since OOS', 'ai-eshop-optimizer'); ?></span>
                </div>
            </div>
            <?php if ((float) $cstot['lost_recent'] > 0) : $ch = isset($settings['channel_pct']) ? (int) $settings['channel_pct'] : 17; ?>
            <div class="aieo-pr-kpi" style="background:#eef2ff;border-color:#c7d2fe;flex:1 1 260px;" title="<?php printf(esc_attr__('Estimate of the online sales we are likely missing = the in-store sales of these out-of-stock products (last %1$d days) x the eshop\'s share of total demand (%2$d%%, e.g. ~500k online vs ~3M in shops). Optimistic reflects the eshop\'s wider national reach (~6,000 visitors/day) beyond the 4 stores\' catchment. An estimate, not a guarantee.', 'ai-eshop-optimizer'), $rec, $ch); ?>">
                <div class="n">≈ <?php echo esc_html(number_format_i18n((float) $cstot['lost_recent'], 2)); ?> €</div>
                <div class="l">
                    <?php printf(esc_html__('Est. recoverable online sales in the last %d days — average', 'ai-eshop-optimizer'), $rec); ?>
                    <br><?php esc_html_e('pessimistic', 'ai-eshop-optimizer'); ?> <strong><?php echo esc_html(number_format_i18n((float) $cstot['lost_pess_recent'], 2)); ?> €</strong>
                    · <?php esc_html_e('optimistic', 'ai-eshop-optimizer'); ?> <strong><?php echo esc_html(number_format_i18n((float) $cstot['lost_opt_recent'], 2)); ?> €</strong>
                    <br><span class="sub">≈ <?php echo esc_html(number_format_i18n((float) $cstot['lost'], 2)); ?> € <?php printf(esc_html__('recoverable since OOS (at %d%% share)', 'ai-eshop-optimizer'), $ch); ?></span>
                </div>
            </div>
            <?php endif; ?>
        </div>
        <p class="description" style="margin:10px 0 0;"><?php printf(esc_html__('Net physical-store revenue (ex-VAT) for products out of stock in the eshop but still selling in the stores. The large figures are the last %d days — the recoverable recent demand that drives the suggested quantities; the grey figures are the all-time totals since each product went out of stock. Restock the rows below to recover it.', 'ai-eshop-optimizer'), $rec); ?></p>
    </div>
    <?php endif; ?>

    <?php ?>
    <?php if (!empty($kpis) && (int) ($kpis['total'] ?? 0) > 0) : ?>
    <div class="aieo-dmm-card">
        <h3><?php esc_html_e('Outcomes — what restock earned', 'ai-eshop-optimizer'); ?></h3>
        <div class="aieo-pr-kpis" style="margin-top:10px;">
            <div class="aieo-pr-kpi"><div class="n"><?php echo esc_html($fmt_int($kpis['total'] ?? 0)); ?></div><div class="l"><?php esc_html_e('Restocks applied', 'ai-eshop-optimizer'); ?> (<?php echo esc_html($fmt_int($kpis['autos'] ?? 0)); ?> <?php esc_html_e('auto', 'ai-eshop-optimizer'); ?> / <?php echo esc_html($fmt_int($kpis['manuals'] ?? 0)); ?> <?php esc_html_e('manual', 'ai-eshop-optimizer'); ?>)</div></div>
            <div class="aieo-pr-kpi"><div class="n"><?php echo $kpis['precision'] === null ? '—' : esc_html($kpis['precision']) . '%'; ?></div><div class="l"><?php esc_html_e('Precision (success ÷ decided)', 'ai-eshop-optimizer'); ?></div></div>
            <div class="aieo-pr-kpi"><div class="n"><?php echo esc_html($fmt_int($kpis['units'] ?? 0)); ?></div><div class="l"><?php esc_html_e('Units recovered (eshop)', 'ai-eshop-optimizer'); ?></div></div>
            <div class="aieo-pr-kpi" style="background:#fef9c3;border-color:#fde68a;flex:1 1 230px;" title="<?php printf(esc_attr__('The online sales we are now aiming to recover from everything restocked = the in-store turnover those products were making while out of stock online, snapshotted at restock, × the eshop channel share (%d%%). It persists after products leave the queue and grows with each restock; the "Turnover recovered" figure to the left is how much of it we have actually captured online so far.', 'ai-eshop-optimizer'), (int) ($kpis['channel_pct'] ?? 17)); ?>">
                <div class="n">≈ <?php echo esc_html(number_format_i18n((float) ($kpis['target_recoverable'] ?? 0), 2)); ?> €</div>
                <div class="l"><strong><?php esc_html_e('Recovery TARGET', 'ai-eshop-optimizer'); ?></strong> — <?php printf(esc_html__('recoverable online from restocked products (at %d%% share)', 'ai-eshop-optimizer'), (int) ($kpis['channel_pct'] ?? 17)); ?></div>
            </div>
            <div class="aieo-pr-kpi"><div class="n"><?php echo esc_html(number_format_i18n((float) ($kpis['turnover'] ?? 0), 2)); ?> €</div><div class="l"><?php printf(esc_html__('Turnover recovered (finalised) · %s units', 'ai-eshop-optimizer'), esc_html($fmt_int($kpis['units'] ?? 0))); ?></div></div>
            <div class="aieo-pr-kpi" style="background:#f5f3ff;border-color:#ddd6fe;flex:1 1 230px;" title="<?php esc_attr_e('The combined value of the whole ONLINE orders placed since restock that included a restocked product (each order counted once). It shows the basket revenue these products were part of — they did not just sell their own units, they were part of larger carts. Updates as outcomes are evaluated; always between the turnover recovered and your total online orders.', 'ai-eshop-optimizer'); ?>"><div class="n"><?php echo esc_html(number_format_i18n((float) ($kpis['basket_turnover_total'] ?? 0), 2)); ?> €</div><div class="l"><strong><?php esc_html_e('Basket turnover from restocks', 'ai-eshop-optimizer'); ?></strong> — <?php esc_html_e('total value of the online orders (since restock) that included these products', 'ai-eshop-optimizer'); ?></div></div>
            <?php if ((float) ($kpis['turnover_draft'] ?? 0) > 0 || (float) ($kpis['units_draft'] ?? 0) > 0) : ?>
            <div class="aieo-pr-kpi" style="background:#fffbeb;border-color:#fde68a;flex:1 1 220px;" title="<?php esc_attr_e('The same restocked products currently sitting in UNFINISHED checkouts (carts in the checkout step, not yet placed as orders) since restock. This is pent-up demand in the pipeline — it is NOT counted in the recovered figure (which is finalised orders only). Some of it will convert.', 'ai-eshop-optimizer'); ?>"><div class="n"><?php echo esc_html(number_format_i18n((float) ($kpis['turnover_draft'] ?? 0), 2)); ?> €</div><div class="l"><strong><?php esc_html_e('In unfinished checkouts (drafts)', 'ai-eshop-optimizer'); ?></strong> — <?php printf(esc_html__('not yet finalised (%s units)', 'ai-eshop-optimizer'), esc_html($fmt_int($kpis['units_draft'] ?? 0))); ?></div></div>
            <div class="aieo-pr-kpi" style="background:#fff7ed;border-color:#fed7aa;flex:1 1 220px;" title="<?php esc_attr_e('The combined value of the whole UNFINISHED-checkout orders (drafts) that included a restocked product since restock (each order once) — the draft / pipeline equivalent of the basket turnover above.', 'ai-eshop-optimizer'); ?>"><div class="n"><?php echo esc_html(number_format_i18n((float) ($kpis['basket_draft_total'] ?? 0), 2)); ?> €</div><div class="l"><strong><?php esc_html_e('Basket turnover in drafts', 'ai-eshop-optimizer'); ?></strong> — <?php esc_html_e('total value of the unfinished-checkout orders that included these products', 'ai-eshop-optimizer'); ?></div></div>
            <?php endif; ?>
            <div class="aieo-pr-kpi" title="<?php esc_attr_e('re-OOS = restocked, then went out of stock again with no online sale. cancelled = a recovering online order was cancelled/refunded. OOS-cancel = an order was cancelled with reason “Out of stock” naming this restocked product (after we restocked it, within the outcome window) — i.e. the restock did not hold.', 'ai-eshop-optimizer'); ?>"><div class="n"><?php echo esc_html($fmt_int((int) ($kpis['failures'] ?? 0) + (int) ($kpis['oos_cancel'] ?? 0))); ?></div><div class="l"><?php esc_html_e('Failures', 'ai-eshop-optimizer'); ?> (<?php echo esc_html($fmt_int($kpis['reoos'] ?? 0)); ?> <?php esc_html_e('re-OOS', 'ai-eshop-optimizer'); ?>, <?php echo esc_html($fmt_int($kpis['cancelled'] ?? 0)); ?> <?php esc_html_e('cancelled', 'ai-eshop-optimizer'); ?>, <?php echo esc_html($fmt_int($kpis['oos_cancel'] ?? 0)); ?> <?php esc_html_e('OOS-cancel', 'ai-eshop-optimizer'); ?>)</div></div>
        </div>
        <p class="description" style="margin:10px 0 0;"><?php esc_html_e('The Recovery TARGET is the recoverable online turnover from every product we have put back in stock — captured at the moment of restock so it is not lost when the product leaves the queue, and it grows with each restock (and re-scales if you change the channel share). “Turnover recovered” tracks how much of that target the eshop has actually earned online. Auto-apply runs whenever detection runs (WP-Cron is disabled here — schedule detection via a real cron or use “Run detection now”).', 'ai-eshop-optimizer'); ?></p>
    </div>
    <?php endif; ?>

    <?php ?>
    <div class="aieo-dmm-card">
        <h3><?php esc_html_e('Confidence thresholds & automation', 'ai-eshop-optimizer'); ?></h3>
        <div class="aieo-pr-grid" style="margin-top:12px;">
            <div><label><?php esc_html_e('Min physical units sold (after OOS)', 'ai-eshop-optimizer'); echo $help(__('How many times the product must have sold in the shops (after it ran out of stock online) before it appears in this list. A higher number shows only products that clearly keep selling.', 'ai-eshop-optimizer')); ?></label><input type="number" id="pr-min_units" min="1" max="999" value="<?php echo esc_attr($settings['min_units']); ?>"></div>
            <div><label><?php esc_html_e('Min distinct sale-days', 'ai-eshop-optimizer'); echo $help(__('Those shop sales must happen on at least this many different days — proof of steady demand, not one single big purchase on one day.', 'ai-eshop-optimizer')); ?></label><input type="number" id="pr-min_days" min="1" max="60" value="<?php echo esc_attr($settings['min_days']); ?>"></div>
            <div><label><?php esc_html_e('Recency window (days)', 'ai-eshop-optimizer'); echo $help(__('How far back we look for recent shop sales. The product must have sold within this many days to appear here, and these recent sales decide the suggested quantity.', 'ai-eshop-optimizer')); ?></label><input type="number" id="pr-recency_days" min="3" max="365" value="<?php echo esc_attr($settings['recency_days']); ?>"></div>
            <div><label><?php esc_html_e('Min days OOS', 'ai-eshop-optimizer'); echo $help(__('The product must have been out of stock online for at least this many days before we flag it — so we ignore items that were only briefly unavailable. Set to 0 to ALSO include items whose out-of-stock start date can’t be determined (e.g. store-only variations never sold online), trusting the physical-sales signal alone. (OOS = out of stock.)', 'ai-eshop-optimizer')); ?></label><input type="number" id="pr-min_days_oos" min="0" max="365" value="<?php echo esc_attr($settings['min_days_oos']); ?>"></div>
            <div><label><?php esc_html_e('Restock qty cap', 'ai-eshop-optimizer'); echo $help(__('The largest quantity we will ever suggest putting back in stock. No suggestion goes above this number — that is why many rows show the same value.', 'ai-eshop-optimizer')); ?></label><input type="number" id="pr-qty_cap" min="1" max="999" value="<?php echo esc_attr($settings['qty_cap']); ?>"></div>
            <div><label><?php esc_html_e('Days of cover (qty target)', 'ai-eshop-optimizer'); echo $help(__('How many days of recent sales the suggested quantity should cover. A bigger number means a larger suggested restock (still limited by the cap above).', 'ai-eshop-optimizer')); ?></label><input type="number" id="pr-cover_days" min="1" max="120" value="<?php echo esc_attr($settings['cover_days']); ?>"></div>
            <div><label><?php esc_html_e('Cooldown between restocks (days)', 'ai-eshop-optimizer'); echo $help(__('After a product is restocked, it will not be auto-restocked again for this many days — this stops the same item being topped up over and over.', 'ai-eshop-optimizer')); ?></label><input type="number" id="pr-cooldown_days" min="1" max="180" value="<?php echo esc_attr($settings['cooldown_days']); ?>"></div>
            <div><label><?php esc_html_e('Outcome window (days)', 'ai-eshop-optimizer'); echo $help(__('After a restock, how long we wait before deciding it worked (it sold online) or failed (went out of stock again with no sale). This feeds the success-rate shown above.', 'ai-eshop-optimizer')); ?></label><input type="number" id="pr-outcome_window" min="3" max="120" value="<?php echo esc_attr($settings['outcome_window']); ?>"></div>
            <div><label><?php esc_html_e('Catalog-gap min units', 'ai-eshop-optimizer'); echo $help(__('For the “Missing Hot Sellers” list (products not on the eshop at all): how many shop sales a product needs before it is listed as worth adding online.', 'ai-eshop-optimizer')); ?></label><input type="number" id="pr-gap_min_units" min="1" max="999" value="<?php echo esc_attr($settings['gap_min_units']); ?>"></div>
            <div><label><?php esc_html_e('Catalog-gap recency (days)', 'ai-eshop-optimizer'); echo $help(__('For “Missing Hot Sellers”: how many days back we count shop sales when ranking which missing products to add to the eshop first.', 'ai-eshop-optimizer')); ?></label><input type="number" id="pr-gap_recency" min="3" max="365" value="<?php echo esc_attr($settings['gap_recency']); ?>"></div>
            <div><label><?php esc_html_e('Eshop share of demand (%)', 'ai-eshop-optimizer'); echo $help(__('Your online revenue as a percentage of in-store revenue (e.g. ~€500k online vs ~€3M in shops ≈ 17%). We multiply the in-store sales of out-of-stock products by this share to estimate the online sales being missed. Lower = more conservative. The optimistic figure goes above this to reflect the eshop’s national reach (~6,000 visitors/day) beyond the 4 stores.', 'ai-eshop-optimizer')); ?></label><input type="number" id="pr-channel_pct" min="1" max="100" value="<?php echo esc_attr($settings['channel_pct']); ?>"></div>
        </div>
        <div style="margin-top:14px;display:flex;align-items:center;gap:18px;flex-wrap:wrap;">
            <label style="display:flex;align-items:center;gap:6px;font-weight:600;">
                <input type="checkbox" id="pr-auto" <?php checked((int) $settings['auto'], 1); ?>>
                <?php esc_html_e('Auto-apply restocks (when thresholds met)', 'ai-eshop-optimizer'); echo $help(__('If ticked, products that pass all the checks above are put back in stock automatically. If unticked (safer to start), they just wait in the list below for you to press “Restock” yourself.', 'ai-eshop-optimizer')); ?>
            </label>
            <span class="description"><?php esc_html_e('Branches counted:', 'ai-eshop-optimizer'); echo $help(__('Which physical shops’ sales we count when deciding what to restock. Untick a shop to ignore its sales.', 'ai-eshop-optimizer')); ?></span>
            <?php foreach ($all_branches as $b) : ?>
                <label style="display:inline-flex;align-items:center;gap:4px;font-size:12px;">
                    <input type="checkbox" class="pr-branch" value="<?php echo esc_attr($b); ?>" <?php checked(in_array($b, (array) $settings['branches'], true)); ?>>
                    <?php echo esc_html(ucfirst($b)); ?>
                </label>
            <?php endforeach; ?>
            <button type="button" class="button button-secondary" id="aieo-pr-save"><?php esc_html_e('Save settings', 'ai-eshop-optimizer'); ?></button>
            <button type="button" class="button button-primary js-pr-runnow" style="margin-left:6px;" title="<?php esc_attr_e('Restock every product that meets the thresholds above (with the quantity it decides), then re-scan the queue', 'ai-eshop-optimizer'); ?>"><?php esc_html_e('Run restock now', 'ai-eshop-optimizer'); ?></button>
        </div>
    </div>

    <?php ?>
    <div class="aieo-dmm-card">
        <div class="aieo-pr-toolbar">
            <h3 style="margin:0;"><?php esc_html_e('Recovery queue — OOS in eshop, selling in stores', 'ai-eshop-optimizer'); ?></h3>
            <span>
                <?php if (!empty($candidates)) : ?>
                    <a class="button" href="<?php echo esc_url(admin_url('admin-ajax.php') . '?action=aieo_pr_export_recovery&nonce=' . rawurlencode($nonce)); ?>"><?php esc_html_e('Export to Excel', 'ai-eshop-optimizer'); ?></a>
                <?php endif; ?>
                <button type="button" class="button" id="aieo-pr-bulk"><?php esc_html_e('Apply all that meet threshold', 'ai-eshop-optimizer'); ?></button>
            </span>
        </div>
        <?php if (empty($candidates)) : ?>
            <p class="description" style="margin-top:10px;"><?php esc_html_e('No candidates. Run detection (needs ERP physical-sales data + eshop OOS products).', 'ai-eshop-optimizer'); ?></p>
        <?php else : ?>
        <table class="aieo-pr-table">
            <thead><tr>
                <th></th>
                <th class="sortable" data-key="product"><?php esc_html_e('Product', 'ai-eshop-optimizer'); ?><span class="arr"></span></th>
                <th class="sortable" data-key="oos"><?php esc_html_e('Out of stock', 'ai-eshop-optimizer'); ?><span class="arr"></span></th>
                <th class="sortable" data-key="units"><?php esc_html_e('Phys. sold', 'ai-eshop-optimizer'); ?><span class="arr"></span></th>
                <th class="sortable" data-key="branches" title="<?php printf(esc_attr__('Units sold per physical store in the last %d days — so pickers know which branch holds the stock', 'ai-eshop-optimizer'), $rec); ?>"><?php esc_html_e('By branch (units)', 'ai-eshop-optimizer'); ?><span class="arr"></span></th>
                <th class="sortable" data-key="lost" title="<?php esc_attr_e('Estimated recoverable online sales = the in-store sales of this product (in the window) × the eshop channel share (capped at its own in-store cash); range = pessimistic (local-only) to optimistic (national reach). Plus the actual in-store net revenue.', 'ai-eshop-optimizer'); ?>"><?php esc_html_e('Recoverable online / in-store', 'ai-eshop-optimizer'); ?><span class="arr"></span></th>
                <th class="sortable" data-key="basket" title="<?php printf(esc_attr__('Basket halo: the total value of the whole in-store orders this product appeared in (last %d days). It shows the product pulls far more than its own line — without it the shopper may take the entire basket elsewhere.', 'ai-eshop-optimizer'), $rec); ?>"><?php esc_html_e('Basket turnover', 'ai-eshop-optimizer'); ?><span class="arr"></span></th>
                <th><?php esc_html_e('Qty', 'ai-eshop-optimizer'); ?></th>
                <th></th>
            </tr></thead>
            <tbody>
            <?php foreach ($candidates as $c) :
                $pid = (int) $c['product_id'];
                $applied = in_array($c['status'], array('applied', 'auto_applied'), true);
                
                
                
                
                $is_variation_row = (!empty($c['is_variation']) && (int) $c['parent_id'] > 0);
                $edit_id = $is_variation_row ? (int) $c['parent_id'] : $pid;
                $edit = $edit_id > 0 ? admin_url('post.php?post=' . $edit_id . '&action=edit') : '';
                if ($edit !== '' && $is_variation_row) { $edit = add_query_arg('aieo_focus_variation', $pid, $edit); }
                
                
                
                $brparts = array();
                foreach (array('piraeus' => 'Πειραιάς', 'keratsini' => 'Κερατσίνι', 'korydallos' => 'Κορυδαλλός', 'kallithea' => 'Καλλιθέα') as $b => $blabel) {
                    $bval = isset($c['phys_' . $b . '_recent']) ? (float) $c['phys_' . $b . '_recent'] : (float) ($c['phys_' . $b] ?? 0);
                    if ($bval > 0) { $brparts[] = $blabel . ' ' . rtrim(rtrim(number_format($bval, 3, '.', ''), '0'), '.'); }
                }
                
                
                
                
                $r          = isset($settings['channel_pct']) ? ((int) $settings['channel_pct']) / 100.0 : 0.1667;
                $c_phys_win = (float) ($c['phys_turnover_recent'] ?? 0);
                $c_lost     = min($c_phys_win * $r, $c_phys_win);
                $c_nm   = function_exists('mb_strtolower') ? mb_strtolower((string) ($c['name'] ?: $c['sku'])) : strtolower((string) ($c['name'] ?: $c['sku']));
            ?>
                <tr class="<?php echo $applied ? 'is-applied' : ''; ?>" data-pid="<?php echo esc_attr($pid); ?>"
                    data-product="<?php echo esc_attr($c_nm); ?>"
                    data-oos="<?php echo esc_attr((int) $c['days_oos']); ?>"
                    data-units="<?php echo esc_attr((float) $c['phys_units_recent']); ?>"
                    data-branches="<?php echo esc_attr(count($brparts)); ?>"
                    data-lost="<?php echo esc_attr($c_lost); ?>"
                    data-basket="<?php echo esc_attr((float) ($c['phys_basket_turnover_recent'] ?? 0)); ?>">
                    <td><?php if (!empty($c['image_url'])) { echo '<img src="' . esc_url($c['image_url']) . '" alt="">'; } ?></td>
                    <td>
                        <?php if ($edit) : ?>
                            <a href="<?php echo esc_url($edit); ?>" target="_blank" rel="noopener" title="<?php esc_attr_e('Open this product in WooCommerce', 'ai-eshop-optimizer'); ?>"><strong><?php echo esc_html($c['name'] ?: ('#' . $pid)); ?></strong></a><br>
                        <?php else : ?>
                            <strong><?php echo esc_html($c['name'] ?: ('#' . $pid)); ?></strong><br>
                        <?php endif; ?>
                        <code style="font-size:11px;color:#6b7280;"><?php echo esc_html($c['sku']); ?></code>
                        <?php if ($applied) { echo '<br>' . $badge(__('restocked', 'ai-eshop-optimizer'), '#dcfce7', '#166534'); } ?>
                        <?php if (!empty($c['blocked_reason'])) { echo ' ' . $badge($c['blocked_reason'], '#fee2e2', '#991b1b'); } ?>
                    </td>
                    <td>
                        <?php if ($c['oos_source'] === 'unknown') : ?>
                            <strong title="<?php esc_attr_e('Out-of-stock start date could not be determined', 'ai-eshop-optimizer'); ?>">—</strong>
                        <?php else : ?>
                            <strong><?php echo esc_html((int) $c['days_oos']); ?></strong> <?php esc_html_e('days', 'ai-eshop-optimizer'); ?>
                        <?php endif; ?><br>
                        <?php
                        if ($c['oos_source'] === 'history') {
                            echo $badge(__('from stock log', 'ai-eshop-optimizer'), '#e0e7ff', '#3730a3', __('Out-of-stock start taken from the daily stock-history log (precise).', 'ai-eshop-optimizer'));
                        } elseif ($c['oos_source'] === 'latest_sale') {
                            echo $badge(__('est. from last online sale', 'ai-eshop-optimizer'), '#fef9c3', '#854d0e', __('No stock-history yet for this product, so the out-of-stock start is estimated from its last ONLINE (eshop) sale date.', 'ai-eshop-optimizer'));
                        } elseif ($c['oos_source'] === 'parent_history' || $c['oos_source'] === 'parent_sale') {
                            echo $badge(__('est. from parent', 'ai-eshop-optimizer'), '#fef9c3', '#854d0e', __('This variation has no online history of its own, so the out-of-stock start is estimated from its parent product’s last online activity.', 'ai-eshop-optimizer'));
                        } else {
                            echo $badge(__('no date', 'ai-eshop-optimizer'), '#f3f4f6', '#6b7280', __('No reliable out-of-stock date — shown for review, never auto-restocked.', 'ai-eshop-optimizer'));
                        }
                        ?>
                    </td>
                    <td>
                        <strong title="<?php printf(esc_attr__('Units sold in the stores in the last %d days — this recent demand drives the suggested quantity', 'ai-eshop-optimizer'), $rec); ?>"><?php echo esc_html(rtrim(rtrim((string) $c['phys_units_recent'], '0'), '.')); ?></strong> <?php printf(esc_html__('units · last %dd', 'ai-eshop-optimizer'), $rec); ?><br>
                        <span style="font-size:11px;color:#6b7280;"><?php echo esc_html(rtrim(rtrim((string) $c['phys_units_after'], '0'), '.')); ?> <?php esc_html_e('since OOS', 'ai-eshop-optimizer'); ?> · <?php echo esc_html((int) $c['phys_sale_days']); ?> <?php esc_html_e('sale-days', 'ai-eshop-optimizer'); ?> · <span title="<?php esc_attr_e('Most recent physical-store sale for this SKU', 'ai-eshop-optimizer'); ?>" style="cursor:help;"><?php esc_html_e('last sold', 'ai-eshop-optimizer'); ?> <?php echo esc_html($c['last_phys_sale_date']); ?></span></span>
                        <?php if ((int) $c['meets_threshold'] === 1) { echo '<br>' . $badge(__('meets threshold', 'ai-eshop-optimizer'), '#dcfce7', '#166534'); } ?>
                    </td>
                    <td style="font-size:11px;color:#4b5563;"><?php echo esc_html(implode(', ', $brparts)); ?></td>
                    <td style="font-size:12px;">
                        <?php if ($c_phys_win > 0) : ?>
                            <strong style="color:#b91c1c;" title="<?php printf(esc_attr__('Estimated recoverable online sales, last %d days = this product\'s in-store sales × the eshop channel share (capped at its own in-store cash).', 'ai-eshop-optimizer'), $rec); ?>">≈ <?php echo esc_html(number_format_i18n($c_lost, 2)); ?> €</strong> <span style="color:#9ca3af;font-size:10px;"><?php printf(esc_html__('recoverable · last %dd', 'ai-eshop-optimizer'), $rec); ?></span>
                            <br><span style="color:#9ca3af;font-size:10px;" title="<?php esc_attr_e('pessimistic (conservative, local-only) – optimistic (eshop national reach)', 'ai-eshop-optimizer'); ?>"><?php echo esc_html(number_format_i18n($c_lost * 0.6, 0)); ?>–<?php echo esc_html(number_format_i18n($c_lost * 2.0, 0)); ?> €</span>
                        <?php else : ?>
                            <span style="color:#9ca3af;">—</span>
                        <?php endif; ?>
                        <br><span style="color:#6b7280;font-size:11px;"><?php esc_html_e('in-store', 'ai-eshop-optimizer'); ?> <?php echo esc_html(number_format_i18n($c_phys_win, 2)); ?> € <?php printf(esc_html__('net · last %dd', 'ai-eshop-optimizer'), $rec); ?> <span style="color:#9ca3af;">(<?php echo esc_html(number_format_i18n((float) $c['phys_turnover_after'], 2)); ?> € <?php esc_html_e('since OOS', 'ai-eshop-optimizer'); ?>)</span></span>
                    </td>
                    <?php $c_basket = (float) ($c['phys_basket_turnover_recent'] ?? 0); $c_basket_ord = (int) ($c['phys_basket_orders_recent'] ?? 0); ?>
                    <td style="font-size:12px;">
                        <?php if ($c_basket > 0) : ?>
                            <strong style="color:#7c3aed;" title="<?php printf(esc_attr__('Total value of the in-store orders this product appeared in, last %d days', 'ai-eshop-optimizer'), $rec); ?>"><?php echo esc_html(number_format_i18n($c_basket, 2)); ?> €</strong>
                            <br><span style="color:#9ca3af;font-size:10px;"><?php printf(esc_html__('across %s orders · last %dd', 'ai-eshop-optimizer'), esc_html(number_format_i18n($c_basket_ord)), $rec); ?></span>
                        <?php else : ?>
                            <span style="color:#9ca3af;">—</span>
                        <?php endif; ?>
                    </td>
                    <td><input type="number" class="pr-qty" min="0" max="999" value="<?php echo esc_attr((int) $c['suggested_restock_qty']); ?>" style="width:60px;" <?php echo $applied ? 'disabled' : ''; ?>></td>
                    <td style="white-space:nowrap;">
                        <?php if (!$applied) : ?>
                            <button type="button" class="button button-primary aieo-pr-btn-sm pr-apply"><?php esc_html_e('Restock', 'ai-eshop-optimizer'); ?></button>
                            <button type="button" class="button aieo-pr-btn-sm pr-dismiss"><?php esc_html_e('Dismiss', 'ai-eshop-optimizer'); ?></button>
                            <button type="button" class="button aieo-pr-btn-sm pr-block" title="<?php esc_attr_e('Never auto-restock this product', 'ai-eshop-optimizer'); ?>">⊘</button>
                        <?php endif; ?>
                    </td>
                </tr>
            <?php endforeach; ?>
            </tbody>
        </table>
        <?php endif; ?>
    </div>

    <?php ?>

    <?php ?>
    <?php if (!empty($events)) : ?>
    <div class="aieo-dmm-card">
        <div style="display:flex;justify-content:space-between;align-items:center;gap:12px;flex-wrap:wrap;">
            <h3 style="margin:0;"><?php esc_html_e('Recent restocks', 'ai-eshop-optimizer'); ?></h3>
            <a class="button" href="<?php echo esc_url(admin_url('admin-ajax.php') . '?action=aieo_pr_export_restocks&nonce=' . rawurlencode($nonce)); ?>"><?php esc_html_e('Export all to Excel', 'ai-eshop-optimizer'); ?></a>
        </div>
        <?php if (!empty($events_total) && (int) $events_total > count($events)) : ?>
            <p class="description" style="margin:6px 0 0;"><?php printf(esc_html__('Showing the %1$s most recent of %2$s total restocks — use “Export all to Excel” for the full history.', 'ai-eshop-optimizer'), esc_html(number_format_i18n(count($events))), esc_html(number_format_i18n((int) $events_total))); ?></p>
        <?php endif; ?>
        <table class="aieo-pr-table" id="aieo-pr-events" style="margin-top:10px;">
            <thead><tr>
                <th data-key="product"><?php esc_html_e('Product', 'ai-eshop-optimizer'); ?></th>
                <th title="<?php esc_attr_e('Which physical stores were selling this product when restocked — so pickers know where to find the stock', 'ai-eshop-optimizer'); ?>"><?php esc_html_e('By branch (units)', 'ai-eshop-optimizer'); ?></th>
                <th data-key="when"><?php esc_html_e('When', 'ai-eshop-optimizer'); ?></th>
                <th data-key="mode"><?php esc_html_e('Mode', 'ai-eshop-optimizer'); ?></th>
                <th data-key="outcome"><?php esc_html_e('Outcome', 'ai-eshop-optimizer'); ?></th>
                <th data-key="recovered"><?php esc_html_e('Recovered', 'ai-eshop-optimizer'); ?></th>
                <th></th>
            </tr></thead>
            <tbody>
            <?php foreach ($events as $e) :
                $oc = $e['outcome'];
                $ocbg = $oc === 'success' ? '#dcfce7' : ($oc === 'failure' ? '#fee2e2' : ($oc === 'reverted' ? '#f3f4f6' : '#fef9c3'));
                $ocfg = $oc === 'success' ? '#166534' : ($oc === 'failure' ? '#991b1b' : ($oc === 'reverted' ? '#6b7280' : '#854d0e'));
                $e_pid    = (int) $e['product_id'];
                $e_isvar  = !empty($e['parent_id']) && (int) $e['parent_id'] !== $e_pid;
                $e_editid = $e_isvar ? (int) $e['parent_id'] : $e_pid;
                $e_edit   = $e_editid > 0 ? admin_url('post.php?post=' . $e_editid . '&action=edit') : '';
                if ($e_edit !== '' && $e_isvar) { $e_edit = add_query_arg('aieo_focus_variation', $e_pid, $e_edit); }
                $e_name   = $e['product_name'] ?: ($e['sku'] ?: ('#' . $e_pid));
                $e_units  = (float) $e['eshop_units_recovered'];
                $e_turn   = (float) $e['eshop_turnover_recovered'];
                $e_units_dr = (float) ($e['eshop_units_draft'] ?? 0);
                $e_turn_dr  = (float) ($e['eshop_turnover_draft'] ?? 0);
                $e_sortnm = function_exists('mb_strtolower') ? mb_strtolower((string) $e_name) : strtolower((string) $e_name);
            ?>
                <tr data-product="<?php echo esc_attr($e_sortnm); ?>" data-when="<?php echo esc_attr($e['applied_at']); ?>" data-mode="<?php echo esc_attr($e['mode']); ?>" data-outcome="<?php echo esc_attr($oc); ?>" data-recovered="<?php echo esc_attr($e_turn); ?>">
                    <td>
                        <div style="display:flex;align-items:center;gap:8px;">
                            <?php if (!empty($e['image_url'])) : ?><img src="<?php echo esc_url($e['image_url']); ?>" alt="" style="width:34px;height:34px;object-fit:cover;border-radius:4px;flex:0 0 auto;"><?php endif; ?>
                            <span>
                                <?php if ($e_edit) : ?>
                                    <a href="<?php echo esc_url($e_edit); ?>" target="_blank" rel="noopener" title="<?php esc_attr_e('Open this product in WooCommerce', 'ai-eshop-optimizer'); ?>"><strong><?php echo esc_html($e_name); ?></strong></a>
                                <?php else : ?>
                                    <strong><?php echo esc_html($e_name); ?></strong>
                                <?php endif; ?>
                                <?php if (!empty($e['sku'])) : ?><br><code style="font-size:11px;color:#6b7280;"><?php echo esc_html($e['sku']); ?></code><?php endif; ?>
                            </span>
                        </div>
                    </td>
                    <?php
                    $ebr = array();
                    foreach (array('piraeus' => 'Πειραιάς', 'keratsini' => 'Κερατσίνι', 'korydallos' => 'Κορυδαλλός', 'kallithea' => 'Καλλιθέα') as $bk => $bl) {
                        $bv = (float) ($e['phys_' . $bk . '_recent'] ?? 0);
                        if ($bv > 0) { $ebr[] = $bl . ' ' . rtrim(rtrim(number_format($bv, 3, '.', ''), '0'), '.'); }
                    }
                    ?>
                    <td style="font-size:11px;color:#4b5563;"><?php echo $ebr ? esc_html(implode(', ', $ebr)) : '<span style="color:#9ca3af;">—</span>'; ?></td>
                    <td style="font-size:11px;color:#6b7280;white-space:nowrap;"><?php echo esc_html($e['applied_at']); ?></td>
                    <td><?php echo esc_html($e['mode']); ?></td>
                    <td><?php echo $badge($oc . ($e['outcome_reason'] ? ' · ' . $e['outcome_reason'] : ''), $ocbg, $ocfg); ?></td>
                    <td style="white-space:nowrap;"><?php echo esc_html(rtrim(rtrim(number_format($e_units, 3, '.', ''), '0'), '.')); ?> <?php esc_html_e('u', 'ai-eshop-optimizer'); ?> / <?php echo esc_html(number_format_i18n($e_turn, 2)); ?> €<?php if ($e_turn_dr > 0 || $e_units_dr > 0) : ?><br><span style="color:#b45309;font-size:11px;" title="<?php esc_attr_e('Sitting in unfinished checkouts — not yet finalised', 'ai-eshop-optimizer'); ?>">+ <?php echo esc_html(rtrim(rtrim(number_format($e_units_dr, 3, '.', ''), '0'), '.')); ?> <?php esc_html_e('u', 'ai-eshop-optimizer'); ?> / <?php echo esc_html(number_format_i18n($e_turn_dr, 2)); ?> € <?php esc_html_e('in drafts', 'ai-eshop-optimizer'); ?></span><?php endif; ?></td>
                    <td><?php if (empty($e['reverted_at'])) : ?><button type="button" class="button aieo-pr-btn-sm pr-revert" data-eid="<?php echo esc_attr((int) $e['id']); ?>"><?php esc_html_e('Revert', 'ai-eshop-optimizer'); ?></button><?php endif; ?></td>
                </tr>
            <?php endforeach; ?>
            </tbody>
        </table>
        <div class="aieo-pr-pager" data-table="aieo-pr-events" data-page-size="25" style="margin-top:10px;text-align:center;"></div>
    </div>
    <?php endif; ?>

</div>

<script>
(function(){
    var PR_NONCE = <?php echo wp_json_encode($nonce); ?>;
    var statusEl = document.getElementById('aieo-pr-status');
    function setStatus(msg, ok){ if(!statusEl) return; statusEl.textContent = msg; statusEl.style.color = ok===false ? '#b91c1c' : (ok ? '#15803d' : '#6b7280'); }
    function post(action, data){
        var fd = new FormData(); fd.append('action', action); fd.append('nonce', PR_NONCE);
        Object.keys(data||{}).forEach(function(k){
            var v = data[k];
            if (Array.isArray(v)) { v.forEach(function(x){ fd.append(k+'[]', x); }); }
            else { fd.append(k, v); }
        });
        return fetch(ajaxurl, {method:'POST', body:fd, credentials:'same-origin'}).then(function(r){ return r.json(); });
    }

    function runDetection(btn){
        btn.disabled = true; setStatus('<?php echo esc_js(__('Running detection…', 'ai-eshop-optimizer')); ?>');
        post('aieo_pr_run_detection', {}).then(function(j){
            btn.disabled = false;
            if (j && j.success) { setStatus(j.data.message, true); setTimeout(function(){ location.reload(); }, 900); }
            else { setStatus((j&&j.data&&j.data.message)||'error', false); }
        }).catch(function(){ btn.disabled=false; setStatus('<?php echo esc_js(__('network error', 'ai-eshop-optimizer')); ?>', false); });
    }
    Array.prototype.forEach.call(document.querySelectorAll('.js-pr-run'), function(btn){
        btn.addEventListener('click', function(){ runDetection(btn); });
    });
    // Shared chunked apply: loops aieo_pr_apply_bulk (50 products/request) until
    // nothing meeting-threshold is left, so a large restock NEVER hits the
    // request/nginx timeout. Each request is short; progress is shown live.
    // Calls onDone(ok, appliedTotal) when finished (or on error).
    function applyAllChunked(onDone){
        var applied = 0, guard = 0;
        (function step(){
            if (++guard > 1000) { setStatus('<?php echo esc_js(__('Stopped after too many batches — please re-run.', 'ai-eshop-optimizer')); ?>', false); onDone && onDone(false, applied); return; }
            post('aieo_pr_apply_bulk', {}).then(function(j){
                if (!j || !j.success) { setStatus((j&&j.data&&j.data.message)||'error', false); onDone && onDone(false, applied); return; }
                applied += (j.data.applied || 0);
                setStatus('<?php echo esc_js(__('Restocked', 'ai-eshop-optimizer')); ?> ' + applied + ' · ' + (j.data.remaining || 0) + ' <?php echo esc_js(__('left', 'ai-eshop-optimizer')); ?>');
                if (j.data.done) { onDone && onDone(true, applied); }
                else { step(); }
            }).catch(function(){ setStatus('<?php echo esc_js(__('network error', 'ai-eshop-optimizer')); ?>', false); onDone && onDone(false, applied); });
        })();
    }
    // "Run now" (beside Save settings) = restock everything that meets the
    // thresholds, IN BATCHES (no timeout), then re-scan the queue once so the
    // now-in-stock products drop off. Distinct from "Run detection now" above.
    Array.prototype.forEach.call(document.querySelectorAll('.js-pr-runnow'), function(btn){
        btn.addEventListener('click', function(){
            if (!window.confirm('<?php echo esc_js(__('Restock every product that meets the thresholds, with the quantity the engine decides?', 'ai-eshop-optimizer')); ?>')) { return; }
            btn.disabled = true; setStatus('<?php echo esc_js(__('Saving settings…', 'ai-eshop-optimizer')); ?>');
            // Save on-screen thresholds first so Run now uses what you see, then
            // restock in batches, then a single re-scan (each step is bounded).
            post('aieo_pr_save_settings', collectSettings()).then(function(){
                // Re-detect with the just-saved thresholds FIRST, so "Run now"
                // restocks based on what's on screen (not the previous scan).
                setStatus('<?php echo esc_js(__('Scanning with your thresholds…', 'ai-eshop-optimizer')); ?>');
                return post('aieo_pr_run_detection', {});
            }).then(function(){
                setStatus('<?php echo esc_js(__('Restocking…', 'ai-eshop-optimizer')); ?>');
                applyAllChunked(function(ok, applied){
                    if (!ok) { btn.disabled = false; return; }
                    setStatus('<?php echo esc_js(__('Re-scanning the queue…', 'ai-eshop-optimizer')); ?>');
                    post('aieo_pr_run_detection', {}).then(function(){
                        btn.disabled = false;
                        setStatus('<?php echo esc_js(__('Done — restocked', 'ai-eshop-optimizer')); ?> ' + applied, true);
                        setTimeout(function(){ location.reload(); }, 1100);
                    }).catch(function(){ btn.disabled = false; setStatus('<?php echo esc_js(__('network error', 'ai-eshop-optimizer')); ?>', false); });
                });
            }).catch(function(){ btn.disabled = false; setStatus('<?php echo esc_js(__('network error', 'ai-eshop-optimizer')); ?>', false); });
        });
    });

    function collectSettings(){
        var ids = ['min_units','min_days','recency_days','min_days_oos','qty_cap','cover_days','cooldown_days','outcome_window','gap_min_units','gap_recency','channel_pct'];
        var data = { auto: document.getElementById('pr-auto').checked ? 1 : 0 };
        ids.forEach(function(k){ var el=document.getElementById('pr-'+k); if(el){ data[k]=el.value; } });
        data.branches = Array.prototype.map.call(document.querySelectorAll('.pr-branch:checked'), function(c){ return c.value; });
        return data;
    }
    var saveBtn = document.getElementById('aieo-pr-save');
    saveBtn && saveBtn.addEventListener('click', function(){
        setStatus('<?php echo esc_js(__('Saving…', 'ai-eshop-optimizer')); ?>');
        post('aieo_pr_save_settings', collectSettings()).then(function(j){ setStatus((j&&j.data&&j.data.message)||'saved', !!(j&&j.success)); });
    });

    document.addEventListener('click', function(ev){
        var tr;
        if (ev.target.classList.contains('pr-apply')) {
            tr = ev.target.closest('tr'); var pid = tr.getAttribute('data-pid');
            var qty = tr.querySelector('.pr-qty') ? tr.querySelector('.pr-qty').value : '';
            ev.target.disabled = true; setStatus('<?php echo esc_js(__('Restocking…', 'ai-eshop-optimizer')); ?>');
            post('aieo_pr_apply_one', {product_id: pid, qty: qty}).then(function(j){
                if (j && j.success) { tr.classList.add('is-applied'); setStatus('<?php echo esc_js(__('Restocked.', 'ai-eshop-optimizer')); ?>', true); setTimeout(function(){ location.reload(); }, 700); }
                else { ev.target.disabled=false; setStatus((j&&j.data&&j.data.message)||'error', false); }
            }).catch(function(){ ev.target.disabled=false; setStatus('<?php echo esc_js(__('network error', 'ai-eshop-optimizer')); ?>', false); });
        } else if (ev.target.classList.contains('pr-dismiss')) {
            tr = ev.target.closest('tr');
            post('aieo_pr_dismiss', {product_id: tr.getAttribute('data-pid')}).then(function(){ tr.style.opacity=0.4; });
        } else if (ev.target.classList.contains('pr-block')) {
            tr = ev.target.closest('tr');
            post('aieo_pr_blocklist', {product_id: tr.getAttribute('data-pid'), on: 1}).then(function(){ tr.style.opacity=0.4; });
        } else if (ev.target.classList.contains('pr-gap-dismiss')) {
            tr = ev.target.closest('tr');
            post('aieo_pr_gap_dismiss', {sku_norm: tr.getAttribute('data-sku')}).then(function(){ tr.style.opacity=0.4; });
        } else if (ev.target.classList.contains('pr-revert')) {
            if (!window.confirm('<?php echo esc_js(__('Revert this product to its prior (out-of-stock) state?', 'ai-eshop-optimizer')); ?>')) return;
            ev.target.disabled = true;
            post('aieo_pr_revert', {event_id: ev.target.getAttribute('data-eid')}).then(function(j){
                if (j && j.success) { setTimeout(function(){ location.reload(); }, 500); }
                else { ev.target.disabled=false; setStatus((j&&j.data&&j.data.message)||'error', false); }
            });
        }
    });

    var bulkBtn = document.getElementById('aieo-pr-bulk');
    bulkBtn && bulkBtn.addEventListener('click', function(){
        if (!window.confirm('<?php echo esc_js(__('Restock every product that meets the threshold?', 'ai-eshop-optimizer')); ?>')) return;
        bulkBtn.disabled = true;
        applyAllChunked(function(ok, applied){
            bulkBtn.disabled = false;
            if (ok) { setStatus('<?php echo esc_js(__('Done — restocked', 'ai-eshop-optimizer')); ?> ' + applied, true); setTimeout(function(){ location.reload(); }, 900); }
        });
    });

    // Client-side column sorting for the recovery queue (Product / Out of stock / Phys. sold / By branch / Lost).
    document.querySelectorAll('.aieo-pr-table th.sortable').forEach(function(th){
        th.addEventListener('click', function(){
            var table = th.closest('table'), body = table ? table.querySelector('tbody') : null;
            if (!body) { return; }
            var key = th.getAttribute('data-key');
            var asc = th.getAttribute('data-dir') !== 'asc';
            th.setAttribute('data-dir', asc ? 'asc' : 'desc');
            var rows = Array.prototype.slice.call(body.querySelectorAll('tr'));
            rows.sort(function(a, b){
                var av = a.getAttribute('data-' + key) || '', bv = b.getAttribute('data-' + key) || '';
                if (key === 'product') { return asc ? av.localeCompare(bv) : bv.localeCompare(av); }
                av = parseFloat(av) || 0; bv = parseFloat(bv) || 0;
                return asc ? av - bv : bv - av;
            });
            rows.forEach(function(r){ body.appendChild(r); });
            table.querySelectorAll('th.sortable .arr').forEach(function(a){ a.textContent = ''; });
            var arrEl = th.querySelector('.arr'); if (arrEl) { arrEl.textContent = asc ? '▲' : '▼'; }
        });
    });
    // Recent restocks — client-side pagination (+ click-to-sort) for the events table.
    (function(){
        var table = document.getElementById('aieo-pr-events');
        if (!table) { return; }
        var tbody = table.querySelector('tbody');
        var pager = document.querySelector('.aieo-pr-pager[data-table="aieo-pr-events"]');
        if (!tbody || !pager) { return; }
        var pageSize = parseInt(pager.getAttribute('data-page-size'), 10) || 25;
        var rows = Array.prototype.slice.call(tbody.querySelectorAll('tr'));
        var page = 1;
        function totalPages(){ return Math.max(1, Math.ceil(rows.length / pageSize)); }
        function render(){
            var tp = totalPages();
            if (page > tp) { page = tp; }
            if (page < 1) { page = 1; }
            var start = (page - 1) * pageSize, end = start + pageSize;
            rows.forEach(function(r, i){ r.style.display = (i >= start && i < end) ? '' : 'none'; });
            pager.innerHTML = '';
            if (rows.length <= pageSize) { return; }
            var mk = function(label, disabled, fn){
                var b = document.createElement('button'); b.type = 'button'; b.className = 'button'; b.textContent = label; b.style.margin = '0 4px';
                if (disabled) { b.disabled = true; } else { b.addEventListener('click', fn); }
                return b;
            };
            pager.appendChild(mk('‹', page <= 1, function(){ page--; render(); }));
            var info = document.createElement('span'); info.style.margin = '0 10px';
            info.textContent = '<?php echo esc_js(__('Page', 'ai-eshop-optimizer')); ?> ' + page + ' / ' + tp + ' (' + rows.length + ')';
            pager.appendChild(info);
            pager.appendChild(mk('›', page >= tp, function(){ page++; render(); }));
        }
        Array.prototype.forEach.call(table.querySelectorAll('thead th[data-key]'), function(th){
            th.style.cursor = 'pointer';
            th.addEventListener('click', function(){
                var key = th.getAttribute('data-key');
                var asc = th.getAttribute('data-dir') !== 'asc';
                Array.prototype.forEach.call(table.querySelectorAll('thead th[data-key]'), function(o){ o.removeAttribute('data-dir'); });
                th.setAttribute('data-dir', asc ? 'asc' : 'desc');
                rows.sort(function(a, b){
                    var av = a.getAttribute('data-' + key) || '', bv = b.getAttribute('data-' + key) || '';
                    var na = parseFloat(av), nb = parseFloat(bv);
                    if (!isNaN(na) && !isNaN(nb)) { return asc ? na - nb : nb - na; }
                    return asc ? av.localeCompare(bv) : bv.localeCompare(av);
                });
                rows.forEach(function(r){ tbody.appendChild(r); });
                page = 1; render();
            });
        });
        render();
    })();
})();
</script>
