<?php
namespace GrCop;

// Exit if accessed directly
if (!defined('ABSPATH')) {
    exit;
}

class GrCop_Form
{
    public static $current_email_order = null;

    public function __construct()
    {
        // Add shortcodes
        add_shortcode('gr_odstop_od_pogodbe_form', [$this, 'render_shortcode']);
        add_shortcode('gr_odstop_od_pogodbe_email_btn', [$this, 'render_email_button_shortcode']);

        // Hooks for WooCommerce My Account
        add_filter('woocommerce_my_account_my_orders_actions', [$this, 'add_my_account_order_actions'], 10, 2);
        add_action('woocommerce_order_details_after_order_table', [$this, 'add_order_details_button']);

        // Footer link injection
        add_action('wp_footer', [$this, 'inject_footer_link']);
        // Inject modal HTML container in footer for general use
        add_action('wp_footer', [$this, 'inject_modal_html']);

        // AJAX actions
        add_action('wp_ajax_grcop_lookup_order', [$this, 'ajax_lookup_order']);
        add_action('wp_ajax_nopriv_grcop_lookup_order', [$this, 'ajax_lookup_order']);

        add_action('wp_ajax_grcop_submit_withdrawal', [$this, 'ajax_submit_withdrawal']);
        add_action('wp_ajax_nopriv_grcop_submit_withdrawal', [$this, 'ajax_submit_withdrawal']);

        // Hooks for transactional emails and context capture
        add_action('woocommerce_email_after_order_table', [$this, 'add_email_order_actions'], 10, 4);
        add_action('woocommerce_email_header', [$this, 'capture_order_from_email_header'], 10, 2);
        add_action('woocommerce_email_before_order_table', [$this, 'capture_order_from_email_order_table'], 10, 4);
    }

    /**
     * Get quantities of items in the order that have already been requested for withdrawal.
     */
    public function get_already_withdrawn_quantities($order_id)
    {
        global $wpdb;
        $table_name = $wpdb->prefix . 'grcop_withdrawals';
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
        $results = $wpdb->get_results($wpdb->prepare("SELECT items_json FROM $table_name WHERE order_id = %d AND status != 'rejected'", intval($order_id)), ARRAY_A);

        $withdrawn = [];
        if (!empty($results)) {
            foreach ($results as $row) {
                $items = json_decode($row['items_json'], true);
                if (is_array($items)) {
                    foreach ($items as $item) {
                        $item_id = $item['item_id'] ?? 0;
                        if ($item_id > 0) {
                            $withdrawn[$item_id] = ($withdrawn[$item_id] ?? 0) + intval($item['qty']);
                        }
                    }
                }
            }
        }
        return $withdrawn;
    }

    /**
     * Check if an order is eligible for withdrawal.
     */
    public function is_order_eligible($order)
    {
        if (!$order) {
            return false;
        }

        // Check status
        $eligible_statuses = get_option('grcop_eligible_statuses', ['completed', 'processing', 'on-hold']);
        if (!in_array($order->get_status(), $eligible_statuses)) {
            return false;
        }

        // Check time window
        $date_completed = $order->get_date_completed();
        if (!$date_completed) {
            $date_completed = $order->get_date_created();
        }

        if (!$date_completed) {
            return false;
        }

        $completion_timestamp = $date_completed->getTimestamp();
        $current_timestamp = time();
        $diff_seconds = $current_timestamp - $completion_timestamp;
        $diff_days = floor($diff_seconds / DAY_IN_SECONDS);

        $window = intval(get_option('grcop_withdrawal_window', 14));

        if ($diff_days > $window) {
            return false;
        }

        // Check if there is at least one non-excluded product in the order that has not been fully returned yet
        $already_withdrawn = $this->get_already_withdrawn_quantities($order->get_id());
        $has_eligible_item = false;
        foreach ($order->get_items() as $item_id => $item) {
            $product = $item->get_product();
            if ($product && !$this->is_product_excluded($product)) {
                $qty = $item->get_quantity();
                $withdrawn_qty = $already_withdrawn[$item_id] ?? 0;
                if ($qty - $withdrawn_qty > 0) {
                    $has_eligible_item = true;
                    break;
                }
            }
        }

        return $has_eligible_item;
    }

    /**
     * Check if a product is excluded from withdrawal.
     */
    public function is_product_excluded($product)
    {
        if (!$product) {
            return true;
        }

        // Check excluded IDs
        $excluded_ids_str = get_option('grcop_excluded_products', '');
        if (!empty($excluded_ids_str)) {
            $excluded_ids = array_map('intval', array_map('trim', explode(',', $excluded_ids_str)));
            if (in_array($product->get_id(), $excluded_ids) || in_array($product->get_parent_id(), $excluded_ids)) {
                return true;
            }
        }

        // Check excluded categories (slugs)
        $excluded_cats = get_option('grcop_excluded_categories', []);
        if (!empty($excluded_cats) && is_array($excluded_cats)) {
            $terms = get_the_terms($product->get_id(), 'product_cat');
            if (!is_wp_error($terms) && !empty($terms)) {
                foreach ($terms as $term) {
                    if (in_array($term->slug, $excluded_cats)) {
                        return true;
                    }
                }
            }
        }

        return false;
    }

    /**
     * Add "Odstop od pogodbe" button to orders list in My Account.
     */
    public function add_my_account_order_actions($actions, $order)
    {
        if ($this->is_order_eligible($order)) {
            $actions['grcop_withdraw'] = [
                'url'  => '#',
                'name' => get_option('grcop_button_text', __('Odstop od pogodbe', 'gr-odstop-od-pogodbe')),
                'class' => 'grcop-open-modal-btn',
            ];
            // Store order details in dataset for JS
            add_filter('woocommerce_my_account_my_orders_actions', function($acts, $ord) use ($order) {
                if ($ord->get_id() === $order->get_id()) {
                    // Injecting dynamic class details or mapping
                }
                return $acts;
            }, 10, 2);
        }
        return $actions;
    }

    /**
     * Add button inside Single Order View page in My Account.
     */
    public function add_order_details_button($order)
    {
        if ($this->is_order_eligible($order)) {
            $btn_text = get_option('grcop_button_text', __('Odstop od pogodbe', 'gr-odstop-od-pogodbe'));
            echo '<div class="grcop-order-details-btn-wrapper" style="margin-bottom: 2em; text-align: right;">';
            echo '<button type="button" class="button grcop-open-modal-btn" data-order-id="' . esc_attr($order->get_id()) . '" data-email="' . esc_attr($order->get_billing_email()) . '">' . esc_html($btn_text) . '</button>';
            echo '</div>';
        }
    }

    /**
     * Render the shortcode form.
     */
    public function render_shortcode($atts)
    {
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended
        $order_id = isset($_GET['grcop_order_id']) ? intval(wp_unslash($_GET['grcop_order_id'])) : 0;
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended
        $email = isset($_GET['grcop_email']) ? sanitize_email(wp_unslash($_GET['grcop_email'])) : '';
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended
        $hash = isset($_GET['grcop_hash']) ? sanitize_text_field(wp_unslash($_GET['grcop_hash'])) : '';

        if ($order_id && $email && $hash) {
            $order = wc_get_order($order_id);
            if ($order && strtolower($order->get_billing_email()) === strtolower($email)) {
                $expected_hash = wp_hash($order->get_id() . '|' . $order->get_order_key() . '|' . $order->get_billing_email(), 'nonce');
                if (hash_equals($expected_hash, $hash) && $this->is_order_eligible($order)) {
                    ob_start();
                    ?>
                    <div class="grcop-form-container" style="max-width: 600px;">
                        <div class="grcop-form-header">
                            <h2><?php esc_html_e('Odstop od pogodbe', 'gr-odstop-od-pogodbe'); ?></h2>
                        </div>
                        <div id="grcop-lookup-result">
                            <?php $this->render_withdrawal_items_form($order); ?>
                        </div>
                    </div>
                    <?php
                    return ob_get_clean();
                }
            }
            // If hash invalid/expired, display notice
            echo '<div class="grcop-badge grcop-badge-danger" style="display:block; padding:15px; margin-bottom:20px; text-align:center; font-family: sans-serif;">' . esc_html__('Povezava za odstop ni več veljavna ali pa je rok že potekel.', 'gr-odstop-od-pogodbe') . '</div>';
        }

        ob_start();
        ?>
        <div class="grcop-form-container">
            <div class="grcop-form-header">
                <h2><?php esc_html_e('Odstop od pogodbe', 'gr-odstop-od-pogodbe'); ?></h2>
                <p><?php esc_html_e('Vnesite številko naročila in e-poštni naslov za začetek postopka odstopa.', 'gr-odstop-od-pogodbe'); ?></p>
            </div>
            
            <form id="grcop-lookup-form" class="grcop-form-box">
                <div class="grcop-input-group">
                    <label for="grcop_order_id"><?php esc_html_e('Številka naročila (Order ID)', 'gr-odstop-od-pogodbe'); ?> <span class="required">*</span></label>
                    <input type="number" name="grcop_order_id" id="grcop_order_id" required placeholder="<?php esc_attr_e('npr. 12345', 'gr-odstop-od-pogodbe'); ?>">
                </div>

                <div class="grcop-input-group">
                    <label for="grcop_email"><?php esc_html_e('E-poštni naslov za račun', 'gr-odstop-od-pogodbe'); ?> <span class="required">*</span></label>
                    <input type="email" name="grcop_email" id="grcop_email" required placeholder="<?php esc_attr_e('ime@domena.si', 'gr-odstop-od-pogodbe'); ?>">
                </div>

                <button type="submit" class="grcop-btn grcop-btn-primary" id="grcop-lookup-submit">
                    <?php esc_html_e('Išči naročilo', 'gr-odstop-od-pogodbe'); ?>
                </button>
                <div class="grcop-loader" style="display:none;"></div>
            </form>

            <div id="grcop-lookup-result" style="display:none;"></div>
        </div>
        <?php
        return ob_get_clean();
    }

    /**
     * Renders a direct button inside customer emails linking to the prefilled form.
     */
    public function add_email_order_actions($order, $sent_to_admin, $plain_text, $email_obj)
    {
        // Don't show in admin emails, plain-text emails, or if the order is not eligible
        if ($sent_to_admin || $plain_text || !$this->is_order_eligible($order)) {
            return;
        }

        $page_id = get_option('grcop_form_page');
        $page_url = $page_id ? get_permalink($page_id) : home_url('/');

        $hash = wp_hash($order->get_id() . '|' . $order->get_order_key() . '|' . $order->get_billing_email(), 'nonce');
        $link = add_query_arg([
            'grcop_order_id' => $order->get_id(),
            'grcop_email'    => urlencode($order->get_billing_email()),
            'grcop_hash'     => $hash
        ], $page_url);

        $btn_text = get_option('grcop_button_text', __('Odstopi od pogodbe tukaj', 'gr-odstop-od-pogodbe'));
        $bg_color = get_option('grcop_email_btn_bg_color', '#2563eb');
        $text_color = get_option('grcop_email_btn_text_color', '#ffffff');

        echo '<div style="margin: 25px 0; text-align: center; font-family: -apple-system, BlinkMacSystemFont, \'Segoe UI\', Roboto, Helvetica, Arial, sans-serif;">';
        echo '<p style="margin: 0 0 10px 0; font-size: 14px; color: #666;">' . esc_html__('Želite odstopiti od pogodbe ali vrniti izdelke?', 'gr-odstop-od-pogodbe') . '</p>';
        echo '<a href="' . esc_url($link) . '" style="background-color: ' . esc_attr($bg_color) . '; color: ' . esc_attr($text_color) . '; padding: 12px 24px; text-decoration: none; border-radius: 5px; font-weight: bold; display: inline-block; font-size: 14px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);">' . esc_html($btn_text) . '</a>';
        echo '</div>';
    }

    /**
     * Inject footer link if enabled.
     */
    public function inject_footer_link()
    {
        if (get_option('grcop_enable_footer_link', 'yes') === 'yes') {
            $btn_text = get_option('grcop_button_text', __('Odstopi od pogodbe tukaj', 'gr-odstop-od-pogodbe'));
            
            $page_id = get_option('grcop_form_page');
            $url = $page_id ? get_permalink($page_id) : '#';
            $class = $page_id ? '' : 'grcop-open-guest-modal';

            echo '<div class="grcop-footer-link-container" style="text-align: center; margin: 15px 0;">';
            echo '<a href="' . esc_url($url) . '" class="' . esc_attr($class) . '" style="font-size: 0.9em; text-decoration: underline; color: inherit;">' . esc_html($btn_text) . '</a>';
            echo '</div>';
        }
    }

    /**
     * Inject dynamic Modal markup in wp_footer.
     */
    public function inject_modal_html()
    {
        ?>
        <div id="grcop-modal" class="grcop-modal-overlay" style="display:none;">
            <div class="grcop-modal-content">
                <span class="grcop-modal-close">&times;</span>
                <div id="grcop-modal-inner">
                    <!-- Loaded dynamically via AJAX -->
                </div>
            </div>
        </div>
        <?php
    }

    /**
     * AJAX action: Lookup order (for guest or popup).
     */
    public function ajax_lookup_order()
    {
        check_ajax_referer('grcop_frontend_nonce', 'security');

        $order_id = isset($_POST['order_id']) ? intval(wp_unslash($_POST['order_id'])) : 0;
        $email = isset($_POST['email']) ? sanitize_email(wp_unslash($_POST['email'])) : '';

        if (!$order_id || !$email) {
            wp_send_json_error(['message' => __('Prosimo, vnesite številko naročila in e-poštni naslov.', 'gr-odstop-od-pogodbe')]);
        }

        $order = wc_get_order($order_id);

        if (!$order || strtolower($order->get_billing_email()) !== strtolower($email)) {
            wp_send_json_error(['message' => __('Naročila s temi podatki ni bilo mogoče najti.', 'gr-odstop-od-pogodbe')]);
        }

        if (!$this->is_order_eligible($order)) {
            wp_send_json_error(['message' => __('To naročilo ni upravičeno do odstopa od pogodbe (ali je potekel rok 14 dni, ali pa ima napačen status).', 'gr-odstop-od-pogodbe')]);
        }

        // Render return items selection form
        ob_start();
        $this->render_withdrawal_items_form($order);
        $html = ob_get_clean();

        wp_send_json_success(['html' => $html]);
    }

    /**
     * Helper to render the item selection and refund options form.
     */
    public function render_withdrawal_items_form($order)
    {
        $allowed_refund_methods = get_option('grcop_refund_methods', ['original', 'iban']);
        ?>
        <form id="grcop-withdrawal-submission-form" class="grcop-form-box">
            <input type="hidden" name="order_id" value="<?php echo esc_attr($order->get_id()); ?>">
            <input type="hidden" name="email" value="<?php echo esc_attr($order->get_billing_email()); ?>">
            
            <h3><?php /* translators: %s: order ID */ printf(esc_html__('Odstop za naročilo #%s', 'gr-odstop-od-pogodbe'), esc_html($order->get_id())); ?></h3>
            <p class="grcop-form-desc"><?php esc_html_e('Izberite izdelke, ki jih želite vrniti, in količino.', 'gr-odstop-od-pogodbe'); ?></p>

            <div class="grcop-items-list">
                <?php
                $already_withdrawn = $this->get_already_withdrawn_quantities($order->get_id());
                foreach ($order->get_items() as $item_id => $item) {
                    $product = $item->get_product();
                    if (!$product) continue;

                    $is_excluded = $this->is_product_excluded($product);
                    $qty = $item->get_quantity();
                    $withdrawn_qty = $already_withdrawn[$item_id] ?? 0;
                    $qty_available = $qty - $withdrawn_qty;

                    if ($qty_available <= 0) {
                        $is_excluded = true;
                    }
                    ?>
                    <div class="grcop-item-row <?php echo $is_excluded ? 'grcop-item-excluded' : ''; ?>">
                        <div class="grcop-item-check">
                            <?php if ($is_excluded) : ?>
                                <input type="checkbox" disabled>
                            <?php else : ?>
                                <input type="checkbox" class="grcop-item-checkbox" name="items[<?php echo esc_attr($item_id); ?>][select]" value="1" data-max-qty="<?php echo esc_attr($qty_available); ?>">
                            <?php endif; ?>
                        </div>
                        <div class="grcop-item-details">
                            <span class="grcop-item-name"><strong><?php echo esc_html($item->get_name()); ?></strong></span>
                            <?php
                            $tax_display_option = get_option('grcop_tax_display', 'shop');
                            $inc_tax = ('shop' === $tax_display_option) ? ('incl' === get_option('woocommerce_tax_display_cart')) : ('incl' === $tax_display_option);
                            $product = $item->get_product();
                            $suffix = '';
                            if ($product) {
                                $suffix = $product->get_price_suffix($order->get_item_total($item, $inc_tax));
                            }
                            ?>
                            <span class="grcop-item-price">
                                <?php echo wp_kses_post(wc_price($order->get_item_total($item, $inc_tax))); ?>
                                <?php if (!empty($suffix)) : ?>
                                    <small class="grcop-price-suffix" style="font-size: 0.85em; color: #666; margin-left: 4px;"><?php echo wp_kses_post($suffix); ?></small>
                                <?php endif; ?>
                            </span>
                            <?php if ($is_excluded) : ?>
                                <span class="grcop-badge grcop-badge-danger">
                                    <?php echo ($qty_available <= 0) ? esc_html__('Že vrnjeno', 'gr-odstop-od-pogodbe') : esc_html__('Odstop ni možen', 'gr-odstop-od-pogodbe'); ?>
                                </span>
                            <?php endif; ?>
                        </div>
                        <div class="grcop-item-qty-select">
                            <?php if (!$is_excluded) : ?>
                                <label><?php esc_html_e('Količina:', 'gr-odstop-od-pogodbe'); ?></label>
                                <select name="items[<?php echo esc_attr($item_id); ?>][qty]" class="grcop-qty-dropdown" disabled>
                                    <?php for ($i = 1; $i <= $qty_available; $i++) : ?>
                                        <option value="<?php echo intval($i); ?>" <?php selected($i, $qty_available); ?>><?php echo intval($i); ?></option>
                                    <?php endfor; ?>
                                </select>
                            <?php endif; ?>
                        </div>
                    </div>
                    <?php
                }
                ?>
            </div>

            <div class="grcop-refund-section">
                <h4><?php esc_html_e('Način vračila kupnine', 'gr-odstop-od-pogodbe'); ?></h4>
                <div class="grcop-refund-options">
                    <?php if (in_array('original', $allowed_refund_methods)) : ?>
                        <label class="grcop-radio-label">
                            <input type="radio" name="refund_method" value="original" checked>
                            <span><?php esc_html_e('Vračilo na prvotni način plačila', 'gr-odstop-od-pogodbe'); ?></span>
                        </label>
                    <?php endif; ?>

                    <?php if (in_array('iban', $allowed_refund_methods)) : ?>
                        <label class="grcop-radio-label">
                            <input type="radio" name="refund_method" value="iban" <?php echo (!in_array('original', $allowed_refund_methods)) ? 'checked' : ''; ?>>
                            <span><?php esc_html_e('Vračilo na bančni račun (TRR)', 'gr-odstop-od-pogodbe'); ?></span>
                        </label>
                        <div class="grcop-iban-input-container" style="display: none; margin-top: 10px; margin-left: 25px;">
                            <label for="grcop_iban"><?php esc_html_e('Številka TRR (IBAN) in podatki o prejemniku:', 'gr-odstop-od-pogodbe'); ?></label>
                            <textarea name="refund_details_iban" id="grcop_iban" rows="2" placeholder="<?php esc_attr_e('SI56... Ime Prejemnika, Ulica...', 'gr-odstop-od-pogodbe'); ?>"></textarea>
                        </div>
                    <?php endif; ?>

                    <?php if (in_array('coupon', $allowed_refund_methods)) : ?>
                        <label class="grcop-radio-label">
                            <input type="radio" name="refund_method" value="coupon">
                            <span><?php esc_html_e('Dobropis / Trgovinski kupon', 'gr-odstop-od-pogodbe'); ?></span>
                        </label>
                    <?php endif; ?>
                </div>
            </div>

            <div class="grcop-reason-section">
                <label for="grcop_reason"><?php esc_html_e('Razlog za odstop (neobvezno):', 'gr-odstop-od-pogodbe'); ?></label>
                <textarea name="grcop_reason" id="grcop_reason" rows="2" placeholder="<?php esc_attr_e('Napišite razlog, če želite...', 'gr-odstop-od-pogodbe'); ?>"></textarea>
            </div>

            <!-- Two-step submit trigger -->
            <button type="button" class="grcop-btn grcop-btn-primary" id="grcop-submit-verification-btn">
                <?php esc_html_e('Nadaljuj na potrditev', 'gr-odstop-od-pogodbe'); ?>
            </button>
            <div class="grcop-submit-loader" style="display:none;"></div>
        </form>
        <?php
    }

    /**
     * AJAX action: Submit withdrawal request.
     */
    public function ajax_submit_withdrawal()
    {
        check_ajax_referer('grcop_frontend_nonce', 'security');

        $order_id = isset($_POST['order_id']) ? intval(wp_unslash($_POST['order_id'])) : 0;
        $email = isset($_POST['email']) ? sanitize_email(wp_unslash($_POST['email'])) : '';
        // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
        $items_raw = isset($_POST['items']) ? (array) wp_unslash($_POST['items']) : [];
        $refund_method = isset($_POST['refund_method']) ? sanitize_text_field(wp_unslash($_POST['refund_method'])) : 'original';
        $reason = isset($_POST['grcop_reason']) ? sanitize_textarea_field(wp_unslash($_POST['grcop_reason'])) : '';

        $refund_details = '';
        if ('iban' === $refund_method && isset($_POST['refund_details_iban'])) {
            $refund_details = sanitize_textarea_field(wp_unslash($_POST['refund_details_iban']));
        }

        if (!$order_id || !$email) {
            wp_send_json_error(['message' => __('Neveljavni podatki o naročilu.', 'gr-odstop-od-pogodbe')]);
        }

        $order = wc_get_order($order_id);
        if (!$order || strtolower($order->get_billing_email()) !== strtolower($email) || !$this->is_order_eligible($order)) {
            wp_send_json_error(['message' => __('Naročilo ni več upravičeno do odstopa.', 'gr-odstop-od-pogodbe')]);
        }

        // Validate items
        $returned_items = [];
        $returned_items_summary = [];

        if (empty($items_raw) || !is_array($items_raw)) {
            wp_send_json_error(['message' => __('Prosimo, izberite vsaj en izdelek za odstop.', 'gr-odstop-od-pogodbe')]);
        }

        $already_withdrawn = $this->get_already_withdrawn_quantities($order_id);

        foreach ($items_raw as $item_id => $data) {
            if (isset($data['select']) && $data['select'] == '1') {
                $order_item = $order->get_item($item_id);
                if ($order_item) {
                    $product = $order_item->get_product();
                    if ($product && !$this->is_product_excluded($product)) {
                        $qty = intval($data['qty']);
                        $max_qty = $order_item->get_quantity();
                        $withdrawn_qty = $already_withdrawn[$item_id] ?? 0;
                        $qty_available = $max_qty - $withdrawn_qty;
                        if ($qty > 0 && $qty <= $qty_available) {
                            $tax_display_option = get_option('grcop_tax_display', 'shop');
                            $inc_tax = ('shop' === $tax_display_option) ? ('incl' === get_option('woocommerce_tax_display_cart')) : ('incl' === $tax_display_option);
                            $returned_items[] = [
                                'item_id' => $item_id,
                                'name'    => $order_item->get_name(),
                                'qty'     => $qty,
                                'price'   => $order->get_item_total($order_item, $inc_tax)
                            ];
                            $returned_items_summary[] = $order_item->get_name() . ' x ' . $qty;
                        }
                    }
                }
            }
        }

        if (empty($returned_items)) {
            wp_send_json_error(['message' => __('Izbrani niso bili nobeni veljavni izdelki.', 'gr-odstop-od-pogodbe')]);
        }

        // Write to log DB
        $log_id = GrCop_Log::log_withdrawal(
            $order_id,
            $order->get_formatted_billing_full_name(),
            $order->get_billing_email(),
            $returned_items,
            $refund_method,
            empty($refund_details) ? $reason : $refund_details . "\nRazlog: " . $reason,
            'pending'
        );

        if (!$log_id) {
            wp_send_json_error(['message' => __('Napaka pri zapisovanju odstopa v bazo.', 'gr-odstop-od-pogodbe')]);
        }

        // Add order note
        $note_text = sprintf(
            /* translators: 1: list of returned items, 2: refund method */
            __("Oddan zahtevek za odstop od pogodbe. Vrnjeni artikli: %1\$s. Način vračila: %2\$s.", "gr-odstop-od-pogodbe"),
            implode(', ', $returned_items_summary),
            $refund_method
        );
        $order->add_order_note($note_text);

        // Send Emails
        $this->send_emails(
            $order,
            $returned_items_summary,
            $refund_method,
            $refund_details,
            $reason
        );

        $instructions = get_option('grcop_return_address', '');
        if (empty($instructions)) {
            $instructions = \GrCop\GrCop_Main::get_default_store_address();
        }

        wp_send_json_success([
            'message'      => __('Vaša izjava o odstopu od pogodbe je bila uspešno oddana. Na vaš e-poštni naslov smo vam poslali potrdilo o prejemu.', 'gr-odstop-od-pogodbe'),
            'instructions' => wpautop(esc_html($instructions)),
            'label_html'   => $this->get_printable_label_html($order, $returned_items)
        ]);
    }

    /**
     * Dispatch email notifications.
     */
    private function send_emails($order, $returned_items_summary, $refund_method, $refund_details, $reason)
    {
        $order_id = $order->get_id();
        $customer_name = $order->get_formatted_billing_full_name();
        $customer_email = $order->get_billing_email();
        $date_time = current_time('mysql');

        $returned_items_str = implode("\n", $returned_items_summary);
        
        $method_labels = [
            'original' => __('Originalno plačilno sredstvo', 'gr-odstop-od-pogodbe'),
            'iban'     => __('Vračilo na bančni račun (TRR)', 'gr-odstop-od-pogodbe'),
            'coupon'   => __('Dobropis / Kupon', 'gr-odstop-od-pogodbe')
        ];
        
        $refund_details_str = $method_labels[$refund_method] ?? $refund_method;
        if (!empty($refund_details)) {
            $refund_details_str .= "\nTRR podatki: " . $refund_details;
        }
        if (!empty($reason)) {
            $refund_details_str .= "\nRazlog: " . $reason;
        }

        $instructions = get_option('grcop_return_address', '');
        if (empty($instructions)) {
            $instructions = \GrCop\GrCop_Main::get_default_store_address();
        }

        $placeholders = [
            '{order_id}'            => $order_id,
            '{customer_name}'       => $customer_name,
            '{date_time}'           => $date_time,
            '{returned_items}'      => $returned_items_str,
            '{refund_details}'      => $refund_details_str,
            '{return_instructions}' => $instructions
        ];

        // 1. Customer Email
        if (get_option('grcop_enable_email_customer', 'yes') === 'yes') {
            $cust_subject = get_option('grcop_email_customer_subject', __('Potrditev prejema izjave o odstopu od pogodbe za naročilo #{order_id}', 'gr-odstop-od-pogodbe'));
            $cust_body = get_option('grcop_email_customer_body');
            
            $cust_subject = strtr($cust_subject, $placeholders);
            $cust_body = strtr($cust_body, $placeholders);

            $headers = ['Content-Type: text/html; charset=UTF-8'];

            $mailer = WC()->mailer();
            $wrapped_cust_body = $mailer->wrap_message($cust_subject, wpautop(make_clickable(esc_html($cust_body))));
            $mailer->send($customer_email, $cust_subject, $wrapped_cust_body, $headers);
        }

        // 2. Merchant Email
        $admin_subject = get_option('grcop_email_admin_subject', __('Nov odstop od pogodbe - Naročilo #{order_id}', 'gr-odstop-od-pogodbe'));
        $admin_body = get_option('grcop_email_admin_body');

        $admin_subject = strtr($admin_subject, $placeholders);
        $admin_body = strtr($admin_body, $placeholders);

        $wrapped_admin_body = $mailer->wrap_message($admin_subject, wpautop(make_clickable(esc_html($admin_body))));
        $admin_email = get_option('grcop_email_admin_recipient', '');
        if (empty($admin_email)) {
            $admin_email = get_option('admin_email');
        }
        $mailer->send($admin_email, $admin_subject, $wrapped_admin_body, $headers);
    }

    /**
     * Capture order context from email header hook.
     */
    public function capture_order_from_email_header($email_heading, $email)
    {
        if ($email && isset($email->object) && is_a($email->object, 'WC_Order')) {
            self::$current_email_order = $email->object;
        }
    }

    /**
     * Capture order context from email before order table hook.
     */
    public function capture_order_from_email_order_table($order, $sent_to_admin, $plain_text, $email)
    {
        if (is_a($order, 'WC_Order')) {
            self::$current_email_order = $order;
        }
    }

    /**
     * Renders a customized direct button for contract withdrawal in emails.
     */
    public function render_email_button_shortcode($atts)
    {
        // Shortcode attributes
        $atts = shortcode_atts([
            'order_id'   => '',
            'bg_color'   => '',
            'text_color' => '',
            'text'       => '',
            'align'      => 'center',
        ], $atts, 'gr_odstop_od_pogodbe_email_btn');

        // Locate order from context
        $order = null;
        $order_id_attr = trim($atts['order_id']);

        if (!empty($order_id_attr) && is_numeric($order_id_attr)) {
            $order = wc_get_order(intval($order_id_attr));
        }

        if (!$order && self::$current_email_order) {
            $order = self::$current_email_order;
        }

        // Fallback for admin preview screens
        if (!$order) {
            // phpcs:ignore WordPress.Security.NonceVerification.Recommended
            $order_id = isset($_GET['order_id']) ? intval(wp_unslash($_GET['order_id'])) : 0;
            // phpcs:ignore WordPress.Security.NonceVerification.Recommended
            if (!$order_id && isset($_GET['post'])) {
                // phpcs:ignore WordPress.Security.NonceVerification.Recommended
                $order_id = intval(wp_unslash($_GET['post']));
            }
            if ($order_id > 0) {
                $check_order = wc_get_order($order_id);
                if ($check_order && is_a($check_order, 'WC_Order')) {
                    $order = $check_order;
                }
            }
        }

        // Return empty string if order is not found or not eligible for withdrawal
        if (!$order || !$this->is_order_eligible($order)) {
            return '';
        }

        // Generate the secure withdrawal link
        $page_id = get_option('grcop_form_page');
        $page_url = $page_id ? get_permalink($page_id) : home_url('/');

        $hash = wp_hash($order->get_id() . '|' . $order->get_order_key() . '|' . $order->get_billing_email(), 'nonce');
        $link = add_query_arg([
            'grcop_order_id' => $order->get_id(),
            'grcop_email'    => urlencode($order->get_billing_email()),
            'grcop_hash'     => $hash
        ], $page_url);

        // Styling parameters
        $bg_color = !empty($atts['bg_color']) ? sanitize_hex_color($atts['bg_color']) : get_option('grcop_email_btn_bg_color', '#2563eb');
        $text_color = !empty($atts['text_color']) ? sanitize_hex_color($atts['text_color']) : get_option('grcop_email_btn_text_color', '#ffffff');
        $btn_text = !empty($atts['text']) ? sanitize_text_field($atts['text']) : get_option('grcop_button_text', __('Odstopi od pogodbe tukaj', 'gr-odstop-od-pogodbe'));
        $align = in_array($atts['align'], ['left', 'center', 'right']) ? $atts['align'] : 'center';

        ob_start();
        ?>
        <div style="margin: 20px 0; text-align: <?php echo esc_attr($align); ?>; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;">
            <a href="<?php echo esc_url($link); ?>" style="background-color: <?php echo esc_attr($bg_color); ?>; color: <?php echo esc_attr($text_color); ?>; padding: 12px 24px; text-decoration: none; border-radius: 5px; font-weight: bold; display: inline-block; font-size: 14px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);"><?php echo esc_html($btn_text); ?></a>
        </div>
        <?php
        return ob_get_clean();
    }

    /**
     * Generate printable HTML for the return label.
     */
    private function get_printable_label_html($order, $returned_items)
    {
        $return_address = get_option('grcop_return_address', '');
        if (empty($return_address)) {
            $return_address = \GrCop\GrCop_Main::get_default_store_address();
        }

        $items_str = '';
        foreach ($returned_items as $item) {
            $items_str .= esc_html($item['name']) . ' x ' . intval($item['qty']) . '<br>';
        }

        ob_start();
        ?>
        <div class="label-box" style="border: 2px dashed #000; padding: 25px; display: inline-block; text-align: left; min-width: 350px; font-family: sans-serif; background: #fff; color: #000;">
            <div class="header" style="border-bottom: 2px solid #000; padding-bottom: 10px; margin-bottom: 15px; text-align: center; font-weight: bold; font-size: 18px; text-transform: uppercase;"><?php esc_html_e('Nalepka za vračilo blaga', 'gr-odstop-od-pogodbe'); ?></div>
            <div class="section" style="margin-bottom: 10px;">
                <span class="title" style="font-weight: bold; font-size: 11px; text-transform: uppercase; color: #666;"><?php esc_html_e('Pošiljatelj (Kupec):', 'gr-odstop-od-pogodbe'); ?></span>
                <div class="content" style="font-size: 14px; font-weight: bold; margin-top: 3px;">
                    <?php echo esc_html($order->get_formatted_billing_full_name()); ?><br>
                    <?php echo esc_html($order->get_billing_address_1()); ?> <?php echo esc_html($order->get_billing_address_2()); ?><br>
                    <?php echo esc_html($order->get_billing_postcode()); ?> <?php echo esc_html($order->get_billing_city()); ?><br>
                    <?php echo esc_html($order->get_billing_country()); ?>
                </div>
            </div>
            <div class="section" style="margin-top: 15px; border-top: 1px solid #ccc; padding-top: 10px; margin-bottom: 10px;">
                <span class="title" style="font-weight: bold; font-size: 11px; text-transform: uppercase; color: #666;"><?php esc_html_e('Prejemnik (Trgovec):', 'gr-odstop-od-pogodbe'); ?></span>
                <div class="content" style="font-size: 15px; font-weight: bold; margin-top: 3px;">
                    <?php echo nl2br(esc_html($return_address)); ?>
                </div>
            </div>
            <div class="section" style="margin-top: 15px; border-top: 2px dashed #000; padding-top: 10px; font-size: 11px; color: #333; line-height: 1.4;">
                <strong><?php esc_html_e('Številka naročila:', 'gr-odstop-od-pogodbe'); ?></strong> #<?php echo esc_html($order->get_id()); ?><br>
                <strong><?php esc_html_e('Izdelki v paketu:', 'gr-odstop-od-pogodbe'); ?></strong><br>
                <?php echo wp_kses_post($items_str); ?>
            </div>
        </div>
        <?php
        return ob_get_clean();
    }
}
