<?php

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

$upload = wp_upload_dir();
$feeds_dir = trailingslashit($upload['basedir']) . 'exports/';
$feeds_url = trailingslashit($upload['baseurl']) . 'exports/';
$availability_instock = isset($availability_instock) ? (string) $availability_instock : (string) get_option('aieo_feed_availability_instock', 'Παράδοση σε 1 - 3 ημέρες');
$availability_oos     = isset($availability_oos)     ? (string) $availability_oos     : (string) get_option('aieo_feed_availability_oos', 'Μη διαθέσιμο');
$shipping_lead_time   = isset($shipping_lead_time)   ? (string) $shipping_lead_time   : (string) get_option('aieo_feed_default_lead_time', '0');
$etsy_who_made     = (string) get_option('aieo_feed_etsy_who_made', 'i_did');
$etsy_when_made    = (string) get_option('aieo_feed_etsy_when_made', 'made_to_order');
$etsy_taxonomy_id  = (string) get_option('aieo_feed_etsy_taxonomy_id', '');
$etsy_ship_profile = (string) get_option('aieo_feed_etsy_shipping_profile_id', '');
$avail_nonce = wp_create_nonce(AIEO_DMM::NONCE_ACTION);
$ajax_url    = admin_url('admin-ajax.php');
?>

<div class="aieo-dmm-section">
    <h2><?php esc_html_e('Availability strings', 'ai-eshop-optimizer'); ?></h2>
    <div class="aieo-dmm-card">
        <p class="description" style="margin:0 0 12px;">
            <?php esc_html_e('Used by every XML feed when emitting <availability>. Stock comes from the AIEO product-vitals snapshot — when stock>0 the in-stock string fires, otherwise the out-of-stock string. Edit + save and re-run any feed for the new values to bake into the XML.', 'ai-eshop-optimizer'); ?>
        </p>
        <table class="form-table" style="margin:0;">
            <tr>
                <th style="width:240px;"><?php esc_html_e('In stock', 'ai-eshop-optimizer'); ?></th>
                <td><input type="text" name="availability_instock" id="aieo-dmm-feed-avail-instock" class="regular-text" value="<?php echo esc_attr($availability_instock); ?>" maxlength="120" style="width:380px;">
                    <p class="description" style="margin:4px 0 0;font-size:11px;"><?php esc_html_e('Skroutz/eMag/etc. expect a Greek shipping-window phrase, e.g. "Παράδοση σε 1 - 3 ημέρες".', 'ai-eshop-optimizer'); ?></p>
                </td>
            </tr>
            <tr>
                <th><?php esc_html_e('Out of stock', 'ai-eshop-optimizer'); ?></th>
                <td><input type="text" name="availability_oos" id="aieo-dmm-feed-avail-oos" class="regular-text" value="<?php echo esc_attr($availability_oos); ?>" maxlength="120" style="width:380px;">
                </td>
            </tr>
            <tr>
                <th><?php esc_html_e('Shipping lead time (days)', 'ai-eshop-optimizer'); ?></th>
                <td><input type="number" name="shipping_lead_time" id="aieo-dmm-feed-lead-time" class="small-text" min="0" max="60" value="<?php echo esc_attr($shipping_lead_time); ?>">
                    <p class="description" style="margin:4px 0 0;font-size:11px;"><?php esc_html_e('Used by Shopflix\'s &lt;Shipping_Lead_Time&gt; tag. Leave at 0 to defer to the partner\'s default.', 'ai-eshop-optimizer'); ?></p>
                </td>
            </tr>
            <tr><th colspan="2" style="padding-top:14px;border-top:1px solid #e6e9ee;"><strong><?php esc_html_e('Etsy listing defaults', 'ai-eshop-optimizer'); ?></strong>
                <span class="description" style="font-weight:400;"><?php esc_html_e('Used by the Etsy (listings JSON) template — these are per-shop and Etsy requires them.', 'ai-eshop-optimizer'); ?></span></th></tr>
            <tr>
                <th><?php esc_html_e('Who made it', 'ai-eshop-optimizer'); ?></th>
                <td><select id="aieo-dmm-feed-etsy-whomade">
                    <option value="i_did"<?php selected($etsy_who_made, 'i_did'); ?>>i_did</option>
                    <option value="someone_else"<?php selected($etsy_who_made, 'someone_else'); ?>>someone_else</option>
                    <option value="collective"<?php selected($etsy_who_made, 'collective'); ?>>collective</option>
                </select></td>
            </tr>
            <tr>
                <th><?php esc_html_e('When made', 'ai-eshop-optimizer'); ?></th>
                <td><select id="aieo-dmm-feed-etsy-whenmade">
                    <?php foreach (array('made_to_order', '2020_2025', '2010_2019', '2006_2009', 'before_2006', '2000_2005', '1990s', '1980s', '1970s', '1960s', 'before_1960') as $wo) :
                        echo '<option value="' . esc_attr($wo) . '"' . selected($etsy_when_made, $wo, false) . '>' . esc_html($wo) . '</option>';
                    endforeach; ?>
                </select></td>
            </tr>
            <tr>
                <th><?php esc_html_e('Taxonomy ID', 'ai-eshop-optimizer'); ?></th>
                <td><input type="number" id="aieo-dmm-feed-etsy-taxonomy" class="small-text" min="0" value="<?php echo esc_attr($etsy_taxonomy_id); ?>">
                    <p class="description" style="margin:4px 0 0;font-size:11px;"><?php esc_html_e('Etsy category taxonomy id (required). Look it up via Etsy’s getSellerTaxonomyNodes API.', 'ai-eshop-optimizer'); ?></p></td>
            </tr>
            <tr>
                <th><?php esc_html_e('Shipping profile ID', 'ai-eshop-optimizer'); ?></th>
                <td><input type="number" id="aieo-dmm-feed-etsy-shipprofile" class="small-text" min="0" value="<?php echo esc_attr($etsy_ship_profile); ?>">
                    <p class="description" style="margin:4px 0 0;font-size:11px;"><?php esc_html_e('Your Etsy shipping profile id (required for physical items).', 'ai-eshop-optimizer'); ?></p></td>
            </tr>
        </table>
        <p style="margin:10px 0 0;">
            <button type="button" class="button button-primary" id="aieo-dmm-feed-avail-save"><?php esc_html_e('Save availability strings', 'ai-eshop-optimizer'); ?></button>
            <span id="aieo-dmm-feed-avail-status" style="margin-left:10px;color:#646970;font-size:13px;"></span>
        </p>
    </div>
</div>
<script>
(function () {
    var btn = document.getElementById('aieo-dmm-feed-avail-save');
    if (!btn) return;
    var status = document.getElementById('aieo-dmm-feed-avail-status');
    btn.addEventListener('click', function () {
        var fd = new FormData();
        fd.set('action', 'aieo_dmm_feed_save_availability');
        fd.set('nonce', '<?php echo esc_js($avail_nonce); ?>');
        fd.set('availability_instock', document.getElementById('aieo-dmm-feed-avail-instock').value);
        fd.set('availability_oos',     document.getElementById('aieo-dmm-feed-avail-oos').value);
        fd.set('shipping_lead_time',   document.getElementById('aieo-dmm-feed-lead-time').value);
        fd.set('etsy_who_made',            document.getElementById('aieo-dmm-feed-etsy-whomade').value);
        fd.set('etsy_when_made',           document.getElementById('aieo-dmm-feed-etsy-whenmade').value);
        fd.set('etsy_taxonomy_id',         document.getElementById('aieo-dmm-feed-etsy-taxonomy').value);
        fd.set('etsy_shipping_profile_id', document.getElementById('aieo-dmm-feed-etsy-shipprofile').value);
        status.style.color = '#646970';
        status.textContent = '<?php echo esc_js(__('Saving…', 'ai-eshop-optimizer')); ?>';
        fetch('<?php echo esc_js($ajax_url); ?>', {method:'POST', body: fd, credentials:'same-origin'})
            .then(function (r) { return r.json(); })
            .then(function (j) {
                status.style.color = (j && j.success) ? '#15803d' : '#b91c1c';
                status.textContent = (j && j.data && j.data.message)
                    || '<?php echo esc_js(__('Save failed.', 'ai-eshop-optimizer')); ?>';
            });
    });
})();
</script>

<div class="aieo-dmm-section">
    <h2><?php esc_html_e('Marketplace feeds', 'ai-eshop-optimizer'); ?></h2>

    <div class="aieo-dmm-card">
        <h3><?php esc_html_e('What this is', 'ai-eshop-optimizer'); ?></h3>
        <p class="description">
            <?php esc_html_e('A "feed" is a file that lists your products in a format a third party can consume — a marketplace (Skroutz, Shopflix, Google Shopping), a comparison engine, an affiliate network, or any partner who needs a scheduled product export. You pick:', 'ai-eshop-optimizer'); ?>
        </p>
        <ol class="description" style="margin:8px 0 8px 22px; padding-left:0;">
            <li><?php esc_html_e('A format (XML or CSV) — pick what the partner requires.', 'ai-eshop-optimizer'); ?></li>
            <li><?php esc_html_e('A template (Skroutz / Shopflix / Google Shopping) for common marketplaces, OR leave it as "custom" to build a fully custom feed with your own tag / column names.', 'ai-eshop-optimizer'); ?></li>
            <li><?php esc_html_e('Rules: which products to include or exclude, by product ID or by brand.', 'ai-eshop-optimizer'); ?></li>
            <li><?php esc_html_e('A field map: for each tag/column the partner wants, pick the DMM source field (brand, name, price, stock, …).', 'ai-eshop-optimizer'); ?></li>
            <li><?php esc_html_e('A schedule: manual, hourly, twice a day, or daily. Manual feeds are only built when you press “Run now”.', 'ai-eshop-optimizer'); ?></li>
            <li><?php esc_html_e('A CDN cache-busting strategy so partners always get fresh data (see below).', 'ai-eshop-optimizer'); ?></li>
        </ol>
        <p class="description">
            <strong><?php esc_html_e('Where feeds are saved:', 'ai-eshop-optimizer'); ?></strong>
            <code><?php echo esc_html($feeds_dir); ?></code><br>
            <strong><?php esc_html_e('Public URL:', 'ai-eshop-optimizer'); ?></strong>
            <code><?php echo esc_html($feeds_url); ?></code>
            <?php esc_html_e('+ the generated filename. Share the per-feed URL shown below (it carries the cache-bust token).', 'ai-eshop-optimizer'); ?>
        </p>
    </div>
</div>

<div class="aieo-dmm-section">
    <h2><?php esc_html_e('Create or update a feed', 'ai-eshop-optimizer'); ?></h2>

    <form id="aieo-dmm-feed-form" class="aieo-dmm-form">
        <input type="hidden" name="id" value="0">

        <!-- Basics -->
        <div class="aieo-dmm-grid">
            <p>
                <label><?php esc_html_e('Slug', 'ai-eshop-optimizer'); ?></label>
                <input type="text" name="slug" id="aieo-dmm-feed-slug" pattern="[a-z0-9_\-]+" required placeholder="skroutz">
                <span class="description"><?php esc_html_e('Used in the filename. Lowercase, digits, hyphens.', 'ai-eshop-optimizer'); ?></span>
            </p>
            <p>
                <label><?php esc_html_e('Label', 'ai-eshop-optimizer'); ?></label>
                <input type="text" name="label" required class="regular-text" placeholder="<?php esc_attr_e('Friendly name — e.g. Skroutz Main Feed', 'ai-eshop-optimizer'); ?>">
            </p>
            <p>
                <label><?php esc_html_e('Template', 'ai-eshop-optimizer'); ?></label>
                <select name="template" id="aieo-dmm-feed-template">
                    <option value=""><?php esc_html_e('— Fully custom —', 'ai-eshop-optimizer'); ?></option>
                    <?php foreach ($templates as $slug => $tpl) : ?>
                        <option value="<?php echo esc_attr($slug); ?>"><?php echo esc_html($tpl['label']); ?></option>
                    <?php endforeach; ?>
                </select>
                <span class="description"><?php esc_html_e('Presets Skroutz / Shopflix / Google default field maps. Leave at “Fully custom” to build your own.', 'ai-eshop-optimizer'); ?></span>
            </p>
            <p id="aieo-dmm-feed-location-row" style="display:none;">
                <label><?php esc_html_e('Location code (Google Local only)', 'ai-eshop-optimizer'); ?></label>
                <input type="text" name="location_code" id="aieo-dmm-feed-location-code" class="regular-text" pattern="[0-9a-zA-Z_\-]+" placeholder="16514942194286569200">
                <span class="description"><?php esc_html_e('The store_code Google Merchant Center assigned to this physical location. Emitted as <g:store_code> in every <item>; the file is saved as google-local-&lt;code&gt;.xml.', 'ai-eshop-optimizer'); ?></span>
            </p>
            <p>
                <label><?php esc_html_e('Format', 'ai-eshop-optimizer'); ?></label>
                <select name="format" id="aieo-dmm-feed-format">
                    <option value="xml">XML</option>
                    <option value="csv">CSV</option>
                    <option value="json">JSON</option>
                </select>
            </p>
            <p>
                <label><?php esc_html_e('Schedule', 'ai-eshop-optimizer'); ?></label>
                <select name="schedule">
                    <option value="manual"><?php esc_html_e('Manual only', 'ai-eshop-optimizer'); ?></option>
                    <option value="hourly"><?php esc_html_e('Hourly', 'ai-eshop-optimizer'); ?></option>
                    <option value="twicedaily"><?php esc_html_e('Twice daily', 'ai-eshop-optimizer'); ?></option>
                    <option value="daily"><?php esc_html_e('Daily', 'ai-eshop-optimizer'); ?></option>
                </select>
            </p>
            <p>
                <label><?php esc_html_e('Enabled', 'ai-eshop-optimizer'); ?></label>
                <input type="checkbox" name="enabled" value="1" checked>
            </p>
        </div>

        <!-- Preview of the output path (updated client-side as the user types) -->
        <div class="aieo-dmm-card" style="background:#f0f7fb; border-color:#c9e0ee;">
            <h3><?php esc_html_e('Where will this feed be saved?', 'ai-eshop-optimizer'); ?></h3>
            <p class="description" style="margin:0;">
                <?php esc_html_e('File path:', 'ai-eshop-optimizer'); ?>
                <code id="aieo-dmm-feed-path-preview"><?php echo esc_html($feeds_dir); ?>&lt;slug&gt;.xml</code><br>
                <?php esc_html_e('Public URL:', 'ai-eshop-optimizer'); ?>
                <code id="aieo-dmm-feed-url-preview"><?php echo esc_html($feeds_url); ?>&lt;slug&gt;.xml</code>
            </p>
        </div>

        <!-- Rules -->
        <h3><?php esc_html_e('Which products are included', 'ai-eshop-optimizer'); ?></h3>
        <p class="description">
            <?php esc_html_e('Leave all rule fields empty to include every published product in your catalogue. Use one or more rules to narrow it down.', 'ai-eshop-optimizer'); ?>
        </p>

        <div class="aieo-dmm-grid aieo-feed-rules">
            <div class="aieo-feed-rule">
                <label><?php esc_html_e('Exclude these products', 'ai-eshop-optimizer'); ?></label>
                <div class="aieo-feed-prodpick" data-field="exclude_ids">
                    <select name="exclude_ids[]" multiple hidden class="aieo-feed-prodpick-store"></select>
                    <div class="aieo-feed-chips" data-empty="<?php esc_attr_e('No products excluded.', 'ai-eshop-optimizer'); ?>"></div>
                    <button type="button" class="button aieo-feed-prodpick-open">+ <?php esc_html_e('Browse / choose products', 'ai-eshop-optimizer'); ?></button>
                </div>
                <span class="description"><?php esc_html_e('Pick simple products, whole variable products, or specific variations. Skipped even if they match the includes.', 'ai-eshop-optimizer'); ?></span>
            </div>
            <p>
                <label><?php esc_html_e('Exclude these brands', 'ai-eshop-optimizer'); ?></label>
                <select name="exclude_brand_ids[]" multiple class="aieo-dmm-brand-select" style="width:100%;"></select>
                <span class="description"><?php esc_html_e('Search and pick brands. Any product in one of these brands is removed from the feed.', 'ai-eshop-optimizer'); ?></span>
            </p>
            <div class="aieo-feed-rule">
                <label><?php esc_html_e('Include ONLY these products', 'ai-eshop-optimizer'); ?></label>
                <div class="aieo-feed-prodpick" data-field="include_ids">
                    <select name="include_ids[]" multiple hidden class="aieo-feed-prodpick-store"></select>
                    <div class="aieo-feed-chips" data-empty="<?php esc_attr_e('No products picked — the whole catalogue is included.', 'ai-eshop-optimizer'); ?>"></div>
                    <button type="button" class="button aieo-feed-prodpick-open">+ <?php esc_html_e('Browse / choose products', 'ai-eshop-optimizer'); ?></button>
                </div>
                <span class="description"><?php esc_html_e('Pick simple products, whole variable products, or specific variations. When set, only these ship — overrides brand includes.', 'ai-eshop-optimizer'); ?></span>
            </div>
            <p>
                <label><?php esc_html_e('Include ONLY these brands', 'ai-eshop-optimizer'); ?></label>
                <select name="include_brand_ids[]" multiple class="aieo-dmm-brand-select" style="width:100%;"></select>
                <span class="description"><?php esc_html_e('Search and pick brands. Products must belong to at least one of these brands to be included.', 'ai-eshop-optimizer'); ?></span>
            </p>
            <p class="aieo-feed-rule-full">
                <label><?php esc_html_e('Exclude auto-restocked products', 'ai-eshop-optimizer'); ?></label>
                <label style="font-weight:normal;display:flex;align-items:center;gap:8px;">
                    <input type="checkbox" name="exclude_auto_restocked" value="1" style="margin:0;flex:0 0 auto;">
                    <span><?php esc_html_e('Leave out products that Stock Recovery put back in stock AUTOMATICALLY. Until you trust that auto-restocked availability, this keeps them off this marketplace feed (they re-appear automatically once they are no longer in the auto-restocked state).', 'ai-eshop-optimizer'); ?></span>
                </label>
            </p>
        </div>

        <!-- Field map -->
        <h3><?php esc_html_e('Field map', 'ai-eshop-optimizer'); ?></h3>
        <p class="description">
            <?php esc_html_e('Each row defines one output element (XML tag / CSV column). “Output name” is whatever the partner expects — e.g. “id”, “title”, “g:price”. “Source” is the DMM data field we copy into it. The defaults below cover what Skroutz / BestPrice / Shopflix / EMAG ask for; rename the output tag per partner.', 'ai-eshop-optimizer'); ?>
            <br>
            <strong><?php esc_html_e('Most marketplace feeds only need 8–12 of the rows below', 'ai-eshop-optimizer'); ?></strong>
            <?php esc_html_e('— set the source to “(none — skip)” for rows your partner does not want, or clear the output name. Either way the field is omitted from the file.', 'ai-eshop-optimizer'); ?>
        </p>
        <?php
        
        
        $aieo_feed_sources = array(
            
            'product_id'         => __('product_id',          'ai-eshop-optimizer'),
            'sku'                => __('sku',                 'ai-eshop-optimizer'),
            'mpn'                => __('mpn (manufacturer part)', 'ai-eshop-optimizer'),
            'ean'                => __('ean / gtin (barcode)',    'ai-eshop-optimizer'),
            
            'name'               => __('name',                'ai-eshop-optimizer'),
            'permalink'          => __('permalink (product URL)', 'ai-eshop-optimizer'),
            'image_url'          => __('image_url (main image)',  'ai-eshop-optimizer'),
            'image_gallery_urls' => __('image_gallery_urls (CSV)', 'ai-eshop-optimizer'),
            
            'category'           => __('category (full path A>B>C)', 'ai-eshop-optimizer'),
            'category_leaf'      => __('category_leaf (deepest only)', 'ai-eshop-optimizer'),
            'top_category'       => __('top_category (root only)', 'ai-eshop-optimizer'),
            'tags'               => __('tags (CSV)',          'ai-eshop-optimizer'),
            
            'brand'              => __('brand / manufacturer', 'ai-eshop-optimizer'),
            
            'price'              => __('price (DMM-adjusted)', 'ai-eshop-optimizer'),
            'regular_price'      => __('regular_price',       'ai-eshop-optimizer'),
            'sale_price'         => __('sale_price',          'ai-eshop-optimizer'),
            
            'stock'              => __('stock (quantity)',    'ai-eshop-optimizer'),
            'instock_yn'         => __('instock_yn (Y/N)',    'ai-eshop-optimizer'),
            'availability'       => __('availability (in stock / out of stock)', 'ai-eshop-optimizer'),
            'availability_text'  => __('availability_text (Greek SLA copy)', 'ai-eshop-optimizer'),
            'shipping_lead_time' => __('shipping_lead_time (days)', 'ai-eshop-optimizer'),
            
            'weight'             => __('weight (kg)',         'ai-eshop-optimizer'),
            'length'             => __('length',              'ai-eshop-optimizer'),
            'width'              => __('width',               'ai-eshop-optimizer'),
            'height'             => __('height',              'ai-eshop-optimizer'),
            'color'              => __('color',               'ai-eshop-optimizer'),
            'size'               => __('size',                'ai-eshop-optimizer'),
            
            'description'        => __('description (short, plain text)', 'ai-eshop-optimizer'),
            'description_long'   => __('description_long (full, plain text)', 'ai-eshop-optimizer'),
            'description_html'   => __('description_html (HTML preserved — Tolstoy etc.)', 'ai-eshop-optimizer'),
            
            'currency_code'      => __('currency_code (e.g. EUR)', 'ai-eshop-optimizer'),
            'currency_symbol'    => __('currency_symbol (e.g. €)', 'ai-eshop-optimizer'),
            
            'etsy_who_made'            => __('etsy: who_made', 'ai-eshop-optimizer'),
            'etsy_when_made'           => __('etsy: when_made', 'ai-eshop-optimizer'),
            'etsy_taxonomy_id'         => __('etsy: taxonomy_id', 'ai-eshop-optimizer'),
            'etsy_shipping_profile_id' => __('etsy: shipping_profile_id', 'ai-eshop-optimizer'),
            'etsy_is_supply'           => __('etsy: is_supply (false)', 'ai-eshop-optimizer'),
        );

        
        
        
        $aieo_feed_default_rows = array(
            array('output' => 'id',                  'source' => 'product_id'),
            array('output' => 'sku',                 'source' => 'sku'),
            array('output' => 'mpn',                 'source' => 'mpn'),
            array('output' => 'ean',                 'source' => 'ean'),
            array('output' => 'name',                'source' => 'name'),
            array('output' => 'link',                'source' => 'permalink'),
            array('output' => 'image',               'source' => 'image_url'),
            array('output' => 'image_gallery',       'source' => 'image_gallery_urls'),
            array('output' => 'category',            'source' => 'category'),
            array('output' => 'brand',               'source' => 'brand'),
            array('output' => 'price',               'source' => 'price'),
            array('output' => 'regular_price',       'source' => 'regular_price'),
            array('output' => 'sale_price',          'source' => 'sale_price'),
            array('output' => 'quantity',            'source' => 'stock'),
            array('output' => 'instock',             'source' => 'instock_yn'),
            array('output' => 'availability',        'source' => 'availability_text'),
            array('output' => 'shipping_lead_time',  'source' => 'shipping_lead_time'),
            array('output' => 'weight',              'source' => 'weight'),
            array('output' => 'color',               'source' => 'color'),
            array('output' => 'size',                'source' => 'size'),
            array('output' => 'description',         'source' => 'description'),
            array('output' => 'tags',                'source' => 'tags'),
        );
        ?>
        <table class="widefat aieo-table" id="aieo-dmm-feed-fields">
            <thead>
                <tr>
                    <th style="width:35%"><?php esc_html_e('Output name (tag / column)', 'ai-eshop-optimizer'); ?></th>
                    <th><?php esc_html_e('Source field', 'ai-eshop-optimizer'); ?></th>
                    <th style="width:60px;text-align:center">+</th>
                </tr>
            </thead>
            <tbody>
                <?php foreach ($aieo_feed_default_rows as $row) : ?>
                <tr>
                    <td><input type="text" name="field_map_output[]" value="<?php echo esc_attr($row['output']); ?>"></td>
                    <td>
                        <select name="field_map_source[]">
                            <option value=""><?php esc_html_e('(none — skip this row)', 'ai-eshop-optimizer'); ?></option>
                            <?php foreach ($aieo_feed_sources as $val => $label) : ?>
                                <option value="<?php echo esc_attr($val); ?>"<?php selected($row['source'], $val); ?>><?php echo esc_html($label); ?></option>
                            <?php endforeach; ?>
                        </select>
                    </td>
                    <td style="text-align:center"><button type="button" class="button aieo-dmm-feed-add-row">+</button></td>
                </tr>
                <?php endforeach; ?>
            </tbody>
        </table>

        <!-- CDN / cache busting -->
        <h3><?php esc_html_e('CDN &amp; caching', 'ai-eshop-optimizer'); ?></h3>
        <div class="aieo-dmm-card" style="background:#fff8e6; border-color:#e6d9a8;">
            <p class="description" style="margin:0;">
                <strong><?php esc_html_e('Important:', 'ai-eshop-optimizer'); ?></strong>
                <?php esc_html_e('Feed files are served from the WordPress uploads folder, which may sit behind a CDN (Cloudflare, Fastly, Bunny, WP Rocket, etc.). CDNs often cache files aggressively; without protection, partners could be reading a stale copy for hours or days after you regenerate. Pick a cache-busting strategy:', 'ai-eshop-optimizer'); ?>
            </p>
        </div>
        <p>
            <label><?php esc_html_e('Cache-busting strategy', 'ai-eshop-optimizer'); ?></label>
            <select name="cache_mode" style="width:100%;max-width:600px;">
                <option value="version_query" selected><?php esc_html_e('Version query string (?v=<etag>) — recommended', 'ai-eshop-optimizer'); ?></option>
                <option value="unique_filename"><?php esc_html_e('Unique filename per run (<slug>-<hash>.xml) — strongest, rewrites URL', 'ai-eshop-optimizer'); ?></option>
                <option value="none"><?php esc_html_e('None — use the raw URL, ask the partner/CDN to honour ETags', 'ai-eshop-optimizer'); ?></option>
            </select>
            <span class="description">
                <?php esc_html_e('Recommended: “Version query string”. It keeps a stable filename but appends a short hash derived from the file content, so any intermediate cache sees a new URL whenever the feed changes. Use “Unique filename” when the partner’s CDN strips query strings.', 'ai-eshop-optimizer'); ?>
            </span>
        </p>

        <p class="submit">
            <button type="submit" class="button button-primary" data-action="aieo_dmm_feed_save">
                <?php esc_html_e('Save feed', 'ai-eshop-optimizer'); ?>
            </button>
        </p>
    </form>
</div>

<?php include AIEO_DIR . 'assets/pages/dmm/_marketplace-feeds-table.php'; ?>

<script>
(function () {
    // Live preview of the file path / public URL as the operator types the slug / picks format.
    var $slug   = document.getElementById('aieo-dmm-feed-slug');
    var $format = document.getElementById('aieo-dmm-feed-format');
    var $path   = document.getElementById('aieo-dmm-feed-path-preview');
    var $url    = document.getElementById('aieo-dmm-feed-url-preview');
    if (!$slug || !$path || !$url || !$format) return;
    var baseDir = <?php echo wp_json_encode($feeds_dir); ?>;
    var baseUrl = <?php echo wp_json_encode($feeds_url); ?>;
    function update() {
        var s = ($slug.value || '').trim() || '<slug>';
        var ext = $format.value === 'csv' ? 'csv' : ($format.value === 'json' ? 'json' : 'xml');
        $path.textContent = baseDir + s + '.' + ext;
        $url.textContent  = baseUrl + s + '.' + ext;
    }
    $slug.addEventListener('input', update);
    $format.addEventListener('change', update);

    // Google Local — show/hide the location_code row based on template,
    // and auto-derive the slug from the location code so the file lands
    // at /uploads/exports/google-local-<code>.xml without the operator
    // having to type the prefix manually.
    var $tpl    = document.getElementById('aieo-dmm-feed-template');
    var $locRow = document.getElementById('aieo-dmm-feed-location-row');
    var $locInp = document.getElementById('aieo-dmm-feed-location-code');
    function syncLocationRow() {
        if (!$tpl || !$locRow) return;
        $locRow.style.display = $tpl.value === 'google_local' ? '' : 'none';
    }
    if ($tpl) { $tpl.addEventListener('change', syncLocationRow); syncLocationRow(); }
    if ($locInp && $slug) {
        $locInp.addEventListener('input', function () {
            if ($tpl && $tpl.value === 'google_local') {
                var code = ($locInp.value || '').trim();
                if (code !== '') { $slug.value = 'google-local-' + code; update(); }
            }
        });
    }

    // -------------------------------------------------------------------
    // Template dropdown: rebuild the field-map rows when the operator
    // picks Skroutz / Shopflix / EMAG / BestPrice / Google etc. so the
    // form reflects exactly what that marketplace expects (tag names,
    // case, source-field bindings). Leaves the rows alone when the user
    // selects "Fully custom".
    // -------------------------------------------------------------------
    var TEMPLATE_FIELD_MAPS = <?php
        $tpl_payload = array();
        foreach ($templates as $slug_key => $tpl) {
            $tpl_payload[$slug_key] = array(
                'format'    => $tpl['format'],
                'field_map' => $tpl['field_map'],
            );
        }
        echo wp_json_encode($tpl_payload);
    ?>;
    var $template = document.getElementById('aieo-dmm-feed-template');
    var $fieldsTable = document.getElementById('aieo-dmm-feed-fields');

    function fieldRowHTML(output, source) {
        var sourceSelect = $fieldsTable.querySelector('tbody select[name="field_map_source[]"]');
        var optionsHTML = sourceSelect ? sourceSelect.innerHTML : '';
        var tr = document.createElement('tr');
        tr.innerHTML =
            '<td><input type="text" name="field_map_output[]" value=""></td>' +
            '<td><select name="field_map_source[]">' + optionsHTML + '</select></td>' +
            '<td style="text-align:center"><button type="button" class="button aieo-dmm-feed-add-row">+</button></td>';
        tr.querySelector('input[name="field_map_output[]"]').value = output;
        var sel = tr.querySelector('select[name="field_map_source[]"]');
        if (sel) {
            sel.value = source;
            // If the source isn't in the existing options (e.g. partner-
            // specific source we haven't surfaced yet), add it on the fly.
            if (sel.value !== source && source) {
                var opt = document.createElement('option');
                opt.value = source; opt.text = source; opt.selected = true;
                sel.appendChild(opt);
            }
        }
        return tr;
    }

    function applyTemplate(slug, opts) {
        var tpl = TEMPLATE_FIELD_MAPS[slug];
        if (!tpl || !$fieldsTable) { return; }
        var tbody = $fieldsTable.querySelector('tbody');
        if (!tbody) { return; }

        var doApply = function () {
            // Rebuild rows from the template's field_map (preserves the
            // PHP-side ordering, which is what the partner expects in XML).
            tbody.innerHTML = '';
            Object.keys(tpl.field_map).forEach(function (output) {
                tbody.appendChild(fieldRowHTML(output, tpl.field_map[output]));
            });
            // Sync the format dropdown (Tolstoy is CSV; everything else XML).
            if ($format && tpl.format && $format.value !== tpl.format) {
                $format.value = tpl.format;
                update(); // refresh the path/URL preview
            }
        };

        // Confirm before clobbering customised rows. Use the in-page
        // modal instead of the native window.confirm() so the dialog
        // matches the rest of the admin styling.
        if (opts && opts.confirmIfDirty) {
            var hasTypedValues = Array.prototype.some.call(
                tbody.querySelectorAll('input[name="field_map_output[]"]'),
                function (i) { return i.value.trim() !== ''; }
            );
            if (hasTypedValues) {
                showConfirmModal({
                    title:  <?php echo wp_json_encode(__('Replace field-map rows?', 'ai-eshop-optimizer')); ?>,
                    body:   <?php echo wp_json_encode(__('Picking a template overwrites the current field-map rows with that marketplace\'s required tag names + source bindings. Your typed values will be lost.', 'ai-eshop-optimizer')); ?>,
                    okText: <?php echo wp_json_encode(__('Replace rows', 'ai-eshop-optimizer')); ?>,
                    onConfirm: doApply,
                    onCancel:  function () {
                        // Snap the dropdown back to its previous value so
                        // the visible selection matches the un-replaced rows.
                        if ($template && $template.dataset.lastValue) {
                            $template.value = $template.dataset.lastValue;
                        }
                    }
                });
                return;
            }
        }
        doApply();
    }

    if ($template) {
        // Track the last "applied" value so a Cancel can revert the
        // visible dropdown selection without re-firing the change event.
        $template.dataset.lastValue = $template.value;
        $template.addEventListener('change', function () {
            applyTemplate($template.value, { confirmIfDirty: true });
            $template.dataset.lastValue = $template.value;
        });
    }

    /* --------------------------------------------------------------- */
    /* In-page confirm modal — replaces window.confirm() so the dialog */
    /* picks up the AIEO admin look + can host longer copy.            */
    /* --------------------------------------------------------------- */
    function showConfirmModal(o) {
        // Tear down any previous instance (defensive — should never
        // collide because the trigger is a single dropdown change).
        var existing = document.getElementById('aieo-dmm-feed-modal');
        if (existing) { existing.remove(); }

        var wrap = document.createElement('div');
        wrap.id = 'aieo-dmm-feed-modal';
        wrap.setAttribute('role', 'dialog');
        wrap.setAttribute('aria-modal', 'true');
        wrap.style.cssText = 'position:fixed;inset:0;z-index:99999;background:rgba(15,23,42,0.55);display:flex;align-items:center;justify-content:center;padding:16px;';

        var card = document.createElement('div');
        card.style.cssText = 'background:#fff;border-radius:10px;box-shadow:0 24px 48px rgba(0,0,0,0.25);width:min(440px,100%);overflow:hidden;font-family:inherit;';
        card.innerHTML =
            '<div style="padding:18px 22px 6px;">' +
            '  <h3 style="margin:0 0 6px;font-size:16px;color:#111827;"></h3>' +
            '  <p style="margin:0;font-size:13px;color:#4b5563;line-height:1.5;"></p>' +
            '</div>' +
            '<div style="display:flex;justify-content:flex-end;gap:8px;padding:14px 22px 16px;background:#f9fafb;border-top:1px solid #e5e7eb;">' +
            '  <button type="button" class="button" data-aieo-modal="cancel"></button>' +
            '  <button type="button" class="button button-primary" data-aieo-modal="ok"></button>' +
            '</div>';
        card.querySelector('h3').textContent = o.title || '';
        card.querySelector('p').textContent  = o.body  || '';
        card.querySelector('[data-aieo-modal="cancel"]').textContent = <?php echo wp_json_encode(__('Cancel', 'ai-eshop-optimizer')); ?>;
        card.querySelector('[data-aieo-modal="ok"]').textContent = o.okText || <?php echo wp_json_encode(__('OK', 'ai-eshop-optimizer')); ?>;
        wrap.appendChild(card);

        var close = function (action) {
            wrap.remove();
            document.removeEventListener('keydown', onKey);
            if (action === 'ok' && typeof o.onConfirm === 'function') { o.onConfirm(); }
            if (action === 'cancel' && typeof o.onCancel === 'function') { o.onCancel(); }
        };
        var onKey = function (e) {
            if (e.key === 'Escape') { close('cancel'); }
            if (e.key === 'Enter')  { close('ok'); }
        };
        wrap.addEventListener('click', function (e) {
            if (e.target === wrap) { close('cancel'); }   // click outside
            var t = e.target.closest('[data-aieo-modal]');
            if (!t) { return; }
            close(t.getAttribute('data-aieo-modal'));
        });
        document.addEventListener('keydown', onKey);
        document.body.appendChild(wrap);
        // Focus the primary action so Enter confirms quickly.
        var okBtn = card.querySelector('[data-aieo-modal="ok"]');
        if (okBtn) { okBtn.focus(); }
    }

    // Swap the "Current feeds" table in-place when ajax_save / ajax_delete
    // returns a list_html payload. Keeps the dropdown selection + form
    // values intact instead of forcing a full page reload.
    function swapList(html) {
        if (!html) { return; }
        var existing = document.getElementById('aieo-dmm-feeds-list');
        if (!existing) { return; }
        var holder = document.createElement('div');
        holder.innerHTML = html;
        var fresh = holder.querySelector('#aieo-dmm-feeds-list');
        if (fresh) { existing.replaceWith(fresh); }
    }
    jQuery(document).on('aieo-dmm:saved', '#aieo-dmm-feed-form', function (_evt, data) {
        if (data && data.list_html) { swapList(data.list_html); }
    });
    // Delete button is delegated globally via dmm.js — listen for any
    // success that includes a list_html refresh. The action whitelist
    // keeps unrelated forms from triggering a swap.
    jQuery(document).on('ajaxSuccess', function (_e, _xhr, settings, resp) {
        if (!settings || typeof settings.data !== 'string') { return; }
        if (settings.data.indexOf('action=aieo_dmm_feed_delete') === -1) { return; }
        if (resp && resp.success && resp.data && resp.data.list_html) {
            swapList(resp.data.list_html);
        }
    });

    /* --------------------------------------------------------------- */
    /* Edit feed — fetch one feed's full config, populate the form     */
    /* above the table, scroll up. The form's hidden id input switches */
    /* ajax_save from INSERT to UPDATE when id > 0.                    */
    /* --------------------------------------------------------------- */
    var $form = document.getElementById('aieo-dmm-feed-form');

    function setVal(name, value) {
        if (!$form) { return; }
        var el = $form.querySelector('[name="' + name + '"]');
        if (!el) { return; }
        if (el.type === 'checkbox') {
            el.checked = !!value;
        } else {
            el.value = value == null ? '' : String(value);
        }
    }

    // Populate a Select2 multi-select (name="foo[]") with preselected
    // {id,text} pairs returned by ajax_get. Each pair becomes a selected
    // <option>; the change trigger makes Select2 render it as a chip. This is
    // what migrates an existing feed's saved product/brand selections into the
    // new searchable dropdowns when the operator opens it to edit.
    function setPickerPairs(name, pairs) {
        if (!$form) { return; }
        var el = $form.querySelector('[name="' + name + '[]"]');
        if (!el || typeof jQuery === 'undefined') { return; }
        var $sel = jQuery(el);
        $sel.empty();
        (pairs || []).forEach(function (p) {
            if (!p) { return; }
            var id = parseInt(p.id, 10);
            if (!id) { return; }
            $sel.append(new Option(p.text || ('#' + id), String(id), true, true));
        });
        $sel.trigger('change');
    }

    /* ================================================================= */
    /* Product / variation picker (modal browser).                       */
    /* The hidden <select multiple name="foo[]"> is the source of truth  */
    /* (serialized on save). Chips display it; the modal edits it. Each   */
    /* <option> carries data-type/data-status/data-parent so chips can be */
    /* styled (drafts + deleted grey, variations badged) and so a picked  */
    /* variation round-trips as its own id.                               */
    /* ================================================================= */
    // Build an admin-ajax URL, reading window.aieoDmm LAZILY at call time.
    // This inline script runs in the page BODY, but wp_localize_script outputs
    // window.aieoDmm in the FOOTER (after this runs) — so capturing the nonce
    // now would freeze it empty and every modal search would fail the nonce
    // check (-1 → "No products found"). Read it fresh each request instead.
    function prodAjaxUrl(query) {
        var c     = window.aieoDmm || {};
        var ajax  = c.ajaxurl || window.ajaxurl || '/wp-admin/admin-ajax.php';
        var nonce = c.nonce || '';
        return ajax + '?' + query + '&nonce=' + encodeURIComponent(nonce);
    }
    var T = {
        deleted:   <?php echo wp_json_encode(__('deleted', 'ai-eshop-optimizer')); ?>,
        draft:     <?php echo wp_json_encode(__('draft', 'ai-eshop-optimizer')); ?>,
        variations:<?php echo wp_json_encode(__('variations', 'ai-eshop-optimizer')); ?>,
        searching: <?php echo wp_json_encode(__('Searching…', 'ai-eshop-optimizer')); ?>,
        none:      <?php echo wp_json_encode(__('No products found.', 'ai-eshop-optimizer')); ?>,
        failed:    <?php echo wp_json_encode(__('Search failed.', 'ai-eshop-optimizer')); ?>,
        loadingV:  <?php echo wp_json_encode(__('Loading variations…', 'ai-eshop-optimizer')); ?>,
        noV:       <?php echo wp_json_encode(__('No variations.', 'ai-eshop-optimizer')); ?>,
        failV:     <?php echo wp_json_encode(__('Failed to load variations.', 'ai-eshop-optimizer')); ?>,
        cancel:    <?php echo wp_json_encode(__('Cancel', 'ai-eshop-optimizer')); ?>,
        done:      <?php echo wp_json_encode(__('Done', 'ai-eshop-optimizer')); ?>,
        ph:        <?php echo wp_json_encode(__('Search products by name or SKU…', 'ai-eshop-optimizer')); ?>,
        browse:    <?php echo wp_json_encode(__('Type to search, or browse below…', 'ai-eshop-optimizer')); ?>,
        selOne:    <?php echo wp_json_encode(__('item selected', 'ai-eshop-optimizer')); ?>,
        selMany:   <?php echo wp_json_encode(__('items selected', 'ai-eshop-optimizer')); ?>,
        titleInc:  <?php echo wp_json_encode(__('Choose products to INCLUDE', 'ai-eshop-optimizer')); ?>,
        titleExc:  <?php echo wp_json_encode(__('Choose products to EXCLUDE', 'ai-eshop-optimizer')); ?>,
        remove:    <?php echo wp_json_encode(__('Remove', 'ai-eshop-optimizer')); ?>
    };
    function pEsc(s) { return String(s == null ? '' : s).replace(/&/g,'&amp;').replace(/"/g,'&quot;').replace(/</g,'&lt;').replace(/>/g,'&gt;'); }
    function isGrey(st) { return st === 'draft' || st === 'private' || st === 'pending' || st === 'missing'; }

    (function injectProdCss() {
        if (document.getElementById('aieo-feed-prod-css')) { return; }
        var css =
        // Rule fields: stable 2-column layout (the shared auto-fit grid blows
        // into 4-5 columns on wide screens, which breaks once a field holds a
        // tall chip list). Products + brands pair up by row; collapses to 1 col
        // on narrow screens.
        '.aieo-feed-rules{grid-template-columns:repeat(2,minmax(0,1fr)) !important;}' +
        '.aieo-feed-rules>p,.aieo-feed-rules>.aieo-feed-rule{min-width:0;}' +
        // The product fields use a <div> wrapper (a <div> is illegal inside <p>
        // and would auto-close it, splitting the field across grid cells). Give
        // that <div> the same vertical-stack rhythm as the sibling <p> fields.
        '.aieo-feed-rule{display:flex;flex-direction:column;gap:4px;margin:0 0 6px;}' +
        '.aieo-feed-rule>label{margin-bottom:0;font-weight:600;}' +
        // Auto-restocked toggle spans the full row (both columns).
        '.aieo-feed-rules>.aieo-feed-rule-full{grid-column:1 / -1;}' +
        '@media (max-width:782px){.aieo-feed-rules{grid-template-columns:minmax(0,1fr) !important;}}' +
        '.aieo-feed-chips{display:flex;flex-wrap:wrap;gap:6px;margin:0 0 8px;max-height:230px;overflow:auto;align-content:flex-start;}' +
        '.aieo-feed-chips .aieo-chip{display:inline-flex;align-items:center;gap:6px;background:#e7156b;color:#fff;border-radius:14px;padding:3px 10px;font-size:12px;line-height:1.5;max-width:100%;}' +
        '.aieo-feed-chips .aieo-chip.is-grey{background:#dcdcde;color:#50575e;}' +
        '.aieo-feed-chips .aieo-chip.is-var{background:#2271b1;}' +
        '.aieo-feed-chips .aieo-chip.is-var.is-grey{background:#c7d2da;color:#3c434a;}' +
        '.aieo-feed-chips .aieo-chip-x{cursor:pointer;font-weight:700;opacity:.85;}' +
        '.aieo-feed-chips .aieo-chip-x:hover{opacity:1;}' +
        '.aieo-feed-chips .aieo-chip-t{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:340px;}' +
        '.aieo-feed-empty{color:#787c82;font-size:12px;font-style:italic;}' +
        '.aieo-pm-overlay{position:fixed;inset:0;z-index:100000;background:rgba(15,23,42,.55);display:flex;align-items:center;justify-content:center;padding:16px;}' +
        // Fixed height so the modal never resizes as result counts change —
        // only the inner .aieo-pm-results list scrolls (flex:1 fills the rest).
        '.aieo-pm-card{background:#fff;border-radius:10px;box-shadow:0 24px 48px rgba(0,0,0,.25);width:min(660px,100%);height:min(86vh,760px);display:flex;flex-direction:column;overflow:hidden;}' +
        '.aieo-pm-head{display:flex;align-items:center;justify-content:space-between;padding:14px 18px;border-bottom:1px solid #e5e7eb;}' +
        '.aieo-pm-head h3{margin:0;font-size:15px;}' +
        '.aieo-pm-close{cursor:pointer;border:0;background:none;font-size:22px;line-height:1;color:#6b7280;}' +
        '.aieo-pm-search{padding:10px 18px;border-bottom:1px solid #f0f0f1;}' +
        '.aieo-pm-search input{width:100%;}' +
        '.aieo-pm-results{overflow:auto;padding:4px 8px;flex:1;min-height:180px;}' +
        '.aieo-pm-row{border-bottom:1px solid #f3f4f5;}' +
        '.aieo-pm-line{display:flex;align-items:center;gap:8px;padding:7px 4px;}' +
        '.aieo-pm-line label{display:flex;align-items:center;gap:8px;margin:0;flex:1;cursor:pointer;}' +
        '.aieo-pm-row.is-grey>.aieo-pm-line label>span:first-of-type{color:#787c82;}' +
        '.aieo-pm-caret{cursor:pointer;width:18px;text-align:center;color:#2271b1;user-select:none;font-size:11px;}' +
        '.aieo-pm-caret.is-spacer{visibility:hidden;cursor:default;}' +
        '.aieo-pm-badge{font-size:10px;text-transform:uppercase;letter-spacing:.03em;border-radius:8px;padding:1px 6px;background:#eef1f4;color:#50575e;white-space:nowrap;}' +
        '.aieo-pm-badge.var{background:#dbeafe;color:#1e40af;}' +
        '.aieo-pm-badge.draft{background:#fef3c7;color:#92400e;}' +
        '.aieo-pm-vars{padding:0 8px 8px 36px;}' +
        '.aieo-pm-vrow{display:flex;align-items:center;gap:8px;padding:5px 4px;}' +
        '.aieo-pm-vrow label{display:flex;align-items:center;gap:8px;margin:0;cursor:pointer;}' +
        '.aieo-pm-foot{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:12px 18px;border-top:1px solid #e5e7eb;background:#f9fafb;}' +
        '.aieo-pm-count{font-size:12px;color:#50575e;}' +
        '.aieo-pm-muted{color:#787c82;font-size:12px;padding:16px 10px;}';
        var st = document.createElement('style');
        st.id = 'aieo-feed-prod-css';
        st.textContent = css;
        document.head.appendChild(st);
    })();

    function pStoreEl(wrap) { return wrap.querySelector('select.aieo-feed-prodpick-store'); }
    function pChipsEl(wrap) { return wrap.querySelector('.aieo-feed-chips'); }

    function pStoreItems(wrap) {
        var sel = pStoreEl(wrap), out = [];
        if (!sel) { return out; }
        Array.prototype.forEach.call(sel.options, function (o) {
            var id = parseInt(o.value, 10);
            if (!id) { return; }
            out.push({
                id: id,
                text: o.getAttribute('data-text') || o.textContent || ('#' + id),
                type: o.getAttribute('data-type') || 'simple',
                status: o.getAttribute('data-status') || 'publish',
                parent_id: parseInt(o.getAttribute('data-parent') || '0', 10) || 0
            });
        });
        return out;
    }
    function pStoreSet(wrap, items) {
        var sel = pStoreEl(wrap);
        if (!sel) { return; }
        sel.innerHTML = '';
        (items || []).forEach(function (it) {
            var id = parseInt(it.id, 10);
            if (!id) { return; }
            var o = document.createElement('option');
            o.value = String(id);
            o.selected = true;
            o.textContent = it.text || ('#' + id);
            o.setAttribute('data-text', it.text || ('#' + id));
            o.setAttribute('data-type', it.type || 'simple');
            o.setAttribute('data-status', it.status || 'publish');
            if (it.parent_id) { o.setAttribute('data-parent', String(it.parent_id)); }
            sel.appendChild(o);
        });
        pRenderChips(wrap);
    }
    function pRenderChips(wrap) {
        var box = pChipsEl(wrap);
        if (!box) { return; }
        var items = pStoreItems(wrap);
        box.innerHTML = '';
        if (!items.length) {
            box.innerHTML = '<span class="aieo-feed-empty">' + pEsc(box.getAttribute('data-empty') || '') + '</span>';
            return;
        }
        items.sort(function (a, b) { return a.id - b.id; });
        items.forEach(function (it) {
            var grey = isGrey(it.status);
            var suffix = (it.status === 'missing') ? (' (' + T.deleted + ')')
                       : (it.status === 'draft') ? (' · ' + T.draft) : '';
            var chip = document.createElement('span');
            chip.className = 'aieo-chip' + (it.type === 'variation' ? ' is-var' : '') + (grey ? ' is-grey' : '');
            chip.innerHTML = '<span class="aieo-chip-t" title="' + pEsc(it.text + suffix) + '">' + pEsc(it.text + suffix) + '</span>' +
                             '<span class="aieo-chip-x" data-id="' + it.id + '" title="' + pEsc(T.remove) + '">×</span>';
            box.appendChild(chip);
        });
    }

    // ----- modal -----
    var pmEl = null;
    var pmState = { wrap: null, sel: {} };

    function pmBuild() {
        if (pmEl) { return pmEl; }
        var ov = document.createElement('div');
        ov.className = 'aieo-pm-overlay';
        ov.style.display = 'none';
        ov.innerHTML =
            '<div class="aieo-pm-card" role="dialog" aria-modal="true">' +
              '<div class="aieo-pm-head"><h3></h3><button type="button" class="aieo-pm-close" aria-label="Close">×</button></div>' +
              '<div class="aieo-pm-search"><input type="search" class="aieo-pm-q"></div>' +
              '<div class="aieo-pm-results"></div>' +
              '<div class="aieo-pm-foot"><span class="aieo-pm-count"></span><span><button type="button" class="button aieo-pm-cancel"></button> <button type="button" class="button button-primary aieo-pm-done"></button></span></div>' +
            '</div>';
        document.body.appendChild(ov);
        pmEl = ov;
        ov.querySelector('.aieo-pm-close').addEventListener('click', pmClose);
        ov.querySelector('.aieo-pm-cancel').addEventListener('click', pmClose);
        ov.addEventListener('click', function (e) { if (e.target === ov) { pmClose(); } });
        ov.querySelector('.aieo-pm-done').addEventListener('click', pmCommit);
        var q = ov.querySelector('.aieo-pm-q');
        var t;
        q.addEventListener('input', function () { clearTimeout(t); t = setTimeout(function () { pmSearch(q.value); }, 250); });
        var res = ov.querySelector('.aieo-pm-results');
        res.addEventListener('click', pmOnClick);
        res.addEventListener('change', pmOnChange);
        ov.querySelector('.aieo-pm-cancel').textContent = T.cancel;
        ov.querySelector('.aieo-pm-done').textContent = T.done;
        q.setAttribute('placeholder', T.ph);
        return ov;
    }
    function pmOpen(wrap) {
        pmBuild();
        pmState.wrap = wrap;
        pmState.sel = {};
        pStoreItems(wrap).forEach(function (it) { pmState.sel[it.id] = it; });
        var isExc = wrap.getAttribute('data-field') === 'exclude_ids';
        pmEl.querySelector('.aieo-pm-head h3').textContent = isExc ? T.titleExc : T.titleInc;
        pmEl.querySelector('.aieo-pm-q').value = '';
        pmCount();
        pmEl.style.display = 'flex';
        document.addEventListener('keydown', pmKey);
        pmSearch('');
        setTimeout(function () { pmEl.querySelector('.aieo-pm-q').focus(); }, 30);
    }
    function pmClose() { if (pmEl) { pmEl.style.display = 'none'; document.removeEventListener('keydown', pmKey); } }
    function pmKey(e) { if (e.key === 'Escape') { pmClose(); } }
    function pmCommit() {
        if (pmState.wrap) {
            var items = Object.keys(pmState.sel).map(function (k) { return pmState.sel[k]; });
            pStoreSet(pmState.wrap, items);
        }
        pmClose();
    }
    function pmCount() {
        var n = Object.keys(pmState.sel).length;
        pmEl.querySelector('.aieo-pm-count').textContent = n + ' ' + (n === 1 ? T.selOne : T.selMany);
    }
    function pmSearch(q) {
        var box = pmEl.querySelector('.aieo-pm-results');
        box.innerHTML = '<div class="aieo-pm-muted">' + T.searching + '</div>';
        var url = prodAjaxUrl('action=aieo_dmm_feed_search_products&q=' + encodeURIComponent(q || ''));
        fetch(url, { credentials: 'same-origin' }).then(function (r) { return r.json(); }).then(function (j) {
            var rows = (j && j.results) ? j.results : [];
            box.innerHTML = '';
            if (!rows.length) { box.innerHTML = '<div class="aieo-pm-muted">' + T.none + '</div>'; return; }
            rows.forEach(function (r) { box.appendChild(pmRow(r)); });
        }).catch(function () { box.innerHTML = '<div class="aieo-pm-muted">' + T.failed + '</div>'; });
    }
    function pmRow(r) {
        var grey = isGrey(r.status);
        var row = document.createElement('div');
        row.className = 'aieo-pm-row' + (grey ? ' is-grey' : '');
        row.setAttribute('data-id', r.id);
        row.setAttribute('data-type', r.type);
        row.setAttribute('data-status', r.status);
        row.setAttribute('data-text', r.text);
        row.setAttribute('data-name', r.name || r.text);
        var caret = (r.type === 'variable' && r.n_variations > 0)
            ? '<span class="aieo-pm-caret" data-act="expand">&#9654;</span>'
            : '<span class="aieo-pm-caret is-spacer">&middot;</span>';
        var badge = '';
        if (r.type === 'variable') { badge += '<span class="aieo-pm-badge var">' + parseInt(r.n_variations, 10) + ' ' + T.variations + '</span>'; }
        if (r.status === 'draft') { badge += '<span class="aieo-pm-badge draft">' + T.draft + '</span>'; }
        row.innerHTML =
            '<div class="aieo-pm-line">' + caret +
              '<label><input type="checkbox" class="aieo-pm-cb"><span>' + pEsc(r.text) + '</span>' + badge + '</label>' +
            '</div><div class="aieo-pm-vars" hidden></div>';
        row.querySelector('.aieo-pm-cb').checked = !!pmState.sel[r.id];
        return row;
    }
    function pmOnClick(e) {
        var caret = e.target.closest('.aieo-pm-caret[data-act="expand"]');
        if (!caret) { return; }
        var row = caret.closest('.aieo-pm-row');
        var box = row.querySelector('.aieo-pm-vars');
        if (!box.hasAttribute('hidden')) { box.setAttribute('hidden', ''); caret.innerHTML = '&#9654;'; return; }
        caret.innerHTML = '&#9660;';
        box.removeAttribute('hidden');
        if (box.getAttribute('data-loaded')) { return; }
        box.innerHTML = '<div class="aieo-pm-muted">' + T.loadingV + '</div>';
        var pid = row.getAttribute('data-id');
        // Prefer the clean parent name from the search endpoint; fall back to
        // stripping a trailing [SKU] only if data-name is absent.
        var pName = row.getAttribute('data-name') || (row.getAttribute('data-text') || '').replace(/\s*\[[^\]]*\]\s*$/, '');
        var pStatus = row.getAttribute('data-status');
        var url = prodAjaxUrl('action=aieo_dmm_feed_get_variations&parent_id=' + encodeURIComponent(pid));
        fetch(url, { credentials: 'same-origin' }).then(function (r) { return r.json(); }).then(function (j) {
            var vs = (j && j.results) ? j.results : [];
            box.setAttribute('data-loaded', '1');
            box.innerHTML = '';
            if (!vs.length) { box.innerHTML = '<div class="aieo-pm-muted">' + T.noV + '</div>'; return; }
            vs.forEach(function (v) {
                var vrow = document.createElement('div');
                vrow.className = 'aieo-pm-vrow';
                vrow.setAttribute('data-id', v.id);
                vrow.setAttribute('data-text', pName + ' — ' + v.text);
                vrow.setAttribute('data-parent', pid);
                vrow.setAttribute('data-status', pStatus);
                vrow.innerHTML = '<label><input type="checkbox" class="aieo-pm-vcb"><span>' + pEsc(v.text) + '</span></label>';
                vrow.querySelector('.aieo-pm-vcb').checked = !!pmState.sel[v.id];
                box.appendChild(vrow);
            });
        }).catch(function () { box.innerHTML = '<div class="aieo-pm-muted">' + T.failV + '</div>'; });
    }
    function pmOnChange(e) {
        var cb = e.target;
        if (cb.classList.contains('aieo-pm-cb')) {
            var row = cb.closest('.aieo-pm-row');
            var id = parseInt(row.getAttribute('data-id'), 10);
            if (cb.checked) { pmState.sel[id] = { id: id, text: row.getAttribute('data-text'), type: row.getAttribute('data-type'), status: row.getAttribute('data-status'), parent_id: 0 }; }
            else { delete pmState.sel[id]; }
            pmCount();
        } else if (cb.classList.contains('aieo-pm-vcb')) {
            var vrow = cb.closest('.aieo-pm-vrow');
            var vid = parseInt(vrow.getAttribute('data-id'), 10);
            if (cb.checked) { pmState.sel[vid] = { id: vid, text: vrow.getAttribute('data-text'), type: 'variation', status: vrow.getAttribute('data-status'), parent_id: parseInt(vrow.getAttribute('data-parent'), 10) || 0 }; }
            else { delete pmState.sel[vid]; }
            pmCount();
        }
    }

    // Called by populateForm to migrate an existing feed's stored ids into chips.
    function setProductStore(fieldKey, pairs) {
        var wrap = $form ? $form.querySelector('.aieo-feed-prodpick[data-field="' + fieldKey + '"]') : null;
        if (!wrap) { return; }
        pStoreSet(wrap, (pairs || []).map(function (p) {
            return { id: parseInt(p.id, 10), text: p.text, type: p.type || 'simple', status: p.status || 'publish', parent_id: parseInt(p.parent_id || 0, 10) || 0 };
        }).filter(function (p) { return p.id; }));
    }

    (function initProdPickers() {
        var wraps = document.querySelectorAll('.aieo-feed-prodpick');
        Array.prototype.forEach.call(wraps, function (wrap) {
            pRenderChips(wrap);
            var openBtn = wrap.querySelector('.aieo-feed-prodpick-open');
            if (openBtn) { openBtn.addEventListener('click', function () { pmOpen(wrap); }); }
            var chips = pChipsEl(wrap);
            if (chips) {
                chips.addEventListener('click', function (e) {
                    var x = e.target.closest('.aieo-chip-x');
                    if (!x) { return; }
                    var id = parseInt(x.getAttribute('data-id'), 10);
                    pStoreSet(wrap, pStoreItems(wrap).filter(function (it) { return it.id !== id; }));
                });
            }
        });
    })();

    function rebuildFieldMap(map) {
        if (!$fieldsTable) { return; }
        var tbody = $fieldsTable.querySelector('tbody');
        if (!tbody) { return; }
        tbody.innerHTML = '';
        Object.keys(map || {}).forEach(function (output) {
            tbody.appendChild(fieldRowHTML(output, map[output]));
        });
    }

    function populateForm(feed) {
        setVal('id',         feed.id);
        setVal('slug',       feed.slug);
        setVal('label',      feed.label);
        setVal('format',     feed.format);
        setVal('template',   feed.template || '');
        setVal('schedule',   feed.schedule);
        setVal('cache_mode', feed.cache_mode);
        setVal('enabled',    parseInt(feed.enabled, 10) === 1);
        setVal('exclude_auto_restocked', parseInt(feed.exclude_auto_restocked, 10) === 1);

        setProductStore('include_ids',      feed.include_products);
        setProductStore('exclude_ids',      feed.exclude_products);
        setPickerPairs('include_brand_ids', feed.include_brands);
        setPickerPairs('exclude_brand_ids', feed.exclude_brands);
        setVal('include_category_ids', (feed.include_category_ids || []).join(', '));
        setVal('exclude_category_ids', (feed.exclude_category_ids || []).join(', '));
        setVal('location_code',        feed.location_code || '');

        rebuildFieldMap(feed.field_map);

        // Sync the Google-Local location-code row visibility now that
        // the template + location_code values are populated.
        if (typeof syncLocationRow === 'function') { syncLocationRow(); }

        if (typeof update === 'function') { update(); }

        var $submit = $form.querySelector('[data-action="aieo_dmm_feed_save"]');
        if ($submit) { $submit.textContent = <?php echo wp_json_encode(__('Update feed', 'ai-eshop-optimizer')); ?>; }

        $form.scrollIntoView({ behavior: 'smooth', block: 'start' });
    }

    function loadFeedIntoForm(id) {
        var cfg = window.aieoDmm || {};
        var ajaxurl = cfg.ajaxurl || window.ajaxurl || '/wp-admin/admin-ajax.php';
        var nonce   = cfg.nonce   || '';
        var url = ajaxurl
            + '?action=aieo_dmm_feed_get&id=' + encodeURIComponent(id)
            + '&nonce=' + encodeURIComponent(nonce);
        fetch(url, { credentials: 'same-origin' })
            .then(function (r) { return r.json(); })
            .then(function (j) {
                if (j && j.success && j.data && j.data.feed) {
                    populateForm(j.data.feed);
                }
            })
            .catch(function () { /* noop — keep current form state on failure */ });
    }

    document.addEventListener('click', function (e) {
        var btn = e.target && e.target.closest && e.target.closest('.aieo-dmm-feed-edit');
        if (!btn) { return; }
        e.preventDefault();
        var id = parseInt(btn.getAttribute('data-id'), 10);
        if (id > 0) { loadFeedIntoForm(id); }
    });
})();
</script>
