<?php

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

class AIEO_DMM_Local_Pickup extends AIEO_DMM_Module_Base {

    const OPTION_KEY = 'aieo_dmm_local_pickup';

    
    
    

    public function get_id()       { return 'local_pickup'; }
    public function get_label()    { return __('Local Pickup', 'ai-eshop-optimizer'); }
    public function get_priority() { return 78; } 
    public function get_group()    { return 'checkout_handling'; }

    public function register_hooks() {
        add_action('wp_ajax_aieo_dmm_local_pickup_save',            array($this, 'ajax_save'));
        add_action('wp_ajax_aieo_dmm_local_pickup_import_legacy',   array($this, 'ajax_import_legacy'));
        add_action('wp_ajax_aieo_dmm_local_pickup_legacy_map_save', array($this, 'ajax_save_legacy_map'));
        add_action('wp_ajax_aieo_dmm_local_pickup_apply_orders',    array($this, 'ajax_apply_orders'));
        add_action('wp_ajax_aieo_dmm_local_pickup_rename',          array($this, 'ajax_rename'));
    }

    
    public static function known_pickup_names() {
        global $wpdb;
        $hpos  = class_exists('Automattic\\WooCommerce\\Utilities\\OrderUtil') && \Automattic\WooCommerce\Utilities\OrderUtil::custom_orders_table_usage_is_enabled();
        $table = $hpos ? $wpdb->prefix . 'wc_orders_meta' : $wpdb->postmeta;
        
        $vals  = $wpdb->get_col($wpdb->prepare("SELECT DISTINCT meta_value FROM {$table} WHERE meta_key = %s AND meta_value <> ''", '_aieo_pickup_location'));
        $names = array();
        foreach ((array) $vals as $v) { $v = (string) $v; if ($v !== '') { $names[$v] = true; } }
        foreach (self::blocks_locations() as $bl) { if (!empty($bl['name'])) { $names[(string) $bl['name']] = true; } }
        return array_keys($names);
    }

    
    
    

    public static function get_settings() {
        $stored = get_option(self::OPTION_KEY, array());
        if (!is_array($stored)) { $stored = array(); }
        return array_merge(array(
            'mode'              => 'legacy', 
            'title'             => 'Παραλαβή από κατάστημα',
            'blocked_countries' => array(), 
        ), $stored);
    }

    
    public static function mode() {
        $s = self::get_settings();
        return ($s['mode'] === 'blocks') ? 'blocks' : 'legacy';
    }

    
    public static function blocked_countries() {
        $s  = self::get_settings();
        $bc = (isset($s['blocked_countries']) && is_array($s['blocked_countries'])) ? $s['blocked_countries'] : array();
        return array_values(array_unique(array_map('strtoupper', array_map('strval', $bc))));
    }

    
    public static function shipping_countries() {
        if (!function_exists('WC') || !WC()->countries) { return array(); }
        $c = WC()->countries->get_shipping_countries();
        return is_array($c) ? $c : array();
    }

    
    
    

    
    public static function legacy_pickup_names() {
        $names = array();
        if (!class_exists('WC_Shipping_Zones')) { return $names; }
        $zones = WC_Shipping_Zones::get_zones();
        $rest  = WC_Shipping_Zones::get_zone(0);
        if ($rest) { $zones[] = array('shipping_methods' => $rest->get_shipping_methods(false)); }
        foreach ($zones as $z) {
            foreach ((isset($z['shipping_methods']) ? $z['shipping_methods'] : array()) as $m) {
                if (!is_object($m) || $m->id !== 'local_pickup') { continue; }
                if (method_exists($m, 'is_enabled') && !$m->is_enabled()) { continue; }
                $title = method_exists($m, 'get_title') ? trim((string) $m->get_title()) : '';
                if ($title !== '' && !in_array($title, $names, true)) { $names[] = $title; }
            }
        }
        return $names;
    }

    
    public static function legacy_pickup_instances() {
        $out = array();
        if (!class_exists('WC_Shipping_Zones')) { return $out; }
        $zones = WC_Shipping_Zones::get_zones();
        $rest  = WC_Shipping_Zones::get_zone(0);
        if ($rest) { $zones[] = array('zone_name' => __('Rest of world', 'ai-eshop-optimizer'), 'shipping_methods' => $rest->get_shipping_methods(false)); }
        foreach ($zones as $z) {
            $zname = isset($z['zone_name']) ? (string) $z['zone_name'] : '';
            foreach ((isset($z['shipping_methods']) ? $z['shipping_methods'] : array()) as $m) {
                if (!is_object($m) || $m->id !== 'local_pickup') { continue; }
                $iid = method_exists($m, 'get_instance_id') ? (int) $m->get_instance_id() : 0;
                if ($iid <= 0) { continue; }
                $title = method_exists($m, 'get_title') ? (string) $m->get_title() : '';
                $out[] = array(
                    'rate_id' => 'local_pickup:' . $iid,
                    'title'   => $title,
                    'label'   => trim(($zname !== '' ? $zname . ' — ' : '') . $title . ' (#' . $iid . ')'),
                );
            }
        }
        return $out;
    }

    
    public static function blocks_locations() {
        $raw = get_option('pickup_location_pickup_locations', array());
        if (!is_array($raw)) { return array(); }
        $out = array();
        foreach ($raw as $loc) {
            if (!is_array($loc)) { continue; }
            $addr = isset($loc['address']) && is_array($loc['address']) ? $loc['address'] : array();
            $out[] = array(
                'name'        => isset($loc['name']) ? (string) $loc['name'] : '',
                'enabled'     => !empty($loc['enabled']),
                'details'     => isset($loc['details']) ? (string) $loc['details'] : '',
                'review_slug' => isset($loc['review_slug']) ? (string) $loc['review_slug'] : '',
                'address' => array(
                    'address_1' => isset($addr['address_1']) ? (string) $addr['address_1'] : '',
                    'city'      => isset($addr['city']) ? (string) $addr['city'] : '',
                    'state'     => isset($addr['state']) ? (string) $addr['state'] : '',
                    'postcode'  => isset($addr['postcode']) ? (string) $addr['postcode'] : '',
                    'country'   => (isset($addr['country']) && $addr['country'] !== '') ? (string) $addr['country'] : 'GR',
                ),
            );
        }
        return $out;
    }

    private static function blocks_enabled() {
        if (class_exists('Automattic\\WooCommerce\\StoreApi\\Utilities\\LocalPickupUtils')) {
            return \Automattic\WooCommerce\StoreApi\Utilities\LocalPickupUtils::is_local_pickup_enabled();
        }
        $o = get_option('woocommerce_pickup_location_settings', array());
        return is_array($o) && isset($o['enabled']) && $o['enabled'] === 'yes';
    }

    
    private static function load_google_reviews() {
        foreach (array('class-aieo-google-reviews-locations.php', 'class-aieo-google-reviews-helpers.php') as $f) {
            $p = (defined('AIEO_DIR') ? AIEO_DIR : '') . 'includes/dmm/google-reviews/' . $f;
            if ($p !== '' && file_exists($p)) { require_once $p; }
        }
    }

    
    public static function review_locations() {
        self::load_google_reviews();
        $out = array();
        if (class_exists('AIEO_Google_Reviews_Locations')) {
            foreach (AIEO_Google_Reviews_Locations::list_all(true) as $r) {
                if (!is_array($r) || empty($r['slug'])) { continue; }
                $out[] = array('slug' => (string) $r['slug'], 'label' => (string) (isset($r['label']) && $r['label'] !== '' ? $r['label'] : $r['slug']));
            }
        }
        return $out;
    }

    
    
    

    public function render_subtab() {
        $s          = self::get_settings();
        $mode       = self::mode();
        $locations  = self::blocks_locations();
        $legacy     = self::legacy_pickup_names();
        $bp_enabled = self::blocks_enabled();
        $review_locs = self::review_locations();
        $nonce      = wp_create_nonce(AIEO_DMM::NONCE_ACTION);
        $ajax       = admin_url('admin-ajax.php');
        $boot       = wp_json_encode(array('mode' => $mode, 'title' => (string) $s['title'], 'locations' => $locations, 'reviewLocations' => $review_locs));
        if (!is_string($boot)) { $boot = '{"mode":"legacy","title":"","locations":[],"reviewLocations":[]}'; }
        ?>
        <div class="aieo-dmm-section">
            <h2><?php esc_html_e('Local Pickup', 'ai-eshop-optimizer'); ?></h2>
            <p class="description" style="max-width:820px;">
                <?php esc_html_e('Choose how store pickup is offered at checkout. Legacy uses core WooCommerce per-zone local_pickup (good for classic checkout). Blocks uses WooCommerce\'s modern Local Pickup with stores defined once, globally — recommended for block checkouts (roosterx) because it has no shipping-zone instance-mismatch bug.', 'ai-eshop-optimizer'); ?>
            </p>

            <div class="aieo-dmm-card" style="margin-top:8px;">
                <h3 style="margin-top:0;"><?php esc_html_e('Pickup architecture', 'ai-eshop-optimizer'); ?></h3>
                <table class="form-table">
                    <tr>
                        <th><?php esc_html_e('Mode', 'ai-eshop-optimizer'); ?></th>
                        <td>
                            <label style="display:block;margin:0 0 8px;">
                                <input type="radio" name="aieo_lp_mode" value="legacy" <?php checked($mode === 'legacy'); ?>>
                                <strong><?php esc_html_e('Legacy', 'ai-eshop-optimizer'); ?></strong>
                                — <?php esc_html_e('core per-zone local_pickup (classic + block, with the zone-flip safety patch). No change to today\'s setup.', 'ai-eshop-optimizer'); ?>
                            </label>
                            <label style="display:block;margin:0;">
                                <input type="radio" name="aieo_lp_mode" value="blocks" <?php checked($mode === 'blocks'); ?>>
                                <strong><?php esc_html_e('Blocks (recommended for block checkout)', 'ai-eshop-optimizer'); ?></strong>
                                — <?php esc_html_e('block checkout uses Blocks Local Pickup (stores below); classic checkout keeps legacy. Bug-free, zone-independent.', 'ai-eshop-optimizer'); ?>
                            </label>
                        </td>
                    </tr>
                    <tr>
                        <th><?php esc_html_e('Pickup label', 'ai-eshop-optimizer'); ?></th>
                        <td>
                            <input type="text" id="aieo-lp-title" value="<?php echo esc_attr((string) $s['title']); ?>" style="width:320px;">
                            <p class="description"><?php esc_html_e('Shown as the "Pickup" tab label in block checkout.', 'ai-eshop-optimizer'); ?></p>
                        </td>
                    </tr>
                </table>
            </div>

            <div id="aieo-lp-locations-card" class="aieo-dmm-card" style="margin-top:18px;">
                <h3 style="margin-top:0;"><?php esc_html_e('Pickup locations (Blocks)', 'ai-eshop-optimizer'); ?></h3>
                <p class="description"><?php esc_html_e('Stores customers can collect from when they choose Pickup in block checkout. Used by Blocks mode.', 'ai-eshop-optimizer'); ?></p>
                <p>
                    <button type="button" class="button" id="aieo-lp-add"><?php esc_html_e('+ Add location', 'ai-eshop-optimizer'); ?></button>
                    <button type="button" class="button" id="aieo-lp-import"><?php esc_html_e('Import from legacy pickups', 'ai-eshop-optimizer'); ?></button>
                    <span id="aieo-lp-import-status" style="margin-left:8px;color:#646970;font-size:12px;"></span>
                </p>
                <table class="widefat striped" id="aieo-lp-table">
                    <thead>
                        <tr>
                            <th style="width:30px;"></th>
                            <th><?php esc_html_e('Name', 'ai-eshop-optimizer'); ?></th>
                            <th><?php esc_html_e('Address', 'ai-eshop-optimizer'); ?></th>
                            <th style="width:90px;"><?php esc_html_e('City', 'ai-eshop-optimizer'); ?></th>
                            <th style="width:70px;"><?php esc_html_e('Postcode', 'ai-eshop-optimizer'); ?></th>
                            <th style="width:55px;"><?php esc_html_e('Country', 'ai-eshop-optimizer'); ?></th>
                            <th><?php esc_html_e('Details', 'ai-eshop-optimizer'); ?></th>
                            <th style="width:150px;"><?php esc_html_e('Google location', 'ai-eshop-optimizer'); ?></th>
                            <th style="width:40px;"></th>
                        </tr>
                    </thead>
                    <tbody id="aieo-lp-rows"></tbody>
                </table>
            </div>

            <?php
            $blocked_cc = self::blocked_countries();
            $ship_cc    = self::shipping_countries();
            ?>
            <div class="aieo-dmm-card" style="margin-top:18px;">
                <h3 style="margin-top:0;"><?php esc_html_e('Restrict pickup by country', 'ai-eshop-optimizer'); ?></h3>
                <p class="description" style="max-width:760px;">
                    <?php esc_html_e('Hide store pickup (both Blocks and legacy) when the customer\'s shipping country is ticked below. Use it to offer pickup for Greece only — e.g. tick Cyprus so Cypriot orders never see a pickup option. Applies to block AND classic checkout.', 'ai-eshop-optimizer'); ?>
                </p>
                <?php if (empty($ship_cc)) : ?>
                    <p class="description"><?php esc_html_e('No shipping countries are configured in WooCommerce → Settings → Shipping yet.', 'ai-eshop-optimizer'); ?></p>
                <?php else : ?>
                    <fieldset id="aieo-lp-cc" style="margin:0;padding:0;border:0;columns:220px 3;max-width:760px;">
                        <?php foreach ($ship_cc as $code => $name) : ?>
                            <label style="display:block;margin:0 0 6px;line-height:1.4;break-inside:avoid;">
                                <input type="checkbox" class="aieo-lp-cc-cb" value="<?php echo esc_attr($code); ?>"
                                       <?php checked(in_array(strtoupper($code), $blocked_cc, true)); ?>>
                                <?php echo esc_html($name . ' (' . $code . ')'); ?>
                            </label>
                        <?php endforeach; ?>
                    </fieldset>
                    <p class="description"><?php esc_html_e('Tick a country to HIDE pickup when the customer\'s shipping country matches. Saved with the Save button below.', 'ai-eshop-optimizer'); ?></p>
                <?php endif; ?>
            </div>

            <div class="aieo-dmm-card" style="margin-top:18px;">
                <h3 style="margin-top:0;"><?php esc_html_e('Status', 'ai-eshop-optimizer'); ?></h3>
                <p style="margin:4px 0;">
                    <?php
                    printf(
                        
                        esc_html__('Legacy local_pickup stores detected: %d', 'ai-eshop-optimizer'),
                        count($legacy)
                    );
                    if (!empty($legacy)) {
                        echo ' — ' . esc_html(implode(', ', $legacy));
                    }
                    ?>
                </p>
                <p style="margin:4px 0;">
                    <?php esc_html_e('Blocks Local Pickup currently:', 'ai-eshop-optimizer'); ?>
                    <strong><?php echo $bp_enabled ? esc_html__('ENABLED', 'ai-eshop-optimizer') : esc_html__('disabled', 'ai-eshop-optimizer'); ?></strong>
                </p>
                <p class="description" style="margin:4px 0;">
                    <?php esc_html_e('Classic checkout always uses legacy local_pickup, protected by the zone-flip equivalence patch. The cheque "Cash payment during pick-up" rule lives in the Free Shipping + COD tab; switching to Blocks mode auto-points it at "Any local pickup" so it keeps working in both checkouts.', 'ai-eshop-optimizer'); ?>
                </p>
            </div>

            <p style="margin-top:18px;">
                <button type="button" class="button button-primary" id="aieo-lp-save"><?php esc_html_e('Save', 'ai-eshop-optimizer'); ?></button>
                <span id="aieo-lp-status" style="margin-left:10px;color:#646970;font-size:13px;"></span>
            </p>

            <?php
            
            
            if (class_exists('AIEO_DMM_Payment_Gating')) {
                AIEO_DMM_Payment_Gating::render_card();
            }
            
            $this->render_legacy_migration();
            
            $this->render_rename();
            ?>
        </div>

        <script>
        (function(){
            var BOOT = <?php echo $boot; ?>;
            var AJAX = <?php echo wp_json_encode($ajax); ?>;
            var NONCE = <?php echo wp_json_encode($nonce); ?>;
            var rowsEl = document.getElementById('aieo-lp-rows');
            function esc(v){ return String(v == null ? '' : v).replace(/&/g,'&amp;').replace(/"/g,'&quot;').replace(/</g,'&lt;').replace(/>/g,'&gt;'); }
            function reviewOptions(sel){
                var html = '<option value="">— —</option>';
                (BOOT.reviewLocations || []).forEach(function(r){
                    html += '<option value="' + esc(r.slug) + '"' + (r.slug === sel ? ' selected' : '') + '>' + esc(r.label) + '</option>';
                });
                return html;
            }
            function addRow(loc){
                loc = loc || {};
                var a = (loc.address || {});
                var tr = document.createElement('tr');
                tr.innerHTML =
                    '<td style="text-align:center;"><input type="checkbox" class="lp-enabled" ' + (loc.enabled === false ? '' : 'checked') + '></td>' +
                    '<td><input type="text" class="lp-name" style="width:100%;" value="' + esc(loc.name) + '"></td>' +
                    '<td><input type="text" class="lp-address_1" style="width:100%;" value="' + esc(a.address_1) + '"></td>' +
                    '<td><input type="text" class="lp-city" style="width:100%;" value="' + esc(a.city) + '"></td>' +
                    '<td><input type="text" class="lp-postcode" style="width:100%;" value="' + esc(a.postcode) + '"></td>' +
                    '<td><input type="text" class="lp-country" style="width:100%;" value="' + esc(a.country || 'GR') + '"></td>' +
                    '<td><input type="text" class="lp-details" style="width:100%;" value="' + esc(loc.details) + '"><input type="hidden" class="lp-state" value="' + esc(a.state) + '"></td>' +
                    '<td><select class="lp-review" style="width:100%;">' + reviewOptions(loc.review_slug || '') + '</select></td>' +
                    '<td style="text-align:center;"><button type="button" class="button-link lp-remove" title="Remove" style="color:#b32d2e;">✕</button></td>';
                tr.querySelector('.lp-remove').addEventListener('click', function(){ tr.parentNode.removeChild(tr); });
                rowsEl.appendChild(tr);
            }
            function collect(){
                var out = [];
                Array.prototype.forEach.call(rowsEl.querySelectorAll('tr'), function(tr){
                    var name = tr.querySelector('.lp-name').value.trim();
                    if (!name) { return; }
                    out.push({
                        name: name,
                        enabled: tr.querySelector('.lp-enabled').checked,
                        details: tr.querySelector('.lp-details').value,
                        review_slug: tr.querySelector('.lp-review').value,
                        address: {
                            address_1: tr.querySelector('.lp-address_1').value,
                            city: tr.querySelector('.lp-city').value,
                            state: tr.querySelector('.lp-state').value,
                            postcode: tr.querySelector('.lp-postcode').value,
                            country: tr.querySelector('.lp-country').value.trim() || 'GR'
                        }
                    });
                });
                return out;
            }
            function currentMode(){
                var r = document.querySelector('input[name="aieo_lp_mode"]:checked');
                return r ? r.value : 'legacy';
            }
            function syncCardVisibility(){
                var card = document.getElementById('aieo-lp-locations-card');
                card.style.opacity = (currentMode() === 'blocks') ? '1' : '0.55';
            }
            // init rows
            (BOOT.locations || []).forEach(addRow);
            if (!(BOOT.locations || []).length) { addRow({address:{country:'GR'}}); }
            syncCardVisibility();
            Array.prototype.forEach.call(document.querySelectorAll('input[name="aieo_lp_mode"]'), function(r){ r.addEventListener('change', syncCardVisibility); });
            document.getElementById('aieo-lp-add').addEventListener('click', function(){ addRow({address:{country:'GR'}}); });

            document.getElementById('aieo-lp-import').addEventListener('click', function(){
                var st = document.getElementById('aieo-lp-import-status');
                st.textContent = '<?php echo esc_js(__('Importing…', 'ai-eshop-optimizer')); ?>';
                var fd = new FormData();
                fd.set('action','aieo_dmm_local_pickup_import_legacy');
                fd.set('nonce', NONCE);
                fetch(AJAX,{method:'POST',credentials:'same-origin',body:fd}).then(function(r){return r.json();}).then(function(j){
                    if (j && j.success && j.data && j.data.locations) {
                        j.data.locations.forEach(addRow);
                        st.textContent = '<?php echo esc_js(__('Imported.', 'ai-eshop-optimizer')); ?> (' + j.data.locations.length + ')';
                    } else {
                        st.textContent = '<?php echo esc_js(__('Nothing to import.', 'ai-eshop-optimizer')); ?>';
                    }
                }).catch(function(){ st.textContent = '<?php echo esc_js(__('Import failed.', 'ai-eshop-optimizer')); ?>'; });
            });

            document.getElementById('aieo-lp-save').addEventListener('click', function(){
                var st = document.getElementById('aieo-lp-status');
                st.style.color = '#646970';
                st.textContent = '<?php echo esc_js(__('Saving…', 'ai-eshop-optimizer')); ?>';
                var fd = new FormData();
                fd.set('action','aieo_dmm_local_pickup_save');
                fd.set('nonce', NONCE);
                fd.set('mode', currentMode());
                fd.set('title', document.getElementById('aieo-lp-title').value);
                fd.set('locations_json', JSON.stringify(collect()));
                fd.set('blocked_countries_json', JSON.stringify(
                    Array.prototype.map.call(document.querySelectorAll('.aieo-lp-cc-cb:checked'), function(c){ return c.value; })
                ));
                fetch(AJAX,{method:'POST',credentials:'same-origin',body:fd}).then(function(r){return r.json();}).then(function(j){
                    if (j && j.success) {
                        st.style.color = '#15803d';
                        st.textContent = (j.data && j.data.message) || '<?php echo esc_js(__('Saved.', 'ai-eshop-optimizer')); ?>';
                    } else {
                        st.style.color = '#b91c1c';
                        st.textContent = (j && j.data && j.data.message) || '<?php echo esc_js(__('Save failed.', 'ai-eshop-optimizer')); ?>';
                    }
                }).catch(function(){ st.style.color = '#b91c1c'; st.textContent = '<?php echo esc_js(__('Save failed.', 'ai-eshop-optimizer')); ?>'; });
            });
        })();
        </script>
        <?php
    }

    
    
    

    
    private function render_legacy_migration() {
        $instances = self::legacy_pickup_instances();
        if (empty($instances)) { return; } 
        $new_names = array();
        foreach (self::blocks_locations() as $bl) {
            if (!empty($bl['name'])) { $new_names[] = (string) $bl['name']; }
        }
        $map = get_option('aieo_pickup_legacy_map', array());
        if (!is_array($map)) { $map = array(); }
        $nonce = wp_create_nonce(AIEO_DMM::NONCE_ACTION);
        $ajax  = admin_url('admin-ajax.php');
        ?>
        <div class="aieo-dmm-card" style="margin-top:18px;">
            <h3 style="margin-top:0;"><?php esc_html_e('Migrate legacy pickup orders → new locations', 'ai-eshop-optimizer'); ?></h3>
            <p class="description" style="max-width:760px;">
                <?php esc_html_e('Map each legacy per-zone pickup method to a new pickup location. Old orders placed with the legacy pickup then resolve to the new location (for the Google Maps link in emails / order pages). Legacy stores were duplicated across two zones, so expect two rows per store — point both at the same new location.', 'ai-eshop-optimizer'); ?>
            </p>
            <table class="widefat striped">
                <thead><tr>
                    <th><?php esc_html_e('Legacy pickup (zone — store)', 'ai-eshop-optimizer'); ?></th>
                    <th style="width:300px;"><?php esc_html_e('New pickup location', 'ai-eshop-optimizer'); ?></th>
                </tr></thead>
                <tbody>
                <?php foreach ($instances as $inst) :
                    $sel = isset($map[$inst['rate_id']]) ? (string) $map[$inst['rate_id']] : ''; ?>
                    <tr>
                        <td><?php echo esc_html($inst['label']); ?></td>
                        <td>
                            <select class="aieo-lpm-sel" data-rateid="<?php echo esc_attr($inst['rate_id']); ?>" style="width:100%;">
                                <option value="">— —</option>
                                <?php foreach ($new_names as $nn) : ?>
                                    <option value="<?php echo esc_attr($nn); ?>" <?php selected($sel, $nn); ?>><?php echo esc_html($nn); ?></option>
                                <?php endforeach; ?>
                            </select>
                        </td>
                    </tr>
                <?php endforeach; ?>
                </tbody>
            </table>
            <p>
                <button type="button" class="button button-primary" id="aieo-lpm-save"><?php esc_html_e('Save migration map', 'ai-eshop-optimizer'); ?></button>
                <span id="aieo-lpm-status" style="margin-left:10px;color:#646970;font-size:13px;"></span>
            </p>
            <p style="margin-top:6px;">
                <button type="button" class="button" id="aieo-lpm-apply"><?php esc_html_e('Apply map to existing orders', 'ai-eshop-optimizer'); ?></button>
                <span id="aieo-lpm-apply-status" style="margin-left:10px;color:#646970;font-size:13px;"></span>
                <span class="description" style="display:block;margin-top:4px;max-width:760px;"><?php esc_html_e('One-time: rewrites past legacy-pickup orders to the new location (shipping line + meta) and stamps the order field _aieo_pickup_location used for statistics. Save the map first. This edits historical orders.', 'ai-eshop-optimizer'); ?></span>
            </p>
            <script>
            (function(){
                var b=document.getElementById('aieo-lpm-save');
                var st=document.getElementById('aieo-lpm-status');
                if(!b)return;
                var ab=document.getElementById('aieo-lpm-apply');
                var ast=document.getElementById('aieo-lpm-apply-status');
                if(ab){ ab.addEventListener('click',function(){
                    if(!confirm('<?php echo esc_js(__('Rewrite past pickup orders to the new locations? This edits historical orders.', 'ai-eshop-optimizer')); ?>'))return;
                    ab.disabled=true; var totalUpd=0, totalProc=0;
                    function run(offset){
                        ast.style.color='#646970'; ast.textContent='<?php echo esc_js(__('Processing… scanned', 'ai-eshop-optimizer')); ?> '+totalProc;
                        var fd=new FormData();
                        fd.set('action','aieo_dmm_local_pickup_apply_orders');
                        fd.set('nonce','<?php echo esc_js($nonce); ?>');
                        fd.set('offset', offset);
                        fetch('<?php echo esc_js($ajax); ?>',{method:'POST',credentials:'same-origin',body:fd}).then(function(r){return r.json();}).then(function(j){
                            if(!(j&&j.success)){ ast.style.color='#b91c1c'; ast.textContent=(j&&j.data&&j.data.message)||'<?php echo esc_js(__('Failed.', 'ai-eshop-optimizer')); ?>'; ab.disabled=false; return; }
                            totalUpd+=j.data.updated; totalProc+=j.data.processed;
                            if(j.data.done){ ast.style.color='#15803d'; ast.textContent='<?php echo esc_js(__('Done. Orders updated:', 'ai-eshop-optimizer')); ?> '+totalUpd+' ('+totalProc+' <?php echo esc_js(__('scanned', 'ai-eshop-optimizer')); ?>)'; ab.disabled=false; }
                            else { run(j.data.next); }
                        }).catch(function(){ ast.style.color='#b91c1c'; ast.textContent='<?php echo esc_js(__('Failed.', 'ai-eshop-optimizer')); ?>'; ab.disabled=false; });
                    }
                    run(0);
                }); }
                b.addEventListener('click',function(){
                    var map={};
                    Array.prototype.forEach.call(document.querySelectorAll('.aieo-lpm-sel'),function(s){
                        var v=s.value; if(v){ map[s.getAttribute('data-rateid')]=v; }
                    });
                    var fd=new FormData();
                    fd.set('action','aieo_dmm_local_pickup_legacy_map_save');
                    fd.set('nonce','<?php echo esc_js($nonce); ?>');
                    fd.set('map_json', JSON.stringify(map));
                    st.style.color='#646970';st.textContent='<?php echo esc_js(__('Saving…', 'ai-eshop-optimizer')); ?>';
                    fetch('<?php echo esc_js($ajax); ?>',{method:'POST',credentials:'same-origin',body:fd}).then(function(r){return r.json();}).then(function(j){
                        if(j&&j.success){st.style.color='#15803d';st.textContent=(j.data&&j.data.message)||'<?php echo esc_js(__('Saved.', 'ai-eshop-optimizer')); ?>';}
                        else{st.style.color='#b91c1c';st.textContent=(j&&j.data&&j.data.message)||'<?php echo esc_js(__('Save failed.', 'ai-eshop-optimizer')); ?>';}
                    }).catch(function(){st.style.color='#b91c1c';st.textContent='<?php echo esc_js(__('Save failed.', 'ai-eshop-optimizer')); ?>';});
                });
            })();
            </script>
        </div>
        <?php
    }

    public function ajax_save_legacy_map() {
        AIEO_DMM::verify_ajax_request();
        $valid_names = array();
        foreach (self::blocks_locations() as $bl) {
            if (!empty($bl['name'])) { $valid_names[] = (string) $bl['name']; }
        }
        
        
        $titles = array();
        foreach (self::legacy_pickup_instances() as $inst) {
            if (!empty($inst['rate_id'])) { $titles[$inst['rate_id']] = isset($inst['title']) ? (string) $inst['title'] : ''; }
        }
        $map = array();
        if (isset($_POST['map_json'])) {
            $decoded = json_decode((string) wp_unslash($_POST['map_json']), true); 
            if (is_array($decoded)) {
                foreach ($decoded as $rid => $name) {
                    $rid  = sanitize_text_field((string) $rid);
                    $name = sanitize_text_field((string) $name);
                    if ($rid === '' || $name === '') { continue; }
                    if (!preg_match('/^local_pickup:\d+$/', $rid)) { continue; }
                    if (!in_array($name, $valid_names, true)) { continue; }
                    $map[$rid] = $name;
                    
                    if (!empty($titles[$rid])) { $map[$titles[$rid]] = $name; }
                }
            }
        }
        update_option('aieo_pickup_legacy_map', $map, false);
        wp_send_json_success(array('message' => __('Migration map saved.', 'ai-eshop-optimizer'), 'count' => count($map)));
    }

    
    public function ajax_apply_orders() {
        AIEO_DMM::verify_ajax_request();
        if (!class_exists('AIEO_Runtime_Pickup_Maps')) {
            wp_send_json_error(array('message' => __('Pickup runtime not available.', 'ai-eshop-optimizer')));
        }
        if (function_exists('set_time_limit')) { @set_time_limit(0); }

        global $wpdb;
        $batch  = 100;
        $offset = isset($_POST['offset']) ? max(0, (int) $_POST['offset']) : 0; 
        $oi  = $wpdb->prefix . 'woocommerce_order_items';
        $oim = $wpdb->prefix . 'woocommerce_order_itemmeta';
        $ids = $wpdb->get_col($wpdb->prepare(
            "SELECT DISTINCT oi.order_id FROM {$oi} oi
             INNER JOIN {$oim} oim ON oim.order_item_id = oi.order_item_id
             WHERE oi.order_item_type = 'shipping' AND oim.meta_key = 'method_id' AND oim.meta_value = 'local_pickup'
             ORDER BY oi.order_id DESC
             LIMIT %d OFFSET %d",
            $batch, $offset
        ));

        $processed = is_array($ids) ? count($ids) : 0;
        $updated   = 0;
        foreach ((array) $ids as $oid) {
            $order = wc_get_order((int) $oid);
            if ($order && AIEO_Runtime_Pickup_Maps::stamp_order_pickup($order, true)) { $updated++; }
        }

        wp_send_json_success(array(
            'processed' => $processed,
            'updated'   => $updated,
            'next'      => $offset + $processed,
            'done'      => ($processed < $batch),
        ));
    }

    
    private function render_rename() {
        $current = array();
        foreach (self::blocks_locations() as $bl) {
            if (!empty($bl['name'])) { $current[] = (string) $bl['name']; }
        }
        $known = self::known_pickup_names();
        if (empty($known) && empty($current)) { return; }
        $nonce = wp_create_nonce(AIEO_DMM::NONCE_ACTION);
        $ajax  = admin_url('admin-ajax.php');
        ?>
        <div class="aieo-dmm-card" style="margin-top:18px;">
            <h3 style="margin-top:0;"><?php esc_html_e('Rename / merge a pickup name', 'ai-eshop-optimizer'); ?></h3>
            <p class="description" style="max-width:760px;">
                <?php esc_html_e('Rename a pickup location everywhere at once: the location itself, all past orders (the statistics field + the shipping line), and the dependent settings (cheque-on-pickup selection + migration map). Use it to fix a name that drifted, or to merge two names into one. Edits historical orders.', 'ai-eshop-optimizer'); ?>
            </p>
            <table class="form-table" role="presentation">
                <tr>
                    <th scope="row"><label for="aieo-lpr-from"><?php esc_html_e('From (existing name)', 'ai-eshop-optimizer'); ?></label></th>
                    <td>
                        <select id="aieo-lpr-from" style="min-width:340px;">
                            <option value="">— —</option>
                            <?php foreach ($known as $n) :
                                $is_cur = in_array($n, $current, true); ?>
                                <option value="<?php echo esc_attr($n); ?>"><?php echo esc_html($is_cur ? $n : $n . '  (' . __('stale — not a current location', 'ai-eshop-optimizer') . ')'); ?></option>
                            <?php endforeach; ?>
                        </select>
                    </td>
                </tr>
                <tr>
                    <th scope="row"><label for="aieo-lpr-to"><?php esc_html_e('To (new name)', 'ai-eshop-optimizer'); ?></label></th>
                    <td>
                        <input type="text" id="aieo-lpr-to" list="aieo-lpr-list" style="width:100%;max-width:480px;" placeholder="<?php esc_attr_e('Pick a current location or type a new name', 'ai-eshop-optimizer'); ?>">
                        <datalist id="aieo-lpr-list"><?php foreach ($current as $n) : ?><option value="<?php echo esc_attr($n); ?>"></option><?php endforeach; ?></datalist>
                        <p class="description"><?php esc_html_e('If "From" is a current location, it gets renamed to this. Otherwise the orders/settings are just re-pointed to this name.', 'ai-eshop-optimizer'); ?></p>
                    </td>
                </tr>
            </table>
            <p>
                <button type="button" class="button button-primary" id="aieo-lpr-go"><?php esc_html_e('Rename / remap', 'ai-eshop-optimizer'); ?></button>
                <span id="aieo-lpr-status" style="margin-left:10px;color:#646970;font-size:13px;"></span>
            </p>
            <script>
            (function(){
                var b=document.getElementById('aieo-lpr-go');
                var st=document.getElementById('aieo-lpr-status');
                if(!b)return;
                b.addEventListener('click',function(){
                    var from=document.getElementById('aieo-lpr-from').value;
                    var to=(document.getElementById('aieo-lpr-to').value||'').trim();
                    if(!from||!to){ st.style.color='#b91c1c'; st.textContent='<?php echo esc_js(__('Pick a source name and type a new name.', 'ai-eshop-optimizer')); ?>'; return; }
                    if(from===to){ st.style.color='#b91c1c'; st.textContent='<?php echo esc_js(__('From and To are identical.', 'ai-eshop-optimizer')); ?>'; return; }
                    if(!confirm('<?php echo esc_js(__('Rename / remap', 'ai-eshop-optimizer')); ?> "'+from+'" → "'+to+'"?\n<?php echo esc_js(__('This edits historical orders and settings.', 'ai-eshop-optimizer')); ?>'))return;
                    b.disabled=true; st.style.color='#646970'; st.textContent='<?php echo esc_js(__('Working…', 'ai-eshop-optimizer')); ?>';
                    var fd=new FormData();
                    fd.set('action','aieo_dmm_local_pickup_rename');
                    fd.set('nonce','<?php echo esc_js($nonce); ?>');
                    fd.set('from',from); fd.set('to',to);
                    fetch('<?php echo esc_js($ajax); ?>',{method:'POST',credentials:'same-origin',body:fd}).then(function(r){return r.json();}).then(function(j){
                        b.disabled=false;
                        if(j&&j.success){ st.style.color='#15803d'; st.textContent=(j.data&&j.data.message)||'<?php echo esc_js(__('Done.', 'ai-eshop-optimizer')); ?>'; setTimeout(function(){location.reload();},1200); }
                        else{ st.style.color='#b91c1c'; st.textContent=(j&&j.data&&j.data.message)||'<?php echo esc_js(__('Failed.', 'ai-eshop-optimizer')); ?>'; }
                    }).catch(function(){ b.disabled=false; st.style.color='#b91c1c'; st.textContent='<?php echo esc_js(__('Failed.', 'ai-eshop-optimizer')); ?>'; });
                });
            })();
            </script>
        </div>
        <?php
    }

    
    public function ajax_rename() {
        AIEO_DMM::verify_ajax_request();
        if (function_exists('set_time_limit')) { @set_time_limit(0); }

        $from = isset($_POST['from']) ? sanitize_text_field(wp_unslash((string) $_POST['from'])) : '';
        $to   = isset($_POST['to'])   ? sanitize_text_field(wp_unslash((string) $_POST['to']))   : '';
        if ($from === '' || $to === '' || $from === $to) {
            wp_send_json_error(array('message' => __('Pick a source name and a different new name.', 'ai-eshop-optimizer')));
        }

        
        
        $raw    = get_option('pickup_location_pickup_locations', array());
        $to_loc = null;
        if (is_array($raw)) {
            $changed = false;
            foreach ($raw as $i => $l) {
                if (is_array($l) && isset($l['name']) && (string) $l['name'] === $from) {
                    $raw[$i]['name'] = $to;
                    $changed = true;
                }
            }
            if ($changed) { update_option('pickup_location_pickup_locations', $raw, false); }
            foreach ($raw as $l) {
                if (is_array($l) && isset($l['name']) && (string) $l['name'] === $to) { $to_loc = $l; break; }
            }
        }
        $to_addr = '';
        if (is_array($to_loc) && !empty($to_loc['address']) && is_array($to_loc['address']) && function_exists('WC') && WC()->countries) {
            $to_addr = (string) WC()->countries->get_formatted_address($to_loc['address'], ', ');
        }
        $to_details = (is_array($to_loc) && isset($to_loc['details'])) ? (string) $to_loc['details'] : '';
        $to_maps    = (is_array($to_loc) && isset($to_loc['maps_url'])) ? (string) $to_loc['maps_url'] : '';

        
        
        $updated = 0;
        for ($pass = 0; $pass < 500; $pass++) {
            $ids = wc_get_orders(array(
                'limit'      => 100,
                'return'     => 'ids',
                'meta_query' => array(array('key' => '_aieo_pickup_location', 'value' => $from)),
            ));
            if (empty($ids)) { break; }
            foreach ($ids as $oid) {
                $order = wc_get_order($oid);
                if (!$order) { continue; }
                $order->update_meta_data('_aieo_pickup_location', $to);
                if ($to_maps !== '') { $order->update_meta_data('_aieo_pickup_maps_url', $to_maps); }
                foreach ($order->get_shipping_methods() as $item) {
                    $pl     = (string) $item->get_meta('pickup_location');
                    $mtitle = method_exists($item, 'get_method_title') ? (string) $item->get_method_title() : '';
                    if ($pl === $from || $mtitle === $from) {
                        $item->update_meta_data('pickup_location', $to);
                        if ($to_addr !== '')    { $item->update_meta_data('pickup_address', $to_addr); }
                        if ($to_details !== '') { $item->update_meta_data('pickup_details', $to_details); }
                        if (method_exists($item, 'set_method_title')) { $item->set_method_title($to); }
                        $item->save();
                    }
                }
                $order->save();
                $updated++;
            }
        }

        
        $pg = get_option('aieo_dmm_payment_gating', array());
        if (is_array($pg) && isset($pg['pickup_locations']) && is_array($pg['pickup_locations'])) {
            $remapped = array();
            foreach ($pg['pickup_locations'] as $n) { $remapped[] = ((string) $n === $from) ? $to : (string) $n; }
            $pg['pickup_locations'] = array_values(array_unique($remapped));
            update_option('aieo_dmm_payment_gating', $pg, false);
        }
        $lm = get_option('aieo_pickup_legacy_map', array());
        if (is_array($lm)) {
            $lm_changed = false;
            foreach ($lm as $k => $v) {
                if ((string) $v === $from) { $lm[$k] = $to; $lm_changed = true; }
            }
            if ($lm_changed) { update_option('aieo_pickup_legacy_map', $lm, false); }
        }

        
        if (class_exists('WC_Cache_Helper')) { WC_Cache_Helper::get_transient_version('shipping', true); }

        wp_send_json_success(array(
            'message' => sprintf(
                
                __('Renamed "%1$s" → "%2$s". Orders updated: %3$d.', 'ai-eshop-optimizer'),
                $from, $to, $updated
            ),
            'updated' => $updated,
        ));
    }

    public function ajax_import_legacy() {
        AIEO_DMM::verify_ajax_request();
        $rows = array();
        foreach (self::legacy_pickup_names() as $name) {
            $rows[] = array(
                'name'    => $name,
                'enabled' => true,
                'details' => '',
                'address' => array('address_1' => '', 'city' => '', 'state' => '', 'postcode' => '', 'country' => 'GR'),
            );
        }
        wp_send_json_success(array('locations' => $rows));
    }

    public function ajax_save() {
        AIEO_DMM::verify_ajax_request();

        $mode  = (isset($_POST['mode']) && sanitize_key(wp_unslash($_POST['mode'])) === 'blocks') ? 'blocks' : 'legacy';
        $title = isset($_POST['title']) ? sanitize_text_field(wp_unslash($_POST['title'])) : '';
        if ($title === '') { $title = 'Παραλαβή από κατάστημα'; }

        
        
        $locations = array();
        if (isset($_POST['locations_json'])) {
            self::load_google_reviews(); 
            $decoded = json_decode((string) wp_unslash($_POST['locations_json']), true); 
            if (is_array($decoded)) {
                foreach ($decoded as $loc) {
                    if (!is_array($loc)) { continue; }
                    $name = isset($loc['name']) ? sanitize_text_field((string) $loc['name']) : '';
                    if ($name === '') { continue; }
                    $addr    = (isset($loc['address']) && is_array($loc['address'])) ? $loc['address'] : array();
                    $country = isset($addr['country']) ? sanitize_text_field((string) $addr['country']) : 'GR';
                    if ($country === '') { $country = 'GR'; }

                    
                    
                    $review_slug = isset($loc['review_slug']) ? sanitize_key((string) $loc['review_slug']) : '';
                    $maps_url    = '';
                    if ($review_slug !== '' && class_exists('AIEO_Google_Reviews_Locations') && class_exists('AIEO_Google_Reviews_Helpers')) {
                        $rl = AIEO_Google_Reviews_Locations::get_by_slug($review_slug);
                        if (is_array($rl)) {
                            $maps_url = (string) AIEO_Google_Reviews_Helpers::maps_url($rl);
                        } else {
                            $review_slug = ''; 
                        }
                    }

                    $locations[] = array(
                        'name'        => $name,
                        'enabled'     => !empty($loc['enabled']),
                        'details'     => isset($loc['details']) ? sanitize_text_field((string) $loc['details']) : '',
                        'review_slug' => $review_slug,
                        'maps_url'    => $maps_url,
                        'address'     => array(
                            'address_1' => isset($addr['address_1']) ? sanitize_text_field((string) $addr['address_1']) : '',
                            'city'      => isset($addr['city']) ? sanitize_text_field((string) $addr['city']) : '',
                            'state'     => isset($addr['state']) ? sanitize_text_field((string) $addr['state']) : '',
                            'postcode'  => isset($addr['postcode']) ? sanitize_text_field((string) $addr['postcode']) : '',
                            'country'   => $country,
                        ),
                    );
                }
            }
        }

        
        
        $blocked_cc = array();
        if (isset($_POST['blocked_countries_json'])) {
            $decoded = json_decode((string) wp_unslash($_POST['blocked_countries_json']), true); 
            if (is_array($decoded)) {
                $valid = array_change_key_case(self::shipping_countries(), CASE_UPPER); 
                foreach ($decoded as $cc) {
                    $cc = strtoupper(sanitize_text_field((string) $cc));
                    if ($cc !== '' && isset($valid[$cc]) && !in_array($cc, $blocked_cc, true)) {
                        $blocked_cc[] = $cc;
                    }
                }
            }
        }

        
        update_option(self::OPTION_KEY, array('mode' => $mode, 'title' => $title, 'blocked_countries' => $blocked_cc), false);

        
        
        
        update_option('pickup_location_pickup_locations', $locations);
        update_option('woocommerce_pickup_location_settings', array(
            'enabled'    => ($mode === 'blocks') ? 'yes' : 'no',
            'title'      => $title,
            'cost'       => '',
            'tax_status' => 'none',
        ));

        
        
        
        
        if (class_exists('AIEO_DMM_Payment_Gating')) {
            $pg = get_option(AIEO_DMM_Payment_Gating::OPTION_KEY, array());
            if (is_array($pg)) {
                $tok = isset($pg['shipping_match_token']) ? (string) $pg['shipping_match_token'] : '';
                if ($mode === 'blocks' && ($tok === 'local_pickup' || $tok === 'pickup_location')) {
                    $pg['shipping_match_token'] = AIEO_DMM_Payment_Gating::PICKUP_ANY_TOKEN;
                    update_option(AIEO_DMM_Payment_Gating::OPTION_KEY, $pg, false);
                }
            }
        }

        wp_send_json_success(array(
            'message' => __('Local pickup settings saved.', 'ai-eshop-optimizer'),
            'mode'    => $mode,
            'count'   => count($locations),
        ));
    }
}
