/**
 * Vollstart Repair Desk — Admin Backend JavaScript
 *
 * Pattern: PHP renders shell, JS loads data via AJAX and builds UI.
 * Uses wp.i18n for translations, jQuery for DOM/AJAX.
 */
(function($) {
    'use strict';

    var __ = wp.i18n.__;
    var sprintf = wp.i18n.sprintf || function(format) {
        var args = Array.prototype.slice.call(arguments, 1);
        var i = 0;
        return format.replace(/%(\d+\$)?s/g, function(match, pos) {
            if (pos) return args[parseInt(pos) - 1] || '';
            return args[i++] || '';
        });
    };
    var cfg = window.vollstartRdAdmin || {};
    var currentTab = 'repairs';
    var currentStatusFilter = '';
    var repairsCache = [];
    var currentCustomer = null; // currently displayed customer in full view
    var _proHandler = null; // Set by a registered add-on — has beforeRender()/afterRender()

    // --- Options Access ---

    /**
     * Get option value by key.
     * RD merges option values into cfg via getValuesMap(), so cfg[key] is the value.
     */
    function option_getVal(key) {
        return cfg[key] != null ? cfg[key] : '';
    }

    // --- PDF URL Helper ---
    function rdPdfUrl(type, id, full) {
        return 'admin.php?page=vollstart-repair-desk&rd_pdf=' + encodeURIComponent(type) + '&id=' + encodeURIComponent(id) + (full ? '&full=1' : '') + '&_wpnonce=' + encodeURIComponent(cfg.pdfNonce);
    }

    // --- Add-on Features Info Box ---
    // Static informational box, no feature locking. WP.org allows pointing out
    // features available in a separate plugin. A registered add-on can replace via filter.
    function renderProFeaturesBox() {
        var features = [
            __('Custom statuses, work-step templates and step materials', 'vollstart-repair-desk'),
            __('Cost tracking, work items and parts catalog with inventory', 'vollstart-repair-desk'),
            __('WooCommerce order creation and invoice PDF from repairs', 'vollstart-repair-desk'),
            __('Customer portal as installable Progressive Web App', 'vollstart-repair-desk'),
            __('Staff management with auth tokens and intake PWA', 'vollstart-repair-desk'),
            __('Recurring maintenance reminders and warranty expiry cron alerts', 'vollstart-repair-desk'),
            __('Rating email invitations and customer portal rating widget', 'vollstart-repair-desk'),
            __('Email body customization and branding removal', 'vollstart-repair-desk')
        ];
        var html = '<div class="rd-pro-features" style="margin-top:14px;padding:18px 20px;border:1px solid #e2e8f0;border-radius:10px;background:linear-gradient(135deg,#fefce8 0%,#fef3c7 100%)">';
        html += '<div style="display:flex;align-items:center;gap:8px;margin-bottom:10px">';
        html += '<span class="dashicons dashicons-star-filled" style="color:#d97706;font-size:18px;width:18px;height:18px"></span>';
        html += '<strong style="font-size:14px;color:#1e293b">' + __('Repair Desk Pro', 'vollstart-repair-desk') + '</strong>';
        html += '</div>';
        html += '<p style="margin:0 0 10px;font-size:13px;color:#475569">' + __('Repair Desk Pro is a separate plugin with additional features for growing workshops:', 'vollstart-repair-desk') + '</p>';
        html += '<ul style="margin:0 0 10px 20px;padding:0;font-size:13px;color:#334155;line-height:1.7">';
        for (var i = 0; i < features.length; i++) {
            html += '<li>' + escHtml(features[i]) + '</li>';
        }
        html += '</ul>';
        html += '<a href="https://vollstart.com/wordpress-plugins/repair-desk/" target="_blank" rel="noopener" style="display:inline-block;font-size:13px;color:#d97706;text-decoration:none;font-weight:600">' + __('Learn more', 'vollstart-repair-desk') + ' &rarr;</a>';
        html += '</div>';
        return html;
    }

    // --- Init ---

    $(document).ready(function() {
        // Expose option_getVal globally for an add-on's JS
        window.vollstartRdOptionGetVal = option_getVal;
        // Fire event so an add-on's JS can hook into options
        $(document).trigger('vollstart_rd_options_loaded');

        // Load the add-on's admin JS dynamically (if installed). When ready,
        // bootApp() renders the page shell and starts the first tab.
        if (cfg.proAdminJs) {
            var s = document.createElement('script');
            s.src = cfg.proAdminJs + '?v=' + (cfg.proVersion || '0') + (cfg.isDebug ? '.' + Date.now() : '');
            s.onload = function () {
                if (typeof window.VollstartRD_ProAdmin === 'function') {
                    _proHandler = window.VollstartRD_ProAdmin(getHelpers());
                }
                bootApp();
            };
            s.onerror = function () { bootApp(); };
            document.head.appendChild(s);
        } else {
            bootApp();
        }
    });

    // --- App boot (renders the page shell, then starts the first tab) ---

    function bootApp() {
        renderShell();
        initTabs();
        initScrollTop();
        loadTab('repairs');
    }

    function getFreeTabs() {
        return [
            { key: 'repairs',      label: __('Repairs', 'vollstart-repair-desk'),      active: true },
            { key: 'customers',    label: __('Customers', 'vollstart-repair-desk') },
            { key: 'devices',      label: __('Devices', 'vollstart-repair-desk') },
            { key: 'repair-types', label: __('Repair Types', 'vollstart-repair-desk') },
            { key: 'step-lists',   label: __('Work Steps', 'vollstart-repair-desk'),   show: !!cfg.enableWorkSteps },
            { key: 'status-flow',  label: __('Status Flow', 'vollstart-repair-desk') },
            { key: 'support',      label: __('Support Info', 'vollstart-repair-desk') },
            { key: 'options',      label: __('Options', 'vollstart-repair-desk') }
        ];
    }

    function renderShell() {
        var tabs = getFreeTabs();
        // A registered add-on can extend/reorder tabs.
        if (_proHandler && _proHandler.getTabs) {
            tabs = _proHandler.getTabs(tabs) || tabs;
        }

        var html = '<div class="rd-wrap">';

        // Header
        html += '<div class="rd-header"><div class="rd-header-inner">';
        html += '<div class="rd-header-left">';
        html += '<span class="dashicons dashicons-admin-tools rd-header-icon"></span>';
        html += '<div class="rd-header-title">';
        html += '<span class="rd-header-name">Repair Desk</span>';
        html += '<span class="rd-header-meta">v' + escHtml(cfg.pluginVersion || '');
        if (cfg.proInstalled && cfg.proVersion) {
            html += ' &middot; Pro v' + escHtml(cfg.proVersion);
        }
        if (cfg.isDebug) {
            html += ' <span title="' + escAttr(__('WP_DEBUG is enabled — disable on production sites', 'vollstart-repair-desk')) + '" style="display:inline-block;margin-left:6px;padding:1px 7px;font-size:10px;font-weight:700;line-height:1.5;color:#fff;background:#d97706;border-radius:999px;vertical-align:middle;letter-spacing:.5px">WP_DEBUG</span>';
        }
        html += '<span id="rd-header-badge"></span>';
        html += '</span></div></div>';
        html += '<div class="rd-header-right">';
        html += '</div></div></div>';

        // Tabs
        html += '<div class="rd-tabs">';
        tabs.forEach(function(t) {
            if (t.show === false) return;
            var cls = 'rd-tab' + (t.active ? ' active' : '');
            html += '<button class="' + cls + '" data-tab="' + escAttr(t.key) + '">' + escHtml(t.label) + '</button>';
        });
        html += '</div>';

        // Body
        html += '<div class="rd-body"><div id="rd-tab-content"></div></div>';

        // Scroll-top
        html += '<button class="rd-scroll-top" id="rd-scroll-top" title="' + escAttr(__('Scroll to top', 'vollstart-repair-desk')) + '"><span class="dashicons dashicons-arrow-up-alt2"></span></button>';


        html += '</div>';
        $('#rd-app').html(html);
    }

    // --- Tabs ---

    function initTabs() {
        $(document).on('click', '.rd-tab', function() {
            var tab = $(this).data('tab');
            $('.rd-tab').removeClass('active');
            $(this).addClass('active');
            loadTab(tab);
        });
    }

    function loadTab(tab) {
        currentTab = tab;
        var $content = $('#rd-tab-content');
        $content.html('<div class="rd-loading"><span class="spinner is-active"></span><span>' + __('Loading...', 'vollstart-repair-desk') + '</span></div>');

        // Pro beforeRender — return true to take over (skip tab render), false to proceed
        if (_proHandler && _proHandler.beforeRender && _proHandler.beforeRender($content, currentTab)) return;

        switch (tab) {
            case 'repairs':
                loadRepairs();
                break;
            case 'customers':
                loadCustomers();
                break;
            case 'devices':
                loadDevices();
                break;
            case 'repair-types':
                loadRepairTypes();
                break;
            case 'step-lists':
                loadStepLists();
                break;
            case 'status-flow':
                loadStatusFlow();
                break;
            case 'options':
                loadOptions();
                break;
            case 'support':
                loadSupportInfo();
                break;
        }

        // Add-on afterRender — can augment/modify the rendered content
        if (_proHandler && _proHandler.afterRender) _proHandler.afterRender($content, currentTab);
    }

    // --- Modal Spinner ---

    var spinnerCount = 0;

    function rdShowSpinner() {
        spinnerCount++;
        if (spinnerCount === 1) {
            $('body').append('<div id="rd-modal-spinner"><span class="spinner is-active"></span></div>');
        }
    }

    function rdHideSpinner() {
        spinnerCount = Math.max(0, spinnerCount - 1);
        if (spinnerCount === 0) {
            $('#rd-modal-spinner').remove();
        }
    }

    // --- AJAX Helper ---

    /**
     * Central AJAX call. Supports multi-action (comma-separated sub_action).
     * After callback, handleResponse() checks for additional keys and
     * updates corresponding UI parts automatically.
     *
     * 4th param opts: { spin: true } to show modal spinner (for destructive/save actions).
     * Spinner is OFF by default. Pass spin:true for user-triggered save/delete actions.
     */
    function rdAjax(subAction, data, callback, opts) {
        opts = opts || {};
        var spin = opts.spin === true;
        if (spin) rdShowSpinner();

        data = data || {};
        data.action = 'vollstart_rd_admin';
        data.sub_action = subAction;
        data.nonce = cfg.nonce;

        var isMulti = subAction.indexOf(',') !== -1;

        // Fetch as text and parse defensively: if another plugin or a PHP notice
        // prints stray output around our JSON, recover the payload instead of
        // failing the whole request.
        $.ajax({ url: cfg.ajaxurl, method: 'POST', data: data, dataType: 'text' }).done(function(raw) {
            var response = rdParseJson(raw);
            if (response === null) {
                if (spin) rdHideSpinner();
                alert(__('Connection error. Please try again.', 'vollstart-repair-desk'));
                return;
            }
            if (response.success) {
                if (isMulti) {
                    // Multi-action: merge all sub-responses for handleResponse
                    var merged = {};
                    $.each(response.data, function(actionKey, actionData) {
                        $.extend(merged, actionData);
                    });
                    if (callback) callback(response.data, merged);
                    handleResponse(merged);
                } else {
                    if (callback) callback(response.data);
                    handleResponse(response.data);
                }
            } else {
                alert(response.data && response.data.message ? response.data.message : __('An error occurred.', 'vollstart-repair-desk'));
            }
            if (spin) rdHideSpinner();
        }).fail(function() {
            if (spin) rdHideSpinner();
            alert(__('Connection error. Please try again.', 'vollstart-repair-desk'));
        });
    }

    /**
     * Parse a JSON response defensively. Tolerates stray output (PHP notices,
     * other plugins' echoes, a BOM) prepended or appended to the body by
     * extracting the payload between the first opening and last closing token.
     * Returns the parsed value, or null if no valid JSON can be recovered.
     */
    function rdParseJson(raw) {
        if (raw && typeof raw === 'object') return raw;
        if (typeof raw !== 'string') return null;
        try { return JSON.parse(raw); } catch (e) {}
        var firstObj = raw.indexOf('{'), firstArr = raw.indexOf('[');
        var start = (firstObj === -1) ? firstArr
                  : (firstArr === -1) ? firstObj : Math.min(firstObj, firstArr);
        var end = Math.max(raw.lastIndexOf('}'), raw.lastIndexOf(']'));
        if (start === -1 || end === -1 || end < start) return null;
        try { return JSON.parse(raw.slice(start, end + 1)); } catch (e2) { return null; }
    }

    /**
     * Open a modal dialog. Returns the jQuery modal element for further customization.
     * @param {string} id - Unique modal ID (used for removal)
     * @param {string} title - Modal header title (can be empty for no header)
     * @param {string} bodyHtml - HTML content for the modal body
     * @param {object} opts - Options: { footer: '', maxWidth: '500px', onClose: null }
     * @returns {jQuery} The modal backdrop element
     */
    function rdModal(id, title, bodyHtml, opts) {
        opts = opts || {};
        var maxWidth = opts.maxWidth || '500px';

        // Remove existing modal with same ID
        $('#' + id).remove();

        var html = '<div class="rd-modal-backdrop" id="' + id + '">';
        html += '<div class="rd-modal" style="max-width:' + maxWidth + '">';
        if (title) {
            html += '<div class="rd-modal-header"><h2>' + title + '</h2><button class="rd-modal-close rd-close-modal">&times;</button></div>';
        }
        html += '<div class="rd-modal-body">' + bodyHtml + '</div>';

        // Build footer from buttons array OR raw HTML
        if (opts.buttons && opts.buttons.length) {
            html += '<div class="rd-modal-footer" style="display:flex;justify-content:flex-end;gap:8px;padding:12px 16px">';
            for (var bi = 0; bi < opts.buttons.length; bi++) {
                var b = opts.buttons[bi];
                var cls = 'rd-btn';
                if (b.type === 'primary') cls += ' rd-btn-primary';
                else if (b.type === 'danger') cls += ' rd-btn-danger';
                else if (b.type === 'secondary') cls += ' rd-btn-secondary';
                if (b.close) cls += ' rd-close-modal';
                html += '<button class="' + cls + '" data-btn-idx="' + bi + '">' + (b.label || '') + '</button>';
            }
            html += '</div>';
        } else if (opts.footer) {
            html += '<div class="rd-modal-footer" style="display:flex;justify-content:flex-end;gap:8px;padding:12px 16px">' + opts.footer + '</div>';
        }
        html += '</div></div>';

        var $modal = $(html).appendTo('body');

        // Bind button callbacks
        if (opts.buttons && opts.buttons.length) {
            $modal.find('[data-btn-idx]').each(function () {
                var idx = parseInt($(this).attr('data-btn-idx'));
                var btn = opts.buttons[idx];
                if (btn && btn.callback) {
                    $(this).on('click', function () { btn.callback($modal); });
                }
            });
        }

        // Close handlers
        $modal.find('.rd-close-modal').on('click', function() {
            $modal.remove();
            if (opts.onClose) opts.onClose();
        });
        $modal.on('click', function(e) {
            if ($(e.target).hasClass('rd-modal-backdrop')) {
                $modal.remove();
                if (opts.onClose) opts.onClose();
            }
        });

        return $modal;
    }

    /**
     * Close and remove a modal by ID.
     */
    function rdModalClose(id) {
        $('#' + id).remove();
    }

    /**
     * rdButton — returns jQuery button element.
     * Label is translated via __(). Options:
     *   type: 'primary' | 'danger' | 'secondary' | '' (default)
     *   size: 'sm' for small button
     *   icon: dashicons class (e.g. 'dashicons-star-filled')
     *   id: HTML id attribute
     *   cls: additional CSS classes
     *   title: HTML title attribute
     *   close: true to add rd-close-modal class
     *   callback: click handler function
     */
    function rdButton(label, opts) {
        opts = opts || {};
        var cls = 'rd-btn';
        if (opts.type === 'primary') cls += ' rd-btn-primary';
        else if (opts.type === 'danger') cls += ' rd-btn-danger';
        else if (opts.type === 'secondary') cls += ' rd-btn-secondary';
        if (opts.size === 'sm') cls += ' rd-btn-sm';
        if (opts.close) cls += ' rd-close-modal';
        if (opts.cls) cls += ' ' + opts.cls;
        var html = '<button class="' + cls + '"';
        if (opts.id) html += ' id="' + escAttr(opts.id) + '"';
        if (opts.title) html += ' title="' + escAttr(opts.title) + '"';
        html += '>';
        if (opts.icon) html += '<span class="dashicons ' + escAttr(opts.icon) + '" style="font-size:14px;width:14px;height:14px"></span> ';
        html += escHtml(__(label, 'vollstart-repair-desk')) + '</button>';
        var $btn = $(html);
        if (opts.callback) $btn.on('click', opts.callback);
        return $btn;
    }

    /**
     * SRP response handler — checks which keys are present and updates
     * the corresponding UI sections. Each key maps to one render function.
     * This way a single AJAX response can update multiple UI parts.
     */
    function handleResponse(data) {
        if (!data) return;

        if (data.counts) {
            updateFilterCounts(data.counts);
        }

        // If audit trail is open and new data arrives, refresh it
        if (data.auditLog && $('#rd-audit-trail-content').is(':visible')) {
            var html = '<table class="rd-table" style="font-size:12px">';
            html += '<thead><tr><th>' + __('Date', 'vollstart-repair-desk') + '</th><th>' + __('Event', 'vollstart-repair-desk') + '</th><th>' + __('Details', 'vollstart-repair-desk') + '</th><th>' + __('By', 'vollstart-repair-desk') + '</th></tr></thead>';
            html += '<tbody>' + getAuditTrailRows(data.auditLog) + '</tbody></table>';
            $('#rd-audit-trail-content').html(html);
        }
    }

    /**
     * Reload DataTables after a mutation (create/update/delete).
     * Called explicitly, not from handleResponse (avoids double-loads).
     */
    function reloadTables() {
        if (currentTab === 'repairs' && repairsDT) {
            repairsDT.ajax.reload(null, false);
        }
        if (currentTab === 'customers' && customersDT) {
            customersDT.ajax.reload(null, false);
        }
    }

    /**
     * Update just the count badges on filter pills without full re-render.
     */
    function updateFilterCounts(counts) {
        var total = 0;
        $.each(counts, function(k, v) { total += v; });
        $('.rd-filter-pill').each(function() {
            var status = $(this).data('status');
            if (status === '' || status === undefined) {
                $(this).find('.rd-count').text(total);
            } else if (counts[status] !== undefined) {
                $(this).find('.rd-count').text(counts[status]);
            }
        });
    }

    var repairsDT = null;
    var customersDT = null;

    // --- Repairs Tab ---

    function loadRepairs() {
        // Render tab shell immediately, DataTable will fetch its own data
        var counts = {};
        // Quick count fetch (lightweight, per_page=0 still returns counts)
        rdAjax('get_repairs', { page: 1, per_page: 1 }, function(result) {
            renderRepairsTab(result.counts || {});
        });
    }

    function renderRepairsTab(counts) {
        var statuses = cfg.statuses || {};
        var total = 0;
        $.each(counts, function(k, v) { total += v; });

        // Favorites + action buttons (one row on desktop, two on mobile)
        var html = '<div style="display:flex;align-items:center;gap:8px;margin-bottom:8px;flex-wrap:wrap">';
        html += '<div id="rd-favorites-row" style="display:none;flex:1;min-width:0"></div>';
        html += '<div style="display:flex;gap:6px;margin-left:auto;flex-shrink:0">';
        html += '<button class="rd-btn rd-btn-secondary" id="rd-scan-qr" style="padding:10px 16px"><span class="dashicons dashicons-camera" style="font-size:20px;width:20px;height:20px"></span></button>';
        html += '<button class="rd-btn rd-btn-primary" id="rd-new-repair"><span class="dashicons dashicons-plus-alt2"></span> ' + __('New Repair', 'vollstart-repair-desk') + '</button>';
        html += '</div></div>';

        // DataTable
        html += '<div class="rd-card">';

        // Status filter pills + action buttons (inside card)
        html += '<div style="padding:10px 16px;display:flex;flex-wrap:wrap;gap:6px;border-bottom:1px solid #f1f5f9;align-items:center">';
        html += '<button class="rd-filter-pill' + (!currentStatusFilter ? ' active' : '') + '" data-status="">' + __('All', 'vollstart-repair-desk') + ' <span class="rd-count">' + total + '</span></button>';
        $.each(statuses, function(slug, def) {
            var cnt = counts[slug] || 0;
            var label = typeof def === 'object' ? def.label : def;
            var color = typeof def === 'object' ? def.color : '#94a3b8';
            if (cnt > 0 || slug === currentStatusFilter) {
                var isActive = currentStatusFilter === slug;
                var pillStyle = isActive ? 'border-color:' + color + ';color:' + color + ';background:' + color + '10' : '';
                html += '<button class="rd-filter-pill' + (isActive ? ' active' : '') + '" data-status="' + slug + '" style="' + pillStyle + '">';
                html += '<span style="width:8px;height:8px;border-radius:50%;background:' + color + ';display:inline-block"></span> ';
                html += escHtml(label) + ' <span class="rd-count">' + cnt + '</span></button>';
            }
        });
        html += '<button class="rd-btn rd-btn-sm rd-btn-secondary" id="rd-export-repairs" title="' + __('Export CSV', 'vollstart-repair-desk') + '" style="margin-left:auto;flex-shrink:0"><span class="dashicons dashicons-download" style="font-size:14px;width:14px;height:14px"></span></button>';
        html += '</div>';
        // Bulk toolbar (hidden, shown when rows selected)
        html += '<div id="rd-bulk-bar" style="display:none;padding:10px 16px;background:#eff6ff;border:1px solid #bfdbfe;border-radius:8px;margin-bottom:8px;display:none;align-items:center;gap:8px;flex-wrap:wrap">';
        html += '<span id="rd-bulk-count" style="font-size:13px;font-weight:600;color:#1e293b"></span>';
        html += '<select id="rd-bulk-status" style="padding:5px 8px;border:1px solid #e2e8f0;border-radius:6px;font-size:13px">';
        html += '<option value="">' + __('Change status to...', 'vollstart-repair-desk') + '</option>';
        $.each(statuses, function(slug, def) {
            var label = typeof def === 'object' ? def.label : def;
            html += '<option value="' + slug + '">' + escHtml(label) + '</option>';
        });
        html += '</select>';
        html += '<button class="rd-btn rd-btn-sm rd-btn-primary" id="rd-bulk-apply-status">' + __('Apply', 'vollstart-repair-desk') + '</button>';
        if (cfg.statusPageEnabled) html += '<button class="rd-btn rd-btn-sm rd-btn-secondary" id="rd-bulk-print"><span class="dashicons dashicons-screenoptions" style="font-size:14px;width:14px;height:14px"></span> ' + __('Print QR', 'vollstart-repair-desk') + '</button>';
        html += '<button class="rd-btn rd-btn-sm rd-btn-danger" id="rd-bulk-delete"><span class="dashicons dashicons-trash" style="font-size:14px;width:14px;height:14px"></span></button>';
        html += '<button class="rd-btn rd-btn-sm rd-btn-secondary" id="rd-bulk-deselect">' + __('Deselect all', 'vollstart-repair-desk') + '</button>';
        html += '</div>';

        html += '<table id="rd-repairs-table" class="rd-table" style="width:100%">';
        html += '<thead><tr>';
        html += '<th style="width:30px"><input type="checkbox" id="rd-select-all" style="width:16px;height:16px"></th>';
        html += '<th>' + __('#', 'vollstart-repair-desk') + '</th>';
        html += '<th>' + __('Customer', 'vollstart-repair-desk') + '</th>';
        html += '<th>' + __('Device', 'vollstart-repair-desk') + '</th>';
        html += '<th>' + __('Status', 'vollstart-repair-desk') + '</th>';
        html += '<th>' + __('Priority', 'vollstart-repair-desk') + '</th>';
        html += '<th>' + (cfg.enableStaffManagement ? __('Assigned To', 'vollstart-repair-desk') : __('Created By', 'vollstart-repair-desk')) + '</th>';
        html += '<th>' + __('Date', 'vollstart-repair-desk') + '</th>';
        html += '<th></th>';
        html += '</tr></thead>';
        html += '</table></div>';

        // Info bars
        html += '<div style="display:flex;gap:8px;flex-wrap:wrap;margin-top:8px">';
        if (cfg.statusPageEnabled) {
            html += '<div class="rd-info-bar" style="flex:1;min-width:250px"><span class="dashicons dashicons-visibility" style="color:#3b82f6;margin-right:6px"></span>';
            html += __('Public status page:', 'vollstart-repair-desk') + ' <a href="' + escAttr(cfg.statusPageUrl) + '" target="_blank"><code>' + escHtml(cfg.statusPageUrl) + '</code></a>';
            html += ' &middot; ' + __('Shortcode:', 'vollstart-repair-desk') + ' <code>[repair_status]</code>';
            html += '</div>';
        }
        // Intake PWA info
        if (cfg.intakeEnabled) {
            html += '<div class="rd-info-bar" style="flex:1;min-width:250px"><span class="dashicons dashicons-smartphone" style="color:#f97316;margin-right:6px"></span>';
            html += __('Intake App active', 'vollstart-repair-desk') + ' &nbsp;&middot;&nbsp; ' + __('Manage tokens in', 'vollstart-repair-desk') + '&nbsp;<a href="#" class="rd-goto-options" data-section="hStaff">' + __('Options &rarr; Staff Management', 'vollstart-repair-desk') + '</a>';
            html += '</div>';
        }
        html += '</div>';

        // Add-on features info box — only shown when the add-on is NOT active.
        // WP.org allows pointing out features available in a separate plugin.
        if (!cfg.proInstalled) {
            html += renderProFeaturesBox();
        }

        $('#rd-tab-content').html(html);

        // Load favorite repair types as quick-start buttons (own row)
        rdAjax('get_repair_types_dropdown', {}, function(result) {
            var favorites = result.favorites || [];
            if (favorites.length > 0) {
                var btns = '<div style="display:flex;gap:6px;flex-wrap:wrap">';
                $.each(favorites, function(i, t) {
                    btns += '<button class="rd-btn rd-btn-secondary rd-quick-new-repair" data-type-id="' + t.id + '" data-price="' + escAttr(t.default_price) + '" style="padding:6px 12px;font-size:13px">';
                    btns += '<span class="dashicons dashicons-' + escAttr(t.icon || 'admin-tools') + '" style="font-size:16px;width:16px;height:16px;margin-right:4px"></span>' + escHtml(t.name);
                    btns += '</button>';
                });
                btns += '</div>';
                $('#rd-favorites-row').html(btns).show();
            }
        });

        // Init DataTable with server-side processing
        var columnMap = ['', 'repair_number', 'customer_name', 'device_brand', 'status', 'priority', '', 'created_at', ''];

        if (repairsDT) { repairsDT.destroy(); repairsDT = null; }

        repairsDT = $('#rd-repairs-table').DataTable({
            responsive: true,
            processing: true,
            serverSide: true,
            ajax: function(dtParams, callback) {
                var col = dtParams.order && dtParams.order[0] ? dtParams.order[0].column : 7;
                var dir = dtParams.order && dtParams.order[0] ? dtParams.order[0].dir : 'desc';
                rdAjax('get_repairs', {
                    page: Math.floor(dtParams.start / dtParams.length) + 1,
                    per_page: dtParams.length,
                    search: dtParams.search.value || '',
                    status: currentStatusFilter,
                    orderby: columnMap[col] || 'created_at',
                    order: dir.toUpperCase()
                }, function(data) {
                    // Update filter counts
                    if (data.counts) updateFilterCounts(data.counts);

                    var rows = (data.repairs || []).map(function(r) {
                        var device = [r.device_brand, r.device_model].filter(Boolean).join(' ') || r.device_type || '\u2014';
                        var sLabel = getStatusLabel(r.status);
                        var sColor = getStatusColor(r.status);
                        var priorityHtml = '';
                        if (r.priority === 'urgent') priorityHtml = '<span style="color:#ef4444;font-weight:700">!!</span>';
                        else if (r.priority === 'high') priorityHtml = '<span style="color:#f59e0b;font-weight:600">!</span>';

                        var unreadBadge = (parseInt(r.unread_messages) > 0) ? ' <span style="display:inline-flex;align-items:center;justify-content:center;background:#ef4444;color:#fff;font-size:10px;font-weight:700;min-width:16px;height:16px;border-radius:999px;padding:0 4px;vertical-align:middle">' + r.unread_messages + '</span>' : '';
                        return [
                            '<input type="checkbox" class="rd-bulk-check" data-id="' + r.id + '" data-number="' + escAttr(r.repair_number) + '" data-code="' + escAttr(r.access_code) + '" style="width:16px;height:16px">',
                            '<strong>' + escHtml(r.repair_number) + '</strong>' + unreadBadge,
                            escHtml(r.customer_name || '\u2014'),
                            escHtml(device),
                            '<span style="display:inline-flex;font-size:11px;font-weight:600;padding:3px 10px;border-radius:999px;background:' + sColor + '15;color:' + sColor + ';border:1px solid ' + sColor + '30">' + escHtml(sLabel) + '</span>',
                            priorityHtml,
                            escHtml((cfg.enableStaffManagement ? r.assigned_to_name : r.created_by_user_name) || '\u2014'),
                            r.created_at ? formatDateTime(r.created_at).split(',')[0] : '',
                            '<div style="display:flex;gap:4px;white-space:nowrap;justify-content:flex-end">' +
                            '<a href="' + escAttr(rdPdfUrl('receipt', r.id, false)) + '" target="_blank" class="rd-btn rd-btn-sm rd-btn-secondary" title="' + __('Receipt', 'vollstart-repair-desk') + '"><span class="dashicons dashicons-media-document" style="font-size:14px;width:14px;height:14px"></span></a>' +
                            (cfg.statusPageEnabled ? '<button class="rd-btn rd-btn-sm rd-btn-secondary rd-print-qr" data-url="' + escAttr(cfg.statusPageUrl + r.repair_number + '/' + r.access_code) + '" data-number="' + escAttr(r.repair_number) + '" data-code="' + escAttr(r.access_code) + '" title="' + __('Print QR', 'vollstart-repair-desk') + '"><span class="dashicons dashicons-screenoptions" style="font-size:14px;width:14px;height:14px"></span></button>' : '') +
                            '<button class="rd-btn rd-btn-sm rd-btn-secondary rd-view-repair" data-id="' + r.id + '">' + __('View', 'vollstart-repair-desk') + '</button>' +
                            '</div>'
                        ];
                    });
                    callback({
                        draw: dtParams.draw,
                        recordsTotal: parseInt(data.total) || 0,
                        recordsFiltered: parseInt(data.filtered) || 0,
                        data: rows
                    });
                });
            },
            pageLength: 20,
            lengthMenu: [10, 20, 50, 100],
            order: [[7, 'desc']],
            columns: [
                { orderable: false, width: 30 },
                { orderable: true },
                { orderable: true },
                { orderable: true },
                { orderable: true },
                { orderable: false, width: 30 },
                { orderable: false },
                { orderable: true, width: 90 },
                { orderable: false, width: 120, className: 'dt-right' }
            ],
            language: {
                search: __('Search:', 'vollstart-repair-desk'),
                lengthMenu: __('Show _MENU_ entries', 'vollstart-repair-desk'),
                info: __('Showing _START_ to _END_ of _TOTAL_ repairs', 'vollstart-repair-desk'),
                infoEmpty: __('No repairs found', 'vollstart-repair-desk'),
                infoFiltered: __('(filtered from _MAX_ total)', 'vollstart-repair-desk'),
                zeroRecords: __('No matching repairs found', 'vollstart-repair-desk'),
                processing: __('Loading...', 'vollstart-repair-desk'),
                paginate: { previous: '&laquo;', next: '&raquo;' }
            },
            dom: '<"rd-dt-top"f>rt<"rd-dt-bottom"lip>',
            drawCallback: function() {
                // Make rows clickable — full view from repairs tab, modal from elsewhere
                $('#rd-repairs-table tbody tr').css('cursor', 'pointer').off('click').on('click', function(e) {
                    if ($(e.target).closest('button, a').length || $(e.target).is('input')) return;
                    var $btn = $(this).find('.rd-view-repair');
                    if ($btn.length) openRepairFullView($btn.data('id'));
                });
            }
        });
    }

    // --- Bulk Actions ---

    function updateBulkBar() {
        var $checked = $('.rd-bulk-check:checked');
        var count = $checked.length;
        if (count > 0) {
            $('#rd-bulk-bar').css('display', 'flex');
            $('#rd-bulk-count').text(count + ' ' + __('selected', 'vollstart-repair-desk'));
        } else {
            $('#rd-bulk-bar').hide();
        }
    }

    function getSelectedIds() {
        return $('.rd-bulk-check:checked').map(function() { return $(this).attr('data-id'); }).get();
    }

    $(document).on('change', '.rd-bulk-check', updateBulkBar);

    $(document).on('change', '#rd-select-all', function() {
        var checked = $(this).is(':checked');
        $('.rd-bulk-check').prop('checked', checked);
        updateBulkBar();
    });

    $(document).on('click', '#rd-bulk-deselect', function() {
        $('.rd-bulk-check, #rd-select-all').prop('checked', false);
        updateBulkBar();
    });

    // Bulk status change
    $(document).on('click', '#rd-bulk-apply-status', function() {
        var status = $('#rd-bulk-status').val();
        if (!status) return;
        var ids = getSelectedIds();
        if (!ids.length) return;
        if (!confirm(__('Change status for', 'vollstart-repair-desk') + ' ' + ids.length + ' ' + __('repairs?', 'vollstart-repair-desk'))) return;
        rdAjax('bulk_change_status', { ids: ids.join(','), status: status }, function() {
            if (repairsDT) repairsDT.ajax.reload(null, false);
            $('#rd-bulk-bar').hide();
            $('#rd-select-all').prop('checked', false);
        }, {spin: true});
    });

    // Bulk print QR
    $(document).on('click', '#rd-bulk-print', function() {
        var repairs = [];
        $('.rd-bulk-check:checked').each(function() {
            repairs.push({
                number: $(this).attr('data-number'),
                code: $(this).attr('data-code'),
                url: cfg.statusPageUrl + $(this).attr('data-number') + '/' + $(this).attr('data-code')
            });
        });
        if (!repairs.length) return;
        var w = window.open('', '_blank', 'width=400,height=600');
        var h = '<html><head><title>' + __('Print QR Labels', 'vollstart-repair-desk') + '</title>';
        h += '<style>body{font-family:-apple-system,sans-serif;padding:10px}.label{text-align:center;padding:16px;page-break-inside:avoid;border-bottom:1px dashed #ccc;margin-bottom:12px}h2{margin:0;font-size:20px}p{margin:4px 0;color:#64748b;font-size:13px}code{font-size:16px;letter-spacing:2px;font-weight:700}.qr{display:inline-block;margin:8px 0}</style>';
        h += '</head><body>';
        for (var i = 0; i < repairs.length; i++) {
            h += '<div class="label"><h2>' + repairs[i].number + '</h2><div class="qr" id="qr-' + i + '"></div>';
            h += '<p>' + __('Access Code', 'vollstart-repair-desk') + '</p><code>' + repairs[i].code + '</code>';
            h += '<p style="font-size:10px;color:#94a3b8;margin-top:8px">' + repairs[i].url + '</p></div>';
        }
        h += '<script src="' + cfg.pluginUrl + 'assets/js/libs/qrcode/qrcode.min.js"><\/script><script>';
        for (var j = 0; j < repairs.length; j++) {
            h += 'new QRCode(document.getElementById("qr-' + j + '"),{text:"' + repairs[j].url + '",width:160,height:160,colorDark:"#1e293b",colorLight:"#fff"});';
        }
        h += 'setTimeout(function(){window.print()},400);<\/script></body></html>';
        w.document.write(h);
        w.document.close();
    });

    // Bulk delete
    $(document).on('click', '#rd-bulk-delete', function() {
        var ids = getSelectedIds();
        if (!ids.length) return;
        if (!confirm(__('Delete', 'vollstart-repair-desk') + ' ' + ids.length + ' ' + __('repairs? This cannot be undone.', 'vollstart-repair-desk'))) return;
        rdAjax('bulk_delete_repairs', { ids: ids.join(',') }, function() {
            if (repairsDT) repairsDT.ajax.reload(null, false);
            $('#rd-bulk-bar').hide();
            $('#rd-select-all').prop('checked', false);
        }, {spin: true});
    });

    // --- Repair Full View ---

    var currentRepair = null;

    function openRepairFullView(id) {
        var $content = $('#rd-tab-content');
        $content.html('<div class="rd-loading"><span class="spinner is-active"></span></div>');
        rdAjax('get_repair', { id: id }, function(result) {
            renderRepairFullView(result.repair, result.customer, result.product, result.files || [], result.checklistProgress || { total: 0, checked: 0, percent: 0 }, result.ratings || [], result.customerAvgRating || 0, result.workItems, result.workItemTotals);
        });
    }

    function renderRepairFullView(repair, customer, product, files, clProgress, ratings, customerAvgRating, workItems, workItemTotals) {
        currentRepair = repair;
        var statuses = cfg.statuses || {};
        var statusLabel = getStatusLabel(repair.status);
        var statusColor = getStatusColor(repair.status);
        var device = [repair.device_brand, repair.device_model].filter(Boolean).join(' ') || repair.device_type || '\u2014';
        var html = '';

        // Header row 1: Back + Title + Badge
        html += '<div style="display:flex;align-items:center;gap:12px;margin-bottom:8px;flex-wrap:wrap">';
        html += '<button class="rd-btn rd-btn-secondary rd-btn-sm" id="rd-back-to-repairs"><span class="dashicons dashicons-arrow-left-alt2"></span> ' + __('Back', 'vollstart-repair-desk') + '</button>';
        html += '<div style="flex:1;min-width:0">';
        html += '<h2 style="font-size:20px;font-weight:700;color:#1e293b;margin:0">' + escHtml(repair.repair_number) + '</h2>';
        html += '<span style="font-size:13px;color:#94a3b8">' + escHtml(formatDateTime(repair.created_at)) + '</span>';
        html += '</div>';
        html += '<span id="rd-fv-status-badge" style="display:inline-flex;align-items:center;font-size:13px;font-weight:600;padding:6px 16px;border-radius:999px;background:' + statusColor + '15;color:' + statusColor + ';border:1px solid ' + statusColor + '40">' + escHtml(statusLabel) + '</span>';
        // Customer rating (if any)
        var custRating = (ratings || []).filter(function(r) { return r.type === 'repair' && parseInt(r.rating) > 0; });
        if (custRating.length) {
            var cr = parseInt(custRating[0].rating);
            html += '<span style="font-size:16px;margin-left:4px" title="' + __('Customer rating', 'vollstart-repair-desk') + '">';
            for (var si = 1; si <= 5; si++) html += '<span style="color:' + (si <= cr ? '#f59e0b' : '#e2e8f0') + '">&#9733;</span>';
            html += '</span>';
        }
        html += '</div>';

        // Status progress chevron (arrow boxes)
        html += '<div style="display:flex;align-items:center;margin-bottom:12px;overflow-x:auto">';
        var statusIdx = 0;
        var currentIdx = -1;
        var statusCount = Object.keys(statuses).length;
        $.each(statuses, function(slug) { if (slug === repair.status) currentIdx = statusIdx; statusIdx++; });
        var currentIsFinal = isFinalStatus(repair.status);
        // Recount without hidden final statuses
        if (currentIsFinal) {
            statusCount = 0;
            $.each(statuses, function(s) { if (s === repair.status || !isFinalStatus(s)) statusCount++; });
        }
        statusIdx = 0;
        $.each(statuses, function(slug, def) {
            // Hide other final statuses when current is final
            if (currentIsFinal && isFinalStatus(slug) && slug !== repair.status) return;
            var label = typeof def === 'object' ? def.label : def;
            var color = typeof def === 'object' ? def.color : '#94a3b8';
            var isCurrent = slug === repair.status;
            var isPast = statusIdx < currentIdx;
            var isFuture = statusIdx > currentIdx;
            var bg = isCurrent ? color : isPast ? '#e2e8f0' : '#f1f5f9';
            var fg = isCurrent ? '#fff' : isPast ? '#475569' : '#cbd5e1';
            var clip = statusIdx === 0
                ? 'polygon(0 0, calc(100% - 8px) 0, 100% 50%, calc(100% - 8px) 100%, 0 100%)'
                : statusIdx === statusCount - 1
                    ? 'polygon(0 0, 100% 0, 100% 100%, 0 100%, 8px 50%)'
                    : 'polygon(0 0, calc(100% - 8px) 0, 100% 50%, calc(100% - 8px) 100%, 0 100%, 8px 50%)';
            html += '<div style="clip-path:' + clip + ';background:' + bg + ';color:' + fg + ';padding:6px 14px 6px ' + (statusIdx === 0 ? '10px' : '16px') + ';font-size:11px;font-weight:' + (isCurrent ? '700' : '500') + ';white-space:nowrap;flex-shrink:0">' + escHtml(label) + '</div>';
            statusIdx++;
        });
        html += '</div>';

        // Header row 2: Status change + actions (right-aligned)
        html += '<div style="display:flex;align-items:center;gap:6px;margin-bottom:20px;justify-content:flex-end">';
        html += '<select id="rd-fv-change-status" style="padding:6px 10px;border:1px solid #e2e8f0;border-radius:8px;font-size:13px">';
        $.each(statuses, function(slug, def) {
            var label = typeof def === 'object' ? def.label : def;
            var sel = slug === repair.status ? ' selected' : '';
            html += '<option value="' + slug + '"' + sel + '>' + escHtml(label) + '</option>';
        });
        html += '</select>';
        var isLocked = isFinalStatus(repair.status);
        html += '<button class="rd-btn rd-btn-sm rd-btn-primary" id="rd-fv-apply-status" data-id="' + repair.id + '" title="' + __('Change Status', 'vollstart-repair-desk') + '"><span class="dashicons dashicons-yes" style="font-size:16px;width:16px;height:16px"></span></button>';
        html += '<button class="rd-btn rd-btn-sm rd-btn-secondary" id="rd-fv-refresh" data-id="' + repair.id + '" title="' + __('Refresh', 'vollstart-repair-desk') + '"><span class="dashicons dashicons-update"></span></button>';
        html += '<button class="rd-btn rd-btn-sm rd-btn-secondary rd-edit-repair" data-id="' + repair.id + '" title="' + __('Edit', 'vollstart-repair-desk') + '"' + (isLocked ? ' disabled style="opacity:0.5;cursor:not-allowed"' : '') + '><span class="dashicons dashicons-edit"></span></button>';
        html += '<a href="' + escAttr(rdPdfUrl('receipt', repair.id, false)) + '" target="_blank" class="rd-btn rd-btn-sm rd-btn-secondary" title="' + __('Receipt PDF', 'vollstart-repair-desk') + '"><span class="dashicons dashicons-media-document"></span></a>';
        html += '<button class="rd-btn rd-btn-sm rd-btn-danger rd-delete-repair" data-id="' + repair.id + '" title="' + __('Delete', 'vollstart-repair-desk') + '"><span class="dashicons dashicons-trash"></span></button>';
        html += '</div>';

        // Info cards
        html += '<div class="rd-info-grid" style="margin-bottom:24px">';

        // Device card (first)
        html += '<div class="rd-card">';
        html += '<div class="rd-card-header"><h3><span class="dashicons dashicons-laptop" style="margin-right:6px;color:#6366f1"></span>' + __('Device', 'vollstart-repair-desk') + '</h3>';
        if (product) {
            html += '<div class="rd-card-actions">';
            html += '<button class="rd-btn rd-btn-sm rd-btn-secondary rd-goto-device" data-id="' + product.id + '"><span class="dashicons dashicons-visibility" style="font-size:14px;width:14px;height:14px"></span> ' + __('View', 'vollstart-repair-desk') + '</button>';
            html += '</div>';
        }
        html += '</div>';
        html += '<div class="rd-card-body">';
        if (repair.device_type) html += infoRow(__('Type', 'vollstart-repair-desk'), escHtml(repair.device_type));
        if (repair.device_brand) html += infoRow(__('Brand', 'vollstart-repair-desk'), escHtml(repair.device_brand));
        if (repair.device_model) html += infoRow(__('Model', 'vollstart-repair-desk'), escHtml(repair.device_model));
        if (repair.device_serial) html += infoRow(__('Serial', 'vollstart-repair-desk'), '<code style="font-size:12px;background:#f1f5f9;padding:2px 6px;border-radius:4px">' + escHtml(repair.device_serial) + '</code>');
        if (product) {
            html += infoRow(__('Registered Device', 'vollstart-repair-desk'), '<span style="color:#22c55e"><span class="dashicons dashicons-yes" style="font-size:14px;width:14px;height:14px"></span> ' + escHtml(product.name || [product.brand, product.model].filter(Boolean).join(' ')) + '</span>');
            // Maintenance warning
            if (product.service_interval_days && product.next_service_date) {
                var mToday = new Date(); mToday.setHours(0,0,0,0);
                var mNext = new Date(product.next_service_date + 'T00:00:00');
                var mDiff = Math.round((mNext - mToday) / 86400000);
                if (mDiff <= 0) {
                    html += '<div style="margin-top:8px;padding:8px 12px;background:#fef2f210;border:1px solid #ef444430;border-radius:8px;font-size:12px;color:#ef4444;font-weight:600"><span class="dashicons dashicons-warning" style="font-size:14px;width:14px;height:14px;margin-right:4px"></span>';
                    html += __('Maintenance overdue', 'vollstart-repair-desk') + ' — ' + __('Interval:', 'vollstart-repair-desk') + ' ' + product.service_interval_days + ' ' + __('days', 'vollstart-repair-desk') + ', ' + __('Due:', 'vollstart-repair-desk') + ' ' + product.next_service_date + ' (' + Math.abs(mDiff) + ' ' + __('days overdue', 'vollstart-repair-desk') + ')</div>';
                } else if (mDiff <= 30) {
                    html += '<div style="margin-top:8px;padding:8px 12px;background:#fef3c710;border:1px solid #f59e0b30;border-radius:8px;font-size:12px;color:#f59e0b;font-weight:600"><span class="dashicons dashicons-clock" style="font-size:14px;width:14px;height:14px;margin-right:4px"></span>';
                    html += __('Maintenance due soon', 'vollstart-repair-desk') + ' — ' + __('Due:', 'vollstart-repair-desk') + ' ' + product.next_service_date + ' (' + mDiff + ' ' + __('days', 'vollstart-repair-desk') + ')</div>';
                } else {
                    html += infoRow(__('Next Service', 'vollstart-repair-desk'), product.next_service_date + ' (' + product.service_interval_days + ' ' + __('days', 'vollstart-repair-desk') + ')');
                }
            } else if (product.service_interval_days) {
                html += infoRow(__('Service Interval', 'vollstart-repair-desk'), product.service_interval_days + ' ' + __('days', 'vollstart-repair-desk') + ' — <span style="color:#94a3b8">' + __('no next date set', 'vollstart-repair-desk') + '</span>');
            }
        } else if (customer && (repair.device_brand || repair.device_model || repair.device_serial)) {
            html += '<div class="rd-save-device-wrap" style="margin-top:8px;padding-top:8px;border-top:1px solid #f1f5f9">';
            html += '<button class="rd-btn rd-btn-sm rd-btn-secondary" id="rd-save-as-device" data-repair-id="' + repair.id + '" data-customer-id="' + customer.id + '">';
            html += '<span class="dashicons dashicons-plus-alt2"></span> ' + __('Save as registered device', 'vollstart-repair-desk') + '</button>';
            html += '</div>';
        }
        html += '</div></div>';

        // Customer card (second)
        html += '<div class="rd-card">';
        html += '<div class="rd-card-header"><h3><span class="dashicons dashicons-id" style="margin-right:6px;color:#3b82f6"></span>' + __('Customer', 'vollstart-repair-desk');
        if (customerAvgRating > 0) {
            html += ' <span style="font-size:14px;font-weight:400;color:#f59e0b" title="' + __('Average internal rating', 'vollstart-repair-desk') + '">';
            for (var csi = 1; csi <= 5; csi++) html += '<span style="color:' + (csi <= Math.round(customerAvgRating) ? '#f59e0b' : '#e2e8f0') + '">&#9733;</span>';
            html += ' <span style="font-size:12px;color:#94a3b8">' + customerAvgRating + '</span></span>';
        }
        html += '</h3>';
        if (customer) {
            html += '<div class="rd-card-actions">';
            html += '<button class="rd-btn rd-btn-sm rd-btn-secondary rd-goto-customer" data-id="' + customer.id + '"><span class="dashicons dashicons-visibility" style="font-size:14px;width:14px;height:14px"></span> ' + __('View', 'vollstart-repair-desk') + '</button>';
            html += '</div>';
        }
        html += '</div>';
        html += '<div class="rd-card-body">';
        if (customer) {
            html += infoRow(__('Name', 'vollstart-repair-desk'), escHtml(customer.name));
            html += infoRow(__('#', 'vollstart-repair-desk'), '<code style="font-size:12px;background:#f1f5f9;padding:2px 6px;border-radius:4px">' + escHtml(customer.customer_number) + '</code>');
            if (customer.email) html += infoRow(__('Email', 'vollstart-repair-desk'), '<a href="mailto:' + escAttr(customer.email) + '" style="color:#3b82f6">' + escHtml(customer.email) + '</a>');
            if (customer.phone) html += infoRow(__('Phone', 'vollstart-repair-desk'), '<a href="tel:' + escAttr(customer.phone) + '" style="color:#3b82f6">' + escHtml(customer.phone) + '</a>');
        } else {
            html += '<p style="color:#94a3b8;font-size:13px">' + __('No customer assigned.', 'vollstart-repair-desk') + '</p>';
        }
        html += '</div></div>';

        html += '</div>'; // end info-grid

        // Repair details card (priority, dates, price, access code)
        html += '<div class="rd-info-grid" style="margin-bottom:24px">';
        html += '<div class="rd-card">';
        html += '<div class="rd-card-header"><h3><span class="dashicons dashicons-clipboard" style="margin-right:6px;color:#f97316"></span>' + __('Repair Details', 'vollstart-repair-desk') + '</h3></div>';
        html += '<div class="rd-card-body"><div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:16px">';
        html += '<div><div style="font-size:11px;color:#64748b;text-transform:uppercase;margin-bottom:2px">' + __('Priority', 'vollstart-repair-desk') + '</div>';
        html += '<div style="font-size:14px;font-weight:500">' + (repair.priority === 'urgent' ? '<span style="color:#ef4444">Urgent</span>' : repair.priority === 'high' ? '<span style="color:#f59e0b">High</span>' : 'Normal') + '</div></div>';
        html += '<div><div style="font-size:11px;color:#64748b;text-transform:uppercase;margin-bottom:2px">' + __('Est. Completion', 'vollstart-repair-desk') + '</div>';
        html += '<div style="font-size:14px;font-weight:500">' + escHtml(repair.estimated_date || '\u2014') + '</div></div>';
        html += '<div><div style="font-size:11px;color:#64748b;text-transform:uppercase;margin-bottom:2px">' + __('Est. Price', 'vollstart-repair-desk') + '</div>';
        html += '<div style="font-size:14px;font-weight:500">' + (repair.estimated_price ? escHtml(repair.estimated_price + ' ' + cfg.currency) : '\u2014') + '</div></div>';
        html += '<div><div style="font-size:11px;color:#64748b;text-transform:uppercase;margin-bottom:2px">' + __('Repair Warranty', 'vollstart-repair-desk') + '</div>';
        if (repair.warranty_until) {
            var wToday = new Date(); wToday.setHours(0,0,0,0);
            var wDate = new Date(repair.warranty_until + 'T00:00:00');
            var wDiff = Math.round((wDate - wToday) / 86400000);
            var wColor = wDiff < 0 ? '#ef4444' : wDiff <= 30 ? '#f59e0b' : '#22c55e';
            var wLabel = wDiff < 0 ? __('Expired', 'vollstart-repair-desk') : wDiff <= 30 ? __('Expiring soon', 'vollstart-repair-desk') : __('Active', 'vollstart-repair-desk');
            html += '<div style="font-size:14px;font-weight:500">' + escHtml(repair.warranty_until) + ' <span style="font-size:11px;color:' + wColor + ';font-weight:600">(' + wLabel + ')</span></div>';
        } else {
            html += '<div style="font-size:14px;font-weight:500;color:#cbd5e1">\u2014</div>';
        }
        html += '</div>';
        html += '<div><div style="font-size:11px;color:#64748b;text-transform:uppercase;margin-bottom:2px">' + __('Created By', 'vollstart-repair-desk') + '</div>';
        var creatorParts = [];
        if (repair.created_by_name) creatorParts.push(escHtml(repair.created_by_name));
        if (repair.created_by_staff_name) {
            creatorParts.push(escHtml(repair.created_by_staff_name));
        }
        html += '<div style="font-size:14px;font-weight:500">' + (creatorParts.length ? creatorParts.join(' / ') : '\u2014') + '</div>';
        html += '</div>';
        if (cfg.enableStaffManagement) {
            html += '<div><div style="font-size:11px;color:#64748b;text-transform:uppercase;margin-bottom:2px">' + __('Assigned To', 'vollstart-repair-desk') + '</div>';
            html += '<div id="rd-fv-assigned-to" data-repair-id="' + repair.id + '" data-staff-id="' + (repair.assigned_to || '') + '" style="font-size:14px;font-weight:500">';
            html += '<span class="rd-fv-assigned-name" style="cursor:pointer" title="' + __('Click to change', 'vollstart-repair-desk') + '">';
            html += repair.assigned_to_name ? escHtml(repair.assigned_to_name) : '<span style="color:#cbd5e1">\u2014</span>';
            html += ' <span class="dashicons dashicons-edit" style="font-size:12px;width:12px;height:12px;color:#94a3b8"></span></span>';
            html += '<select class="rd-fv-assigned-select" style="display:none;padding:4px 8px;border:1px solid #e2e8f0;border-radius:6px;font-size:13px">';
            html += '<option value="">' + __('— not assigned —', 'vollstart-repair-desk') + '</option>';
            html += '</select>';
            html += '<span class="rd-fv-assigned-feedback" style="display:none;font-size:12px;color:#22c55e;margin-left:6px"></span>';
            html += '</div></div>';
        }
        html += '</div>';
        // Access code + status page link (full width, below grid)
        html += '<div style="margin-top:12px;padding-top:12px;border-top:1px solid #f1f5f9;display:flex;align-items:center;gap:8px;flex-wrap:wrap">';
        html += '<span style="font-size:11px;color:#64748b;text-transform:uppercase">' + __('Access Code', 'vollstart-repair-desk') + '</span>';
        html += '<code id="rd-fv-access-code" style="font-size:16px;background:#f1f5f9;padding:4px 10px;border-radius:4px;letter-spacing:2px;font-weight:700">' + escHtml(repair.access_code) + '</code>';
        html += '<button class="rd-btn rd-btn-sm rd-btn-secondary" id="rd-regenerate-code" data-id="' + repair.id + '" title="' + __('Revoke & regenerate access code', 'vollstart-repair-desk') + '"><span class="dashicons dashicons-update" style="font-size:14px;width:14px;height:14px"></span></button>';
        if (cfg.statusPageEnabled) {
            var statusUrl = cfg.statusPageUrl + repair.repair_number + '/' + repair.access_code;
            html += '<a href="' + escAttr(statusUrl) + '" target="_blank" class="rd-btn rd-btn-sm rd-btn-secondary" title="' + __('Open public status page', 'vollstart-repair-desk') + '" style="white-space:nowrap"><span class="dashicons dashicons-external" style="font-size:14px;width:14px;height:14px"></span> ' + __('Status Page', 'vollstart-repair-desk') + '</a>';
            html += '<button class="rd-btn rd-btn-sm rd-copy-link" data-url="' + escAttr(statusUrl) + '" title="' + __('Copy link', 'vollstart-repair-desk') + '"><span class="dashicons dashicons-admin-page" style="font-size:14px;width:14px;height:14px"></span></button>';
            html += '<button class="rd-btn rd-btn-sm rd-btn-secondary rd-print-qr" data-url="' + escAttr(statusUrl) + '" data-number="' + escAttr(repair.repair_number) + '" data-code="' + escAttr(repair.access_code) + '" title="' + __('Print QR label', 'vollstart-repair-desk') + '"><span class="dashicons dashicons-screenoptions" style="font-size:14px;width:14px;height:14px"></span></button>';
        }
        html += '</div>';
        html += '</div></div>';

        // Defect description
        html += '<div class="rd-card">';
        html += '<div class="rd-card-header"><h3><span class="dashicons dashicons-warning" style="margin-right:6px;color:#ef4444"></span>' + __('Defect Description', 'vollstart-repair-desk') + '</h3></div>';
        html += '<div class="rd-card-body"><p style="white-space:pre-wrap;color:#374151;margin:0;font-size:14px">' + (repair.defect_description ? escHtml(repair.defect_description) : '-') + '</p></div>';
        html += '</div>';
        html += '</div>';

        // Internal notes
        if (repair.internal_notes) {
            html += '<div class="rd-card" style="margin-bottom:24px">';
            html += '<div class="rd-card-header"><h3><span class="dashicons dashicons-lock" style="margin-right:6px;color:#f59e0b"></span>' + __('Internal Notes', 'vollstart-repair-desk') + '</h3></div>';
            html += '<div class="rd-card-body" style="background:#fffbeb"><p style="white-space:pre-wrap;color:#78350f;margin:0;font-size:13px">' + escHtml(repair.internal_notes) + '</p></div>';
            html += '</div>';
        }

        // Photos
        html += '<div class="rd-card" style="margin-bottom:24px">';
        html += '<div class="rd-card-header"><h3><span class="dashicons dashicons-camera" style="margin-right:6px;color:#8b5cf6"></span>' + __('Photos & Files', 'vollstart-repair-desk') + ' <span style="color:#94a3b8;font-weight:400">(' + files.length + ')</span></h3></div>';
        html += '<div class="rd-card-body" id="rd-repair-files-' + repair.id + '"></div>';
        html += '</div>';

        // Messages (above work steps so worker sees discussion first)
        var repairIsFinal = isFinalStatus(repair.status);
        if (cfg.enableMessages) {
        html += '<div class="rd-card" style="margin-bottom:24px">';
        html += '<div class="rd-card-header"><h3><span class="dashicons dashicons-format-chat" style="margin-right:6px;color:#64748b"></span>' + __('Messages', 'vollstart-repair-desk') + '</h3></div>';
        html += '<div id="rd-messages-content" data-repair-id="' + repair.id + '"><div class="rd-loading"><span class="spinner is-active"></span></div></div>';
        if (!repairIsFinal) {
            html += '<div style="padding:12px 16px;border-top:1px solid #f1f5f9">';
            html += '<div style="display:flex;gap:8px">';
            html += '<textarea id="rd-message-text" rows="2" placeholder="' + __('Write a message to the customer...', 'vollstart-repair-desk') + '" style="flex:1;padding:8px 12px;border:1px solid #e2e8f0;border-radius:8px;font-size:14px;resize:vertical;box-sizing:border-box"></textarea>';
            html += '<button class="rd-btn rd-btn-primary" id="rd-send-message" data-repair-id="' + repair.id + '" style="align-self:flex-end;white-space:nowrap"><span class="dashicons dashicons-yes" style="font-size:16px;width:16px;height:16px"></span> ' + __('Send', 'vollstart-repair-desk') + '</button>';
            html += '</div>';
            html += '<div style="font-size:11px;color:#94a3b8;margin-top:4px">' + __('Visible to the customer on the public status page (if enabled).', 'vollstart-repair-desk') + '</div>';
            html += '</div>';
        } else {
            html += '<div style="padding:8px 16px;border-top:1px solid #f1f5f9;font-size:12px;color:#94a3b8;text-align:center">' + __('Repair is closed — messaging disabled.', 'vollstart-repair-desk') + '</div>';
        }
        html += '</div>';
        } // end enableMessages

        // Checklist / Progress
        if (cfg.enableWorkSteps) {
        clProgress = clProgress || { total: 0, checked: 0, percent: 0 };
        html += '<div class="rd-card" style="margin-bottom:24px">';
        html += '<div class="rd-card-header"><h3><span class="dashicons dashicons-yes-alt" style="margin-right:6px;color:#22c55e"></span>' + __('Work Steps Checklist', 'vollstart-repair-desk');
        html += ' <span style="color:#94a3b8;font-weight:400" id="rd-checklist-count">(' + (clProgress.total > 0 ? clProgress.checked + '/' + clProgress.total : '0') + ')</span>';
        html += '</h3></div>';
        if (clProgress.total > 0) {
            html += '<div style="padding:0 16px 12px"><div style="height:6px;background:#e2e8f0;border-radius:999px;overflow:hidden"><div style="height:100%;width:' + clProgress.percent + '%;background:#22c55e;border-radius:999px;transition:width 0.3s" id="rd-checklist-progress-bar"></div></div></div>';
        }
        html += '<div id="rd-checklist-content"><div class="rd-loading"><span class="spinner is-active"></span></div></div>';
        html += '</div>';
        }

        // Timeline — collapsed, lazy loaded on click
        html += '<div class="rd-card" style="margin-top:24px">';
        html += '<div class="rd-card-header"><h3><span class="dashicons dashicons-backup" style="margin-right:6px;color:#22c55e"></span>' + __('Status Timeline', 'vollstart-repair-desk') + '</h3>';
        html += '<div class="rd-card-actions">';
        html += '<button class="rd-btn rd-btn-sm rd-btn-secondary" id="rd-load-timeline" data-id="' + repair.id + '"><span class="dashicons dashicons-arrow-down-alt2" style="font-size:14px;width:14px;height:14px"></span></button>';
        html += '</div>';
        html += '</div>';
        html += '<div id="rd-timeline-content" style="display:none"></div>';
        html += '</div>';

        // Rating — internal + customer ratings
        if (cfg.enableRatings) {
            html += '<div class="rd-card" style="margin-top:24px">';
            html += '<div class="rd-card-header"><h3><span class="dashicons dashicons-star-filled" style="margin-right:6px;color:#f59e0b"></span>' + __('Ratings', 'vollstart-repair-desk') + '</h3>';
            html += '<div class="rd-card-actions">';
            if (customer && customer.email) {
                html += '<button class="rd-btn rd-btn-sm rd-btn-secondary" id="rd-send-rating-email" data-id="' + repair.id + '" title="' + __('Request rating from customer', 'vollstart-repair-desk') + '"><span class="dashicons dashicons-email" style="font-size:14px;width:14px;height:14px;margin-right:4px"></span>' + __('Request Rating', 'vollstart-repair-desk') + '</button>';
            }
            html += '<button class="rd-btn rd-btn-sm rd-btn-secondary" id="rd-load-ratings" data-id="' + repair.id + '"><span class="dashicons dashicons-arrow-down-alt2" style="font-size:14px;width:14px;height:14px"></span></button>';
            html += '</div></div>';
            if (!customer || !customer.email) {
                html += '<div style="padding:8px 16px;font-size:12px;color:#94a3b8;border-bottom:1px solid #f1f5f9"><span class="dashicons dashicons-info" style="font-size:12px;width:12px;height:12px;margin-right:4px"></span>' + __('No customer email — the customer can rate via the status page or customer portal.', 'vollstart-repair-desk') + '</div>';
            }
            // Rating forms: repair + customer
            function ratingRow(label, type, existingRatings, repairId) {
                var ex = existingRatings.filter(function(r) { return r.type === type; });
                var val = ex.length ? parseInt(ex[0].rating) : 0;
                var com = ex.length ? ex[0].comment || '' : '';
                var h = '<div style="padding:10px 16px;border-bottom:1px solid #f1f5f9">';
                h += '<div style="display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:6px">';
                h += '<span style="font-size:12px;color:#64748b;min-width:80px">' + label + '</span>';
                h += '<span class="rd-rating-stars" data-type="' + type + '" data-repair-id="' + repairId + '" style="font-size:22px;cursor:pointer">';
                for (var s = 1; s <= 5; s++) {
                    h += '<span class="rd-istar" data-value="' + s + '" style="color:' + (s <= val ? '#f59e0b' : '#e2e8f0') + ';transition:color 0.15s">&#9733;</span>';
                }
                h += '</span>';
                h += '<input type="hidden" class="rd-rating-val" data-type="' + type + '" value="' + val + '">';
                h += '<input type="text" class="rd-rating-comment" data-type="' + type + '" value="' + escAttr(com) + '" placeholder="' + __('Comment', 'vollstart-repair-desk') + '" style="flex:1;padding:5px 8px;border:1px solid #e2e8f0;border-radius:6px;font-size:12px;min-width:100px">';
                h += '<button class="rd-btn rd-btn-sm rd-btn-primary rd-save-rating" data-type="' + type + '" data-repair-id="' + repairId + '">' + __('Save', 'vollstart-repair-desk') + '</button>';
                h += '</div></div>';
                return h;
            }
            html += ratingRow(__('Repair:', 'vollstart-repair-desk'), 'internal', ratings || [], repair.id);
            if (customer) {
                html += ratingRow(__('Customer:', 'vollstart-repair-desk'), 'customer', ratings || [], repair.id);
            }
            html += '<div id="rd-ratings-content" style="display:none"></div>';
            html += '</div>';
        }

        // Email History — collapsed, lazy loaded + manual send button
        html += '<div class="rd-card" style="margin-top:24px">';
        html += '<div class="rd-card-header"><h3><span class="dashicons dashicons-email" style="margin-right:6px;color:#3b82f6"></span>' + __('Emails', 'vollstart-repair-desk') + '</h3>';
        html += '<div class="rd-card-actions">';
        html += '<button class="rd-btn rd-btn-sm rd-btn-primary" id="rd-send-manual-email" data-id="' + repair.id + '"><span class="dashicons dashicons-email-alt" style="font-size:14px;width:14px;height:14px"></span> ' + __('Send Update', 'vollstart-repair-desk') + '</button>';
        html += '<button class="rd-btn rd-btn-sm rd-btn-secondary" id="rd-load-email-log" data-id="' + repair.id + '"><span class="dashicons dashicons-arrow-down-alt2" style="font-size:14px;width:14px;height:14px"></span></button>';
        html += '</div></div>';
        html += '<div id="rd-email-log-content" style="display:none"></div>';
        html += '</div>';

        // Audit Trail — lazy loaded on click
        html += '<div class="rd-card" style="margin-top:24px">';
        html += '<div class="rd-card-header"><h3><span class="dashicons dashicons-list-view" style="margin-right:6px;color:#64748b"></span>' + __('Audit Trail', 'vollstart-repair-desk') + '</h3>';
        html += '<div class="rd-card-actions">';
        html += '<button class="rd-btn rd-btn-sm rd-btn-secondary" id="rd-export-audit-csv" data-id="' + repair.id + '" data-repair-number="' + escAttr(repair.repair_number) + '" style="display:none"><span class="dashicons dashicons-download" style="font-size:14px;width:14px;height:14px"></span> CSV</button>';
        html += '<button class="rd-btn rd-btn-sm rd-btn-secondary" id="rd-load-audit" data-id="' + repair.id + '"><span class="dashicons dashicons-arrow-down-alt2" style="font-size:14px;width:14px;height:14px"></span></button>';
        html += '</div>';
        html += '</div>';
        html += '<div id="rd-audit-trail-content" style="display:none"></div>';
        html += '</div>';

        $('#rd-tab-content').html(html);

        // Load file upload widget
        renderUploadWidget('#rd-repair-files-' + repair.id, 'repair', repair.id, { showThumbnail: false, showCamera: true });

        // Load checklist immediately (always open)
        if (cfg.enableWorkSteps) loadChecklistContent(repair.id);

        // Load messages
        if (cfg.enableMessages) loadMessages(repair.id);
    }

    function loadMessages(repairId) {
        rdAjax('get_messages', { repair_id: repairId }, function(result) {
            var messages = result.messages || [];
            var html = '';
            if (messages.length === 0) {
                html = '<p style="color:#94a3b8;font-size:13px;text-align:center;padding:12px">' + __('No messages yet.', 'vollstart-repair-desk') + '</p>';
            } else {
                html = '<div style="padding:12px 16px;max-height:400px;overflow-y:auto">';
                for (var i = 0; i < messages.length; i++) {
                    var m = messages[i];
                    var isStaff = m.sender_type === 'staff' || m.sender_type === 'shop';
                    html += '<div style="display:flex;margin-bottom:10px;justify-content:' + (isStaff ? 'flex-end' : 'flex-start') + '">';
                    html += '<div style="max-width:80%;padding:8px 12px;border-radius:10px;background:' + (isStaff ? '#eff6ff' : '#f1f5f9') + '">';
                    html += '<div style="font-size:13px;white-space:pre-wrap">' + escHtml(m.message) + '</div>';
                    html += '<div style="font-size:11px;color:#94a3b8;margin-top:2px">' + escHtml(m.sender_name || (isStaff ? __('Staff', 'vollstart-repair-desk') : __('Customer', 'vollstart-repair-desk'))) + ' &middot; ' + escHtml(m.created_at) + '</div>';
                    html += '</div></div>';
                }
                html += '</div>';
            }
            $('#rd-messages-content').html(html);
        });
    }

    // Send message
    $(document).on('click', '#rd-send-message', function() {
        var repairId = $(this).data('repair-id');
        var $text = $('#rd-message-text');
        var message = $text.val().trim();
        if (!message) return;
        var $btn = $(this);
        var origHtml = $btn.html();
        $btn.prop('disabled', true).html('<span class="spinner is-active" style="float:none;margin:0"></span> ' + __('Sending...', 'vollstart-repair-desk'));
        $text.prop('disabled', true);
        rdAjax('send_message', { repair_id: repairId, message: message }, function() {
            $btn.prop('disabled', false).html(origHtml);
            $text.prop('disabled', false).val('');
            loadMessages(repairId);
        }, {spin: true});
    });

    // Ctrl+Enter to send message
    $(document).on('keydown', '#rd-message-text', function(e) {
        if (e.ctrlKey && e.key === 'Enter') {
            $('#rd-send-message').trigger('click');
        }
    });

    // Back to repairs list
    $(document).on('click', '#rd-fv-refresh', function() {
        openRepairFullView($(this).data('id'));
    });

    // Confirm send PDF invoice
    $(document).on('click', '#rd-confirm-send-pdf', function() {
        var repairId = $(this).data('id');
        var email = $('#rd-send-pdf-email').val().trim();
        var updateEmail = $('#rd-send-pdf-update-email').is(':checked') ? 1 : 0;

        if (!email) { $('#rd-send-pdf-email').focus(); return; }

        var $btn = $(this);
        $btn.prop('disabled', true).text(__('Sending...', 'vollstart-repair-desk'));

        rdAjax('send_invoice_pdf', { repair_id: repairId, email: email, update_email: updateEmail }, function(result) {
            rdModalClose('rd-send-pdf-modal');
            if (result.sent) {
                var msg = __('Invoice sent successfully.', 'vollstart-repair-desk');
                if (result.email_updated) {
                    msg += ' ' + __('Customer email updated.', 'vollstart-repair-desk');
                }
                alert(msg);
            } else {
                alert(__('Failed to send email.', 'vollstart-repair-desk'));
            }
        }, { spin: true });
    });

    // --- Inline Assigned To edit in repair full view ---
    $(document).on('click', '.rd-fv-assigned-name', function() {
        var $wrap = $(this).closest('#rd-fv-assigned-to');
        var $name = $wrap.find('.rd-fv-assigned-name');
        var $sel = $wrap.find('.rd-fv-assigned-select');
        var currentId = $wrap.data('staff-id') || '';

        // Load staff options if not yet loaded
        if ($sel.find('option').length <= 1) {
            rdAjax('get_staff_dropdown', {}, function(result) {
                $.each(result.staffList || [], function(i, s) {
                    var sel = (s.id == currentId) ? ' selected' : '';
                    $sel.append('<option value="' + s.id + '"' + sel + '>' + escHtml(s.name) + '</option>');
                });
                $name.hide();
                $sel.show().focus();
            });
        } else {
            $sel.val(currentId);
            $name.hide();
            $sel.show().focus();
        }
    });

    $(document).on('change', '.rd-fv-assigned-select', function() {
        var $wrap = $(this).closest('#rd-fv-assigned-to');
        var repairId = $wrap.data('repair-id');
        var newStaffId = $(this).val();
        var newName = $(this).find('option:selected').text();
        var $name = $wrap.find('.rd-fv-assigned-name');
        var $feedback = $wrap.find('.rd-fv-assigned-feedback');
        var $sel = $(this);

        rdAjax('update_repair', { id: repairId, assigned_to: newStaffId }, function() {
            $wrap.data('staff-id', newStaffId);
            $wrap.attr('data-staff-id', newStaffId);
            $name.html(newStaffId ? escHtml(newName) + ' <span class="dashicons dashicons-edit" style="font-size:12px;width:12px;height:12px;color:#94a3b8"></span>' : '<span style="color:#cbd5e1">\u2014</span> <span class="dashicons dashicons-edit" style="font-size:12px;width:12px;height:12px;color:#94a3b8"></span>');
            $sel.hide();
            $name.show();
            $feedback.text(__('Saved', 'vollstart-repair-desk')).show();
            setTimeout(function() { $feedback.fadeOut(); }, 2000);
        });
    });

    $(document).on('blur', '.rd-fv-assigned-select', function() {
        var $wrap = $(this).closest('#rd-fv-assigned-to');
        // Small delay to allow change event to fire first
        var $sel = $(this);
        setTimeout(function() {
            if ($sel.is(':visible')) {
                $sel.hide();
                $wrap.find('.rd-fv-assigned-name').show();
            }
        }, 200);
    });

    $(document).on('click', '.rd-goto-options', function(e) {
        e.preventDefault();
        $('.rd-tab').removeClass('active');
        $('.rd-tab[data-tab="options"]').addClass('active');
        loadTab('options');
    });

    $(document).on('click', '#rd-back-to-repairs', function() {
        loadRepairs();
    });

    // Regenerate access code
    $(document).on('click', '#rd-regenerate-code', function() {
        var repairId = $(this).data('id');
        if (!confirm(__('Revoke the current access code and generate a new one? The old code will stop working immediately.', 'vollstart-repair-desk'))) return;
        rdAjax('regenerate_access_code', { id: repairId }, function(result) {
            if (result.access_code) {
                openRepairFullView(repairId);
            }
        });
    });

    // Navigate from repair to device full view
    $(document).on('click', '.rd-goto-device', function() {
        var id = $(this).data('id');
        if (id) {
            currentTab = 'devices';
            $('.rd-tab').removeClass('active').filter('[data-tab="devices"]').addClass('active');
            $('html, body').animate({ scrollTop: 0 }, 200);
            openDeviceFullView(id);
        }
    });

    // Navigate from repair to customer full view
    $(document).on('click', '.rd-goto-customer', function() {
        var id = $(this).data('id');
        if (id) {
            // Set customers tab as active
            currentTab = 'customers';
            $('.rd-tab').removeClass('active');
            $('.rd-tab[data-tab="customers"]').addClass('active');
            $('html, body').animate({ scrollTop: 0 }, 200);
            openCustomerFullView(id);
        }
    });

    // Lazy-load audit trail
    // Star rating — select + hover (generic for all rating rows)
    $(document).on('click', '.rd-istar', function() {
        var val = $(this).data('value');
        var $stars = $(this).closest('.rd-rating-stars');
        var type = $stars.data('type');
        $stars.find('.rd-istar').each(function() {
            $(this).css('color', $(this).data('value') <= val ? '#f59e0b' : '#e2e8f0');
        });
        $('.rd-rating-val[data-type="' + type + '"]').val(val);
    });
    $(document).on('mouseenter', '.rd-istar', function() {
        var val = $(this).data('value');
        $(this).closest('.rd-rating-stars').find('.rd-istar').each(function() {
            $(this).css('color', $(this).data('value') <= val ? '#f59e0b' : '#e2e8f0');
        });
    });
    $(document).on('mouseleave', '.rd-rating-stars', function() {
        var type = $(this).data('type');
        var selected = parseInt($('.rd-rating-val[data-type="' + type + '"]').val()) || 0;
        $(this).find('.rd-istar').each(function() {
            $(this).css('color', $(this).data('value') <= selected ? '#f59e0b' : '#e2e8f0');
        });
    });

    // Customer rating stars in customer view
    $(document).on('click', '.rd-cstar', function() {
        var val = $(this).data('value');
        $('#rd-cust-rate-val').val(val);
        $(this).parent().find('.rd-cstar').each(function() {
            $(this).css('color', $(this).data('value') <= val ? '#f59e0b' : '#e2e8f0');
        });
    });
    $(document).on('mouseenter', '.rd-cstar', function() {
        var val = $(this).data('value');
        $(this).parent().find('.rd-cstar').each(function() {
            $(this).css('color', $(this).data('value') <= val ? '#f59e0b' : '#e2e8f0');
        });
    });
    $(document).on('mouseleave', '.rd-cust-rate-stars', function() {
        var selected = parseInt($('#rd-cust-rate-val').val()) || 0;
        $(this).find('.rd-cstar').each(function() {
            $(this).css('color', $(this).data('value') <= selected ? '#f59e0b' : '#e2e8f0');
        });
    });

    // Load ratings list
    $(document).on('click', '#rd-load-ratings', function() {
        var $btn = $(this);
        var $content = $('#rd-ratings-content');
        if ($content.is(':visible')) {
            $content.slideUp(200);
            $btn.find('.dashicons').removeClass('dashicons-arrow-up-alt2').addClass('dashicons-arrow-down-alt2');
            return;
        }
        $content.html('<div class="rd-loading"><span class="spinner is-active"></span></div>').slideDown(200);
        $btn.find('.dashicons').removeClass('dashicons-arrow-down-alt2').addClass('dashicons-arrow-up-alt2');
        rdAjax('get_ratings', { repair_id: $btn.data('id') }, function(result) {
            var ratings = result.ratings || [];
            var html = '<div class="rd-card-body">';
            if (!ratings.length) {
                html += '<p style="color:#94a3b8;font-size:13px;text-align:center">' + __('No ratings yet.', 'vollstart-repair-desk') + '</p>';
            } else {
                $.each(ratings, function(i, r) {
                    var stars = '';
                    for (var s = 1; s <= 5; s++) stars += '<span style="color:' + (s <= r.rating ? '#f59e0b' : '#e2e8f0') + '">&#9733;</span>';
                    var typeLabel = r.type === 'internal' ? __('Internal', 'vollstart-repair-desk') : r.type === 'repair' ? __('Customer', 'vollstart-repair-desk') : __('Business', 'vollstart-repair-desk');
                    html += '<div style="display:flex;align-items:center;gap:10px;padding:8px 0;border-bottom:1px solid #f1f5f9">';
                    html += '<span style="font-size:11px;padding:2px 8px;border-radius:999px;background:#f1f5f9;color:#64748b">' + typeLabel + '</span>';
                    html += '<span style="font-size:16px">' + stars + '</span>';
                    if (r.comment) html += '<span style="font-size:12px;color:#64748b;flex:1">' + escHtml(r.comment) + '</span>';
                    html += '<span style="font-size:11px;color:#94a3b8">' + escHtml(r.created_at) + '</span>';
                    html += '</div>';
                });
            }
            html += '</div>';
            $content.html(html);
        });
    });

    // Manual send email
    $(document).on('click', '#rd-send-manual-email', function() {
        var $btn = $(this);
        var repairId = $btn.data('id');
        $btn.prop('disabled', true).find('.dashicons').removeClass('dashicons-email-alt').addClass('dashicons-update');
        rdAjax('send_manual_email', { repair_id: repairId }, function(result) {
            $btn.prop('disabled', false).find('.dashicons').removeClass('dashicons-update').addClass('dashicons-email-alt');
            if (result.sent) {
                $btn.text(__('Sent!', 'vollstart-repair-desk'));
                setTimeout(function() { $btn.html('<span class="dashicons dashicons-email-alt" style="font-size:14px;width:14px;height:14px"></span> ' + __('Send Update', 'vollstart-repair-desk')); }, 2000);
            } else {
                alert(__('Could not send email. Check customer email address.', 'vollstart-repair-desk'));
            }
        }, {spin: true});
    });

    // Email log toggle (lazy load)
    $(document).on('click', '#rd-load-email-log', function() {
        var $btn = $(this);
        var repairId = $btn.data('id');
        var $content = $('#rd-email-log-content');
        if ($content.is(':visible')) {
            $content.slideUp(200);
            $btn.find('.dashicons').removeClass('dashicons-arrow-up-alt2').addClass('dashicons-arrow-down-alt2');
            return;
        }
        $content.html('<div class="rd-loading"><span class="spinner is-active"></span></div>').slideDown(200);
        $btn.find('.dashicons').removeClass('dashicons-arrow-down-alt2').addClass('dashicons-arrow-up-alt2');
        rdAjax('get_email_log', { repair_id: repairId }, function(result) {
            var emails = result.emails || [];
            var html = '<div class="rd-card-body">';
            if (!emails.length) {
                html += '<p style="color:#94a3b8;font-size:13px;text-align:center">' + __('No emails sent yet.', 'vollstart-repair-desk') + '</p>';
            } else {
                html += '<table class="rd-table" style="width:100%;font-size:13px"><thead><tr><th>' + __('Date', 'vollstart-repair-desk') + '</th><th>' + __('Type', 'vollstart-repair-desk') + '</th><th>' + __('To', 'vollstart-repair-desk') + '</th><th>' + __('Subject', 'vollstart-repair-desk') + '</th><th></th></tr></thead><tbody>';
                $.each(emails, function(i, e) {
                    var statusIcon = e.success && e.success !== '0' ? '<span style="color:#22c55e">&#10003;</span>' : '<span style="color:#ef4444">&#10007;</span>';
                    html += '<tr>';
                    html += '<td style="white-space:nowrap">' + escHtml(e.created_at) + '</td>';
                    html += '<td>' + statusIcon + ' ' + escHtml(e.email_type) + '</td>';
                    html += '<td>' + escHtml(e.recipient) + '</td>';
                    html += '<td style="max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap" title="' + escAttr(e.subject) + '">' + escHtml(e.subject) + '</td>';
                    html += '<td style="text-align:right;white-space:nowrap"><div style="display:flex;gap:4px;justify-content:flex-end">';
                    html += '<button class="rd-btn rd-btn-sm rd-btn-secondary rd-view-email" data-body="' + escAttr(e.body) + '" data-subject="' + escAttr(e.subject) + '" title="' + __('View', 'vollstart-repair-desk') + '"><span class="dashicons dashicons-visibility" style="font-size:14px;width:14px;height:14px"></span></button>';
                    html += '<button class="rd-btn rd-btn-sm rd-btn-secondary rd-resend-email" data-id="' + e.id + '" title="' + __('Resend', 'vollstart-repair-desk') + '"><span class="dashicons dashicons-controls-repeat" style="font-size:14px;width:14px;height:14px"></span></button>';
                    html += '</div></td>';
                    html += '</tr>';
                });
                html += '</tbody></table>';
            }
            html += '</div>';
            $content.html(html);
        });
    });

    // View email body
    $(document).on('click', '.rd-view-email', function() {
        var subject = $(this).attr('data-subject');
        var body = $(this).attr('data-body');
        rdModal('rd-email-preview', escHtml(subject), '<div style="padding:16px">' + body + '</div>', { maxWidth: '600px' });
    });

    // Resend email
    $(document).on('click', '.rd-resend-email', function() {
        var $btn = $(this);
        var logId = $btn.data('id');
        if (!confirm(__('Resend this email to the current customer email address?', 'vollstart-repair-desk'))) return;
        $btn.prop('disabled', true);
        rdAjax('resend_email', { log_id: logId }, function(result) {
            $btn.prop('disabled', false);
            if (result.sent) {
                $btn.find('.dashicons').removeClass('dashicons-controls-repeat').addClass('dashicons-yes');
                setTimeout(function() { $btn.find('.dashicons').removeClass('dashicons-yes').addClass('dashicons-controls-repeat'); }, 2000);
            }
        }, {spin: true});
    });

    // Timeline toggle (lazy load)
    $(document).on('click', '#rd-load-timeline', function() {
        var $btn = $(this);
        var id = $btn.data('id');
        var $content = $('#rd-timeline-content');

        if ($content.is(':visible')) {
            $content.slideUp(200);
            $btn.find('.dashicons').removeClass('dashicons-arrow-up-alt2').addClass('dashicons-arrow-down-alt2');
            return;
        }

        $content.html('<div class="rd-loading"><span class="spinner is-active"></span></div>').slideDown(200);
        $btn.find('.dashicons').removeClass('dashicons-arrow-down-alt2').addClass('dashicons-arrow-up-alt2');

        rdAjax('get_repair', { id: id }, function(result) {
            var timeline = result.timeline || [];
            var html = '<div class="rd-card-body"><div class="rd-timeline">';
            if (timeline.length) {
                $.each(timeline, function(i, entry) {
                    if (entry.event_type === 'time_tracked') {
                        html += '<div class="rd-timeline-item" style="--tl-color:#8b5cf6">';
                        html += '<div class="rd-timeline-date">' + escHtml(formatDateTime(entry.created_at)) + '</div>';
                        html += '<div class="rd-timeline-text"><span class="dashicons dashicons-clock" style="font-size:12px;width:12px;height:12px;color:#8b5cf6"></span> <strong style="color:#8b5cf6">' + __('Time tracked', 'vollstart-repair-desk') + '</strong>';
                        if (entry.note) html += '<br><span style="color:#64748b;font-size:12px">' + escHtml(entry.note) + '</span>';
                        html += '</div>';
                        html += '<div class="rd-timeline-by">' + escHtml(entry.changed_by) + '</div>';
                        html += '</div>';
                    } else {
                        var newLabel = getStatusLabel(entry.new_status);
                        var newColor = getStatusColor(entry.new_status);
                        html += '<div class="rd-timeline-item" style="--tl-color:' + newColor + '">';
                        html += '<div class="rd-timeline-date">' + escHtml(formatDateTime(entry.created_at)) + '</div>';
                        html += '<div class="rd-timeline-text">';
                        if (entry.old_status) {
                            html += '<span style="color:#94a3b8">' + escHtml(getStatusLabel(entry.old_status)) + '</span> \u2192 ';
                        }
                        html += '<strong style="color:' + newColor + '">' + escHtml(newLabel) + '</strong>';
                        if (entry.note) html += '<br><span style="color:#64748b;font-size:12px">' + escHtml(entry.note) + '</span>';
                        html += '</div>';
                        html += '<div class="rd-timeline-by">' + escHtml(entry.changed_by) + '</div>';
                        html += '</div>';
                    }
                });
            } else {
                html += '<p style="color:#94a3b8;font-size:13px">' + __('No status changes yet.', 'vollstart-repair-desk') + '</p>';
            }
            html += '</div></div>';
            $content.html(html);
        });
    });

    $(document).on('click', '#rd-load-audit', function() {
        var $btn = $(this);
        var id = $btn.data('id');
        var $content = $('#rd-audit-trail-content');

        if ($content.is(':visible')) {
            $content.slideUp(200);
            $btn.find('.dashicons').removeClass('dashicons-arrow-up-alt2').addClass('dashicons-arrow-down-alt2');
            $('#rd-export-audit-csv').hide();
            return;
        }

        $content.html('<div class="rd-loading"><span class="spinner is-active"></span></div>').slideDown(200);
        $btn.find('.dashicons').removeClass('dashicons-arrow-down-alt2').addClass('dashicons-arrow-up-alt2');
        $('#rd-export-audit-csv').show();

        rdAjax('get_audit_log', { id: id }, function(result) {
            var html = '<table class="rd-table" style="font-size:12px">';
            html += '<thead><tr><th>' + __('Date', 'vollstart-repair-desk') + '</th><th>' + __('Event', 'vollstart-repair-desk') + '</th><th>' + __('Details', 'vollstart-repair-desk') + '</th><th>' + __('By', 'vollstart-repair-desk') + '</th></tr></thead>';
            html += '<tbody>' + getAuditTrailRows(result.auditLog) + '</tbody></table>';
            $content.html(html);
            // Store data for CSV export
            $content.data('audit', result.auditLog);
        });
    });

    // Export audit trail as CSV
    $(document).on('click', '#rd-export-audit-csv', function() {
        var auditLog = $('#rd-audit-trail-content').data('audit');
        if (!auditLog || !auditLog.length) return;

        var repairNumber = $(this).data('repair-number') || 'repair';
        var labels = getAuditEventLabels();
        var rows = [['Date', 'Event', 'Details', 'Changed By']];

        $.each(auditLog, function(i, e) {
            rows.push([
                e.created_at || '',
                labels[e.event_type] || e.event_type,
                (e.note || '').replace(/"/g, '""'),
                e.changed_by || ''
            ]);
        });

        var csv = rows.map(function(r) {
            return r.map(function(c) { return '"' + c + '"'; }).join(',');
        }).join('\n');

        var blob = new Blob(['\uFEFF' + csv], { type: 'text/csv;charset=utf-8' });
        var url = URL.createObjectURL(blob);
        var a = document.createElement('a');
        a.href = url;
        a.download = 'audit-trail-' + repairNumber + '-' + new Date().toISOString().slice(0, 10) + '.csv';
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
        URL.revokeObjectURL(url);
    });

    // Load checklist for repair (lazy)
    $(document).on('click', '#rd-load-checklist', function() {
        var $btn = $(this);
        var repairId = $btn.data('id');
        var $content = $('#rd-checklist-content');
        if ($content.is(':visible')) {
            $content.slideUp(200);
            $btn.find('.dashicons').removeClass('dashicons-arrow-up-alt2').addClass('dashicons-arrow-down-alt2');
            return;
        }
        $content.html('<div class="rd-loading"><span class="spinner is-active"></span></div>').slideDown(200);
        $btn.find('.dashicons').removeClass('dashicons-arrow-down-alt2').addClass('dashicons-arrow-up-alt2');
        loadChecklistContent(repairId);
    });

    function loadChecklistContent(repairId) {
        rdAjax('get_repair_steps', { repair_id: repairId }, function(result) {
            var steps = result.steps || {};
            var html = '';
            var hasSteps = false;

            $.each(steps, function(groupName, items) {
                hasSteps = true;
                html += '<div style="padding:8px 16px"><div style="display:flex;align-items:center;margin-bottom:8px">';
                html += '<span style="font-size:12px;font-weight:600;color:#64748b;text-transform:uppercase;flex:1">' + escHtml(groupName) + '</span>';
                if (cfg.allowRemoveSteps) {
                    html += '<button class="rd-remove-group" data-repair-id="' + repairId + '" data-group="' + escAttr(groupName) + '" style="background:none;border:none;color:#dc2626;cursor:pointer;font-size:11px;padding:2px 6px" title="' + __('Remove all steps in this group', 'vollstart-repair-desk') + '"><span class="dashicons dashicons-trash" style="font-size:12px;width:12px;height:12px"></span></button>';
                }
                html += '</div>';
                $.each(items, function(i, step) {
                    var checked = step.is_checked && step.is_checked !== '0';
                    var isRunning = !!step.timer_started_at;
                    var trackedMin = parseFloat(step.tracked_duration) || 0;
                    var defDur = parseFloat(step.default_duration) || 0;
                    var hasInstructions = (step.instructions && step.instructions.trim()) || (step.instruction_files && step.instruction_files.length > 0);

                    var isRemoved = step._removed;

                    // Card per step
                    html += '<div class="rd-step-card" style="border:1px solid ' + (isRemoved ? '#fca5a5' : checked ? '#a7f3d0' : '#e2e8f0') + ';border-radius:8px;margin-bottom:8px;background:' + (isRemoved ? '#fef2f2' : checked ? '#f0fdf4' : '#fff') + ';overflow:hidden' + (isRemoved ? ';opacity:0.6' : '') + '">';

                    // Top row: checkbox + title + timer
                    html += '<div style="display:flex;align-items:center;gap:10px;padding:10px 12px">';
                    html += '<input type="checkbox" class="rd-toggle-step" data-step-id="' + step.id + '" data-repair-id="' + step.repair_id + '"' + (checked ? ' checked' : '') + ' style="width:22px;height:22px;cursor:pointer;flex-shrink:0">';
                    html += '<div style="flex:1;min-width:0">';
                    html += '<div class="rd-step-title" style="font-size:14px;font-weight:500;' + (isRemoved ? 'text-decoration:line-through;color:#dc2626' : checked ? 'text-decoration:line-through;color:#94a3b8' : 'color:#1e293b') + '">' + escHtml(step.title) + (isRemoved ? ' <span style="font-size:11px;font-weight:400">(' + __('removed from template', 'vollstart-repair-desk') + ')</span>' : '') + '</div>';

                    // Short description preview (from instructions)
                    if (step.instructions && step.instructions.trim()) {
                        var preview = step.instructions.trim().substring(0, 80);
                        if (step.instructions.trim().length > 80) preview += '...';
                        html += '<div style="font-size:12px;color:#94a3b8;margin-top:2px">' + escHtml(preview) + '</div>';
                    }

                    // Meta: price + duration + checked by
                    var meta = [];
                    var stepPrice = parseFloat(step.default_price) || 0;
                    if (stepPrice > 0) {
                        meta.push(stepPrice.toFixed(2) + ' ' + cfg.currency);
                    }
                    if (defDur > 0) meta.push(defDur + ' min');
                    if (checked && step.checked_by) meta.push(escHtml(step.checked_by));
                    if (meta.length > 0) html += '<div style="font-size:11px;color:#94a3b8;margin-top:2px">' + meta.join(' \u00b7 ') + '</div>';

                    html += '</div>';

                    // Timer (only if time tracking enabled)
                    if (cfg.enableTimeTracking) {
                        var trackedSec = trackedMin * 60;
                        html += '<span id="rd-elapsed-' + step.id + '" style="font-size:22px;font-weight:600;font-variant-numeric:tabular-nums;color:' + (isRunning ? '#ef4444' : '#64748b') + '">' + formatTimerHMS(trackedSec) + '</span>';

                        // Register running timer
                        if (isRunning && step.timer_started_at) {
                            var serverNow = result._serverTime ? new Date(result._serverTime.replace(' ', 'T')).getTime() : Date.now();
                            var startedMs = new Date(step.timer_started_at.replace(' ', 'T')).getTime();
                            runningTimers[step.id] = {
                                started: Date.now() - (serverNow - startedMs),
                                trackedSec: trackedSec
                            };
                        }

                        // Play/Pause button (disabled when step checked off or repair is final)
                        var timerDisabled = checked || (currentRepair && isFinalStatus(currentRepair.status));
                        html += '<button class="rd-timer-btn" data-step-id="' + step.id + '" data-repair-id="' + step.repair_id + '"' + (timerDisabled ? ' disabled' : '') + ' style="background:' + (timerDisabled ? '#cbd5e1' : isRunning ? '#ef4444' : '#22c55e') + ';color:#fff;border:none;border-radius:6px;width:32px;height:32px;display:flex;align-items:center;justify-content:center;cursor:' + (timerDisabled ? 'not-allowed' : 'pointer') + ';flex-shrink:0">';
                        html += '<span class="dashicons dashicons-controls-' + (isRunning ? 'pause' : 'play') + '" style="font-size:16px;width:16px;height:16px"></span>';
                        html += '</button>';
                        // Manual time edit button
                        if (cfg.allowManualTimeEdit && cfg.allowManualTimeEdit !== '0') {
                            html += '<button class="rd-edit-time-btn" data-step-id="' + step.id + '" data-repair-id="' + step.repair_id + '" data-seconds="' + trackedSec + '" title="' + __('Edit tracked time', 'vollstart-repair-desk') + '" style="background:none;border:1px solid #e2e8f0;border-radius:6px;width:32px;height:32px;display:flex;align-items:center;justify-content:center;cursor:pointer;flex-shrink:0;color:#94a3b8">';
                            html += '<span class="dashicons dashicons-edit" style="font-size:14px;width:14px;height:14px"></span>';
                            html += '</button>';
                        }
                    }

                    // Delete button
                    if (cfg.allowRemoveSteps) {
                        html += '<button class="rd-delete-step" data-step-id="' + step.id + '" data-repair-id="' + step.repair_id + '" style="background:none;border:none;color:#cbd5e1;cursor:pointer;padding:4px;flex-shrink:0"><span class="dashicons dashicons-no" style="font-size:16px;width:16px;height:16px"></span></button>';
                    }
                    html += '</div>';

                    // Instruction images (always visible if available)
                    if (step.instruction_files && step.instruction_files.length > 0) {
                        html += '<div style="padding:0 12px 8px"><div class="rd-file-gallery">' + renderFileGallery(step.instruction_files, 'checklist_item', step.checklist_item_id || 0, false, { noDelete: true }) + '</div></div>';
                    }

                    // Full instructions (expandable if long)
                    if (step.instructions && step.instructions.trim().length > 80) {
                        html += '<div class="rd-step-instr-panel" id="rd-step-instr-' + step.id + '" style="display:none;padding:8px 12px;background:#eff6ff;border-top:1px solid #bfdbfe">';
                        html += '<p style="margin:0;font-size:13px;color:#1e3a5f;white-space:pre-wrap">' + escHtml(step.instructions) + '</p>';
                        html += '</div>';
                        html += '<button class="rd-show-instr-btn" data-step-id="' + step.id + '" style="display:block;width:100%;background:none;border:none;border-top:1px solid #f1f5f9;padding:4px;color:#3b82f6;font-size:11px;cursor:pointer">' + __('Read more', 'vollstart-repair-desk') + '</button>';
                    }

                    html += '</div>'; // end card
                });
                html += '</div>';
            });

            if (!hasSteps) {
                html += '<p style="color:#94a3b8;font-size:13px;text-align:center;padding:12px">' + __('No checklist items.', 'vollstart-repair-desk') + '</p>';
            }

            // Totals (duration + step cost breakdown)
            if (result.totals) {
                var t = result.totals;
                html += '<div style="padding:8px 16px;display:flex;gap:16px;font-size:12px;color:#64748b;border-top:1px solid #f1f5f9;flex-wrap:wrap">';
                if (t.estimated_duration > 0) html += '<span>' + __('Est.', 'vollstart-repair-desk') + ' ' + formatTimerHMS(t.estimated_duration * 60) + '</span>';
                if (t.tracked_duration > 0) html += '<span>' + __('Tracked', 'vollstart-repair-desk') + ' ' + formatTimerHMS(t.tracked_duration * 60) + '</span>';
                if (t.estimated_price > 0) html += '<span>' + __('Price', 'vollstart-repair-desk') + ' ' + t.estimated_price.toFixed(2) + ' ' + cfg.currency + '</span>';
                html += '</div>';
            }

            // Action bar: add work steps list + manual step
            html += '<div style="padding:10px 16px;border-top:1px solid #e2e8f0;display:flex;gap:8px;flex-wrap:wrap">';
            html += '<button class="rd-btn rd-btn-secondary rd-btn-sm" id="rd-add-worklist" data-repair-id="' + repairId + '"><span class="dashicons dashicons-list-view" style="font-size:14px;width:14px;height:14px"></span> ' + __('Add Work Steps', 'vollstart-repair-desk') + '</button>';
            if (cfg.allowManualSteps) {
                html += '<div style="flex:1;display:flex;gap:8px">';
                html += '<input type="text" id="rd-new-step-title" placeholder="' + __('Add a step...', 'vollstart-repair-desk') + '" style="flex:1;padding:8px 12px;border:1px solid #e2e8f0;border-radius:6px;font-size:14px">';
                html += '<button class="rd-btn rd-btn-primary rd-btn-sm" id="rd-add-step" data-repair-id="' + repairId + '" style="padding:8px 12px"><span class="dashicons dashicons-plus-alt2"></span></button>';
                html += '</div>';
            }
            html += '</div>';

            $('#rd-checklist-content').html(html);
        });
    }

    // Show/hide step instructions in repair
    $(document).on('click', '.rd-show-instr-btn', function() {
        var stepId = $(this).data('step-id');
        $('#rd-step-instr-' + stepId).slideToggle(200);
    });

    // Click instruction image → lightbox
    $(document).on('click', '.rd-instr-img', function() {
        openLightbox($(this).data('url'), $(this).data('name'), 'image');
    });

    // Add work steps list to repair — shows picker
    $(document).on('click', '#rd-add-worklist', function() {
        var repairId = $(this).data('repair-id');
        // Get existing checklist IDs in this repair + all available lists
        rdAjax('get_repair_steps', { repair_id: repairId }, function(stepsResult) {
            // Collect already-used checklist IDs
            var usedIds = [];
            $.each(stepsResult.steps || {}, function(group, items) {
                $.each(items, function(i, s) {
                    if (s.checklist_id && usedIds.indexOf(parseInt(s.checklist_id)) === -1) {
                        usedIds.push(parseInt(s.checklist_id));
                    }
                });
            });

            rdAjax('get_checklists', {}, function(result) {
                var checklists = result.checklists || [];
                if (checklists.length === 0) {
                    alert(__('No work steps defined yet. Create them in the Work Steps tab.', 'vollstart-repair-desk'));
                    return;
                }
                var bodyHtml = '';
                $.each(checklists, function(i, cl) {
                    var stepCount = (cl.items || []).length;
                    var alreadyAdded = usedIds.indexOf(parseInt(cl.id)) !== -1;
                    if (alreadyAdded) {
                        bodyHtml += '<div style="display:flex;align-items:center;gap:8px;width:100%;margin-bottom:6px;padding:10px 14px;background:#f8fafc;border:1px solid #e2e8f0;border-radius:8px;opacity:0.5">';
                        bodyHtml += '<strong style="flex:1;color:#94a3b8">' + escHtml(cl.name) + '</strong>';
                        bodyHtml += '<span style="color:#94a3b8;font-size:12px">' + __('already added', 'vollstart-repair-desk') + '</span>';
                        bodyHtml += '</div>';
                    } else {
                        bodyHtml += '<button class="rd-btn rd-btn-secondary rd-pick-worklist" data-repair-id="' + repairId + '" data-checklist-id="' + cl.id + '" style="display:flex;align-items:center;gap:8px;width:100%;margin-bottom:6px;padding:10px 14px;text-align:left">';
                        bodyHtml += '<strong style="flex:1">' + escHtml(cl.name) + '</strong>';
                        bodyHtml += '<span style="color:#94a3b8;font-size:12px">' + stepCount + ' ' + __('steps', 'vollstart-repair-desk') + '</span>';
                        bodyHtml += '</button>';
                    }
                });
                rdModal('rd-add-worklist-modal', __('Add Work Steps', 'vollstart-repair-desk'), bodyHtml, { maxWidth: '440px' });
            });
        });
    });

    // Pick a work steps list → add to repair
    $(document).on('click', '.rd-pick-worklist', function() {
        var repairId = $(this).data('repair-id');
        var checklistId = $(this).data('checklist-id');
        $('.rd-modal-backdrop').remove();
        rdAjax('add_worklist_to_repair', { repair_id: repairId, checklist_id: checklistId }, function(result) {
            if (result.progress) updateProgressBar(result.progress);
            loadChecklistContent(repairId);
        });
    });

    // Remove entire work steps group from repair
    $(document).on('click', '.rd-remove-group', function() {
        var repairId = $(this).data('repair-id');
        var groupName = $(this).data('group');
        if (!confirm(__('Remove all steps in', 'vollstart-repair-desk') + ' "' + groupName + '"? ' + __('This includes time tracking and checkmarks.', 'vollstart-repair-desk'))) return;
        rdAjax('remove_repair_group', { repair_id: repairId, group_name: groupName }, function(result) {
            if (result.progress) updateProgressBar(result.progress);
            loadChecklistContent(repairId);
        }, {spin: true});
    });

    // Timer start/stop — toggle via server, update step from response
    $(document).on('click', '.rd-timer-btn', function() {
        var $btn = $(this);
        var stepId = $btn.attr('data-step-id');
        $btn.prop('disabled', true);
        rdAjax('toggle_timer', { step_id: stepId }, function(result) {
            $btn.prop('disabled', false);
            if (!result.step) return;
            var step = result.step;
            var isRunning = !!step.timer_started_at;
            var trackedMin = parseFloat(step.tracked_duration) || 0;
            var trackedSec = trackedMin * 60;

            // Button: color + icon
            $btn.css('background', isRunning ? '#ef4444' : '#22c55e');
            $btn.find('.dashicons').removeClass('dashicons-controls-play dashicons-controls-pause')
                .addClass(isRunning ? 'dashicons-controls-pause' : 'dashicons-controls-play');

            // Elapsed span: show server value
            var el = document.getElementById('rd-elapsed-' + stepId);
            if (el) {
                el.textContent = formatTimerHMS(trackedSec);
                el.style.color = isRunning ? '#ef4444' : '#64748b';
            }

            // Registry: add or remove
            if (isRunning) {
                var serverNow = result._serverTime ? new Date(result._serverTime.replace(' ', 'T')).getTime() : Date.now();
                var startedMs = new Date(step.timer_started_at.replace(' ', 'T')).getTime();
                runningTimers[stepId] = {
                    started: Date.now() - (serverNow - startedMs),
                    trackedSec: trackedSec
                };
            } else {
                delete runningTimers[stepId];
            }
        });
    });

    // Manual time edit popup
    $(document).on('click', '.rd-edit-time-btn, .rd-edit-time-btn *', function(e) {
        var $btn = $(this).closest('.rd-edit-time-btn');
        if ($btn.prop('disabled')) return;
        e.preventDefault();
        e.stopPropagation();
        e.stopImmediatePropagation();
        var stepId = $btn.attr('data-step-id');
        var repairId = $btn.attr('data-repair-id');
        var currentSec = parseFloat($btn.attr('data-seconds')) || 0;
        var currentH = Math.floor(currentSec / 3600);
        var currentM = Math.floor((currentSec % 3600) / 60);
        var currentS = Math.floor(currentSec % 60);

        var bodyHtml = '<div style="display:flex;gap:8px;align-items:center;margin-bottom:16px">';
        bodyHtml += '<input type="number" id="rd-te-hours" value="' + currentH + '" min="0" step="1" style="width:60px;padding:8px;border:1px solid #e2e8f0;border-radius:6px;font-size:16px;text-align:center">';
        bodyHtml += '<span style="font-size:14px;color:#64748b">' + __('h', 'vollstart-repair-desk') + '</span>';
        bodyHtml += '<input type="number" id="rd-te-minutes" value="' + currentM + '" min="0" max="59" step="1" style="width:60px;padding:8px;border:1px solid #e2e8f0;border-radius:6px;font-size:16px;text-align:center">';
        bodyHtml += '<span style="font-size:14px;color:#64748b">' + __('min', 'vollstart-repair-desk') + '</span>';
        bodyHtml += '<input type="number" id="rd-te-seconds" value="' + currentS + '" min="0" max="59" step="1" style="width:60px;padding:8px;border:1px solid #e2e8f0;border-radius:6px;font-size:16px;text-align:center">';
        bodyHtml += '<span style="font-size:14px;color:#64748b">' + __('sec', 'vollstart-repair-desk') + '</span>';
        bodyHtml += '</div>';

        var footerHtml = '<button class="rd-btn rd-btn-secondary rd-close-modal">' + __('Cancel', 'vollstart-repair-desk') + '</button>';
        footerHtml += '<button class="rd-btn rd-btn-primary rd-te-save" data-step-id="' + stepId + '" data-repair-id="' + repairId + '">' + __('Save', 'vollstart-repair-desk') + '</button>';

        rdModal('rd-time-edit-modal', __('Edit tracked time', 'vollstart-repair-desk'), bodyHtml, { maxWidth: '320px', footer: footerHtml });
        setTimeout(function() { $('#rd-te-hours').focus().select(); }, 100);
    });

    // Save manual time
    $(document).on('click', '.rd-te-save', function() {
        var stepId = $(this).data('step-id');
        var repairId = $(this).data('repair-id');
        var hours = parseInt($('#rd-te-hours').val()) || 0;
        var minutes = parseInt($('#rd-te-minutes').val()) || 0;
        var seconds = parseInt($('#rd-te-seconds').val()) || 0;
        var totalMinutes = (hours * 60) + minutes + (seconds / 60);
        rdAjax('set_step_time', { step_id: stepId, tracked_duration: totalMinutes }, function(result) {
            $('#rd-time-edit-modal').remove();
            if (result.step) {
                var sec = (parseFloat(result.step.tracked_duration) || 0) * 60;
                $('#rd-elapsed-' + stepId).text(formatTimerHMS(sec)).css('color', '#64748b');
                $('.rd-edit-time-btn[data-step-id="' + stepId + '"]').attr('data-seconds', sec);
            }
        }, {spin: true});
    });

    // Cancel / close time edit modal — handled by rdModal close handlers

    // Toggle step — update in-place, no re-render
    $(document).on('change', '.rd-toggle-step', function() {
        var $cb = $(this);
        var stepId = $cb.data('step-id');
        var repairId = $cb.data('repair-id');
        $cb.prop('disabled', true);
        rdAjax('toggle_step', { step_id: stepId }, function(result) {
            $cb.prop('disabled', false);
            if (result.progress) updateProgressBar(result.progress);

            var step = result.step;
            if (step) {
                var checked = step.is_checked && step.is_checked !== '0';
                var $card = $cb.closest('.rd-step-card');

                // Card style
                $card.css({
                    'border-color': checked ? '#a7f3d0' : '#e2e8f0',
                    'background': checked ? '#f0fdf4' : '#fff'
                });

                // Title strikethrough
                $card.find('.rd-step-title').css({
                    'text-decoration': checked ? 'line-through' : 'none',
                    'color': checked ? '#94a3b8' : '#1e293b'
                });

                // Timer button: disable when checked, enable when unchecked
                var $timerBtn = $card.find('.rd-timer-btn');
                if ($timerBtn.length) {
                    $timerBtn.prop('disabled', checked).css({
                        'background': checked ? '#cbd5e1' : '#22c55e',
                        'cursor': checked ? 'not-allowed' : 'pointer'
                    });
                }

                // Timer: if auto-stopped on check, update elapsed + remove from registry
                if (checked && !step.timer_started_at) {
                    var trackedMin = parseFloat(step.tracked_duration) || 0;
                    var el = document.getElementById('rd-elapsed-' + stepId);
                    if (el) {
                        el.textContent = formatTimerHMS(trackedMin * 60);
                        el.style.color = '#64748b';
                    }
                    delete runningTimers[stepId];
                    $timerBtn.find('.dashicons').removeClass('dashicons-controls-pause').addClass('dashicons-controls-play');
                }
            }

            // Auto status change — update badge in-place
            if (result.trigger_status) {
                rdAjax('change_status', { id: repairId, status: result.trigger_status, note: __('Work steps completed', 'vollstart-repair-desk') }, function() {
                    updateStatusBadge(result.trigger_status);
                });
            }

        });
    });

    // Delete step — confirm first
    $(document).on('click', '.rd-delete-step', function() {
        var stepId = $(this).data('step-id');
        var repairId = $(this).data('repair-id');
        if (!confirm(__('Delete this step?', 'vollstart-repair-desk'))) return;
        rdAjax('delete_repair_step', { step_id: stepId }, function(result) {
            if (result.progress) updateProgressBar(result.progress);
            loadChecklistContent(repairId);
        }, {spin: true});
    });

    // Add step
    $(document).on('click', '#rd-add-step', function() {
        var title = $('#rd-new-step-title').val().trim();
        if (!title) return;
        var repairId = $(this).data('repair-id');
        rdAjax('add_repair_step', { repair_id: repairId, title: title }, function(result) {
            if (result.progress) updateProgressBar(result.progress);
            loadChecklistContent(repairId);
        });
    });

    // Enter key on add step input
    $(document).on('keydown', '#rd-new-step-title', function(e) {
        if (e.key === 'Enter') {
            e.preventDefault();
            $('#rd-add-step').trigger('click');
        }
    });

    function updateProgressBar(progress) {
        $('#rd-checklist-count').text('(' + progress.checked + '/' + progress.total + ')');
        $('#rd-checklist-progress-bar').css('width', progress.percent + '%');
    }

    function updateStatusBadge(slug) {
        var label = getStatusLabel(slug);
        var color = getStatusColor(slug);
        var $badge = $('#rd-fv-status-badge');
        $badge.text(label).css({
            'background': color + '15',
            'color': color,
            'border-color': color + '40'
        });
        // Sync dropdown
        $('#rd-fv-change-status').val(slug);
    }

    // Save repair device data as registered product for the customer
    $(document).on('click', '#rd-save-as-device', function() {
        var repairId = $(this).data('repair-id');
        var customerId = $(this).data('customer-id');
        if (!currentRepair) return;

        rdAjax('create_product', {
            customer_id: customerId,
            name: currentRepair.device_type || '',
            brand: currentRepair.device_brand || '',
            model: currentRepair.device_model || '',
            serial_number: currentRepair.device_serial || ''
        }, function(result) {
            if (result.product) {
                // Link the new product to this repair
                rdAjax('update_repair', { id: repairId, product_id: result.product.id }, function() {
                    openRepairFullView(repairId);
                }, {spin: true});
            }
        }, {spin: true});
    });

    // Full view: change status
    $(document).on('click', '#rd-fv-apply-status', function() {
        var id = $(this).data('id');
        var newStatus = $('#rd-fv-change-status').val();
        var newLabel = getStatusLabel(newStatus);

        // Note dialog
        var noteBody = '<p style="margin-bottom:12px">' + __('New status:', 'vollstart-repair-desk') + ' <strong style="color:' + getStatusColor(newStatus) + '">' + escHtml(newLabel) + '</strong></p>';
        noteBody += '<div class="rd-form-group"><label>' + __('Note (optional)', 'vollstart-repair-desk') + '</label>';
        noteBody += '<textarea id="rd-fv-status-note" rows="2" placeholder="' + __('e.g. Waiting for customer approval', 'vollstart-repair-desk') + '"></textarea></div>';
        var noteFooter = '<button class="rd-btn rd-btn-secondary rd-close-modal">' + __('Cancel', 'vollstart-repair-desk') + '</button>';
        noteFooter += '<button class="rd-btn rd-btn-primary" id="rd-fv-confirm-status" data-id="' + id + '" data-status="' + newStatus + '">' + __('Confirm', 'vollstart-repair-desk') + '</button>';
        rdModal('rd-status-note-modal', __('Change Status', 'vollstart-repair-desk'), noteBody, { maxWidth: '440px', footer: noteFooter });
        $('#rd-fv-status-note').focus();
    });

    $(document).on('click', '#rd-fv-confirm-status', function() {
        var id = $(this).data('id');
        var status = $(this).data('status');
        var note = $('#rd-fv-status-note').val();
        $('#rd-status-note-modal').remove();
        rdAjax('change_status', { id: id, status: status, note: note }, function() {
            updateStatusBadge(status);
        });
    });

    // --- Repair Detail Modal (peek from customer view etc.) ---

    function openRepairDetail(id) {
        rdAjax('get_repair', { id: id }, function(result) {
            renderRepairModal(result.repair, result.customer, result.timeline);
        });
    }

    function renderRepairModal(repair, customer, timeline) {
        var statuses = cfg.statuses || {};
        var statusLabel = statuses[repair.status] || repair.status;
        var device = [repair.device_brand, repair.device_model].filter(Boolean).join(' ') || repair.device_type || '—';

        var html = '';

        // Status + actions
        var statusColor = getStatusColor(repair.status);
        html += '<div style="display:flex;align-items:center;gap:12px;margin-bottom:20px;flex-wrap:wrap">';
        html += '<span class="rd-status-pill" style="background:' + statusColor + '15;color:' + statusColor + ';border:1px solid ' + statusColor + '40;font-size:13px;padding:5px 14px;border-radius:999px;font-weight:600">' + escHtml(statusLabel) + '</span>';
        html += '<select id="rd-change-status" style="padding:6px 10px;border:1px solid #e2e8f0;border-radius:8px;font-size:13px">';
        $.each(statuses, function(slug, def) {
            var label = typeof def === 'object' ? def.label : def;
            var sel = slug === repair.status ? ' selected' : '';
            html += '<option value="' + slug + '"' + sel + '>' + escHtml(label) + '</option>';
        });
        html += '</select>';
        html += '<button class="rd-btn rd-btn-sm rd-btn-primary" id="rd-change-status-btn" data-id="' + repair.id + '">' + __('Change Status', 'vollstart-repair-desk') + '</button>';
        if (repair.access_code) {
            html += '<span style="font-size:12px;color:#94a3b8;margin-left:auto">' + __('Access Code:', 'vollstart-repair-desk') + ' <strong>' + escHtml(repair.access_code) + '</strong></span>';
        }
        html += '</div>';

        // Details grid
        html += '<div class="rd-form-grid" style="margin-bottom:20px">';
        html += detailField(__('Customer', 'vollstart-repair-desk'), customer ? escHtml(customer.customer_number + ' — ' + customer.name) : '—');
        html += detailField(__('Device', 'vollstart-repair-desk'), escHtml([repair.device_type, repair.device_brand, repair.device_model].filter(Boolean).join(' / ') || '—'));
        html += detailField(__('Serial', 'vollstart-repair-desk'), escHtml(repair.device_serial || '—'));
        html += detailField(__('Priority', 'vollstart-repair-desk'), escHtml(repair.priority));
        html += detailField(__('Est. Date', 'vollstart-repair-desk'), escHtml(repair.estimated_date || '—'));
        html += detailField(__('Est. Price', 'vollstart-repair-desk'), repair.estimated_price ? escHtml(repair.estimated_price + ' ' + cfg.currency) : '—');
        html += '</div>';

        // Defect
        html += '<div style="margin-bottom:16px"><label style="font-size:12px;font-weight:600;color:#475569;text-transform:uppercase">' + __('Defect Description', 'vollstart-repair-desk') + '</label>';
        html += '<p style="margin:4px 0;color:#374151;font-size:14px;white-space:pre-wrap">' + (repair.defect_description ? escHtml(repair.defect_description) : '-') + '</p></div>';

        // Internal notes
        if (repair.internal_notes) {
            html += '<div style="margin-bottom:16px;padding:12px;background:#fef3c7;border-radius:8px"><label style="font-size:12px;font-weight:600;color:#92400e;text-transform:uppercase">' + __('Internal Notes', 'vollstart-repair-desk') + '</label>';
            html += '<p style="margin:4px 0;color:#78350f;font-size:13px;white-space:pre-wrap">' + escHtml(repair.internal_notes) + '</p></div>';
        }

        // Timeline
        html += '<h3 style="font-size:14px;font-weight:600;color:#1e293b;margin-bottom:12px">' + __('Status Timeline', 'vollstart-repair-desk') + '</h3>';
        html += '<div class="rd-timeline">';
        if (timeline && timeline.length) {
            $.each(timeline, function(i, entry) {
                var newLabel = getStatusLabel(entry.new_status);
                var newColor = getStatusColor(entry.new_status);
                html += '<div class="rd-timeline-item" style="--tl-color:' + newColor + '">';
                html += '<div class="rd-timeline-date">' + escHtml(formatDateTime(entry.created_at)) + '</div>';
                html += '<div class="rd-timeline-text">';
                if (entry.old_status) {
                    html += '<span style="color:#94a3b8">' + escHtml(getStatusLabel(entry.old_status)) + '</span> → ';
                }
                html += '<strong style="color:' + newColor + '">' + escHtml(newLabel) + '</strong>';
                if (entry.note) html += '<br><span style="color:#64748b;font-size:12px">' + escHtml(entry.note) + '</span>';
                html += '</div>';
                html += '<div class="rd-timeline-by">' + escHtml(entry.changed_by) + '</div>';
                html += '</div>';
            });
        } else {
            html += '<p style="color:#94a3b8;font-size:13px">' + __('No status changes yet.', 'vollstart-repair-desk') + '</p>';
        }
        html += '</div>';

        // Photos section
        html += '<h3 style="font-size:14px;font-weight:600;color:#1e293b;margin:20px 0 12px">' + __('Photos & Files', 'vollstart-repair-desk') + '</h3>';
        html += '<div id="rd-repair-files-' + repair.id + '"></div>';

        // Action buttons
        html += '<div class="rd-form-actions">';
        html += '<button class="rd-btn rd-btn-danger rd-btn-sm rd-delete-repair" data-id="' + repair.id + '">' + __('Delete', 'vollstart-repair-desk') + '</button>';
        html += '<button class="rd-btn rd-btn-secondary rd-close-modal">' + __('Close', 'vollstart-repair-desk') + '</button>';
        html += '<button class="rd-btn rd-btn-primary rd-edit-repair" data-id="' + repair.id + '">' + __('Edit', 'vollstart-repair-desk') + '</button>';
        html += '</div>';

        var $modal = rdModal('rd-repair-modal', escHtml(repair.repair_number) + ' — ' + escHtml(device), html, { maxWidth: '800px' });

        // Load file upload widget for this repair
        renderUploadWidget('#rd-repair-files-' + repair.id, 'repair', repair.id, { showThumbnail: false, showCamera: true });
    }

    function detailField(label, value) {
        return '<div class="rd-form-group"><label>' + label + '</label><div style="font-size:14px;color:#374151">' + value + '</div></div>';
    }

    // --- New/Edit Repair Modal ---

    var currentTempToken = '';

    var selectedCustomer = null;

    function openRepairForm(repair) {
        var isEdit = !!repair;

        if (!isEdit) {
            currentTempToken = crypto.randomUUID ? crypto.randomUUID() : ('t-' + Date.now() + '-' + Math.random().toString(36).substr(2, 9));
            selectedCustomer = null;
            rdAjax('cleanup_temp_files', {}, null);
        } else {
            currentTempToken = '';
        }

        if (isEdit) {
            // Edit: use modal
            rdAjax('get_customers_dropdown', {}, function(result) {
                var customers = (result.customers_dropdown || result).customers || result.customers || [];
                renderRepairFormModal(repair, customers);
            });
        } else {
            // New: full page
            renderRepairFormPage(null);
        }
    }

    /**
     * Full-page repair create form (replaces tab content).
     */
    function renderRepairFormPage(repair) {
        var r = repair || {};
        var html = '';

        // Header
        html += '<div style="display:flex;align-items:center;gap:12px;margin-bottom:20px">';
        html += '<button class="rd-btn rd-btn-secondary rd-btn-sm rd-cancel-repair-form"><span class="dashicons dashicons-arrow-left-alt2"></span> ' + __('Cancel', 'vollstart-repair-desk') + '</button>';
        html += '<h2 style="font-size:20px;font-weight:700;color:#1e293b;margin:0;flex:1">' + __('New Repair', 'vollstart-repair-desk') + '</h2>';
        html += '<button class="rd-btn rd-btn-primary" id="rd-save-repair" data-id=""><span class="dashicons dashicons-yes"></span> ' + __('Create Repair', 'vollstart-repair-desk') + '</button>';
        html += '</div>';

        // Two-column layout: left = form, right = photos
        html += '<div class="rd-create-grid">';

        // LEFT: Form
        html += '<div>';

        // Customer search
        html += '<div class="rd-card" style="margin-bottom:16px">';
        html += '<div class="rd-card-header"><h3><span class="dashicons dashicons-id" style="margin-right:6px;color:#3b82f6"></span>' + __('Customer', 'vollstart-repair-desk') + '</h3></div>';
        html += '<div class="rd-card-body">';
        html += '<div class="rd-search" style="margin-bottom:8px"><span class="dashicons dashicons-search"></span>';
        html += '<input type="text" id="rd-f-customer-search" placeholder="' + __('Search by name, email, phone or number...', 'vollstart-repair-desk') + '" autocomplete="off"></div>';
        html += '<div id="rd-customer-results"></div>';
        html += '<div id="rd-selected-customer" style="display:none"></div>';
        html += '<input type="hidden" id="rd-f-customer" value="">';
        html += '<button class="rd-btn rd-btn-sm rd-btn-secondary" id="rd-inline-new-customer" style="margin-top:8px"><span class="dashicons dashicons-plus-alt2"></span> ' + __('New Customer', 'vollstart-repair-desk') + '</button>';
        html += '<div id="rd-inline-customer-form" style="display:none;margin-top:12px;padding-top:12px;border-top:1px solid #f1f5f9">';
        html += '<div class="rd-form-grid">';
        html += formField('rd-f-new-cust-name', __('Name', 'vollstart-repair-desk'), 'text', '');
        html += formField('rd-f-new-cust-phone', __('Phone', 'vollstart-repair-desk'), 'text', '');
        html += formField('rd-f-new-cust-email', __('Email', 'vollstart-repair-desk'), 'email', '');
        html += '<div class="rd-form-group rd-form-full"><label>' + __('Notes', 'vollstart-repair-desk') + '</label>';
        html += '<textarea id="rd-f-new-cust-notes" rows="2" placeholder="' + __('Internal notes about this customer', 'vollstart-repair-desk') + '"></textarea></div>';
        html += '</div>';
        html += '<button class="rd-btn rd-btn-sm rd-btn-primary" id="rd-save-inline-customer" style="margin-top:8px">' + __('Add Customer', 'vollstart-repair-desk') + '</button>';
        html += '</div>';
        html += '</div></div>';

        // Product dropdown (loaded when customer selected)
        html += '<div id="rd-product-row" style="display:none;margin-bottom:16px">';
        html += '<div class="rd-card"><div class="rd-card-header"><h3><span class="dashicons dashicons-laptop" style="margin-right:6px;color:#8b5cf6"></span>' + __('Registered Device', 'vollstart-repair-desk') + '</h3></div>';
        html += '<div class="rd-card-body">';
        html += '<select id="rd-f-product" style="width:100%;padding:8px 12px;border:1px solid #e2e8f0;border-radius:8px;font-size:14px"><option value="">' + __('— New device (enter manually below) —', 'vollstart-repair-desk') + '</option></select>';
        html += '<input type="hidden" id="rd-f-product-id" value="">';
        html += '</div></div></div>';

        // Repair type (loaded on render)
        html += '<div id="rd-repair-type-section" style="margin-bottom:16px"></div>';

        // Device details
        html += '<div class="rd-card" style="margin-bottom:16px">';
        html += '<div class="rd-card-header"><h3><span class="dashicons dashicons-admin-tools" style="margin-right:6px;color:#6366f1"></span>' + __('Device & Defect', 'vollstart-repair-desk') + '</h3></div>';
        html += '<div class="rd-card-body"><div class="rd-form-grid">';
        html += renderDeviceTypeField('rd-f-device-type', '');
        html += formField('rd-f-device-brand', __('Brand', 'vollstart-repair-desk'), 'text', '');
        html += formField('rd-f-device-model', __('Model', 'vollstart-repair-desk'), 'text', '');
        html += formField('rd-f-device-serial', __('Serial Number', 'vollstart-repair-desk'), 'text', '');
        html += '<div class="rd-form-group rd-form-full"><label style="display:flex;align-items:center;gap:6px;cursor:pointer;text-transform:none;font-size:13px">';
        html += '<input type="checkbox" id="rd-f-save-as-device" checked style="width:auto;margin:0"> ';
        html += __('Save as registered device for this customer', 'vollstart-repair-desk');
        html += '</label></div>';
        html += '<div class="rd-form-group rd-form-full"><label>' + __('Defect Description', 'vollstart-repair-desk') + '</label>';
        html += '<textarea id="rd-f-defect" rows="4" placeholder="' + __('What is broken? What does the customer report?', 'vollstart-repair-desk') + '"></textarea></div>';
        html += '</div></div></div>';

        // Priority + Dates
        html += '<div class="rd-card">';
        html += '<div class="rd-card-header"><h3><span class="dashicons dashicons-flag" style="margin-right:6px;color:#f59e0b"></span>' + __('Details', 'vollstart-repair-desk') + '</h3></div>';
        html += '<div class="rd-card-body"><div class="rd-form-grid">';
        html += '<div class="rd-form-group"><label>' + __('Priority', 'vollstart-repair-desk') + '</label>';
        html += '<select id="rd-f-priority" style="padding:8px 12px;border:1px solid #e2e8f0;border-radius:8px;font-size:14px">';
        html += '<option value="normal">' + __('Normal', 'vollstart-repair-desk') + '</option>';
        html += '<option value="high">' + __('High', 'vollstart-repair-desk') + '</option>';
        html += '<option value="urgent">' + __('Urgent', 'vollstart-repair-desk') + '</option>';
        html += '</select></div>';
        html += formField('rd-f-estimated-date', __('Estimated Completion', 'vollstart-repair-desk'), 'date', '');
        html += formField('rd-f-estimated-price', __('Estimated Price', 'vollstart-repair-desk'), 'number', '', cfg.currency);
        html += '<div class="rd-form-group rd-form-full"><label>' + __('Internal Notes', 'vollstart-repair-desk') + '</label>';
        html += '<textarea id="rd-f-notes" rows="2" placeholder="' + __('Only visible to staff', 'vollstart-repair-desk') + '"></textarea></div>';
        if (cfg.enableStaffManagement) {
            html += '<div class="rd-form-group"><label>' + __('Assigned To', 'vollstart-repair-desk') + '</label>';
            html += '<select id="rd-f-assigned-to" style="padding:8px 12px;border:1px solid #e2e8f0;border-radius:8px;font-size:14px">';
            html += '<option value="">' + __('— not assigned —', 'vollstart-repair-desk') + '</option>';
            html += '</select></div>';
        }
        html += '</div></div></div>';

        html += '</div>'; // end left

        // RIGHT: Photos
        html += '<div>';
        html += '<div class="rd-card" style="position:sticky;top:80px">';
        html += '<div class="rd-card-header"><h3><span class="dashicons dashicons-camera" style="margin-right:6px;color:#8b5cf6"></span>' + __('Intake Photos', 'vollstart-repair-desk') + '</h3></div>';
        html += '<div class="rd-card-body" id="rd-create-repair-files"></div>';
        html += '</div>';
        html += '</div>'; // end right

        html += '</div>'; // end grid

        // Bottom action bar (visible on mobile when top is scrolled away)
        html += '<div style="display:flex;gap:8px;justify-content:flex-end;margin-top:20px;padding-top:16px;border-top:1px solid #e2e8f0">';
        html += '<button class="rd-btn rd-btn-secondary rd-cancel-repair-form">' + __('Cancel', 'vollstart-repair-desk') + '</button>';
        html += '<button class="rd-btn rd-btn-primary rd-save-repair-bottom" id="rd-save-repair-bottom"><span class="dashicons dashicons-yes"></span> ' + __('Create Repair', 'vollstart-repair-desk') + '</button>';
        html += '</div>';

        html += '<input type="hidden" id="rd-f-temp-token" value="' + escAttr(currentTempToken) + '">';

        $('#rd-tab-content').html(html);

        // Init upload widget
        if (currentTempToken) {
            renderTempUploadWidget('#rd-create-repair-files', currentTempToken);
        }

        // Load repair types dropdown for the form
        rdAjax('get_repair_types_dropdown', {}, function(result) {
            var types = result.repairTypes || [];
            var html = '';

            if (types.length > 0) {
                html += '<div class="rd-card"><div class="rd-card-header"><h3><span class="dashicons dashicons-category" style="margin-right:6px;color:#f97316"></span>' + __('Repair Type', 'vollstart-repair-desk') + '</h3></div>';
                html += '<div class="rd-card-body">';
                html += '<select id="rd-f-repair-type" style="width:100%;padding:8px 12px;border:1px solid #e2e8f0;border-radius:8px;font-size:14px">';
                html += '<option value="">' + __('— Select repair type (optional) —', 'vollstart-repair-desk') + '</option>';
                $.each(types, function(i, t) {
                    var label = t.name;
                    if (t.estimated_duration_hours && t.estimated_duration_hours !== '0.0') label += ' (' + t.estimated_duration_hours + 'h)';
                    if (t.default_price && t.default_price !== '0.00') label += ' \u2014 ' + t.default_price + ' ' + cfg.currency;
                    html += '<option value="' + t.id + '" data-duration="' + escAttr(t.estimated_duration_hours) + '" data-price="' + escAttr(t.default_price) + '">' + escHtml(label) + '</option>';
                });
                html += '</select>';
                html += '</div></div>';
            }

            $('#rd-repair-type-section').html(html);
        });

        // Load staff dropdown for assignment
        if (cfg.enableStaffManagement) {
            rdAjax('get_staff_dropdown', {}, function(result) {
                var $sel = $('#rd-f-assigned-to');
                $.each(result.staffList || [], function(i, s) {
                    $sel.append('<option value="' + s.id + '">' + escHtml(s.name) + '</option>');
                });
            });
        }
    }

    /**
     * Modal repair form (for editing existing repairs).
     */
    function renderRepairFormModal(repair, customers) {
        var r = repair;
        var html = '<div class="rd-form-grid">';

        // Customer dropdown (edit mode — already selected)
        html += '<div class="rd-form-group rd-form-full"><label>' + __('Customer', 'vollstart-repair-desk') + '</label>';
        html += '<select id="rd-f-customer">';
        html += '<option value="">' + __('— Select customer —', 'vollstart-repair-desk') + '</option>';
        $.each(customers, function(i, c) {
            var sel = (r.customer_id && r.customer_id == c.id) ? ' selected' : '';
            html += '<option value="' + c.id + '"' + sel + '>' + escHtml(c.customer_number + ' — ' + c.name + (c.phone ? ' (' + c.phone + ')' : '')) + '</option>';
        });
        html += '</select></div>';

        // Product dropdown
        html += '<div class="rd-form-group rd-form-full" id="rd-product-row" style="display:none">';
        html += '<label>' + __('Device', 'vollstart-repair-desk') + '</label>';
        html += '<select id="rd-f-product"><option value="">' + __('— New device (enter below) —', 'vollstart-repair-desk') + '</option></select>';
        html += '<input type="hidden" id="rd-f-product-id" value="' + escAttr(r.product_id || '') + '">';
        html += '</div>';

        // Repair type dropdown (edit)
        html += '<div class="rd-form-group rd-form-full"><label>' + __('Repair Type', 'vollstart-repair-desk') + '</label>';
        html += '<select id="rd-f-repair-type" data-original="' + escAttr(r.repair_type_id || '') + '">';
        html += '<option value="">' + __('— No repair type —', 'vollstart-repair-desk') + '</option>';
        html += '</select>';
        html += '<input type="hidden" id="rd-f-original-repair-type" value="' + escAttr(r.repair_type_id || '') + '">';
        html += '</div>';

        html += renderDeviceTypeField('rd-f-device-type', r.device_type || '');
        html += formField('rd-f-device-brand', __('Brand', 'vollstart-repair-desk'), 'text', r.device_brand || '');
        html += formField('rd-f-device-model', __('Model', 'vollstart-repair-desk'), 'text', r.device_model || '');
        html += formField('rd-f-device-serial', __('Serial Number', 'vollstart-repair-desk'), 'text', r.device_serial || '');
        html += '<div class="rd-form-group rd-form-full"><label>' + __('Defect Description', 'vollstart-repair-desk') + '</label>';
        html += '<textarea id="rd-f-defect" rows="3">' + escHtml(r.defect_description || '') + '</textarea></div>';
        html += '<div class="rd-form-group"><label>' + __('Priority', 'vollstart-repair-desk') + '</label>';
        html += '<select id="rd-f-priority">';
        html += '<option value="normal"' + (r.priority === 'normal' || !r.priority ? ' selected' : '') + '>' + __('Normal', 'vollstart-repair-desk') + '</option>';
        html += '<option value="high"' + (r.priority === 'high' ? ' selected' : '') + '>' + __('High', 'vollstart-repair-desk') + '</option>';
        html += '<option value="urgent"' + (r.priority === 'urgent' ? ' selected' : '') + '>' + __('Urgent', 'vollstart-repair-desk') + '</option>';
        html += '</select></div>';
        html += formField('rd-f-estimated-date', __('Estimated Completion', 'vollstart-repair-desk'), 'date', (r.estimated_date && r.estimated_date !== '0000-00-00') ? r.estimated_date : '');
        html += formField('rd-f-estimated-price', __('Estimated Price', 'vollstart-repair-desk'), 'number', r.estimated_price || '', cfg.currency);
        var warrantyDays = parseInt(cfg.warrantyDefaultDays) || 0;
        html += '<div class="rd-form-group"><label>' + __('Repair warranty until', 'vollstart-repair-desk') + '</label>';
        html += '<div style="display:flex;gap:6px;align-items:center">';
        html += '<input type="date" id="rd-f-warranty" value="' + escAttr((r.warranty_until && r.warranty_until !== '0000-00-00') ? r.warranty_until : '') + '" style="flex:1">';
        if (warrantyDays > 0) {
            html += '<button type="button" id="rd-warranty-prefill" class="rd-btn rd-btn-sm rd-btn-secondary" title="' + __('Set default warranty', 'vollstart-repair-desk') + '" style="white-space:nowrap">+' + warrantyDays + 'd</button>';
        }
        html += '</div></div>';
        if (cfg.enableStaffManagement) {
            html += '<div class="rd-form-group"><label>' + __('Assigned To', 'vollstart-repair-desk') + '</label>';
            html += '<select id="rd-f-assigned-to">';
            html += '<option value="">' + __('— not assigned —', 'vollstart-repair-desk') + '</option>';
            html += '</select></div>';
        }
        html += '<div class="rd-form-group rd-form-full"><label>' + __('Internal Notes', 'vollstart-repair-desk') + '</label>';
        html += '<textarea id="rd-f-notes" rows="2">' + escHtml(r.internal_notes || '') + '</textarea></div>';
        html += '</div>';

        html += '<input type="hidden" id="rd-f-temp-token" value="">';
        var repairFooter = '<button class="rd-btn rd-btn-secondary rd-close-modal">' + __('Cancel', 'vollstart-repair-desk') + '</button>';
        repairFooter += '<button class="rd-btn rd-btn-primary" id="rd-save-repair" data-id="' + r.id + '">' + __('Save', 'vollstart-repair-desk') + '</button>';

        rdModal('rd-repair-form-modal', __('Edit Repair', 'vollstart-repair-desk'), html, { maxWidth: '500px', footer: repairFooter });

        if (r.customer_id) {
            $('#rd-f-customer').trigger('change');
            if (r.product_id) {
                setTimeout(function() {
                    $('#rd-f-product').val(r.product_id);
                    $('#rd-f-product-id').val(r.product_id);
                }, 500);
            }
        }

        // Load repair types into dropdown
        rdAjax('get_repair_types_dropdown', {}, function(result) {
            var types = result.repairTypes || [];
            var $sel = $('#rd-f-repair-type');
            $.each(types, function(i, t) {
                var sel = (r.repair_type_id && r.repair_type_id == t.id) ? ' selected' : '';
                $sel.append('<option value="' + t.id + '"' + sel + '>' + escHtml(t.name) + '</option>');
            });
        });

        // Load staff dropdown for assignment (edit mode)
        if (cfg.enableStaffManagement) {
            rdAjax('get_staff_dropdown', {}, function(result) {
                var $sel = $('#rd-f-assigned-to');
                $.each(result.staffList || [], function(i, s) {
                    var sel = (r.assigned_to && r.assigned_to == s.id) ? ' selected' : '';
                    $sel.append('<option value="' + s.id + '"' + sel + '>' + escHtml(s.name) + '</option>');
                });
            });
        }
    }

    function formField(id, label, type, value, placeholder) {
        return '<div class="rd-form-group"><label>' + label + '</label><input type="' + type + '" id="' + id + '" value="' + escAttr(value) + '"' + (placeholder ? ' placeholder="' + escAttr(placeholder) + '"' : '') + '></div>';
    }

    function renderDeviceTypeField(id, value) {
        var types = cfg.deviceTypes ? String(cfg.deviceTypes).split(',').map(function(t) { return t.trim(); }).filter(Boolean) : [];
        if (types.length === 0) {
            return formField(id, __('Device Type', 'vollstart-repair-desk'), 'text', value, __('e.g. Bicycle, Laptop, Phone', 'vollstart-repair-desk'));
        }
        var html = '<div class="rd-form-group"><label>' + __('Device Type', 'vollstart-repair-desk') + '</label>';
        html += '<select id="' + id + '" style="width:100%;padding:8px 12px;border:1px solid #e2e8f0;border-radius:8px;font-size:14px">';
        for (var i = 0; i < types.length; i++) {
            var sel = (value === types[i]) ? ' selected' : (!value && i === 0 ? ' selected' : '');
            html += '<option value="' + escAttr(types[i]) + '"' + sel + '>' + escHtml(types[i]) + '</option>';
        }
        if (value && types.indexOf(value) < 0) {
            html += '<option value="' + escAttr(value) + '" selected>' + escHtml(value) + '</option>';
        }
        html += '</select></div>';
        return html;
    }

    // --- Customers Tab ---

    function loadCustomers() {
        renderCustomersTab();
    }

    function renderCustomersTab() {
        var html = '<div class="rd-toolbar">';
        html += '<div class="rd-toolbar-right">';
        html += '<button class="rd-btn rd-btn-secondary" id="rd-export-customers" title="' + __('Export CSV', 'vollstart-repair-desk') + '"><span class="dashicons dashicons-download" style="font-size:16px;width:16px;height:16px"></span></button>';
        html += '<button class="rd-btn rd-btn-secondary" id="rd-import-customers" title="' + __('Import CSV', 'vollstart-repair-desk') + '"><span class="dashicons dashicons-upload" style="font-size:16px;width:16px;height:16px"></span></button>';
        html += '<button class="rd-btn rd-btn-primary" id="rd-new-customer"><span class="dashicons dashicons-plus-alt2"></span> ' + __('New Customer', 'vollstart-repair-desk') + '</button>';
        html += '</div></div>';

        html += '<div class="rd-card">';
        html += '<table id="rd-customers-table" class="rd-table" style="width:100%">';
        html += '<thead><tr>';
        html += '<th>' + __('#', 'vollstart-repair-desk') + '</th>';
        html += '<th>' + __('Name', 'vollstart-repair-desk') + '</th>';
        html += '<th>' + __('Email', 'vollstart-repair-desk') + '</th>';
        html += '<th>' + __('Phone', 'vollstart-repair-desk') + '</th>';
        html += '<th>' + __('Repairs', 'vollstart-repair-desk') + '</th>';
        html += '<th>' + __('Devices', 'vollstart-repair-desk') + '</th>';
        html += '<th></th>';
        html += '</tr></thead>';
        html += '</table></div>';

        $('#rd-tab-content').html(html);

        var columnMap = ['customer_number', 'name', 'email', 'phone', 'repair_count', 'product_count', ''];

        if (customersDT) { customersDT.destroy(); customersDT = null; }

        customersDT = $('#rd-customers-table').DataTable({
            responsive: true,
            processing: true,
            serverSide: true,
            ajax: function(dtParams, callback) {
                var col = dtParams.order && dtParams.order[0] ? dtParams.order[0].column : 1;
                var dir = dtParams.order && dtParams.order[0] ? dtParams.order[0].dir : 'asc';
                rdAjax('get_customers', {
                    page: Math.floor(dtParams.start / dtParams.length) + 1,
                    per_page: dtParams.length,
                    search: dtParams.search.value || '',
                    orderby: columnMap[col] || 'name',
                    order: dir.toUpperCase()
                }, function(data) {
                    var rows = (data.customers || []).map(function(c) {
                        var repairCount = parseInt(c.repair_count) || 0;
                        var productCount = parseInt(c.product_count) || 0;
                        return [
                            '<code style="font-size:12px;background:#f1f5f9;padding:2px 6px;border-radius:4px">' + escHtml(c.customer_number) + '</code>',
                            '<span style="font-weight:500">' + escHtml(c.name || '\u2014') + '</span>',
                            '<span style="color:#64748b">' + escHtml(c.email || '\u2014') + '</span>',
                            '<span style="color:#64748b">' + escHtml(c.phone || '\u2014') + '</span>',
                            repairCount > 0 ? '<strong>' + repairCount + '</strong>' : '<span style="color:#cbd5e1">0</span>',
                            productCount > 0 ? '<strong>' + productCount + '</strong>' : '<span style="color:#cbd5e1">0</span>',
                            '<div style="white-space:nowrap;display:flex;gap:4px;justify-content:flex-end">'
                            + '<button class="rd-btn rd-btn-sm rd-btn-secondary rd-customer-pdf" data-id="' + c.id + '" data-full="0" title="PDF"><span class="dashicons dashicons-media-document" style="font-size:14px;width:14px;height:14px"></span></button>'
                            + '<button class="rd-btn rd-btn-sm rd-btn-secondary rd-view-customer" data-id="' + c.id + '"><span class="dashicons dashicons-visibility" style="font-size:14px;width:14px;height:14px"></span></button>'
                            + '</div>'
                        ];
                    });
                    callback({
                        draw: dtParams.draw,
                        recordsTotal: parseInt(data.total) || 0,
                        recordsFiltered: parseInt(data.filtered) || 0,
                        data: rows
                    });
                });
            },
            pageLength: 20,
            lengthMenu: [10, 20, 50, 100],
            order: [[1, 'asc']],
            columns: [
                { orderable: true, width: 90 },
                { orderable: true },
                { orderable: true },
                { orderable: true },
                { orderable: true, width: 60 },
                { orderable: true, width: 60 },
                { orderable: false, width: 80 }
            ],
            language: {
                search: __('Search:', 'vollstart-repair-desk'),
                lengthMenu: __('Show _MENU_ entries', 'vollstart-repair-desk'),
                info: __('Showing _START_ to _END_ of _TOTAL_ customers', 'vollstart-repair-desk'),
                infoEmpty: __('No customers found', 'vollstart-repair-desk'),
                infoFiltered: __('(filtered from _MAX_ total)', 'vollstart-repair-desk'),
                zeroRecords: __('No matching customers found', 'vollstart-repair-desk'),
                processing: __('Loading...', 'vollstart-repair-desk'),
                paginate: { previous: '&laquo;', next: '&raquo;' }
            },
            dom: '<"rd-dt-top"f>rt<"rd-dt-bottom"lip>',
            drawCallback: function() {
                $('#rd-customers-table tbody tr').css('cursor', 'pointer').off('click').on('click', function(e) {
                    if ($(e.target).closest('button').length) return;
                    var $btn = $(this).find('.rd-view-customer');
                    if ($btn.length) openCustomerFullView($btn.data('id'));
                });
            }
        });
    }

    // --- Customer Detail View ---

    /**
     * Full-page customer detail (replaces tab content).
     * Used when clicking a customer in the Customers tab.
     */
    function openCustomerFullView(id) {
        var $content = $('#rd-tab-content');
        $content.html('<div class="rd-loading"><span class="spinner is-active"></span></div>');
        rdAjax('get_customer', { id: id }, function(result) {
            renderCustomerFullView(result.customer, result.customerRepairs || [], result.customerProducts || [], result.customerRatings || [], result.customerAvgRating || 0);
        });
    }

    function renderCustomerFullView(customer, repairs, products, customerRatings, customerAvgRating) {
        var c = customer;
        currentCustomer = c;
        var html = '';

        // Top bar: back + number + actions
        html += '<div style="display:flex;align-items:center;gap:12px;margin-bottom:12px">';
        html += '<button class="rd-btn rd-btn-secondary rd-btn-sm" id="rd-back-to-customers"><span class="dashicons dashicons-arrow-left-alt2"></span> ' + __('Back', 'vollstart-repair-desk') + '</button>';
        html += '<div style="flex:1"><code style="font-size:13px;background:#f1f5f9;padding:3px 8px;border-radius:4px">' + escHtml(c.customer_number) + '</code></div>';
        html += '<button class="rd-btn rd-btn-sm rd-btn-secondary rd-customer-pdf" data-id="' + c.id + '" data-full="0" title="PDF"><span class="dashicons dashicons-media-document" style="font-size:14px;width:14px;height:14px"></span> PDF</button>';
        html += '<button class="rd-btn rd-btn-sm rd-btn-secondary rd-customer-pdf" data-id="' + c.id + '" data-full="1" title="' + __('Full PDF', 'vollstart-repair-desk') + '"><span class="dashicons dashicons-media-document" style="font-size:14px;width:14px;height:14px"></span> ' + __('Full', 'vollstart-repair-desk') + '</button>';
        html += '<button class="rd-btn rd-btn-sm rd-btn-secondary rd-export-customer-data" data-id="' + c.id + '" data-name="' + escAttr(c.name) + '" title="' + __('GDPR: Export all data', 'vollstart-repair-desk') + '"><span class="dashicons dashicons-download" style="font-size:14px;width:14px;height:14px"></span></button>';
        html += '<button class="rd-btn rd-btn-sm rd-btn-secondary rd-anonymize-customer" data-id="' + c.id + '" title="' + __('GDPR: Erase personal data', 'vollstart-repair-desk') + '" style="color:#dc2626"><span class="dashicons dashicons-privacy" style="font-size:14px;width:14px;height:14px"></span></button>';
        html += '<button class="rd-btn rd-btn-primary rd-btn-sm rd-edit-customer-from-view" data-id="' + c.id + '"><span class="dashicons dashicons-edit"></span> ' + __('Edit', 'vollstart-repair-desk') + '</button>';
        html += '<button class="rd-btn rd-btn-danger rd-btn-sm rd-delete-customer" data-id="' + c.id + '"><span class="dashicons dashicons-trash"></span></button>';
        html += '</div>';

        // Name + customer since
        html += '<h2 id="rd-cv-name" style="font-size:22px;font-weight:700;color:#1e293b;margin:0 0 2px">' + escHtml(c.name) + '</h2>';
        html += '<p id="rd-cv-since" style="font-size:13px;color:#94a3b8;margin:0 0 20px">' + __('Customer since', 'vollstart-repair-desk') + ' ' + escHtml(formatDateTime(c.created_at).split(',')[0]) + '</p>';

        // Info cards row
        html += '<div class="rd-info-grid" style="margin-bottom:24px">';

        // Contact card
        html += '<div class="rd-card">';
        html += '<div class="rd-card-header"><h3><span class="dashicons dashicons-id" style="margin-right:6px;color:#3b82f6"></span>' + __('Contact', 'vollstart-repair-desk') + '</h3></div>';
        html += '<div class="rd-card-body" id="rd-cv-contact">';
        html += renderContactCardContent(c);
        html += '</div></div>';

        // Stats card
        var totalRepairs = repairs.length;
        var openRepairs = 0, doneRepairs = 0;
        $.each(repairs, function(i, r) {
            if (r.status === 'delivered' || r.status === 'cancelled') doneRepairs++;
            else openRepairs++;
        });

        html += '<div class="rd-card">';
        html += '<div class="rd-card-header"><h3><span class="dashicons dashicons-chart-bar" style="margin-right:6px;color:#22c55e"></span>' + __('Overview', 'vollstart-repair-desk') + '</h3></div>';
        html += '<div class="rd-card-body">';
        html += infoRow(__('Total Repairs', 'vollstart-repair-desk'), '<strong>' + totalRepairs + '</strong>');
        html += infoRow(__('Open', 'vollstart-repair-desk'), openRepairs > 0 ? '<span style="color:#f97316;font-weight:600">' + openRepairs + '</span>' : '0');
        html += infoRow(__('Completed', 'vollstart-repair-desk'), doneRepairs);
        html += '</div></div>';

        html += '</div>'; // end info-grid

        // Notes card (always render, show/hide based on content)
        html += '<div class="rd-card" id="rd-cv-notes-card" style="margin-bottom:24px;' + (c.notes ? '' : 'display:none') + '">';
        html += '<div class="rd-card-header"><h3><span class="dashicons dashicons-edit" style="margin-right:6px;color:#f59e0b"></span>' + __('Notes', 'vollstart-repair-desk') + '</h3></div>';
        html += '<div class="rd-card-body" id="rd-cv-notes"><p style="white-space:pre-wrap;color:#374151;margin:0">' + escHtml(c.notes || '') + '</p></div>';
        html += '</div>';

        // Products table
        html += '<div class="rd-card" style="margin-bottom:24px">';
        html += '<div class="rd-card-header"><h3><span class="dashicons dashicons-laptop" style="margin-right:6px;color:#8b5cf6"></span>' + __('Devices / Products', 'vollstart-repair-desk') + ' <span style="color:#94a3b8;font-weight:400">(' + (products ? products.length : 0) + ')</span></h3>';
        html += '<div class="rd-card-actions">';
        html += '<button class="rd-btn rd-btn-primary rd-btn-sm" id="rd-add-product" data-customer-id="' + c.id + '"><span class="dashicons dashicons-plus-alt2"></span> ' + __('Add Device', 'vollstart-repair-desk') + '</button>';
        html += '</div>';
        html += '</div>';

        if (!products || products.length === 0) {
            html += '<div class="rd-card-body"><p style="color:#94a3b8;text-align:center;padding:12px 0">' + __('No devices registered yet.', 'vollstart-repair-desk') + '</p></div>';
        } else {
            html += '<table class="rd-table">';
            html += '<thead><tr>';
            html += '<th style="width:60px"></th>';
            html += '<th>' + __('Name', 'vollstart-repair-desk') + '</th>';
            html += '<th class="rd-hide-mobile">' + __('Brand / Model', 'vollstart-repair-desk') + '</th>';
            html += '<th class="rd-hide-mobile">' + __('Serial', 'vollstart-repair-desk') + '</th>';
            html += '<th style="width:110px"></th>';
            html += '</tr></thead><tbody>';

            $.each(products, function(i, p) {
                var brandModel = [p.brand, p.model].filter(Boolean).join(' ');
                var thumbHtml = '';
                if (p.thumbnail_url) {
                    thumbHtml = '<img src="' + escAttr(p.thumbnail_url) + '" style="width:52px;height:52px;object-fit:cover;border-radius:8px;display:block">';
                } else {
                    thumbHtml = '<span style="display:flex;width:52px;height:52px;border-radius:8px;background:#f1f5f9;align-items:center;justify-content:center;color:#cbd5e1"><span class="dashicons dashicons-camera" style="font-size:20px;width:20px;height:20px"></span></span>';
                }
                html += '<tr>';
                html += '<td id="rd-product-thumb-' + p.id + '" style="padding:6px 8px">' + thumbHtml + '</td>';
                html += '<td><strong>' + escHtml(p.name || brandModel || '\u2014') + '</strong>';
                // Show brand/serial inline on mobile (hidden columns)
                html += '<span class="rd-show-mobile" style="display:none"><br><span style="font-size:11px;color:#64748b">' + escHtml(brandModel) + (p.serial_number ? ' · ' + p.serial_number : '') + '</span></span>';
                html += '</td>';
                html += '<td class="rd-hide-mobile">' + escHtml(brandModel || '\u2014') + '</td>';
                html += '<td class="rd-hide-mobile" style="font-family:monospace;font-size:12px;color:#64748b">' + escHtml(p.serial_number || '\u2014') + '</td>';
                html += '<td style="text-align:right;white-space:nowrap">';
                html += '<div class="rd-product-actions">';
                html += '<button class="rd-btn rd-btn-sm rd-btn-secondary rd-goto-device" data-id="' + p.id + '" title="' + __('View', 'vollstart-repair-desk') + '"><span class="dashicons dashicons-visibility" style="font-size:14px;width:14px;height:14px"></span></button>';
                html += '<button class="rd-btn rd-btn-sm rd-btn-secondary rd-toggle-product-files" data-product-id="' + p.id + '" title="' + __('Photos', 'vollstart-repair-desk') + '"><span class="dashicons dashicons-camera" style="font-size:14px;width:14px;height:14px"></span></button>';
                html += '<button class="rd-btn rd-btn-sm rd-btn-secondary rd-edit-product" data-id="' + p.id + '" data-customer-id="' + c.id + '" title="' + __('Edit', 'vollstart-repair-desk') + '"><span class="dashicons dashicons-edit" style="font-size:14px;width:14px;height:14px"></span></button>';
                html += '<button class="rd-btn rd-btn-sm rd-btn-danger rd-delete-product" data-id="' + p.id + '" data-customer-id="' + c.id + '" title="' + __('Delete', 'vollstart-repair-desk') + '"><span class="dashicons dashicons-trash" style="font-size:14px;width:14px;height:14px"></span></button>';
                html += '</div>';
                html += '</td>';
                html += '</tr>';
                // Inline photo row (hidden, toggled by camera button)
                html += '<tr class="rd-product-files-row" id="rd-product-files-row-' + p.id + '" style="display:none">';
                html += '<td colspan="5" style="padding:12px 16px;background:#f8fafc" data-show-thumbnail="1">';
                html += '<div id="rd-product-files-' + p.id + '"></div>';
                html += '</td>';
                html += '</tr>';
            });
            html += '</tbody></table>';
        }
        html += '</div>';

        // Repairs table
        html += '<div class="rd-card">';
        html += '<div class="rd-card-header"><h3><span class="dashicons dashicons-admin-tools" style="margin-right:6px;color:#6366f1"></span>' + __('Repairs', 'vollstart-repair-desk') + ' <span style="color:#94a3b8;font-weight:400">(' + totalRepairs + ')</span></h3></div>';

        if (repairs.length === 0) {
            html += '<div class="rd-card-body"><p style="color:#94a3b8;text-align:center;padding:20px 0">' + __('No repairs yet.', 'vollstart-repair-desk') + '</p></div>';
        } else {
            html += '<table class="rd-table">';
            html += '<thead><tr>';
            html += '<th>' + __('#', 'vollstart-repair-desk') + '</th>';
            html += '<th>' + __('Device', 'vollstart-repair-desk') + '</th>';
            html += '<th>' + __('Defect', 'vollstart-repair-desk') + '</th>';
            html += '<th>' + __('Status', 'vollstart-repair-desk') + '</th>';
            html += '<th>' + __('Date', 'vollstart-repair-desk') + '</th>';
            html += '</tr></thead><tbody>';

            $.each(repairs, function(i, r) {
                var device = [r.device_brand, r.device_model].filter(Boolean).join(' ') || r.device_type || '\u2014';
                var defect = r.defect_description || '';
                if (defect.length > 60) defect = defect.substring(0, 60) + '...';
                var sLabel = getStatusLabel(r.status);
                var sColor = getStatusColor(r.status);

                html += '<tr class="rd-customer-repair-row" data-id="' + r.id + '" style="cursor:pointer">';
                html += '<td><strong>' + escHtml(r.repair_number) + '</strong></td>';
                html += '<td>' + escHtml(device) + '</td>';
                html += '<td style="color:#64748b;font-size:12px">' + escHtml(defect) + '</td>';
                html += '<td><span style="display:inline-flex;font-size:11px;font-weight:600;padding:3px 10px;border-radius:999px;background:' + sColor + '15;color:' + sColor + ';border:1px solid ' + sColor + '30">' + escHtml(sLabel) + '</span></td>';
                html += '<td style="font-size:12px;white-space:nowrap">' + escHtml(formatDateTime(r.created_at).split(',')[0]) + '</td>';
                html += '</tr>';
            });
            html += '</tbody></table>';
        }
        html += '</div>';

        // Ratings (full row when shown)
        if (cfg.enableRatings) {
            html += '<div style="margin-top:24px">';
            html += '<div class="rd-card" style="margin-bottom:24px">';
            html += '<div class="rd-card-header"><h3><span class="dashicons dashicons-star-filled" style="margin-right:6px;color:#f59e0b"></span>' + __('Ratings', 'vollstart-repair-desk');
            if (customerAvgRating > 0) {
                html += ' <span style="font-size:14px;font-weight:400;color:#94a3b8">' + customerAvgRating + '/5</span>';
            }
            html += '</h3></div>';
            html += '<div class="rd-card-body">';
            if ((customerRatings || []).length > 0) {
                $.each(customerRatings, function(i, r) {
                    if (parseInt(r.rating) <= 0) return;
                    var stars = '';
                    for (var si = 1; si <= 5; si++) stars += '<span style="color:' + (si <= parseInt(r.rating) ? '#f59e0b' : '#e2e8f0') + '">&#9733;</span>';
                    var typeLabel = r.type === 'internal' ? __('Internal', 'vollstart-repair-desk') : r.type === 'repair' ? __('Customer', 'vollstart-repair-desk') : __('Business', 'vollstart-repair-desk');
                    html += '<div style="display:flex;align-items:center;gap:8px;padding:6px 0;border-bottom:1px solid #f1f5f9;flex-wrap:wrap">';
                    html += '<span style="font-size:10px;padding:2px 8px;border-radius:999px;background:' + (r.type === 'internal' ? '#eff6ff;color:#3b82f6' : '#fef3c7;color:#d97706') + '">' + typeLabel + '</span>';
                    html += '<span style="font-size:16px">' + stars + '</span>';
                    if (r.comment) html += '<span style="font-size:12px;color:#64748b;flex:1">' + escHtml(r.comment) + '</span>';
                    html += '<span style="font-size:11px;color:#94a3b8">' + escHtml(r.created_at) + '</span>';
                    html += '</div>';
                });
            } else {
                html += '<p style="color:#94a3b8;font-size:13px;text-align:center;padding:8px">' + __('No ratings yet.', 'vollstart-repair-desk') + '</p>';
            }
            // Quick rate customer form
            html += '<div style="padding:10px 16px;border-top:1px solid #e2e8f0;display:flex;align-items:center;gap:8px;flex-wrap:wrap">';
            html += '<span style="font-size:12px;color:#64748b">' + __('Rate customer:', 'vollstart-repair-desk') + '</span>';
            html += '<span class="rd-cust-rate-stars" data-customer-id="' + c.id + '" style="font-size:22px;cursor:pointer">';
            for (var crs = 1; crs <= 5; crs++) html += '<span class="rd-cstar" data-value="' + crs + '" style="color:#e2e8f0;transition:color 0.15s">&#9733;</span>';
            html += '</span>';
            html += '<input type="hidden" id="rd-cust-rate-val" value="0">';
            html += '<input type="text" id="rd-cust-rate-comment" placeholder="' + __('Comment', 'vollstart-repair-desk') + '" style="flex:1;padding:5px 8px;border:1px solid #e2e8f0;border-radius:6px;font-size:12px;min-width:80px">';
            html += '<button class="rd-btn rd-btn-sm rd-btn-primary" id="rd-save-cust-rating" data-id="' + c.id + '">' + __('Save', 'vollstart-repair-desk') + '</button>';
            html += '</div>';
            html += '</div></div>';
            html += '</div>';
        }

        // Change History — full width
        html += '<div class="rd-card" style="margin-top:24px">';
        html += '<div class="rd-card-header"><h3><span class="dashicons dashicons-backup" style="margin-right:6px;color:#8b5cf6"></span>' + __('Change History', 'vollstart-repair-desk') + '</h3>';
        html += '<div class="rd-card-actions">';
        html += '<button class="rd-btn rd-btn-sm rd-btn-secondary rd-export-customer-history" data-id="' + c.id + '" data-name="' + escAttr(c.customer_number) + '" style="display:none"><span class="dashicons dashicons-download" style="font-size:14px;width:14px;height:14px"></span> CSV</button>';
        html += '<button class="rd-btn rd-btn-sm rd-btn-secondary rd-load-customer-history" data-id="' + c.id + '"><span class="dashicons dashicons-arrow-down-alt2" style="font-size:14px;width:14px;height:14px"></span></button>';
        html += '</div></div>';
        html += '<div id="rd-customer-history-content" style="display:none"></div>';
        html += '</div>';

        $('#rd-tab-content').html(html);
    }

    // Lazy-load customer change history
    $(document).on('click', '.rd-load-customer-history', function() {
        var $btn = $(this);
        var id = $btn.data('id');
        var $content = $('#rd-customer-history-content');

        if ($content.is(':visible')) {
            $content.slideUp(200);
            $btn.find('.dashicons').removeClass('dashicons-arrow-up-alt2').addClass('dashicons-arrow-down-alt2');
            $btn.closest('.rd-card-header').find('.rd-export-customer-history').hide();
            return;
        }

        $content.html('<div class="rd-loading"><span class="spinner is-active"></span></div>').slideDown(200);
        $btn.find('.dashicons').removeClass('dashicons-arrow-down-alt2').addClass('dashicons-arrow-up-alt2');

        rdAjax('get_customer_history', { id: id }, function(result) {
            var history = result.history || [];
            var fieldLabels = {
                'name': __('Name', 'vollstart-repair-desk'),
                'email': __('Email', 'vollstart-repair-desk'),
                'phone': __('Phone', 'vollstart-repair-desk'),
                'address': __('Address', 'vollstart-repair-desk'),
                'notes': __('Notes', 'vollstart-repair-desk'),
                '_created': __('Customer created', 'vollstart-repair-desk')
            };
            var html = '';
            if (history.length === 0) {
                html = '<p style="color:#94a3b8;font-size:13px;text-align:center;padding:12px">' + __('No changes recorded.', 'vollstart-repair-desk') + '</p>';
            } else {
                html = '<table class="rd-table" style="font-size:12px">';
                html += '<thead><tr><th>' + __('Date', 'vollstart-repair-desk') + '</th><th>' + __('Field', 'vollstart-repair-desk') + '</th><th>' + __('Old', 'vollstart-repair-desk') + '</th><th>' + __('New', 'vollstart-repair-desk') + '</th><th>' + __('By', 'vollstart-repair-desk') + '</th></tr></thead><tbody>';
                $.each(history, function(i, h) {
                    var fieldLabel = fieldLabels[h.field_name] || h.field_name;
                    var oldVal = h.old_value || '';
                    var newVal = h.new_value || '';
                    if (oldVal.length > 50) oldVal = oldVal.substring(0, 50) + '...';
                    if (newVal.length > 50) newVal = newVal.substring(0, 50) + '...';
                    html += '<tr>';
                    html += '<td style="white-space:nowrap;color:#94a3b8">' + escHtml(formatDateTime(h.changed_at)) + '</td>';
                    html += '<td>' + escHtml(fieldLabel) + '</td>';
                    html += '<td style="color:#dc2626" title="' + escAttr(h.old_value) + '">' + escHtml(oldVal) + '</td>';
                    html += '<td style="color:#22c55e" title="' + escAttr(h.new_value) + '">' + escHtml(newVal) + '</td>';
                    html += '<td style="color:#94a3b8">' + escHtml(h.changed_by_name || '') + '</td>';
                    html += '</tr>';
                });
                html += '</tbody></table>';
            }
            $content.html(html).data('history', history);
            if (history.length > 0) {
                $btn.closest('.rd-card-header').find('.rd-export-customer-history').show();
            }
        });
    });

    // Export customer history CSV
    $(document).on('click', '.rd-export-customer-history', function() {
        var history = $('#rd-customer-history-content').data('history');
        if (!history || !history.length) return;

        var custNumber = $(this).data('name') || 'customer';
        var fieldLabels = { 'name': 'Name', 'email': 'Email', 'phone': 'Phone', 'address': 'Address', 'notes': 'Notes', '_created': 'Created' };
        var rows = [['Date', 'Field', 'Old Value', 'New Value', 'Changed By']];
        $.each(history, function(i, h) {
            rows.push([
                h.changed_at || '',
                fieldLabels[h.field_name] || h.field_name,
                (h.old_value || '').replace(/"/g, '""'),
                (h.new_value || '').replace(/"/g, '""'),
                h.changed_by_name || ''
            ]);
        });
        var csv = rows.map(function(r) { return r.map(function(c) { return '"' + c + '"'; }).join(','); }).join('\n');
        var blob = new Blob(['\uFEFF' + csv], { type: 'text/csv;charset=utf-8' });
        var url = URL.createObjectURL(blob);
        var a = document.createElement('a');
        a.href = url;
        a.download = 'customer-history-' + custNumber + '-' + new Date().toISOString().slice(0, 10) + '.csv';
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
        URL.revokeObjectURL(url);
    });

    function renderContactCardContent(c) {
        var dash = '<span style="color:#cbd5e1">\u2014</span>';
        var html = '';
        html += infoRow(__('Name', 'vollstart-repair-desk'), c.name ? escHtml(c.name) : dash);
        html += infoRow(__('Email', 'vollstart-repair-desk'), c.email ? '<a href="mailto:' + escAttr(c.email) + '" style="color:#3b82f6">' + escHtml(c.email) + '</a>' : dash);
        html += infoRow(__('Phone', 'vollstart-repair-desk'), c.phone ? '<a href="tel:' + escAttr(c.phone) + '" style="color:#3b82f6">' + escHtml(c.phone) + '</a>' : dash);
        html += infoRow(__('Address', 'vollstart-repair-desk'), c.address ? escHtml(c.address) : dash);
        html += infoRow(__('VAT Number', 'vollstart-repair-desk'), c.vat_number ? escHtml(c.vat_number) : dash);
        return html;
    }

    /**
     * Update customer full view in-place after edit (no reload).
     * Merges server response into currentCustomer, re-renders only affected parts.
     */
    function updateCustomerViewInPlace(updatedCustomer) {
        // Merge server data into local state
        currentCustomer = $.extend(currentCustomer, updatedCustomer);
        var c = currentCustomer;

        // Update header name
        $('#rd-cv-name').text(c.name);

        // Update contact card content
        $('#rd-cv-contact').html(renderContactCardContent(c));

        // Update notes card
        if (c.notes) {
            $('#rd-cv-notes').html('<p style="white-space:pre-wrap;color:#374151;margin:0">' + escHtml(c.notes) + '</p>');
            $('#rd-cv-notes-card').show();
        } else {
            $('#rd-cv-notes-card').hide();
        }
    }

    // Back to customers list
    $(document).on('click', '#rd-back-to-customers', function() {
        loadCustomers();
    });

    /**
     * Quick-peek modal (used from repair detail → click customer).
     * Smaller, just key info.
     */
    function openCustomerDetail(id) {
        rdAjax('get_customer', { id: id }, function(result) {
            renderCustomerPeekModal(result.customer, result.customerRepairs || []);
        });
    }

    function renderCustomerPeekModal(customer, repairs) {
        var c = customer;

        var html = '';

        // Customer info cards
        html += '<div class="rd-info-grid" style="margin-bottom:20px">';

        // Contact card
        html += '<div class="rd-card">';
        html += '<div class="rd-card-header"><h3><span class="dashicons dashicons-id" style="margin-right:6px;color:#3b82f6"></span>' + __('Contact', 'vollstart-repair-desk') + '</h3></div>';
        html += '<div class="rd-card-body">';
        html += infoRow(__('Name', 'vollstart-repair-desk'), escHtml(c.name));
        if (c.email) html += infoRow(__('Email', 'vollstart-repair-desk'), '<a href="mailto:' + escAttr(c.email) + '" style="color:#3b82f6">' + escHtml(c.email) + '</a>');
        if (c.phone) html += infoRow(__('Phone', 'vollstart-repair-desk'), '<a href="tel:' + escAttr(c.phone) + '" style="color:#3b82f6">' + escHtml(c.phone) + '</a>');
        if (c.address) html += infoRow(__('Address', 'vollstart-repair-desk'), escHtml(c.address));
        html += infoRow(__('Customer since', 'vollstart-repair-desk'), escHtml(formatDateTime(c.created_at)));
        html += '</div></div>';

        // Stats card
        html += '<div class="rd-card">';
        html += '<div class="rd-card-header"><h3><span class="dashicons dashicons-chart-bar" style="margin-right:6px;color:#22c55e"></span>' + __('Overview', 'vollstart-repair-desk') + '</h3></div>';
        html += '<div class="rd-card-body">';
        var totalRepairs = repairs.length;
        var openRepairs = 0;
        var doneRepairs = 0;
        $.each(repairs, function(i, r) {
            if (r.status === 'delivered' || r.status === 'cancelled') doneRepairs++;
            else openRepairs++;
        });
        html += infoRow(__('Total Repairs', 'vollstart-repair-desk'), '<strong>' + totalRepairs + '</strong>');
        html += infoRow(__('Open', 'vollstart-repair-desk'), openRepairs > 0 ? '<span style="color:#f97316;font-weight:600">' + openRepairs + '</span>' : '0');
        html += infoRow(__('Completed', 'vollstart-repair-desk'), doneRepairs);
        if (c.notes) {
            html += '<div style="margin-top:8px;padding-top:8px;border-top:1px solid #f1f5f9">';
            html += '<div style="font-size:12px;color:#64748b;margin-bottom:2px">' + __('Notes', 'vollstart-repair-desk') + '</div>';
            html += '<div style="font-size:13px;color:#374151;white-space:pre-wrap">' + escHtml(c.notes) + '</div>';
            html += '</div>';
        }
        html += '</div></div>';

        html += '</div>'; // end info-grid

        // Repairs list
        html += '<h3 style="font-size:14px;font-weight:600;color:#1e293b;margin-bottom:12px">' + __('Repairs', 'vollstart-repair-desk') + '</h3>';

        if (repairs.length === 0) {
            html += '<p style="color:#94a3b8;font-size:13px;text-align:center;padding:16px 0">' + __('No repairs yet.', 'vollstart-repair-desk') + '</p>';
        } else {
            html += '<table class="rd-table">';
            html += '<thead><tr>';
            html += '<th>' + __('#', 'vollstart-repair-desk') + '</th>';
            html += '<th>' + __('Device', 'vollstart-repair-desk') + '</th>';
            html += '<th>' + __('Status', 'vollstart-repair-desk') + '</th>';
            html += '<th>' + __('Date', 'vollstart-repair-desk') + '</th>';
            html += '</tr></thead><tbody>';

            $.each(repairs, function(i, r) {
                var device = [r.device_brand, r.device_model].filter(Boolean).join(' ') || r.device_type || '—';
                var sLabel = getStatusLabel(r.status);
                var sColor = getStatusColor(r.status);

                html += '<tr class="rd-customer-repair-row" data-id="' + r.id + '" style="cursor:pointer">';
                html += '<td><strong>' + escHtml(r.repair_number) + '</strong></td>';
                html += '<td>' + escHtml(device) + '</td>';
                html += '<td><span style="display:inline-flex;align-items:center;font-size:11px;font-weight:600;padding:3px 10px;border-radius:999px;background:' + sColor + '15;color:' + sColor + ';border:1px solid ' + sColor + '30">' + escHtml(sLabel) + '</span></td>';
                html += '<td style="font-size:12px">' + escHtml(formatDateTime(r.created_at).split(',')[0]) + '</td>';
                html += '</tr>';
            });
            html += '</tbody></table>';
        }

        // Action buttons
        html += '<div class="rd-form-actions">';
        html += '<button class="rd-btn rd-btn-danger rd-btn-sm rd-delete-customer" data-id="' + c.id + '">' + __('Delete', 'vollstart-repair-desk') + '</button>';
        html += '<button class="rd-btn rd-btn-secondary rd-close-modal">' + __('Close', 'vollstart-repair-desk') + '</button>';
        html += '<button class="rd-btn rd-btn-primary rd-edit-customer-from-view" data-id="' + c.id + '">' + __('Edit', 'vollstart-repair-desk') + '</button>';
        html += '</div>';

        rdModal('rd-customer-modal', escHtml(c.customer_number) + ' — ' + escHtml(c.name), html, { maxWidth: '600px' });
    }

    // --- Product Form Modal ---

    function openProductForm(product, customerId) {
        var isEdit = !!product;
        var title = isEdit ? __('Edit Device', 'vollstart-repair-desk') : __('Add Device', 'vollstart-repair-desk');
        var p = product || {};

        var bodyHtml = '<div class="rd-form-grid">';
        // Device name: dropdown if deviceTypes configured, text field otherwise
        var deviceTypes = cfg.deviceTypes ? String(cfg.deviceTypes).split(',').map(function(t) { return t.trim(); }).filter(Boolean) : [];
        if (deviceTypes.length > 0) {
            bodyHtml += '<div class="rd-form-group"><label>' + __('Device Type', 'vollstart-repair-desk') + '</label>';
            bodyHtml += '<select id="rd-pf-name" style="width:100%;padding:8px 12px;border:1px solid #e2e8f0;border-radius:8px;font-size:14px">';
            for (var dti = 0; dti < deviceTypes.length; dti++) {
                var sel = (p.name === deviceTypes[dti]) ? ' selected' : (!p.name && dti === 0 ? ' selected' : '');
                bodyHtml += '<option value="' + escAttr(deviceTypes[dti]) + '"' + sel + '>' + escHtml(deviceTypes[dti]) + '</option>';
            }
            // If existing value not in list, add it
            if (p.name && deviceTypes.indexOf(p.name) < 0) {
                bodyHtml += '<option value="' + escAttr(p.name) + '" selected>' + escHtml(p.name) + '</option>';
            }
            bodyHtml += '</select></div>';
        } else {
            bodyHtml += formField('rd-pf-name', __('Device Name', 'vollstart-repair-desk'), 'text', p.name || '', __('e.g. Work Laptop, Mountain Bike', 'vollstart-repair-desk'));
        }
        bodyHtml += formField('rd-pf-brand', __('Brand', 'vollstart-repair-desk'), 'text', p.brand || '', __('e.g. Apple, Trek, Samsung', 'vollstart-repair-desk'));
        bodyHtml += formField('rd-pf-model', __('Model', 'vollstart-repair-desk'), 'text', p.model || '', __('e.g. MacBook Pro 14", Marlin 7', 'vollstart-repair-desk'));
        bodyHtml += formField('rd-pf-serial', __('Serial Number', 'vollstart-repair-desk'), 'text', p.serial_number || '');
        bodyHtml += '<div class="rd-form-group rd-form-full"><label>' + __('Notes', 'vollstart-repair-desk') + '</label>';
        bodyHtml += '<textarea id="rd-pf-notes" rows="3" placeholder="' + __('Accessories, condition, special instructions...', 'vollstart-repair-desk') + '">' + escHtml(p.notes || '') + '</textarea></div>';
        bodyHtml += '</div>';

        var prodFooter = '<button class="rd-btn rd-btn-secondary rd-close-modal">' + __('Cancel', 'vollstart-repair-desk') + '</button>';
        prodFooter += '<button class="rd-btn rd-btn-primary" id="rd-save-product" data-id="' + (p.id || '') + '" data-customer-id="' + customerId + '">' + (isEdit ? __('Save', 'vollstart-repair-desk') : __('Add Device', 'vollstart-repair-desk')) + '</button>';

        rdModal('rd-product-form-modal', title, bodyHtml, { maxWidth: '500px', footer: prodFooter });
    }

    // Toggle product files/photos (inline row)
    $(document).on('click', '.rd-toggle-product-files', function() {
        var productId = $(this).data('product-id');
        var $row = $('#rd-product-files-row-' + productId);
        var $container = $('#rd-product-files-' + productId);

        if ($row.is(':visible')) {
            $row.hide();
        } else {
            // Close other open photo rows
            $('.rd-product-files-row:visible').hide();
            $row.show();
            // Load upload widget if not yet loaded
            if (!$container.find('.rd-upload-widget').length) {
                renderUploadWidget('#rd-product-files-' + productId, 'product', productId, { showThumbnail: true, showCamera: true });
            }
        }
    });

    // Add product
    $(document).on('click', '#rd-add-product', function() {
        openProductForm(null, $(this).data('customer-id'));
    });

    // Edit product
    $(document).on('click', '.rd-edit-product', function() {
        var id = $(this).data('id');
        var customerId = $(this).data('customer-id');
        rdAjax('get_product', { id: id }, function(result) {
            openProductForm(result.product, customerId);
        });
    });

    // Save product
    $(document).on('click', '#rd-save-product', function() {
        var id = $(this).data('id');
        var customerId = $(this).data('customer-id');
        var data = {
            customer_id: customerId,
            name: $('#rd-pf-name').val(),
            brand: $('#rd-pf-brand').val(),
            model: $('#rd-pf-model').val(),
            serial_number: $('#rd-pf-serial').val(),
            notes: $('#rd-pf-notes').val()
        };
        var action = id ? 'update_product' : 'create_product';
        if (id) data.id = id;

        rdAjax(action, data, function(result) {
            $('.rd-modal-backdrop').remove();
            var productId = id || (result.id ? result.id : null);
            // Return to where we came from
            if (currentTab === 'devices' && productId) {
                openDeviceFullView(productId);
            } else if (customerId) {
                openCustomerFullView(customerId);
            } else {
                loadDevices();
            }
        }, {spin: true});
    });

    // Delete product
    $(document).on('click', '.rd-delete-product', function() {
        if (!confirm(__('Delete this device?', 'vollstart-repair-desk'))) return;
        var id = $(this).data('id');
        var customerId = $(this).data('customer-id');
        rdAjax('delete_product', { id: id }, function() {
            if (currentTab === 'devices') {
                loadDevices();
            } else if (customerId) {
                openCustomerFullView(customerId);
            }
        }, {spin: true});
    });

    // --- Customer Form Modal ---

    function openCustomerForm(customer) {
        var isEdit = !!customer;
        var title = isEdit ? __('Edit Customer', 'vollstart-repair-desk') : __('New Customer', 'vollstart-repair-desk');
        var c = customer || {};

        var bodyHtml = '<div class="rd-form-grid">';
        bodyHtml += formField('rd-cf-name', __('Name', 'vollstart-repair-desk'), 'text', c.name || '');
        bodyHtml += formField('rd-cf-email', __('Email', 'vollstart-repair-desk'), 'email', c.email || '');
        bodyHtml += formField('rd-cf-phone', __('Phone', 'vollstart-repair-desk'), 'text', c.phone || '');
        bodyHtml += '<div class="rd-form-group rd-form-full"><label>' + __('Address', 'vollstart-repair-desk') + '</label>';
        bodyHtml += '<textarea id="rd-cf-address" rows="2">' + escHtml(c.address || '') + '</textarea></div>';
        bodyHtml += formField('rd-cf-vat', __('VAT Number', 'vollstart-repair-desk'), 'text', c.vat_number || '', __('e.g. DE123456789', 'vollstart-repair-desk'));
        bodyHtml += '<div class="rd-form-group rd-form-full"><label>' + __('Notes', 'vollstart-repair-desk') + '</label>';
        bodyHtml += '<textarea id="rd-cf-notes" rows="2">' + escHtml(c.notes || '') + '</textarea></div>';
        bodyHtml += '</div>';

        var custFooter = '';
        if (isEdit) {
            custFooter += '<button class="rd-btn rd-btn-danger rd-btn-sm rd-delete-customer" data-id="' + c.id + '">' + __('Delete', 'vollstart-repair-desk') + '</button>';
        }
        custFooter += '<button class="rd-btn rd-btn-secondary rd-close-modal">' + __('Cancel', 'vollstart-repair-desk') + '</button>';
        custFooter += '<button class="rd-btn rd-btn-primary" id="rd-save-customer" data-id="' + (c.id || '') + '">' + (isEdit ? __('Save', 'vollstart-repair-desk') : __('Create Customer', 'vollstart-repair-desk')) + '</button>';

        rdModal('rd-customer-form-modal', title, bodyHtml, { maxWidth: '500px', footer: custFooter });
    }

    // --- Devices Tab ---

    var devicesDT = null;

    function loadDevices() {
        var html = '<div class="rd-toolbar"><div class="rd-toolbar-right">';
        html += '<button class="rd-btn rd-btn-secondary" id="rd-export-devices" title="' + __('Export CSV', 'vollstart-repair-desk') + '"><span class="dashicons dashicons-download" style="font-size:16px;width:16px;height:16px"></span></button>';
        html += '</div></div>';
        html += '<div class="rd-card"><table id="rd-devices-table" class="rd-table" style="width:100%">';
        html += '<thead><tr>';
        html += '<th style="width:60px"></th>';
        html += '<th>ID</th>';
        html += '<th>' + __('Name', 'vollstart-repair-desk') + '</th>';
        html += '<th>' + __('Brand / Model', 'vollstart-repair-desk') + '</th>';
        html += '<th class="rd-hide-mobile">' + __('Serial', 'vollstart-repair-desk') + '</th>';
        html += '<th>' + __('Customer', 'vollstart-repair-desk') + '</th>';
        html += '<th>' + __('Repairs', 'vollstart-repair-desk') + '</th>';
        html += '<th class="rd-hide-mobile">' + __('Next Service', 'vollstart-repair-desk') + '</th>';
        html += '<th></th>';
        html += '</tr></thead></table></div>';

        $('#rd-tab-content').html(html);

        var columnMap = ['', 'id', 'name', 'brand', 'serial_number', 'customer_name', 'repair_count', 'next_service_date', ''];
        if (devicesDT) { devicesDT.destroy(); devicesDT = null; }

        devicesDT = $('#rd-devices-table').DataTable({
            responsive: true, processing: true, serverSide: true,
            ajax: function(dtParams, callback) {
                var col = dtParams.order && dtParams.order[0] ? dtParams.order[0].column : 1;
                var dir = dtParams.order && dtParams.order[0] ? dtParams.order[0].dir : 'asc';
                rdAjax('get_products', {
                    page: Math.floor(dtParams.start / dtParams.length) + 1,
                    per_page: dtParams.length,
                    search: dtParams.search.value || '',
                    orderby: columnMap[col] || 'name',
                    order: dir.toUpperCase()
                }, function(data) {
                    var rows = (data.products || []).map(function(p) {
                        var brandModel = [p.brand, p.model].filter(Boolean).join(' ');
                        var thumb = p.thumbnail_url
                            ? '<img src="' + escAttr(p.thumbnail_url) + '" style="width:40px;height:40px;object-fit:cover;border-radius:6px">'
                            : '<span style="display:inline-flex;width:40px;height:40px;border-radius:6px;background:#f1f5f9;align-items:center;justify-content:center;color:#cbd5e1"><span class="dashicons dashicons-camera" style="font-size:16px;width:16px;height:16px"></span></span>';
                        var repairCount = parseInt(p.repair_count) || 0;
                        var serviceHtml = '\u2014';
                        if (p.next_service_date) {
                            var sToday = new Date(); sToday.setHours(0,0,0,0);
                            var sNext = new Date(p.next_service_date + 'T00:00:00');
                            var sDiff = Math.round((sNext - sToday) / 86400000);
                            var sColor = sDiff < 0 ? '#ef4444' : sDiff <= 30 ? '#f59e0b' : '#64748b';
                            serviceHtml = '<span style="color:' + sColor + ';font-size:12px;font-weight:' + (sDiff <= 0 ? '700' : '400') + '">' + escHtml(p.next_service_date) + '</span>';
                        }
                        return [
                            thumb,
                            '<span style="font-family:monospace;font-size:12px;color:#64748b">' + p.id + '</span>',
                            '<strong>' + escHtml(p.name || brandModel || '\u2014') + '</strong>',
                            escHtml(brandModel || '\u2014'),
                            '<span style="font-family:monospace;font-size:12px;color:#64748b">' + escHtml(p.serial_number || '\u2014') + '</span>',
                            escHtml(p.customer_name || '\u2014'),
                            repairCount > 0 ? '<strong>' + repairCount + '</strong>' : '<span style="color:#cbd5e1">0</span>',
                            serviceHtml,
                            '<div style="white-space:nowrap;display:flex;gap:4px;justify-content:flex-end">'
                                + '<button class="rd-btn rd-btn-sm rd-btn-secondary rd-device-pdf" data-id="' + p.id + '" data-full="0" title="PDF"><span class="dashicons dashicons-media-document" style="font-size:14px;width:14px;height:14px"></span></button>'
                                + '<button class="rd-btn rd-btn-sm rd-btn-secondary rd-view-device" data-id="' + p.id + '"><span class="dashicons dashicons-visibility" style="font-size:14px;width:14px;height:14px"></span></button>'
                                + '</div>'
                        ];
                    });
                    callback({ draw: dtParams.draw, recordsTotal: parseInt(data.total) || 0, recordsFiltered: parseInt(data.filtered) || 0, data: rows });
                });
            },
            pageLength: 20, lengthMenu: [10, 20, 50, 100], order: [[1, 'asc']],
            columns: [
                { orderable: false, width: 50 },
                { orderable: true, width: 50 },
                { orderable: true },
                { orderable: true },
                { orderable: true },
                { orderable: true },
                { orderable: true, width: 60 },
                { orderable: true, width: 100 },
                { orderable: false, width: 80 }
            ],
            language: {
                search: __('Search:', 'vollstart-repair-desk'), lengthMenu: __('Show _MENU_', 'vollstart-repair-desk'),
                info: __('_START_–_END_ of _TOTAL_ devices', 'vollstart-repair-desk'),
                infoEmpty: __('No devices found', 'vollstart-repair-desk'), zeroRecords: __('No matching devices', 'vollstart-repair-desk'),
                processing: __('Loading...', 'vollstart-repair-desk'), paginate: { previous: '&laquo;', next: '&raquo;' }
            },
            dom: '<"rd-dt-top"f>rt<"rd-dt-bottom"lip>',
            drawCallback: function() {
                $('#rd-devices-table tbody tr').css('cursor', 'pointer').off('click').on('click', function(e) {
                    if ($(e.target).closest('button').length) return;
                    var $btn = $(this).find('.rd-view-device');
                    if ($btn.length) openDeviceFullView($btn.data('id'));
                });
            }
        });
    }

    // Device Full View
    function openDeviceFullView(id) {
        $('#rd-tab-content').html('<div class="rd-loading"><span class="spinner is-active"></span></div>');
        rdAjax('get_device_detail', { id: id }, function(result) {
            renderDeviceFullView(result.product, result.customer, result.repairs || [], result.files || []);
        });
    }

    function renderDeviceFullView(product, customer, repairs, files) {
        var p = product;
        var brandModel = [p.brand, p.model].filter(Boolean).join(' ');
        var html = '';

        // Top bar
        html += '<div style="display:flex;align-items:center;gap:12px;margin-bottom:12px">';
        html += '<button class="rd-btn rd-btn-secondary rd-btn-sm" id="rd-back-to-devices"><span class="dashicons dashicons-arrow-left-alt2"></span> ' + __('Back', 'vollstart-repair-desk') + '</button>';
        html += '<div style="flex:1"></div>';
        html += '<button class="rd-btn rd-btn-sm rd-btn-secondary rd-device-pdf" data-id="' + p.id + '" data-full="0" title="PDF"><span class="dashicons dashicons-media-document"></span> PDF</button>';
        html += '<button class="rd-btn rd-btn-sm rd-btn-secondary rd-device-pdf" data-id="' + p.id + '" data-full="1" title="' + __('Full PDF', 'vollstart-repair-desk') + '"><span class="dashicons dashicons-media-document"></span> ' + __('Full', 'vollstart-repair-desk') + '</button>';
        html += '<button class="rd-btn rd-btn-primary rd-btn-sm rd-edit-product" data-id="' + p.id + '" data-customer-id="' + p.customer_id + '"><span class="dashicons dashicons-edit"></span> ' + __('Edit', 'vollstart-repair-desk') + '</button>';
        html += '<button class="rd-btn rd-btn-danger rd-btn-sm rd-delete-product" data-id="' + p.id + '" data-customer-id="' + p.customer_id + '"><span class="dashicons dashicons-trash"></span></button>';
        html += '</div>';

        // Name
        html += '<h2 style="font-size:22px;font-weight:700;color:#1e293b;margin:0 0 2px">' + escHtml(p.name || brandModel || '\u2014') + '</h2>';
        html += '<p style="font-size:13px;color:#94a3b8;margin:0 0 20px">' + escHtml(brandModel) + (p.serial_number ? ' · ' + p.serial_number : '') + '</p>';

        // Info cards
        html += '<div class="rd-info-grid" style="margin-bottom:24px">';

        // Device card
        html += '<div class="rd-card">';
        html += '<div class="rd-card-header"><h3><span class="dashicons dashicons-laptop" style="margin-right:6px;color:#6366f1"></span>' + __('Device Details', 'vollstart-repair-desk') + '</h3></div>';
        html += '<div class="rd-card-body">';
        html += infoRow('ID', '<code style="font-size:12px;background:#f1f5f9;padding:2px 6px;border-radius:4px">' + p.id + '</code>');
        html += infoRow(__('Type', 'vollstart-repair-desk'), escHtml(p.name || '\u2014'));
        if (p.brand) html += infoRow(__('Brand', 'vollstart-repair-desk'), escHtml(p.brand));
        if (p.model) html += infoRow(__('Model', 'vollstart-repair-desk'), escHtml(p.model));
        if (p.serial_number) html += infoRow(__('Serial', 'vollstart-repair-desk'), '<code style="font-size:12px;background:#f1f5f9;padding:2px 6px;border-radius:4px">' + escHtml(p.serial_number) + '</code>');
        if (p.notes) html += infoRow(__('Notes', 'vollstart-repair-desk'), escHtml(p.notes));
        html += '</div></div>';

        // Customer card
        html += '<div class="rd-card">';
        html += '<div class="rd-card-header"><h3><span class="dashicons dashicons-id" style="margin-right:6px;color:#3b82f6"></span>' + __('Owner', 'vollstart-repair-desk') + '</h3>';
        if (customer) {
            html += '<div class="rd-card-actions">';
            html += '<button class="rd-btn rd-btn-sm rd-btn-secondary rd-goto-customer" data-id="' + customer.id + '"><span class="dashicons dashicons-visibility" style="font-size:14px;width:14px;height:14px"></span> ' + __('View', 'vollstart-repair-desk') + '</button>';
            html += '</div>';
        }
        html += '</div><div class="rd-card-body">';
        if (customer) {
            html += infoRow(__('Name', 'vollstart-repair-desk'), escHtml(customer.name));
            html += infoRow(__('#', 'vollstart-repair-desk'), '<code>' + escHtml(customer.customer_number) + '</code>');
            if (customer.phone) html += infoRow(__('Phone', 'vollstart-repair-desk'), escHtml(customer.phone));
        } else {
            html += '<p style="color:#94a3b8;font-size:13px">' + __('No owner assigned.', 'vollstart-repair-desk') + '</p>';
        }
        html += '</div></div>';

        // Maintenance card
        {
        html += '<div class="rd-card">';
        html += '<div class="rd-card-header"><h3><span class="dashicons dashicons-calendar-alt" style="margin-right:6px;color:#f97316"></span>' + __('Maintenance', 'vollstart-repair-desk') + '</h3>';
        html += '<div class="rd-card-actions">';
        html += '<button class="rd-btn rd-btn-sm rd-btn-primary" id="rd-save-maintenance" data-id="' + p.id + '">' + __('Save', 'vollstart-repair-desk') + '</button>';
        html += '</div>';
        html += '</div>';
        html += '<div class="rd-card-body">';

        var intervalVal = parseInt(p.service_interval_days) || 0;
        var presets = [0, 30, 60, 90, 180, 365];
        var isCustom = intervalVal > 0 && presets.indexOf(intervalVal) === -1;

        html += '<div style="margin-bottom:12px"><label style="font-size:13px;font-weight:500;color:#475569">' + __('Service Interval', 'vollstart-repair-desk') + '</label>';
        html += '<div style="display:flex;gap:8px;margin-top:4px">';
        html += '<select id="rd-maint-interval" style="flex:1;padding:6px 10px;border:1px solid #e2e8f0;border-radius:6px;font-size:13px">';
        html += '<option value="0"' + (!intervalVal ? ' selected' : '') + '>' + __('None', 'vollstart-repair-desk') + '</option>';
        html += '<option value="30"' + (intervalVal === 30 ? ' selected' : '') + '>30 ' + __('days', 'vollstart-repair-desk') + '</option>';
        html += '<option value="60"' + (intervalVal === 60 ? ' selected' : '') + '>60 ' + __('days', 'vollstart-repair-desk') + '</option>';
        html += '<option value="90"' + (intervalVal === 90 ? ' selected' : '') + '>90 ' + __('days', 'vollstart-repair-desk') + '</option>';
        html += '<option value="180"' + (intervalVal === 180 ? ' selected' : '') + '>180 ' + __('days', 'vollstart-repair-desk') + '</option>';
        html += '<option value="365"' + (intervalVal === 365 ? ' selected' : '') + '>365 ' + __('days', 'vollstart-repair-desk') + ' (1 ' + __('year', 'vollstart-repair-desk') + ')</option>';
        html += '<option value="custom"' + (isCustom ? ' selected' : '') + '>' + __('Custom', 'vollstart-repair-desk') + '</option>';
        html += '</select>';
        html += '<input type="number" id="rd-maint-custom" min="1" max="3650" value="' + (isCustom ? intervalVal : '') + '" placeholder="' + __('days', 'vollstart-repair-desk') + '" style="width:80px;padding:6px 10px;border:1px solid #e2e8f0;border-radius:6px;font-size:13px;display:' + (isCustom ? 'block' : 'none') + '">';
        html += '</div></div>';

        html += '<div style="margin-bottom:12px"><label style="font-size:13px;font-weight:500;color:#475569">' + __('Next Service Date', 'vollstart-repair-desk') + '</label>';
        html += '<input type="date" id="rd-maint-next-date" value="' + escAttr(p.next_service_date || '') + '" style="display:block;width:100%;padding:6px 10px;border:1px solid #e2e8f0;border-radius:6px;font-size:13px;margin-top:4px"></div>';

        // Status badge (live-updated by updateMaintenanceStatus)
        html += '<div id="rd-maint-status-badge" style="display:' + (p.next_service_date ? 'flex' : 'none') + ';align-items:center;gap:6px;padding:8px 12px;border:1px solid transparent;border-radius:8px;font-size:13px;font-weight:600"></div>';

        html += '</div>';
        html += '</div>';
        }
        html += '</div>';

        // Photos
        html += '<div class="rd-card" style="margin-bottom:24px">';
        html += '<div class="rd-card-header"><h3><span class="dashicons dashicons-media-default" style="margin-right:6px;color:#8b5cf6"></span>' + __('Files', 'vollstart-repair-desk') + ' <span style="color:#94a3b8;font-weight:400">(' + files.length + ')</span></h3></div>';
        html += '<div class="rd-card-body" id="rd-device-files-' + p.id + '"></div>';
        html += '</div>';

        // Repairs
        html += '<div class="rd-card" style="margin-bottom:24px">';
        html += '<div class="rd-card-header"><h3><span class="dashicons dashicons-admin-tools" style="margin-right:6px;color:#22c55e"></span>' + __('Repair History', 'vollstart-repair-desk') + ' <span style="color:#94a3b8;font-weight:400">(' + repairs.length + ')</span></h3></div>';
        if (repairs.length === 0) {
            html += '<div class="rd-card-body"><p style="color:#94a3b8;text-align:center;padding:12px">' + __('No repairs for this device.', 'vollstart-repair-desk') + '</p></div>';
        } else {
            html += '<table class="rd-table"><thead><tr>';
            html += '<th>' + __('#', 'vollstart-repair-desk') + '</th><th>' + __('Defect', 'vollstart-repair-desk') + '</th><th>' + __('Status', 'vollstart-repair-desk') + '</th><th>' + __('Date', 'vollstart-repair-desk') + '</th>';
            html += '</tr></thead><tbody>';
            $.each(repairs, function(i, r) {
                var sLabel = getStatusLabel(r.status);
                var sColor = getStatusColor(r.status);
                var defect = (r.defect_description || '').substring(0, 50);
                if (r.defect_description && r.defect_description.length > 50) defect += '...';
                html += '<tr class="rd-device-repair-row" data-id="' + r.id + '" style="cursor:pointer">';
                html += '<td><strong>' + escHtml(r.repair_number) + '</strong></td>';
                html += '<td style="color:#64748b;font-size:12px">' + escHtml(defect) + '</td>';
                html += '<td><span style="display:inline-flex;font-size:11px;font-weight:600;padding:3px 10px;border-radius:999px;background:' + sColor + '15;color:' + sColor + ';border:1px solid ' + sColor + '30">' + escHtml(sLabel) + '</span></td>';
                html += '<td style="font-size:12px">' + escHtml(formatDateTime(r.created_at).split(',')[0]) + '</td>';
                html += '</tr>';
            });
            html += '</tbody></table>';
        }
        html += '</div>';

        // Change History (lazy)
        html += '<div class="rd-card">';
        html += '<div class="rd-card-header"><h3><span class="dashicons dashicons-backup" style="margin-right:6px;color:#8b5cf6"></span>' + __('Change History', 'vollstart-repair-desk') + '</h3>';
        html += '<div class="rd-card-actions">';
        html += '<button class="rd-btn rd-btn-sm rd-btn-secondary rd-export-device-history" data-id="' + p.id + '" style="display:none"><span class="dashicons dashicons-download" style="font-size:14px;width:14px;height:14px"></span> CSV</button>';
        html += '<button class="rd-btn rd-btn-sm rd-btn-secondary rd-load-device-history" data-id="' + p.id + '"><span class="dashicons dashicons-arrow-down-alt2" style="font-size:14px;width:14px;height:14px"></span></button>';
        html += '</div></div>';
        html += '<div id="rd-device-history-content" style="display:none"></div>';
        html += '</div>';

        $('#rd-tab-content').html(html);
        renderUploadWidget('#rd-device-files-' + p.id, 'product', p.id, { showThumbnail: true, showCamera: true });
        // Init maintenance status badge
        updateMaintenanceStatus();
    }

    // Maintenance: interval dropdown toggle
    $(document).on('change', '#rd-maint-interval', function() {
        var val = $(this).val();
        if (val === 'custom') {
            $('#rd-maint-custom').show().focus();
        } else {
            $('#rd-maint-custom').hide().val('');
        }
    });

    // Save maintenance
    // Auto-calculate next service date when interval changes
    $(document).on('change', '#rd-maint-interval, #rd-maint-custom', function() {
        var intervalSelect = $('#rd-maint-interval').val();
        var days = intervalSelect === 'custom' ? (parseInt($('#rd-maint-custom').val()) || 0) : parseInt(intervalSelect) || 0;
        if (days > 0) {
            var d = new Date();
            d.setDate(d.getDate() + days);
            var yyyy = d.getFullYear();
            var mm = String(d.getMonth() + 1).padStart(2, '0');
            var dd = String(d.getDate()).padStart(2, '0');
            $('#rd-maint-next-date').val(yyyy + '-' + mm + '-' + dd);
        } else {
            $('#rd-maint-next-date').val('');
        }
        updateMaintenanceStatus();
    });

    $(document).on('change', '#rd-maint-next-date', function() {
        updateMaintenanceStatus();
    });

    function updateMaintenanceStatus() {
        var nextDate = $('#rd-maint-next-date').val();
        var $badge = $('#rd-maint-status-badge');
        if (!nextDate) { $badge.html('').hide(); return; }
        var today = new Date(); today.setHours(0,0,0,0);
        var nDate = new Date(nextDate + 'T00:00:00');
        var diff = Math.round((nDate - today) / 86400000);
        var color, text, icon;
        if (diff < 0) { color = '#ef4444'; text = __('Overdue', 'vollstart-repair-desk') + ' (' + Math.abs(diff) + ' ' + __('days', 'vollstart-repair-desk') + ')'; icon = 'warning'; }
        else if (diff <= 30) { color = '#f59e0b'; text = __('Due soon', 'vollstart-repair-desk') + ' (' + diff + ' ' + __('days', 'vollstart-repair-desk') + ')'; icon = 'clock'; }
        else { color = '#22c55e'; text = __('OK', 'vollstart-repair-desk') + ' (' + diff + ' ' + __('days', 'vollstart-repair-desk') + ')'; icon = 'yes'; }
        $badge.html('<span class="dashicons dashicons-' + icon + '" style="font-size:16px;width:16px;height:16px"></span>' + text)
            .css({ color: color, background: color + '10', borderColor: color + '30' }).show();
    }

    // Back to devices list
    $(document).on('click', '#rd-back-to-devices', function() { loadDevices(); });

    // Device PDF — direct URL, on-the-fly
    $(document).on('click', '.rd-device-pdf', function() {
        window.open(rdPdfUrl('device', $(this).data('id'), $(this).data('full')), '_blank');
    });

    // Customer PDF — direct URL, on-the-fly
    $(document).on('click', '.rd-customer-pdf', function() {
        window.open(rdPdfUrl('customer', $(this).data('id'), $(this).data('full')), '_blank');
    });

    // View device
    $(document).on('click', '.rd-view-device', function() {
        var id = $(this).data('id');
        if (id) openDeviceFullView(id);
    });

    // Click repair in device view → repair full view
    $(document).on('click', '.rd-device-repair-row', function() {
        var id = $(this).data('id');
        if (id) {
            currentTab = 'repairs';
            $('.rd-tab').removeClass('active').filter('[data-tab="repairs"]').addClass('active');
            $('html, body').animate({ scrollTop: 0 }, 200);
            openRepairFullView(id);
        }
    });

    // Lazy-load device change history
    $(document).on('click', '.rd-load-device-history', function() {
        var $btn = $(this);
        var id = $btn.data('id');
        var $content = $('#rd-device-history-content');
        if ($content.is(':visible')) {
            $content.slideUp(200);
            $btn.find('.dashicons').removeClass('dashicons-arrow-up-alt2').addClass('dashicons-arrow-down-alt2');
            $btn.closest('.rd-card-header').find('.rd-export-device-history').hide();
            return;
        }
        $content.html('<div class="rd-loading"><span class="spinner is-active"></span></div>').slideDown(200);
        $btn.find('.dashicons').removeClass('dashicons-arrow-down-alt2').addClass('dashicons-arrow-up-alt2');

        rdAjax('get_product_history', { id: id }, function(result) {
            var history = result.history || [];
            var fieldLabels = { 'name': __('Name', 'vollstart-repair-desk'), 'brand': __('Brand', 'vollstart-repair-desk'), 'model': __('Model', 'vollstart-repair-desk'), 'serial_number': __('Serial', 'vollstart-repair-desk'), 'notes': __('Notes', 'vollstart-repair-desk') };
            var html = '';
            if (history.length === 0) {
                html = '<p style="color:#94a3b8;font-size:13px;text-align:center;padding:12px">' + __('No changes recorded.', 'vollstart-repair-desk') + '</p>';
            } else {
                html = '<table class="rd-table" style="font-size:12px"><thead><tr><th>' + __('Date', 'vollstart-repair-desk') + '</th><th>' + __('Field', 'vollstart-repair-desk') + '</th><th>' + __('Old', 'vollstart-repair-desk') + '</th><th>' + __('New', 'vollstart-repair-desk') + '</th><th>' + __('By', 'vollstart-repair-desk') + '</th></tr></thead><tbody>';
                $.each(history, function(i, h) {
                    var oldVal = (h.old_value || '').substring(0, 50);
                    var newVal = (h.new_value || '').substring(0, 50);
                    html += '<tr><td style="white-space:nowrap;color:#94a3b8">' + escHtml(formatDateTime(h.changed_at)) + '</td>';
                    html += '<td>' + escHtml(fieldLabels[h.field_name] || h.field_name) + '</td>';
                    html += '<td style="color:#dc2626" title="' + escAttr(h.old_value) + '">' + escHtml(oldVal) + '</td>';
                    html += '<td style="color:#22c55e" title="' + escAttr(h.new_value) + '">' + escHtml(newVal) + '</td>';
                    html += '<td style="color:#94a3b8">' + escHtml(h.changed_by_name || '') + '</td></tr>';
                });
                html += '</tbody></table>';
            }
            $content.html(html).data('history', history);
            if (history.length > 0) $btn.closest('.rd-card-header').find('.rd-export-device-history').show();
        });
    });

    // Export device history CSV
    $(document).on('click', '.rd-export-device-history', function() {
        var history = $('#rd-device-history-content').data('history');
        if (!history || !history.length) return;
        var fieldLabels = { 'name': 'Name', 'brand': 'Brand', 'model': 'Model', 'serial_number': 'Serial', 'notes': 'Notes' };
        var rows = [['Date', 'Field', 'Old Value', 'New Value', 'Changed By']];
        $.each(history, function(i, h) {
            rows.push([h.changed_at || '', fieldLabels[h.field_name] || h.field_name, (h.old_value || '').replace(/"/g, '""'), (h.new_value || '').replace(/"/g, '""'), h.changed_by_name || '']);
        });
        var csv = rows.map(function(r) { return r.map(function(c) { return '"' + c + '"'; }).join(','); }).join('\n');
        var blob = new Blob(['\uFEFF' + csv], { type: 'text/csv;charset=utf-8' });
        var url = URL.createObjectURL(blob);
        var a = document.createElement('a');
        a.href = url;
        a.download = 'device-history-' + $(this).data('id') + '-' + new Date().toISOString().slice(0, 10) + '.csv';
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
        URL.revokeObjectURL(url);
    });

    // Delete product from device view → back to list
    // (reuse existing .rd-delete-product handler, but check if in devices tab)

    // --- Repair Types Tab ---

    function loadRepairTypes() {
        rdAjax('get_repair_types', {}, function(result) {
            renderRepairTypesTab(result.repairTypes || [], result.icons || []);
        });
    }

    function renderRepairTypesTab(types, icons) {
        var info = '<strong>' + __('What are Repair Types?', 'vollstart-repair-desk') + '</strong> '
                 + __('Reusable templates for the kinds of jobs you do — e.g. "Bike Service", "Screen Replacement", "Tyre Change". Each type can hold an icon, an estimated duration and a default price; favourites show as quick-start tiles in the intake form. Repair types speed up new repairs (one click pre-fills duration + price) and group reports by job type.', 'vollstart-repair-desk');
        if (cfg.enableWorkSteps) {
            info += ' ' + __('You can also attach Work Step checklists to a repair type so the steps are auto-applied to new repairs.', 'vollstart-repair-desk');
        }
        var html = infoBox(info);

        html += '<div class="rd-toolbar"><div class="rd-toolbar-right">';
        html += '<button class="rd-btn rd-btn-secondary" id="rd-export-repair-types" title="' + __('Export JSON', 'vollstart-repair-desk') + '"><span class="dashicons dashicons-download" style="font-size:16px;width:16px;height:16px"></span></button>';
        html += '<button class="rd-btn rd-btn-secondary" id="rd-import-repair-types" title="' + __('Import JSON', 'vollstart-repair-desk') + '"><span class="dashicons dashicons-upload" style="font-size:16px;width:16px;height:16px"></span></button>';
        if (cfg.enableWorkSteps) html += '<button class="rd-btn rd-btn-secondary" id="rd-manage-step-lists"><span class="dashicons dashicons-list-view"></span> ' + __('Work Steps', 'vollstart-repair-desk') + '</button>';
        html += '<button class="rd-btn rd-btn-primary" id="rd-new-repair-type"><span class="dashicons dashicons-plus-alt2"></span> ' + __('New Repair Type', 'vollstart-repair-desk') + '</button>';
        html += '</div></div>';

        html += '<div class="rd-card">';
        if (types.length === 0) {
            html += '<div class="rd-empty"><span class="dashicons dashicons-admin-tools"></span><p>' + __('No repair types defined yet.', 'vollstart-repair-desk') + '</p>';
            html += '<button class="rd-btn rd-btn-primary" id="rd-new-repair-type-empty"><span class="dashicons dashicons-plus-alt2"></span> ' + __('Create first repair type', 'vollstart-repair-desk') + '</button></div>';
        } else {
            html += '<div id="rd-repair-types-list" style="padding:8px 0">';
            $.each(types, function(i, t) {
                var activeClass = t.active && t.active !== '0' ? '' : ' opacity:0.4;';
                html += '<div class="rd-repair-type-item" data-id="' + t.id + '" style="display:flex;align-items:center;gap:12px;padding:12px 16px;border-bottom:1px solid #f1f5f9;' + activeClass + '">';
                html += '<span class="rd-rt-handle" style="cursor:grab;color:#cbd5e1">&#9776;</span>';
                html += '<span class="dashicons dashicons-' + escAttr(t.icon || 'admin-tools') + '" style="font-size:24px;width:24px;height:24px;color:#6366f1"></span>';
                html += '<div style="flex:1">';
                html += '<div style="font-weight:600;font-size:14px">' + escHtml(t.name) + '</div>';
                if (t.description) html += '<div style="font-size:12px;color:#64748b">' + escHtml(t.description.substring(0, 80)) + '</div>';
                html += '</div>';
                if (t.estimated_duration_hours && t.estimated_duration_hours !== '0.0') {
                    html += '<span style="font-size:12px;color:#94a3b8;white-space:nowrap">' + escHtml(t.estimated_duration_hours) + 'h</span>';
                }
                if (t.default_price && t.default_price !== '0.00') {
                    html += '<span style="font-size:12px;color:#94a3b8;white-space:nowrap">' + escHtml(t.default_price) + ' ' + cfg.currency + '</span>';
                }
                if (t.is_favorite && t.is_favorite !== '0') {
                    html += '<span class="dashicons dashicons-star-filled" style="color:#f59e0b;font-size:16px;width:16px;height:16px"></span>';
                }
                html += '<div class="rd-product-actions">';
                html += '<button class="rd-btn rd-btn-sm rd-btn-secondary rd-view-repair-type" data-id="' + t.id + '"><span class="dashicons dashicons-visibility" style="font-size:14px;width:14px;height:14px"></span></button>';
                html += '<button class="rd-btn rd-btn-sm rd-btn-secondary rd-edit-repair-type" data-id="' + t.id + '"><span class="dashicons dashicons-edit" style="font-size:14px;width:14px;height:14px"></span></button>';
                html += '<button class="rd-btn rd-btn-sm rd-btn-danger rd-delete-repair-type" data-id="' + t.id + '"><span class="dashicons dashicons-trash" style="font-size:14px;width:14px;height:14px"></span></button>';
                html += '</div>';
                html += '</div>';
            });
            html += '</div>';
        }
        html += '</div>';

        $('#rd-tab-content').html(html);
        initRepairTypesDragDrop();
    }

    function initRepairTypesDragDrop() {
        var list = document.getElementById('rd-repair-types-list');
        if (!list) return;
        var dragItem = null;

        $(list).on('mousedown touchstart', '.rd-rt-handle', function(e) {
            dragItem = $(this).closest('.rd-repair-type-item')[0];
            dragItem.style.opacity = '0.5';
            e.preventDefault();
        });

        $(document).on('mousemove touchmove', function(e) {
            if (!dragItem) return;
            var clientY = e.clientY || (e.originalEvent.touches && e.originalEvent.touches[0].clientY);
            var items = list.querySelectorAll('.rd-repair-type-item');
            var closest = null, closestDist = Infinity;
            items.forEach(function(item) {
                if (item === dragItem) return;
                var rect = item.getBoundingClientRect();
                var dist = Math.abs(clientY - (rect.top + rect.height / 2));
                if (dist < closestDist) { closestDist = dist; closest = item; }
            });
            if (closest) {
                var rect = closest.getBoundingClientRect();
                if (clientY < rect.top + rect.height / 2) list.insertBefore(dragItem, closest);
                else list.insertBefore(dragItem, closest.nextSibling);
            }
        });

        $(document).on('mouseup touchend', function() {
            if (!dragItem) return;
            dragItem.style.opacity = '';
            dragItem = null;
            // Save new order
            var order = [];
            $('#rd-repair-types-list .rd-repair-type-item').each(function() { order.push($(this).data('id')); });
            rdAjax('save_repair_types_order', { order: JSON.stringify(order) }, null, {spin: true});
        });
    }

    // New repair type
    $(document).on('click', '#rd-new-repair-type, #rd-new-repair-type-empty', function() {
        openRepairTypeForm(null);
    });

    // Edit repair type
    $(document).on('click', '.rd-edit-repair-type', function() {
        var id = $(this).data('id');
        rdAjax('get_repair_types', {}, function(result) {
            var type = (result.repairTypes || []).find(function(t) { return t.id == id; });
            if (type) openRepairTypeForm(type, result.icons);
        });
    });

    // Delete repair type
    $(document).on('click', '.rd-delete-repair-type', function() {
        if (!confirm(__('Delete this repair type?', 'vollstart-repair-desk'))) return;
        rdAjax('delete_repair_type', { id: $(this).data('id') }, function(result) {
            if (result.repairTypes) renderRepairTypesTab(result.repairTypes, []);
        }, {spin: true});
    });

    function openRepairTypeForm(type, icons) {
        var isEdit = !!type;
        var t = type || {};
        var iconList = icons || ['admin-tools','smartphone','laptop','desktop','tablet','camera','car','bike','hammer','wrench','shield','lightbulb','performance','clock','visibility','star-filled','heart','flag','tag','category'];

        var rtBody = '<div class="rd-form-grid">';
        rtBody += formField('rd-rt-name', __('Name', 'vollstart-repair-desk'), 'text', t.name || '', __('e.g. Tire Change, Screen Repair', 'vollstart-repair-desk'));

        // Icon picker
        rtBody += '<div class="rd-form-group"><label>' + __('Icon', 'vollstart-repair-desk') + '</label>';
        rtBody += '<div style="display:flex;flex-wrap:wrap;gap:6px" id="rd-rt-icon-picker">';
        $.each(iconList, function(i, icon) {
            var sel = (t.icon === icon || (!t.icon && icon === 'admin-tools')) ? 'border-color:#f97316;background:#fff7ed;color:#f97316' : '';
            rtBody += '<button type="button" class="rd-rt-icon-btn" data-icon="' + icon + '" style="width:36px;height:36px;border:2px solid #e2e8f0;border-radius:6px;display:flex;align-items:center;justify-content:center;cursor:pointer;background:#fff;color:#64748b;' + sel + '"><span class="dashicons dashicons-' + icon + '" style="font-size:18px;width:18px;height:18px"></span></button>';
        });
        rtBody += '</div>';
        rtBody += '<input type="hidden" id="rd-rt-icon" value="' + escAttr(t.icon || 'admin-tools') + '">';
        rtBody += '</div>';

        rtBody += '<div class="rd-form-group rd-form-full"><label>' + __('Description', 'vollstart-repair-desk') + '</label>';
        rtBody += '<textarea id="rd-rt-desc" rows="2">' + escHtml(t.description || '') + '</textarea></div>';
        rtBody += formField('rd-rt-duration', __('Est. Duration (hours)', 'vollstart-repair-desk'), 'number', t.estimated_duration_hours || '');
        rtBody += formField('rd-rt-price', __('Default Price', 'vollstart-repair-desk'), 'number', t.default_price || '', '0.00 ' + cfg.currency);

        rtBody += '<div class="rd-form-group"><label style="display:flex;align-items:center;gap:6px;cursor:pointer;text-transform:none;font-size:13px">';
        rtBody += '<input type="checkbox" id="rd-rt-favorite"' + (t.is_favorite && t.is_favorite !== '0' ? ' checked' : '') + ' style="width:auto;margin:0"> ';
        rtBody += '<span class="dashicons dashicons-star-filled" style="color:#f59e0b;font-size:16px;width:16px;height:16px"></span> ' + __('Favorite (Quick-Start)', 'vollstart-repair-desk');
        rtBody += '</label></div>';

        rtBody += '<div class="rd-form-group"><label style="display:flex;align-items:center;gap:6px;cursor:pointer;text-transform:none;font-size:13px">';
        rtBody += '<input type="checkbox" id="rd-rt-active"' + (isEdit ? (t.active && t.active !== '0' ? ' checked' : '') : ' checked') + ' style="width:auto;margin:0"> ';
        rtBody += __('Active', 'vollstart-repair-desk');
        rtBody += '</label></div>';

        rtBody += '</div>';

        // Checklist assignment
        if (cfg.enableWorkSteps) {
        rtBody += '<div style="margin-top:16px;padding-top:16px;border-top:1px solid #f1f5f9">';
        rtBody += '<label style="font-size:12px;font-weight:600;color:#475569;text-transform:uppercase;display:block;margin-bottom:8px">' + __('Work Steps', 'vollstart-repair-desk') + '</label>';
        rtBody += '<p style="font-size:12px;color:#94a3b8;margin:0 0 8px">' + __('Select which work steps should be auto-applied when creating repairs of this type.', 'vollstart-repair-desk') + '</p>';
        rtBody += '<div id="rd-rt-checklists-list"><div class="rd-loading"><span class="spinner is-active"></span></div></div>';
        rtBody += '</div>';
        }

        var rtFooter = '<button class="rd-btn rd-btn-secondary rd-close-modal">' + __('Cancel', 'vollstart-repair-desk') + '</button>';
        rtFooter += '<button class="rd-btn rd-btn-primary" id="rd-save-repair-type" data-id="' + (t.id || '') + '">' + (isEdit ? __('Save', 'vollstart-repair-desk') : __('Create', 'vollstart-repair-desk')) + '</button>';

        rdModal('rd-repair-type-form', (isEdit ? __('Edit Repair Type', 'vollstart-repair-desk') : __('New Repair Type', 'vollstart-repair-desk')), rtBody, { maxWidth: '500px', footer: rtFooter });

        // Load checklists for assignment
        var loadAction = isEdit ? 'get_checklists_for_type' : 'get_checklists';
        var loadData = isEdit ? { repair_type_id: t.id } : {};
        rdAjax(loadAction, loadData, function(result) {
            var checklists = result.checklists || [];
            var assignedIds = result.assignedIds || [];
            var clHtml = '';
            if (checklists.length === 0) {
                clHtml = '<p style="color:#94a3b8;font-size:13px">' + __('No work steps created yet. Create one in the Work Steps section below.', 'vollstart-repair-desk') + '</p>';
            } else {
                $.each(checklists, function(i, cl) {
                    var checked = assignedIds.indexOf(String(cl.id)) !== -1 || assignedIds.indexOf(Number(cl.id)) !== -1;
                    var stepCount = (cl.items || []).length;
                    clHtml += '<label style="display:flex;align-items:center;gap:8px;padding:8px 0;border-bottom:1px solid #f8fafc;cursor:pointer;font-size:13px">';
                    clHtml += '<input type="checkbox" class="rd-rt-checklist-cb" value="' + cl.id + '"' + (checked ? ' checked' : '') + ' style="width:16px;height:16px">';
                    clHtml += '<strong>' + escHtml(cl.name) + '</strong>';
                    clHtml += '<span style="color:#94a3b8;font-size:12px">(' + stepCount + ' ' + __('steps', 'vollstart-repair-desk') + ')</span>';
                    clHtml += '</label>';
                });
            }
            $('#rd-rt-checklists-list').html(clHtml);
        });
    }

    // Icon picker click
    $(document).on('click', '.rd-rt-icon-btn', function() {
        $('#rd-rt-icon-picker .rd-rt-icon-btn').css({ 'border-color': '#e2e8f0', 'background': '#fff', 'color': '#64748b' });
        $(this).css({ 'border-color': '#f97316', 'background': '#fff7ed', 'color': '#f97316' });
        $('#rd-rt-icon').val($(this).data('icon'));
    });

    // Save repair type
    $(document).on('click', '#rd-save-repair-type', function() {
        var id = $(this).data('id');
        var data = {
            name: $('#rd-rt-name').val(),
            description: $('#rd-rt-desc').val(),
            icon: $('#rd-rt-icon').val(),
            estimated_duration_hours: $('#rd-rt-duration').val(),
            default_price: $('#rd-rt-price').val(),
            is_favorite: $('#rd-rt-favorite').is(':checked') ? '1' : '0',
            active: $('#rd-rt-active').is(':checked') ? '1' : '0'
        };
        var action = id ? 'update_repair_type' : 'create_repair_type';
        if (id) data.id = id;

        rdAjax(action, data, function(result) {
            var typeId = result.repairType ? result.repairType.id : id;
            // Assign selected checklists to this repair type
            if (typeId) {
                var clIds = [];
                $('.rd-rt-checklist-cb:checked').each(function() { clIds.push($(this).val()); });
                rdAjax('assign_checklists_to_type', {
                    repair_type_id: typeId,
                    checklist_ids: JSON.stringify(clIds)
                }, function() {
                    $('.rd-modal-backdrop').remove();
                    loadRepairTypes();
                }, {spin: true});
            } else {
                $('.rd-modal-backdrop').remove();
                loadRepairTypes();
            }
        }, {spin: true});
    });

    // --- Work Steps Tab ---

    function loadStepLists() {
        rdAjax('get_checklists', {}, function(result) {
            renderStepListsTab(result.checklists || []);
        });
    }

    function renderStepListsTab(checklists) {
        var html = infoBox(
            '<strong>' + __('What are Work Steps?', 'vollstart-repair-desk') + '</strong> '
            + __('Reusable checklists for each kind of repair (e.g. "Bike Service" or "Phone Screen Repair"). Assign a list to a Repair Type — the steps are automatically added when a new repair is created. Inside each step you can set an estimated time, a default price, an instruction text and attach photos or materials from your catalog.', 'vollstart-repair-desk')
        );

        html += '<div class="rd-toolbar"><div class="rd-toolbar-right">';
        html += '<button class="rd-btn rd-btn-secondary" id="rd-export-work-steps" title="' + __('Export JSON', 'vollstart-repair-desk') + '"><span class="dashicons dashicons-download" style="font-size:16px;width:16px;height:16px"></span></button>';
        html += '<button class="rd-btn rd-btn-secondary" id="rd-import-work-steps" title="' + __('Import JSON', 'vollstart-repair-desk') + '"><span class="dashicons dashicons-upload" style="font-size:16px;width:16px;height:16px"></span></button>';
        html += '<button class="rd-btn rd-btn-primary" id="rd-new-steplist-tab"><span class="dashicons dashicons-plus-alt2"></span> ' + __('New Work Steps', 'vollstart-repair-desk') + '</button>';
        html += '</div></div>';

        if (checklists.length === 0) {
            html += '<div class="rd-card"><div class="rd-empty"><span class="dashicons dashicons-list-view"></span><p>' + __('No work steps yet.', 'vollstart-repair-desk') + '</p></div></div>';
        } else {
            html += '<div class="rd-card"><div style="padding:8px 0">';
            $.each(checklists, function(i, cl) {
                var items = cl.items || [];
                var totalDur = 0, totalPrice = 0, totalFiles = 0, totalInstr = 0;
                $.each(items, function(j, it) {
                    totalDur += parseFloat(it.default_duration) || 0;
                    totalPrice += parseFloat(it.default_price) || 0;
                    totalFiles += parseInt(it.file_count) || 0;
                    if (it.instructions && it.instructions.trim()) totalInstr++;
                });

                html += '<div class="rd-step-list-card" data-id="' + cl.id + '" style="border-bottom:1px solid #f1f5f9;padding:12px 16px">';
                html += '<div style="display:flex;align-items:center;gap:12px;cursor:pointer" class="rd-step-list-toggle">';
                html += '<span class="dashicons dashicons-arrow-right-alt2 rd-step-list-arrow" style="font-size:14px;width:14px;height:14px;transition:transform 0.2s"></span>';
                html += '<div style="flex:1">';
                html += '<strong style="font-size:14px">' + escHtml(cl.name) + '</strong>';
                html += '<span style="color:#94a3b8;font-size:12px;margin-left:8px">' + items.length + ' ' + __('steps', 'vollstart-repair-desk') + '</span>';
                if (totalDur > 0) html += '<span style="color:#94a3b8;font-size:12px;margin-left:8px">' + totalDur.toFixed(1) + ' min</span>';
                if (totalPrice > 0) html += '<span style="color:#94a3b8;font-size:12px;margin-left:8px">' + totalPrice.toFixed(2) + ' ' + cfg.currency + '</span>';
                if (totalInstr > 0) html += '<span style="font-size:11px;margin-left:6px" title="' + totalInstr + ' ' + __('steps with instructions', 'vollstart-repair-desk') + '"><span class="dashicons dashicons-book" style="font-size:13px;width:13px;height:13px;color:#f97316"></span></span>';
                if (totalFiles > 0) html += '<span style="font-size:11px;background:#eff6ff;color:#3b82f6;padding:1px 6px;border-radius:999px;margin-left:4px" title="' + totalFiles + ' ' + __('files', 'vollstart-repair-desk') + '">' + totalFiles + ' <span class="dashicons dashicons-camera" style="font-size:11px;width:11px;height:11px"></span></span>';
                if (cl.trigger_status_start || cl.trigger_status) html += '<span class="dashicons dashicons-randomize" style="font-size:14px;width:14px;height:14px;color:#3b82f6;margin-left:4px" title="' + __('Status triggers configured', 'vollstart-repair-desk') + '"></span>';
                html += '</div>';
                html += '<div class="rd-product-actions">';
                html += '<button class="rd-btn rd-btn-sm rd-btn-secondary rd-view-steplist" data-id="' + cl.id + '"><span class="dashicons dashicons-visibility" style="font-size:14px;width:14px;height:14px"></span></button>';
                html += '<button class="rd-btn rd-btn-sm rd-btn-secondary rd-edit-steplist" data-id="' + cl.id + '"><span class="dashicons dashicons-edit" style="font-size:14px;width:14px;height:14px"></span></button>';
                html += '<button class="rd-btn rd-btn-sm rd-btn-danger rd-delete-steplist" data-id="' + cl.id + '"><span class="dashicons dashicons-trash" style="font-size:14px;width:14px;height:14px"></span></button>';
                html += '</div></div>';

                // Expandable area
                html += '<div class="rd-step-list-body" style="display:none;margin-top:8px">';

                // Used by Repair Types
                var repairTypes = cl.repair_types || [];
                if (repairTypes.length > 0) {
                    html += '<div style="margin-bottom:8px;padding:8px 10px;background:#f0fdf4;border:1px solid #a7f3d0;border-radius:6px;font-size:12px">';
                    html += '<span style="color:#64748b">' + __('Used by Repair Types:', 'vollstart-repair-desk') + '</span> ';
                    $.each(repairTypes, function(ri, rt) {
                        if (ri > 0) html += ', ';
                        html += '<a href="#" class="rd-goto-repair-type" data-id="' + rt.id + '" style="color:#22c55e;font-weight:500;text-decoration:none">';
                        html += '<span class="dashicons dashicons-' + escAttr(rt.icon || 'admin-tools') + '" style="font-size:12px;width:12px;height:12px"></span> ' + escHtml(rt.name);
                        html += '</a>';
                    });
                    html += '</div>';
                }

                // Hint
                html += '<div style="font-size:11px;color:#94a3b8;padding:4px 0 8px"><span class="dashicons dashicons-info" style="font-size:12px;width:12px;height:12px"></span> ' + __('Click the eye icon to open the full editor — add instructions, set times, and attach catalog items to each step.', 'vollstart-repair-desk') + '</div>';

                // Steps table
                if (items.length > 0) {
                    html += '<table class="rd-table" style="font-size:12px"><thead><tr>';
                    html += '<th>#</th><th>' + __('Step', 'vollstart-repair-desk') + '</th><th>' + __('Duration (min)', 'vollstart-repair-desk') + '</th><th>' + __('Price', 'vollstart-repair-desk') + '</th><th></th>';
                    html += '</tr></thead><tbody>';
                    $.each(items, function(j, it) {
                        var hasInstr = (it.instructions && it.instructions.trim());
                        var fileCount = parseInt(it.file_count) || 0;
                        var badges = '';
                        if (hasInstr) badges += '<span class="dashicons dashicons-book" style="font-size:13px;width:13px;height:13px;color:#f97316" title="' + __('Has instructions', 'vollstart-repair-desk') + '"></span> ';
                        if (fileCount > 0) badges += '<span style="font-size:11px;background:#eff6ff;color:#3b82f6;padding:1px 6px;border-radius:999px" title="' + fileCount + ' ' + __('files', 'vollstart-repair-desk') + '">' + fileCount + ' <span class="dashicons dashicons-camera" style="font-size:11px;width:11px;height:11px"></span></span>';

                        html += '<tr><td style="color:#94a3b8">' + (j + 1) + '</td>';
                        html += '<td>' + escHtml(it.title);
                        if (it.instructions && it.instructions.trim()) {
                            var instrPreview = it.instructions.trim().substring(0, 100);
                            if (it.instructions.trim().length > 100) instrPreview += '...';
                            html += '<div style="font-size:11px;color:#94a3b8;margin-top:2px">' + escHtml(instrPreview) + '</div>';
                        }
                        html += '</td>';
                        var files = it.files || [];
                        var hasFiles = files.length > 0;
                        html += '<td>' + (parseFloat(it.default_duration) || '\u2014') + '</td>';
                        html += '<td>' + (parseFloat(it.default_price) ? it.default_price + ' ' + cfg.currency : '\u2014') + '</td>';
                        html += '<td style="text-align:right">' + badges + '</td></tr>';
                        if (hasFiles) {
                            html += '<tr><td colspan="5" style="padding:4px 8px 12px"><div class="rd-file-gallery">' + renderFileGallery(files, 'checklist_item', it.id, false, { noDelete: true }) + '</div></td></tr>';
                        }
                    });
                    html += '</tbody></table>';
                } else {
                    html += '<p style="color:#94a3b8;font-size:13px;padding:8px 0">' + __('No steps defined.', 'vollstart-repair-desk') + '</p>';
                }
                html += '</div></div>';
            });
            html += '</div></div>';
        }

        $('#rd-tab-content').html(html);
    }

    // View repair type — full view
    $(document).on('click', '.rd-view-repair-type, .rd-goto-repair-type', function(e) {
        e.preventDefault();
        var id = $(this).data('id');
        if (id) {
            currentTab = 'repair-types';
            $('.rd-tab').removeClass('active').filter('[data-tab="repair-types"]').addClass('active');
            $('html, body').animate({ scrollTop: 0 }, 200);
            openRepairTypeFullView(id);
        }
    });

    function openRepairTypeFullView(id) {
        $('#rd-tab-content').html('<div class="rd-loading"><span class="spinner is-active"></span></div>');
        rdAjax('get_repair_type_detail', { id: id }, function(result) {
            renderRepairTypeFullView(result.repairType, result.checklists || [], result.repairs || [], result.stats || {});
        });
    }

    function renderRepairTypeFullView(type, checklists, repairs, stats) {
        var t = type;
        var html = '';

        // Top bar
        html += '<div style="display:flex;align-items:center;gap:12px;margin-bottom:12px">';
        html += '<button class="rd-btn rd-btn-secondary rd-btn-sm" id="rd-back-to-repair-types"><span class="dashicons dashicons-arrow-left-alt2"></span> ' + __('Back', 'vollstart-repair-desk') + '</button>';
        html += '<div style="flex:1"></div>';
        html += '<button class="rd-btn rd-btn-primary rd-btn-sm rd-edit-repair-type" data-id="' + t.id + '"><span class="dashicons dashicons-edit"></span> ' + __('Edit', 'vollstart-repair-desk') + '</button>';
        html += '<button class="rd-btn rd-btn-danger rd-btn-sm rd-delete-repair-type" data-id="' + t.id + '"><span class="dashicons dashicons-trash"></span></button>';
        html += '</div>';

        // Name with icon
        html += '<div style="display:flex;align-items:center;gap:12px;margin-bottom:4px">';
        html += '<span class="dashicons dashicons-' + escAttr(t.icon || 'admin-tools') + '" style="font-size:32px;width:32px;height:32px;color:#6366f1"></span>';
        html += '<h2 style="font-size:22px;font-weight:700;color:#1e293b;margin:0">' + escHtml(t.name) + '</h2>';
        if (t.is_favorite && t.is_favorite !== '0') html += '<span class="dashicons dashicons-star-filled" style="color:#f59e0b;font-size:20px;width:20px;height:20px"></span>';
        if (!t.active || t.active === '0') html += '<span style="font-size:12px;background:#fee2e2;color:#dc2626;padding:2px 8px;border-radius:999px">' + __('Inactive', 'vollstart-repair-desk') + '</span>';
        html += '</div>';
        if (t.description) html += '<p style="font-size:13px;color:#64748b;margin:0 0 20px">' + escHtml(t.description) + '</p>';
        else html += '<div style="margin-bottom:20px"></div>';

        // Info cards
        html += '<div class="rd-info-grid" style="margin-bottom:24px">';

        // Details card
        html += '<div class="rd-card">';
        html += '<div class="rd-card-header"><h3><span class="dashicons dashicons-admin-tools" style="margin-right:6px;color:#6366f1"></span>' + __('Details', 'vollstart-repair-desk') + '</h3></div>';
        html += '<div class="rd-card-body">';
        html += infoRow(__('Est. Duration', 'vollstart-repair-desk'), t.estimated_duration_hours && t.estimated_duration_hours !== '0.0' ? t.estimated_duration_hours + ' h' : '\u2014');
        html += infoRow(__('Default Price', 'vollstart-repair-desk'), t.default_price && t.default_price !== '0.00' ? t.default_price + ' ' + cfg.currency : '\u2014');
        html += infoRow(__('Favorite', 'vollstart-repair-desk'), t.is_favorite && t.is_favorite !== '0' ? '<span style="color:#f59e0b">\u2605 Yes</span>' : 'No');
        html += infoRow(__('Status', 'vollstart-repair-desk'), t.active && t.active !== '0' ? '<span style="color:#22c55e">Active</span>' : '<span style="color:#dc2626">Inactive</span>');
        html += '</div></div>';

        // Stats card
        html += '<div class="rd-card">';
        html += '<div class="rd-card-header"><h3><span class="dashicons dashicons-chart-bar" style="margin-right:6px;color:#22c55e"></span>' + __('Statistics', 'vollstart-repair-desk') + '</h3></div>';
        html += '<div class="rd-card-body">';
        html += infoRow(__('Total Repairs', 'vollstart-repair-desk'), '<strong>' + (stats.repair_count || 0) + '</strong>');
        html += infoRow(__('Work Steps', 'vollstart-repair-desk'), checklists.length > 0 ? checklists.length + ' ' + __('lists assigned', 'vollstart-repair-desk') : '\u2014');
        html += '</div></div>';

        html += '</div>';

        // Work Steps
        html += '<div class="rd-card" style="margin-bottom:24px">';
        html += '<div class="rd-card-header"><h3><span class="dashicons dashicons-list-view" style="margin-right:6px;color:#8b5cf6"></span>' + __('Work Steps', 'vollstart-repair-desk') + '</h3></div>';
        if (checklists.length === 0) {
            html += '<div class="rd-card-body"><p style="color:#94a3b8;text-align:center;padding:12px">' + __('No work steps assigned.', 'vollstart-repair-desk') + '</p></div>';
        } else {
            $.each(checklists, function(ci, cl) {
                html += '<div style="padding:10px 16px;border-bottom:1px solid #f1f5f9">';
                html += '<strong>' + escHtml(cl.name) + '</strong>';
                var items = cl.items || [];
                if (items.length > 0) {
                    html += '<div style="margin-top:6px">';
                    $.each(items, function(si, step) {
                        html += '<div style="display:flex;align-items:center;gap:6px;padding:3px 0;font-size:13px;color:#374151">';
                        html += '<span style="color:#cbd5e1;font-size:11px;width:16px">' + (si + 1) + '.</span>';
                        html += '<span style="flex:1">' + escHtml(step.title) + '</span>';
                        if (step.default_duration && parseFloat(step.default_duration) > 0) html += '<span style="font-size:11px;color:#94a3b8">' + step.default_duration + ' min</span>';
                        if (step.default_price && parseFloat(step.default_price) > 0) html += '<span style="font-size:11px;color:#94a3b8">' + step.default_price + ' ' + cfg.currency + '</span>';
                        html += '</div>';
                    });
                    html += '</div>';
                }
                html += '</div>';
            });
        }
        html += '</div>';

        // Repairs using this type
        html += '<div class="rd-card" style="margin-bottom:24px">';
        html += '<div class="rd-card-header"><h3><span class="dashicons dashicons-admin-tools" style="margin-right:6px;color:#f97316"></span>' + __('Repairs', 'vollstart-repair-desk') + ' <span style="color:#94a3b8;font-weight:400">(' + repairs.length + ')</span></h3></div>';
        if (repairs.length === 0) {
            html += '<div class="rd-card-body"><p style="color:#94a3b8;text-align:center;padding:12px">' + __('No repairs with this type yet.', 'vollstart-repair-desk') + '</p></div>';
        } else {
            html += '<table class="rd-table"><thead><tr>';
            html += '<th>' + __('#', 'vollstart-repair-desk') + '</th><th>' + __('Customer', 'vollstart-repair-desk') + '</th><th>' + __('Device', 'vollstart-repair-desk') + '</th><th>' + __('Status', 'vollstart-repair-desk') + '</th><th>' + __('Date', 'vollstart-repair-desk') + '</th>';
            html += '</tr></thead><tbody>';
            $.each(repairs, function(ri, r) {
                var device = [r.device_brand, r.device_model].filter(Boolean).join(' ') || r.device_type || '\u2014';
                var sLabel = getStatusLabel(r.status);
                var sColor = getStatusColor(r.status);
                html += '<tr class="rd-rt-repair-row" data-id="' + r.id + '" style="cursor:pointer">';
                html += '<td><strong>' + escHtml(r.repair_number) + '</strong></td>';
                html += '<td>' + escHtml(r.customer_name || '\u2014') + '</td>';
                html += '<td>' + escHtml(device) + '</td>';
                html += '<td><span style="display:inline-flex;font-size:11px;font-weight:600;padding:3px 10px;border-radius:999px;background:' + sColor + '15;color:' + sColor + ';border:1px solid ' + sColor + '30">' + escHtml(sLabel) + '</span></td>';
                html += '<td style="font-size:12px">' + escHtml(formatDateTime(r.created_at).split(',')[0]) + '</td>';
                html += '</tr>';
            });
            html += '</tbody></table>';
        }
        html += '</div>';

        // Change History (lazy)
        html += '<div class="rd-card">';
        html += '<div class="rd-card-header"><h3><span class="dashicons dashicons-backup" style="margin-right:6px;color:#8b5cf6"></span>' + __('Change History', 'vollstart-repair-desk') + '</h3>';
        html += '<div class="rd-card-actions">';
        html += '<button class="rd-btn rd-btn-sm rd-btn-secondary rd-export-rt-history" data-id="' + t.id + '" data-name="' + escAttr(t.name) + '" style="display:none"><span class="dashicons dashicons-download" style="font-size:14px;width:14px;height:14px"></span> CSV</button>';
        html += '<button class="rd-btn rd-btn-sm rd-btn-secondary rd-load-rt-history" data-id="' + t.id + '"><span class="dashicons dashicons-arrow-down-alt2" style="font-size:14px;width:14px;height:14px"></span></button>';
        html += '</div></div>';
        html += '<div id="rd-rt-history-content" style="display:none"></div>';
        html += '</div>';

        $('#rd-tab-content').html(html);
    }

    // Back to repair types list
    $(document).on('click', '#rd-back-to-repair-types', function() { loadRepairTypes(); });

    // Click repair in repair type view → repair full view
    $(document).on('click', '.rd-rt-repair-row', function() {
        var id = $(this).data('id');
        if (id) {
            currentTab = 'repairs';
            $('.rd-tab').removeClass('active').filter('[data-tab="repairs"]').addClass('active');
            $('html, body').animate({ scrollTop: 0 }, 200);
            openRepairFullView(id);
        }
    });

    // Lazy-load repair type history
    $(document).on('click', '.rd-load-rt-history', function() {
        var $btn = $(this), id = $btn.data('id');
        var $content = $('#rd-rt-history-content');
        if ($content.is(':visible')) {
            $content.slideUp(200);
            $btn.find('.dashicons').removeClass('dashicons-arrow-up-alt2').addClass('dashicons-arrow-down-alt2');
            $btn.closest('.rd-card-header').find('.rd-export-rt-history').hide();
            return;
        }
        $content.html('<div class="rd-loading"><span class="spinner is-active"></span></div>').slideDown(200);
        $btn.find('.dashicons').removeClass('dashicons-arrow-down-alt2').addClass('dashicons-arrow-up-alt2');

        rdAjax('get_repair_type_history', { id: id }, function(result) {
            var history = result.history || [];
            var fieldLabels = { 'name': __('Name', 'vollstart-repair-desk'), 'description': __('Description', 'vollstart-repair-desk'), 'icon': __('Icon', 'vollstart-repair-desk'), 'estimated_duration_hours': __('Duration', 'vollstart-repair-desk'), 'default_price': __('Price', 'vollstart-repair-desk'), 'is_favorite': __('Favorite', 'vollstart-repair-desk'), 'active': __('Active', 'vollstart-repair-desk') };
            var html = '';
            if (history.length === 0) {
                html = '<p style="color:#94a3b8;font-size:13px;text-align:center;padding:12px">' + __('No changes recorded.', 'vollstart-repair-desk') + '</p>';
            } else {
                html = '<table class="rd-table" style="font-size:12px"><thead><tr><th>' + __('Date', 'vollstart-repair-desk') + '</th><th>' + __('Field', 'vollstart-repair-desk') + '</th><th>' + __('Old', 'vollstart-repair-desk') + '</th><th>' + __('New', 'vollstart-repair-desk') + '</th><th>' + __('By', 'vollstart-repair-desk') + '</th></tr></thead><tbody>';
                $.each(history, function(i, h) {
                    html += '<tr><td style="white-space:nowrap;color:#94a3b8">' + escHtml(formatDateTime(h.changed_at)) + '</td>';
                    html += '<td>' + escHtml(fieldLabels[h.field_name] || h.field_name) + '</td>';
                    html += '<td style="color:#dc2626" title="' + escAttr(h.old_value) + '">' + escHtml((h.old_value || '').substring(0, 50)) + '</td>';
                    html += '<td style="color:#22c55e" title="' + escAttr(h.new_value) + '">' + escHtml((h.new_value || '').substring(0, 50)) + '</td>';
                    html += '<td style="color:#94a3b8">' + escHtml(h.changed_by_name || '') + '</td></tr>';
                });
                html += '</tbody></table>';
            }
            $content.html(html).data('history', history);
            if (history.length > 0) $btn.closest('.rd-card-header').find('.rd-export-rt-history').show();
        });
    });

    // Export repair type history CSV
    $(document).on('click', '.rd-export-rt-history', function() {
        var history = $('#rd-rt-history-content').data('history');
        if (!history || !history.length) return;
        var fieldLabels = { 'name': 'Name', 'description': 'Description', 'icon': 'Icon', 'estimated_duration_hours': 'Duration', 'default_price': 'Price', 'is_favorite': 'Favorite', 'active': 'Active' };
        var rows = [['Date', 'Field', 'Old Value', 'New Value', 'Changed By']];
        $.each(history, function(i, h) {
            rows.push([h.changed_at || '', fieldLabels[h.field_name] || h.field_name, (h.old_value || '').replace(/"/g, '""'), (h.new_value || '').replace(/"/g, '""'), h.changed_by_name || '']);
        });
        var csv = rows.map(function(r) { return r.map(function(c) { return '"' + c + '"'; }).join(','); }).join('\n');
        var blob = new Blob(['\uFEFF' + csv], { type: 'text/csv;charset=utf-8' });
        var url = URL.createObjectURL(blob);
        var a = document.createElement('a');
        a.href = url;
        a.download = 'repair-type-history-' + ($(this).data('name') || 'type') + '-' + new Date().toISOString().slice(0, 10) + '.csv';
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
        URL.revokeObjectURL(url);
    });

    // New work steps from tab
    $(document).on('click', '#rd-new-steplist-tab', function() {
        openStepListForm(null);
    });

    // View work steps → full view
    $(document).on('click', '.rd-view-steplist', function(e) {
        e.stopPropagation();
        openWorkStepsFullView($(this).data('id'));
    });

    // Edit work steps (from full view or list)
    $(document).on('click', '.rd-edit-steplist', function(e) {
        e.stopPropagation();
        var id = $(this).data('id');
        rdAjax('get_checklist_detail', { id: id }, function(result) {
            if (result.checklist) openStepListForm(result.checklist);
        });
    });

    function openWorkStepsFullView(id) {
        $('#rd-tab-content').html('<div class="rd-loading"><span class="spinner is-active"></span></div>');
        rdAjax('get_checklist_detail', { id: id }, function(result) {
            renderWorkStepsFullView(result.checklist);
        });
    }

    function renderWorkStepsFullView(cl) {
        var items = cl.items || [];
        var repairTypes = cl.repair_types || [];
        var html = '';

        // Top bar
        html += '<div style="display:flex;align-items:center;gap:12px;margin-bottom:12px">';
        html += '<button class="rd-btn rd-btn-secondary rd-btn-sm" id="rd-back-to-steplists"><span class="dashicons dashicons-arrow-left-alt2"></span> ' + __('Back', 'vollstart-repair-desk') + '</button>';
        html += '<div style="flex:1"></div>';
        html += '<button class="rd-btn rd-btn-primary rd-btn-sm rd-edit-steplist" data-id="' + cl.id + '"><span class="dashicons dashicons-edit"></span> ' + __('Edit', 'vollstart-repair-desk') + '</button>';
        html += '<button class="rd-btn rd-btn-danger rd-btn-sm rd-delete-steplist" data-id="' + cl.id + '"><span class="dashicons dashicons-trash"></span></button>';
        html += '</div>';

        // Name + description
        html += '<h2 style="font-size:22px;font-weight:700;color:#1e293b;margin:0 0 2px">' + escHtml(cl.name) + '</h2>';
        if (cl.description) html += '<p style="font-size:13px;color:#64748b;margin:0 0 4px">' + escHtml(cl.description) + '</p>';
        html += '<p style="font-size:12px;color:#94a3b8;margin:0 0 8px">' + items.length + ' ' + __('steps', 'vollstart-repair-desk') + (cl.sort_order && cl.sort_order !== '0' ? ' · ' + __('Order', 'vollstart-repair-desk') + ': ' + cl.sort_order : '') + '</p>';

        // Status triggers
        if (cl.trigger_status_start || cl.trigger_status) {
            html += '<div style="margin-bottom:16px;padding:8px 12px;background:#eff6ff;border:1px solid #bfdbfe;border-radius:8px;font-size:13px;display:flex;gap:16px;flex-wrap:wrap">';
            if (cl.trigger_status_start) {
                html += '<span><span class="dashicons dashicons-controls-play" style="font-size:14px;width:14px;height:14px;color:#22c55e"></span> ' + __('On check:', 'vollstart-repair-desk') + ' <strong>' + escHtml(getStatusLabel(cl.trigger_status_start)) + '</strong></span>';
            }
            if (cl.trigger_status) {
                html += '<span><span class="dashicons dashicons-flag" style="font-size:14px;width:14px;height:14px;color:#f97316"></span> ' + __('On done:', 'vollstart-repair-desk') + ' <strong>' + escHtml(getStatusLabel(cl.trigger_status)) + '</strong></span>';
            }
            html += '</div>';
        }

        // Used by Repair Types
        if (repairTypes.length > 0) {
            html += '<div style="margin-bottom:16px;padding:10px 12px;background:#f0fdf4;border:1px solid #a7f3d0;border-radius:8px;font-size:13px">';
            html += '<span style="color:#64748b">' + __('Used by Repair Types:', 'vollstart-repair-desk') + '</span> ';
            $.each(repairTypes, function(ri, rt) {
                if (ri > 0) html += ', ';
                html += '<a href="#" class="rd-goto-repair-type" data-id="' + rt.id + '" style="color:#22c55e;font-weight:500;text-decoration:none">';
                html += '<span class="dashicons dashicons-' + escAttr(rt.icon || 'admin-tools') + '" style="font-size:12px;width:12px;height:12px"></span> ' + escHtml(rt.name);
                html += '</a>';
            });
            html += '</div>';
        }

        // Steps management
        html += '<div class="rd-card" style="margin-bottom:24px">';
        html += '<div class="rd-card-header"><h3><span class="dashicons dashicons-list-view" style="margin-right:6px;color:#8b5cf6"></span>' + __('Steps', 'vollstart-repair-desk') + ' <span style="color:#94a3b8;font-weight:400">(' + items.length + ')</span></h3></div>';

        if (items.length > 0) {
            html += '<div style="padding:8px 0">';
            $.each(items, function(j, it) {
                var hasInstr = it.instructions && it.instructions.trim();
                var fileCount = parseInt(it.file_count) || 0;
                var files = it.files || [];

                html += '<div style="padding:10px 16px;border-bottom:1px solid #f1f5f9">';
                html += '<div style="display:flex;align-items:flex-start;gap:8px">';
                html += '<span style="color:#94a3b8;font-size:12px;width:20px;padding-top:2px">' + (j + 1) + '.</span>';
                html += '<div style="flex:1">';
                html += '<div style="font-size:14px;font-weight:500;color:#1e293b">' + escHtml(it.title) + '</div>';
                if (hasInstr) html += '<div style="font-size:12px;color:#94a3b8;margin-top:2px">' + escHtml(it.instructions.substring(0, 120)) + (it.instructions.length > 120 ? '...' : '') + '</div>';

                var meta = [];
                if (parseFloat(it.default_duration) > 0) meta.push(it.default_duration + ' min');
                if (parseFloat(it.default_price) > 0) meta.push(it.default_price + ' ' + cfg.currency);
                if (fileCount > 0) meta.push(fileCount + ' ' + __('files', 'vollstart-repair-desk'));
                if (meta.length > 0) html += '<div style="font-size:11px;color:#94a3b8;margin-top:2px">' + meta.join(' · ') + '</div>';

                // Show files
                if (files.length > 0) {
                    html += '<div class="rd-file-gallery" style="margin-top:6px">' + renderFileGallery(files, 'checklist_item', it.id, false, { noDelete: true }) + '</div>';
                }

                // Edit + Delete per step
                html += '<div class="rd-product-actions" style="flex-shrink:0">';
                html += '<button class="rd-btn rd-btn-sm rd-btn-secondary rd-edit-step-item" data-item-id="' + it.id + '" data-checklist-id="' + cl.id + '"><span class="dashicons dashicons-edit" style="font-size:14px;width:14px;height:14px"></span></button>';
                html += '<button class="rd-btn rd-btn-sm rd-btn-danger rd-delete-step-item" data-item-id="' + it.id + '" data-checklist-id="' + cl.id + '"><span class="dashicons dashicons-trash" style="font-size:14px;width:14px;height:14px"></span></button>';
                html += '</div>';
                html += '</div></div>';
            });
            html += '</div>';
        } else {
            html += '<div class="rd-card-body"><p style="color:#94a3b8;text-align:center;padding:12px">' + __('No steps yet. Click Edit to add steps.', 'vollstart-repair-desk') + '</p></div>';
        }

        // Add step inline
        html += '<div style="padding:10px 16px;border-top:1px solid #e2e8f0;display:flex;gap:8px">';
        html += '<input type="text" id="rd-ws-new-step" placeholder="' + __('Add step...', 'vollstart-repair-desk') + '" style="flex:1;padding:8px 12px;border:1px solid #e2e8f0;border-radius:6px;font-size:14px">';
        html += '<button class="rd-btn rd-btn-primary rd-btn-sm" id="rd-ws-add-step" data-checklist-id="' + cl.id + '" style="padding:8px 12px"><span class="dashicons dashicons-plus-alt2"></span></button>';
        html += '</div>';
        html += '</div>';

        $('#rd-tab-content').html(html);
    }

    // Back to work steps list
    $(document).on('click', '#rd-back-to-steplists', function() { loadStepLists(); });

    // Add step from full view
    $(document).on('click', '#rd-ws-add-step', function() {
        var clId = $(this).data('checklist-id');
        var title = $('#rd-ws-new-step').val().trim();
        if (!title) return;

        rdAjax('add_checklist_item', { checklist_id: clId, title: title }, function(result) {
            // Find the new item (last one) and open edit modal
            var items = (result.checklist && result.checklist.items) || [];
            var newItem = items.length > 0 ? items[items.length - 1] : null;
            openWorkStepsFullView(clId);
            if (newItem) {
                setTimeout(function() { openStepItemForm(newItem, clId); }, 300);
            }
        });
    });

    $(document).on('keydown', '#rd-ws-new-step', function(e) {
        if (e.key === 'Enter') { e.preventDefault(); $('#rd-ws-add-step').trigger('click'); }
    });

    // Edit step item — modal with all fields
    $(document).on('click', '.rd-edit-step-item', function() {
        var itemId = $(this).data('item-id');
        var clId = $(this).data('checklist-id');
        rdAjax('get_checklist_detail', { id: clId }, function(result) {
            var item = (result.checklist.items || []).find(function(it) { return it.id == itemId; });
            if (!item) return;
            openStepItemForm(item, clId);
        });
    });

    function openStepItemForm(item, checklistId) {
        var siBody = '<div class="rd-form-grid">';
        siBody += formField('rd-si-title', __('Title', 'vollstart-repair-desk'), 'text', item.title || '');
        siBody += formField('rd-si-duration', __('Duration (minutes)', 'vollstart-repair-desk'), 'number', item.default_duration || '');
        siBody += formField('rd-si-price', __('Price', 'vollstart-repair-desk'), 'number', item.default_price || '', '0.00 ' + cfg.currency);
        siBody += '<div class="rd-form-group rd-form-full"><label>' + __('Instructions', 'vollstart-repair-desk') + '</label>';
        siBody += '<textarea id="rd-si-instr" rows="4" placeholder="' + __('How to perform this step...', 'vollstart-repair-desk') + '">' + escHtml(item.instructions || '') + '</textarea></div>';
        siBody += '</div>';

        // File upload for this step
        siBody += '<div style="margin-top:12px"><label style="font-size:12px;font-weight:600;color:#475569;text-transform:uppercase;display:block;margin-bottom:6px">' + __('Photos & Files', 'vollstart-repair-desk') + '</label>';
        siBody += '<div id="rd-si-files-' + item.id + '"></div></div>';

        var siFooter = '<button class="rd-btn rd-btn-secondary rd-close-modal">' + __('Cancel', 'vollstart-repair-desk') + '</button>';
        siFooter += '<button class="rd-btn rd-btn-primary" id="rd-save-step-item" data-item-id="' + item.id + '" data-checklist-id="' + checklistId + '">' + __('Save', 'vollstart-repair-desk') + '</button>';

        rdModal('rd-step-item-form', __('Edit Step', 'vollstart-repair-desk'), siBody, { maxWidth: '520px', footer: siFooter });

        renderUploadWidget('#rd-si-files-' + item.id, 'checklist_item', item.id, { showThumbnail: false, showCamera: true });
    }

    // Save step item
    $(document).on('click', '#rd-save-step-item', function() {
        var itemId = $(this).data('item-id');
        var clId = $(this).data('checklist-id');

        var stepData = {
            item_id: itemId,
            title: $('#rd-si-title').val().trim(),
            instructions: $('#rd-si-instr').val() || '',
            default_duration: $('#rd-si-duration').val() || 0,
            default_price: $('#rd-si-price').val() || 0
        };
        rdAjax('update_checklist_item', stepData, function() {
            $('.rd-modal-backdrop').remove();
            openWorkStepsFullView(clId);
        }, {spin: true});
    });

    // Delete step item from full view
    $(document).on('click', '.rd-delete-step-item', function() {
        if (!confirm(__('Delete this step?', 'vollstart-repair-desk'))) return;
        var itemId = $(this).data('item-id');
        var clId = $(this).data('checklist-id');

        rdAjax('delete_checklist_item', { item_id: itemId }, function() {
            openWorkStepsFullView(clId);
        }, {spin: true});
    });

    function openStepListForm(cl) {
        var isEdit = !!cl;
        var c = cl || {};

        var slBody = '<div class="rd-form-grid">';
        slBody += formField('rd-sl-name', __('Name', 'vollstart-repair-desk'), 'text', c.name || '', __('e.g. Standard Bike Service', 'vollstart-repair-desk'));
        slBody += formField('rd-sl-order', __('Sort Order', 'vollstart-repair-desk'), 'number', c.sort_order || '0');
        slBody += '<div class="rd-form-group rd-form-full"><label>' + __('Description', 'vollstart-repair-desk') + '</label>';
        slBody += '<textarea id="rd-sl-desc" rows="3" placeholder="' + __('Describe this work step list...', 'vollstart-repair-desk') + '">' + escHtml(c.description || '') + '</textarea></div>';
        // Status trigger dropdowns
        var statusOpts = '<option value="">' + __('— None —', 'vollstart-repair-desk') + '</option>';
        $.each(cfg.statuses || {}, function(slug, def) {
            var label = typeof def === 'object' ? def.label : def;
            statusOpts += '<option value="' + escAttr(slug) + '">' + escHtml(label) + '</option>';
        });
        slBody += '<div class="rd-form-group"><label>' + __('On step checked', 'vollstart-repair-desk') + '</label>';
        slBody += '<select id="rd-sl-trigger-start">' + statusOpts.replace('value="' + escAttr(c.trigger_status_start || '') + '"', 'value="' + escAttr(c.trigger_status_start || '') + '" selected') + '</select>';
        slBody += '<div style="font-size:11px;color:#94a3b8;margin-top:2px">' + __('Advance when any step is checked', 'vollstart-repair-desk') + '</div></div>';
        slBody += '<div class="rd-form-group"><label>' + __('On all completed', 'vollstart-repair-desk') + '</label>';
        slBody += '<select id="rd-sl-trigger-done">' + statusOpts.replace('value="' + escAttr(c.trigger_status || '') + '"', 'value="' + escAttr(c.trigger_status || '') + '" selected') + '</select>';
        slBody += '<div style="font-size:11px;color:#94a3b8;margin-top:2px">' + __('Advance when all steps are done', 'vollstart-repair-desk') + '</div></div>';
        slBody += '</div>';

        var slFooter = '<button class="rd-btn rd-btn-secondary rd-close-modal">' + __('Cancel', 'vollstart-repair-desk') + '</button>';
        slFooter += '<button class="rd-btn rd-btn-primary" id="rd-save-steplist" data-id="' + (c.id || '') + '">' + (isEdit ? __('Save', 'vollstart-repair-desk') : __('Create', 'vollstart-repair-desk')) + '</button>';

        rdModal('rd-steplist-form', (isEdit ? __('Edit Work Steps', 'vollstart-repair-desk') : __('New Work Steps', 'vollstart-repair-desk')), slBody, { maxWidth: '480px', footer: slFooter });
    }

    function renderStepRow(index, title, duration, price, instructions, itemId) {
        var durVal = (duration && parseFloat(duration) > 0) ? duration : '';
        var priceVal = (price && parseFloat(price) > 0) ? price : '';
        var hasInstr = instructions && instructions.trim();
        var html = '<div class="rd-sl-step-row" style="margin-bottom:6px" data-item-id="' + (itemId || '') + '">';
        html += '<div style="display:flex;gap:4px;align-items:center">';
        html += '<span style="color:#cbd5e1;font-size:12px;width:20px">' + (index + 1) + '.</span>';
        html += '<input type="text" class="rd-sl-step-title" value="' + escAttr(title || '') + '" style="flex:1;padding:5px 8px;border:1px solid #e2e8f0;border-radius:6px;font-size:13px">';
        html += '<input type="number" class="rd-sl-step-dur" value="' + escAttr(durVal) + '" placeholder="\u2014" title="' + __('Duration in minutes', 'vollstart-repair-desk') + '" style="width:70px;padding:5px 8px;border:1px solid #e2e8f0;border-radius:6px;font-size:13px;text-align:center">';
        html += '<input type="number" class="rd-sl-step-price" value="' + escAttr(priceVal) + '" placeholder="\u2014" title="' + __('Price', 'vollstart-repair-desk') + ' (' + cfg.currency + ')" style="width:80px;padding:5px 8px;border:1px solid #e2e8f0;border-radius:6px;font-size:13px;text-align:center">';
        html += '<button type="button" class="rd-sl-toggle-instr" style="background:none;border:1px solid ' + (hasInstr ? '#f97316' : '#e2e8f0') + ';border-radius:4px;cursor:pointer;padding:3px 5px;color:' + (hasInstr ? '#f97316' : '#94a3b8') + '" title="' + __('Instructions & Photos', 'vollstart-repair-desk') + '"><span class="dashicons dashicons-book" style="font-size:14px;width:14px;height:14px"></span></button>';
        html += '<button type="button" class="rd-sl-remove-step" style="background:none;border:none;color:#dc2626;cursor:pointer;padding:2px"><span class="dashicons dashicons-no" style="font-size:14px;width:14px;height:14px"></span></button>';
        html += '</div>';
        // Instructions area (hidden)
        html += '<div class="rd-sl-instr-area" style="display:none;margin:6px 0 0 24px;padding:8px;background:#f8fafc;border-radius:6px">';
        html += '<textarea class="rd-sl-step-instr" rows="3" placeholder="' + __('How to perform this step — visible to workers during repair...', 'vollstart-repair-desk') + '" style="width:100%;padding:6px 8px;border:1px solid #e2e8f0;border-radius:6px;font-size:12px;font-family:inherit;margin-bottom:6px">' + escHtml(instructions || '') + '</textarea>';
        if (itemId) {
            html += '<div id="rd-sl-instr-files-' + itemId + '"></div>';
        } else {
            html += '<p style="font-size:11px;color:#94a3b8;margin:0">' + __('Save first, then add photos to each step.', 'vollstart-repair-desk') + '</p>';
        }
        html += '</div>';
        html += '</div>';
        return html;
    }

    // Toggle instructions area
    $(document).on('click', '.rd-sl-toggle-instr', function() {
        var $area = $(this).closest('.rd-sl-step-row').find('.rd-sl-instr-area');
        $area.slideToggle(200);
        // Load file upload widget if step has an ID
        var itemId = $(this).closest('.rd-sl-step-row').data('item-id');
        if (itemId && !$area.find('.rd-upload-widget').length) {
            var $fileContainer = $area.find('[id^="rd-sl-instr-files-"]');
            if ($fileContainer.length) {
                renderUploadWidget('#rd-sl-instr-files-' + itemId, 'checklist_item', itemId, { showThumbnail: false, showCamera: true });
            }
        }
    });

    // Add step in form
    $(document).on('click', '#rd-sl-add-step', function() {
        var title = $('#rd-sl-new-step').val().trim();
        if (!title) return;
        var dur = $('#rd-sl-new-dur').val();
        var price = $('#rd-sl-new-price').val();
        var index = $('#rd-sl-steps .rd-sl-step-row').length;
        $('#rd-sl-steps').append(renderStepRow(index, title, dur, price));
        $('#rd-sl-new-step').val('').focus();
        $('#rd-sl-new-dur').val('');
        $('#rd-sl-new-price').val('');
    });

    $(document).on('keydown', '#rd-sl-new-step', function(e) {
        if (e.key === 'Enter') { e.preventDefault(); $('#rd-sl-add-step').trigger('click'); }
    });

    // Remove step row
    $(document).on('click', '.rd-sl-remove-step', function() {
        $(this).closest('.rd-sl-step-row').remove();
    });

    // Save work steps
    $(document).on('click', '#rd-save-steplist', function() {
        var id = $(this).data('id');
        var name = $('#rd-sl-name').val().trim();
        if (!name) { alert(__('Name is required.', 'vollstart-repair-desk')); return; }

        rdAjax('save_checklist', {
            checklist_id: id || 0,
            name: name,
            description: $('#rd-sl-desc').val() || '',
            trigger_status_start: $('#rd-sl-trigger-start').val() || '',
            trigger_status: $('#rd-sl-trigger-done').val() || '',
            sort_order: $('#rd-sl-order').val() || 0
        }, function(result) {
            $('.rd-modal-backdrop').remove();
            var clId = result.checklist ? result.checklist.id : id;
            if (clId) {
                openWorkStepsFullView(clId);
            } else {
                loadStepLists();
            }
        }, {spin: true});
    });

    // Keep the old modal opener for Repair Types tab button
    $(document).on('click', '#rd-manage-step-lists', function() {
        // Switch to Work Steps tab
        currentTab = 'step-lists';
        $('.rd-tab').removeClass('active').filter('[data-tab="step-lists"]').addClass('active');
        loadStepLists();
    });

    // Legacy — kept for compatibility but now redirects to tab
    function renderStepListsModal(checklists) {
        var bodyHtml = '<div id="rd-step-lists-container">';
        if (checklists.length === 0) {
            bodyHtml += '<p style="color:#94a3b8;text-align:center;padding:16px 0">' + __('No work steps yet.', 'vollstart-repair-desk') + '</p>';
        } else {
            $.each(checklists, function(i, cl) {
                bodyHtml += renderStepListCard(cl);
            });
        }
        bodyHtml += '</div>';

        // New list form
        bodyHtml += '<div style="margin-top:16px;padding-top:16px;border-top:1px solid #e2e8f0">';
        bodyHtml += '<div style="display:flex;gap:8px">';
        bodyHtml += '<input type="text" id="rd-new-steplist-name" placeholder="' + __('New work steps name...', 'vollstart-repair-desk') + '" style="flex:1;padding:8px 12px;border:1px solid #e2e8f0;border-radius:8px;font-size:13px">';
        bodyHtml += '<button class="rd-btn rd-btn-primary" id="rd-create-steplist"><span class="dashicons dashicons-plus-alt2"></span></button>';
        bodyHtml += '</div></div>';

        rdModal('rd-step-lists-modal', __('Work Steps', 'vollstart-repair-desk'), bodyHtml, { maxWidth: '600px' });
    }

    function renderStepListCard(cl) {
        var items = cl.items || [];
        var html = '<div class="rd-step-list-card" data-id="' + cl.id + '" style="border:1px solid #e2e8f0;border-radius:8px;margin-bottom:8px;overflow:hidden">';
        html += '<div style="display:flex;align-items:center;gap:8px;padding:10px 12px;background:#f8fafc;cursor:pointer" class="rd-step-list-toggle">';
        html += '<span class="dashicons dashicons-arrow-right-alt2 rd-step-list-arrow" style="font-size:14px;width:14px;height:14px;transition:transform 0.2s"></span>';
        html += '<strong style="flex:1;font-size:14px">' + escHtml(cl.name) + '</strong>';
        html += '<span style="color:#94a3b8;font-size:12px">' + items.length + ' ' + __('steps', 'vollstart-repair-desk') + '</span>';
        if (cl.trigger_status_start || cl.trigger_status) {
            html += '<span class="dashicons dashicons-randomize" style="font-size:14px;width:14px;height:14px;color:#3b82f6" title="' + __('Status triggers configured', 'vollstart-repair-desk') + '"></span>';
        }
        html += '<button class="rd-btn rd-btn-sm rd-btn-danger rd-delete-steplist" data-id="' + cl.id + '" style="padding:2px 6px"><span class="dashicons dashicons-trash" style="font-size:14px;width:14px;height:14px"></span></button>';
        html += '</div>';

        // Trigger status info (shown when expanded)
        var triggerInfo = '';
        if (cl.trigger_status_start) {
            var startLabel = getStatusLabel(cl.trigger_status_start);
            triggerInfo += '<span style="font-size:12px;color:#64748b"><span class="dashicons dashicons-controls-play" style="font-size:12px;width:12px;height:12px;color:#22c55e"></span> ' + __('On check:', 'vollstart-repair-desk') + ' <strong>' + escHtml(startLabel) + '</strong></span>';
        }
        if (cl.trigger_status) {
            var doneLabel = getStatusLabel(cl.trigger_status);
            if (triggerInfo) triggerInfo += '<span style="margin:0 8px;color:#e2e8f0">|</span>';
            triggerInfo += '<span style="font-size:12px;color:#64748b"><span class="dashicons dashicons-flag" style="font-size:12px;width:12px;height:12px;color:#f97316"></span> ' + __('On done:', 'vollstart-repair-desk') + ' <strong>' + escHtml(doneLabel) + '</strong></span>';
        }

        // Expandable steps area
        html += '<div class="rd-step-list-body" style="display:none;padding:8px 12px">';
        if (triggerInfo) html += '<div style="padding:4px 0 8px;border-bottom:1px solid #f1f5f9">' + triggerInfo + '</div>';
        $.each(items, function(j, item) {
            html += '<div style="display:flex;align-items:center;gap:6px;padding:4px 0;border-bottom:1px solid #f8fafc">';
            html += '<span style="color:#cbd5e1;font-size:12px">' + (j + 1) + '.</span>';
            html += '<span style="flex:1;font-size:13px">' + escHtml(item.title) + '</span>';
            html += '</div>';
        });
        html += '<div style="display:flex;gap:6px;margin-top:8px">';
        html += '<input type="text" class="rd-new-step-input" data-checklist-id="' + cl.id + '" placeholder="' + __('Add step...', 'vollstart-repair-desk') + '" style="flex:1;padding:6px 8px;border:1px solid #e2e8f0;border-radius:6px;font-size:12px">';
        html += '<button class="rd-btn rd-btn-sm rd-btn-primary rd-add-step-to-list" data-checklist-id="' + cl.id + '"><span class="dashicons dashicons-plus-alt2" style="font-size:12px;width:12px;height:12px"></span></button>';
        html += '</div>';
        html += '</div>';

        html += '</div>';
        return html;
    }

    // Toggle work steps expand
    $(document).on('click', '.rd-step-list-toggle', function(e) {
        if ($(e.target).closest('button').length) return;
        var $body = $(this).next('.rd-step-list-body');
        var $arrow = $(this).find('.rd-step-list-arrow');
        $body.slideToggle(200);
        $arrow.css('transform', $body.is(':visible') ? '' : 'rotate(90deg)');
    });

    // Create new work steps
    $(document).on('click', '#rd-create-steplist', function() {
        var name = $('#rd-new-steplist-name').val().trim();
        if (!name) return;
        rdAjax('save_checklist', { checklist_id: 0, name: name }, function(result) {
            $('#rd-step-lists-modal').remove();
            if (result.checklist) {
                openWorkStepsFullView(result.checklist.id);
            }
        }, {spin: true});
    });

    $(document).on('keydown', '#rd-new-steplist-name', function(e) {
        if (e.key === 'Enter') { e.preventDefault(); $('#rd-create-steplist').trigger('click'); }
    });

    // Add step to list — keep list open, refocus input
    $(document).on('click', '.rd-add-step-to-list', function() {
        var clId = $(this).data('checklist-id');
        var $input = $(this).prev('.rd-new-step-input');
        var title = $input.val().trim();
        if (!title) return;

        $input.val('').prop('disabled', true);

        rdAjax('add_checklist_item', { checklist_id: clId, title: title }, function(result2) {
            if (result2.checklist) {
                var updatedCl = result2.checklist;
                var $card = $('.rd-step-list-card[data-id="' + clId + '"]');
                $card.replaceWith(renderStepListCard(updatedCl));
                var $newCard = $('.rd-step-list-card[data-id="' + clId + '"]');
                $newCard.find('.rd-step-list-body').show();
                $newCard.find('.rd-step-list-arrow').css('transform', 'rotate(90deg)');
                $newCard.find('.rd-new-step-input').focus();
            }
        });
    });

    $(document).on('keydown', '.rd-new-step-input', function(e) {
        if (e.key === 'Enter') { e.preventDefault(); $(this).next('.rd-add-step-to-list').trigger('click'); }
    });

    // Delete work steps
    $(document).on('click', '.rd-delete-steplist', function(e) {
        e.stopPropagation();
        if (!confirm(__('Delete this work steps?', 'vollstart-repair-desk'))) return;
        rdAjax('delete_checklist', { id: $(this).data('id') }, function(result) {
            if (result.checklists) {
                $('#rd-step-lists-modal').remove();
                renderStepListsModal(result.checklists);
            }
        }, {spin: true});
    });

    // --- Status Flow Tab ---

    function loadStatusFlow() {
        rdAjax('get_status_flow', {}, function(result) {
            renderStatusFlowTab(result.statusFlow || []);
        });
    }

    function renderStatusFlowTab(flow) {
        var html = '<div class="rd-card">';
        html += '<div class="rd-card-header"><h3>' + __('Status Flow Configuration', 'vollstart-repair-desk') + '</h3>';
        html += '<div class="rd-card-actions">';
        html += '<button class="rd-btn rd-btn-primary rd-btn-sm" id="rd-save-status-flow">' + __('Save Order', 'vollstart-repair-desk') + '</button>';
        html += '</div></div>';
        html += '<div class="rd-card-body">';
        html += '<p style="color:#64748b;font-size:13px;margin-bottom:16px">' + __('Drag to reorder. Toggle to activate/deactivate. "Storniert" is always available from any status.', 'vollstart-repair-desk') + '</p>';

        var builtinSlugs = ['received', 'diagnosis', 'quote', 'waiting_for_parts', 'in_progress', 'quality_check', 'done', 'delivered', 'cancelled'];

        html += '<div id="rd-status-flow-list">';
        $.each(flow, function(i, s) {
            var opacity = s.active ? '1' : '0.5';
            var isCustom = builtinSlugs.indexOf(s.slug) === -1;
            html += '<div class="rd-status-flow-item" data-slug="' + s.slug + '" style="opacity:' + opacity + '">';
            html += '<span class="rd-flow-handle" style="cursor:grab;color:#94a3b8;margin-right:8px">&#9776;</span>';
            html += '<span class="rd-flow-dot" style="width:12px;height:12px;border-radius:50%;background:' + s.color + ';display:inline-block;margin-right:10px;flex-shrink:0"></span>';
            html += '<span class="rd-flow-label" style="flex:1;font-size:14px;font-weight:500">' + escHtml(s.label) + '</span>';
            html += '<span style="font-size:11px;color:#94a3b8;margin-right:12px">' + escHtml(s.slug) + '</span>';
            if (s.is_final) {
                html += '<span style="font-size:10px;color:#64748b;background:#f1f5f9;padding:2px 8px;border-radius:999px;margin-right:8px">' + __('Final', 'vollstart-repair-desk') + '</span>';
            }
            if (isCustom) {
                html += '<span style="font-size:10px;color:#f97316;background:#fff7ed;padding:2px 8px;border-radius:999px;margin-right:8px">' + __('Custom', 'vollstart-repair-desk') + '</span>';
            }
            html += '<button class="rd-edit-status" data-slug="' + s.slug + '" data-name="' + escAttr(s.label) + '" data-color="' + escAttr(s.color) + '" data-icon="' + escAttr(s.icon || '') + '" data-final="' + (s.is_final ? '1' : '0') + '" data-custom="' + (isCustom ? '1' : '0') + '" style="background:none;border:1px solid #e2e8f0;border-radius:4px;padding:2px 6px;cursor:pointer;color:#64748b;margin-right:4px;font-size:11px" title="' + __('Edit', 'vollstart-repair-desk') + '"><span class="dashicons dashicons-edit" style="font-size:12px;width:12px;height:12px"></span></button>';
            if (isCustom) {
                html += '<button class="rd-delete-status" data-slug="' + s.slug + '" style="background:none;border:1px solid #fecaca;border-radius:4px;padding:2px 6px;cursor:pointer;color:#ef4444;margin-right:4px;font-size:11px" title="' + __('Delete', 'vollstart-repair-desk') + '"><span class="dashicons dashicons-trash" style="font-size:12px;width:12px;height:12px"></span></button>';
            }
            html += '<label class="rd-flow-toggle" style="position:relative;display:inline-block;width:40px;height:22px;margin:0">';
            html += '<input type="checkbox" class="rd-flow-active" data-slug="' + s.slug + '"' + (s.active ? ' checked' : '') + ' style="opacity:0;width:0;height:0">';
            html += '<span style="position:absolute;cursor:pointer;top:0;left:0;right:0;bottom:0;background:' + (s.active ? s.color : '#cbd5e1') + ';border-radius:22px;transition:background .3s"></span>';
            html += '<span style="position:absolute;content:\'\';height:16px;width:16px;left:' + (s.active ? '21px' : '3px') + ';bottom:3px;background:#fff;border-radius:50%;transition:left .3s;box-shadow:0 1px 3px rgba(0,0,0,.2)"></span>';
            html += '</label>';
            html += '</div>';
        });
        html += '</div>';

        if (cfg.proInstalled) {
            html += '<div style="margin-top:16px;display:flex;gap:8px;align-items:center">';
            html += '<button class="rd-btn rd-btn-sm rd-btn-secondary" id="rd-add-custom-status"><span class="dashicons dashicons-plus-alt2" style="font-size:14px;width:14px;height:14px"></span> ' + __('Add Custom Status', 'vollstart-repair-desk') + '</button>';
            html += '</div>';
        }

        html += '</div></div>';
        $('#rd-tab-content').html(html);

        // Make sortable with native drag and drop
        initStatusFlowDragDrop();
    }

    function initStatusFlowDragDrop() {
        var list = document.getElementById('rd-status-flow-list');
        if (!list) return;

        var dragItem = null;

        $(list).on('mousedown', '.rd-flow-handle', function(e) {
            dragItem = $(this).closest('.rd-status-flow-item')[0];
            dragItem.style.opacity = '0.6';
            e.preventDefault();
        });

        $(document).on('mousemove.rdflow', function(e) {
            if (!dragItem) return;
            var items = list.querySelectorAll('.rd-status-flow-item');
            var mouseY = e.clientY;
            var closestItem = null;
            var closestDist = Infinity;

            items.forEach(function(item) {
                if (item === dragItem) return;
                var rect = item.getBoundingClientRect();
                var mid = rect.top + rect.height / 2;
                var dist = Math.abs(mouseY - mid);
                if (dist < closestDist) {
                    closestDist = dist;
                    closestItem = item;
                }
            });

            if (closestItem) {
                var rect = closestItem.getBoundingClientRect();
                if (mouseY < rect.top + rect.height / 2) {
                    list.insertBefore(dragItem, closestItem);
                } else {
                    list.insertBefore(dragItem, closestItem.nextSibling);
                }
            }
        });

        $(document).on('mouseup.rdflow', function() {
            if (dragItem) {
                dragItem.style.opacity = $(dragItem).find('.rd-flow-active').is(':checked') ? '1' : '0.5';
                dragItem = null;
            }
        });

        // Toggle active
        $(list).on('change', '.rd-flow-active', function() {
            var $item = $(this).closest('.rd-status-flow-item');
            var isChecked = $(this).is(':checked');
            $item.css('opacity', isChecked ? 1 : 0.5);
            // Update toggle visual
            var color = isChecked ? getStatusColor($(this).data('slug')) : '#cbd5e1';
            $(this).next('span').css('background', color);
            $(this).siblings('span').last().css('left', isChecked ? '21px' : '3px');
        });
    }

    // Save status flow
    $(document).on('click', '#rd-save-status-flow', function() {
        var flow = [];
        $('#rd-status-flow-list .rd-status-flow-item').each(function() {
            flow.push({
                slug: $(this).data('slug'),
                active: $(this).find('.rd-flow-active').is(':checked')
            });
        });
        rdAjax('save_status_flow', { flow: JSON.stringify(flow) }, function(result) {
            if (result.statuses) cfg.statuses = result.statuses;
            if (result.allStatuses) cfg.allStatuses = result.allStatuses;
            alert(__('Status flow saved.', 'vollstart-repair-desk'));
        }, {spin: true});
    });

    // Close edit status modal — handled by rdModal close handlers

    // --- Settings Tab ---

    // --- Options Tab ---

    function loadOptions() {
        rdAjax('get_settings', {}, function(result) {
            renderOptionsTab(result.options || []);
        });
    }

    function renderOptionsTab(options) {
        var html = '';

        // Sub-tabs: Options | Change History
        html += '<div class="rd-options-toolbar">';
        html += '<div style="display:flex;gap:0;flex:1">';
        html += '<button class="rd-options-subtab active" data-subtab="options-main">' + __('Options', 'vollstart-repair-desk') + '</button>';
        html += '<button class="rd-options-subtab" data-subtab="options-history"><span class="dashicons dashicons-backup" style="font-size:14px;width:14px;height:14px;margin-right:4px"></span>' + __('Change History', 'vollstart-repair-desk') + '</button>';
        html += '</div>';
        html += '<div style="display:flex;gap:8px">';
        html += '<button class="rd-btn rd-btn-secondary rd-btn-sm" id="rd-export-options"><span class="dashicons dashicons-download"></span> ' + __('Export', 'vollstart-repair-desk') + '</button>';
        html += '<button class="rd-btn rd-btn-secondary rd-btn-sm" id="rd-import-options-btn"><span class="dashicons dashicons-upload"></span> ' + __('Import', 'vollstart-repair-desk') + '</button>';
        html += '<input type="file" id="rd-import-file" accept=".json" style="display:none">';
        html += '<button class="rd-btn rd-btn-danger rd-btn-sm" id="rd-reset-options"><span class="dashicons dashicons-image-rotate"></span> ' + __('Reset to Default', 'vollstart-repair-desk') + '</button>';
        html += '</div>';
        html += '</div>';

        // History container (hidden initially)
        html += '<div id="rd-options-history-panel" style="display:none"></div>';

        // Options main panel
        html += '<div id="rd-options-main-panel"></div>';

        $('#rd-tab-content').html(html);

        // Render options form into the main panel
        renderOptionsMainPanel(options);
    }

    function renderOptionsMainPanel(options) {
        var html = '';

        // Collect section headings for the sticky-nav. Nav order is
        // alphabetical so the user can scan it like an index. The actual
        // content below preserves the options-array order (set by
        // initOptions + the section filter), so an add-on's section can stay
        // at the top of the form even though it sorts mid-list in the nav.
        var sections = [];
        $.each(options, function(i, opt) {
            if (opt.type === 'heading' && opt.label) {
                sections.push({ id: 'rd-section-' + opt.key, label: opt.label });
            }
        });
        sections.sort(function(a, b) { return a.label.localeCompare(b.label); });

        // Section navigation
        html += '<div class="rd-options-nav">';
        $.each(sections, function(i, sec) {
            html += '<a href="#' + escAttr(sec.id) + '" class="rd-options-nav-item">' + escHtml(sec.label) + '</a>';
        });
        html += '</div>';

        // Group options by section. Order is preserved from the options
        // array — no alphabetical re-sort.
        var optionGroups = [];
        var currentGroup = null;
        $.each(options, function(i, opt) {
            if (opt.type === 'heading') {
                currentGroup = { key: opt.key, label: opt.label || '', options: [] };
                optionGroups.push(currentGroup);
                return;
            }
            if (!currentGroup) return;
            if (!opt.label) return;
            currentGroup.options.push(opt);
        });

        // Options card
        html += '<div class="rd-card"><form id="rd-settings-form">';

        $.each(optionGroups, function(gi, group) {
            html += '<div class="rd-options-section">';
            html += '<div class="rd-option-group-title" id="rd-section-' + escAttr(group.key) + '"><span class="dashicons dashicons-arrow-right-alt2"></span>' + escHtml(group.label) + '</div>';

            $.each(group.options, function(oi, opt) {

            // Option row: 2-column layout (label | input)
            html += '<div class="rd-option-row" data-key="' + escAttr(opt.key) + '">';

            // Label column
            html += '<div class="rd-option-label-col">';
            html += '<div class="rd-option-label">' + escHtml(opt.label);
            html += ' <code class="rd-option-key">' + escHtml(opt.key) + '</code></div>';
            if (opt.desc) {
                html += '<div class="rd-option-desc">' + escHtml(opt.desc) + '</div>';
            }
            html += '</div>';

            // Input column
            html += '<div class="rd-option-input-col">';


            // Special: status multiselect checkboxes
            if (opt.key === 'emailStatusChangeStatuses' || opt.key === 'billingVisibleStatuses') {
                var selected = (opt.value || '').split(',').map(function(s) { return s.trim(); });
                html += '<div class="rd-status-checkboxes" data-key="' + escAttr(opt.key) + '" style="display:flex;flex-wrap:wrap;gap:6px">';
                $.each(cfg.statuses || {}, function(slug, def) {
                    var label = typeof def === 'object' ? def.label : def;
                    var color = typeof def === 'object' ? def.color : '#94a3b8';
                    var checked = !opt.value || selected.indexOf(slug) >= 0 ? ' checked' : '';
                    html += '<label style="display:flex;align-items:center;gap:4px;font-size:12px;padding:4px 8px;border-radius:6px;border:1px solid #e2e8f0;cursor:pointer">';
                    html += '<input type="checkbox" value="' + escAttr(slug) + '"' + checked + ' style="width:14px;height:14px">';
                    html += '<span style="width:8px;height:8px;border-radius:50%;background:' + color + '"></span>' + escHtml(label);
                    html += '</label>';
                });
                html += '</div>';
            } else

            switch (opt.type) {
                case 'checkbox':
                    html += '<input type="checkbox" class="rd-option-input" data-key="' + escAttr(opt.key) + '"' +
                        (opt.value && opt.value !== '0' ? ' checked' : '') + '>';
                    break;
                case 'number':
                    var min = (opt.min !== undefined) ? ' min="' + escAttr(opt.min) + '"' : '';
                    var max = (opt.max !== undefined) ? ' max="' + escAttr(opt.max) + '"' : '';
                    var step = (opt.step !== undefined) ? ' step="' + escAttr(opt.step) + '"' : '';
                    html += '<input type="number" class="rd-option-input" data-key="' + escAttr(opt.key) + '" value="' + escAttr(opt.value) + '"' + min + max + step + '>';
                    break;
                case 'textarea':
                    html += '<textarea class="rd-option-input rd-option-textarea" data-key="' + escAttr(opt.key) + '" rows="6"' + '>' + escHtml(opt.value || '') + '</textarea>';
                    break;
                case 'dropdown':
                    html += '<select class="rd-option-input" data-key="' + escAttr(opt.key) + '"' + '>';
                    if (opt.values) {
                        $.each(opt.values, function(j, v) {
                            var sel = (v.value == opt.value) ? ' selected' : '';
                            html += '<option value="' + escAttr(v.value) + '"' + sel + '>' + escHtml(v.label) + '</option>';
                        });
                    }
                    html += '</select>';
                    break;
                default: // text
                    html += '<input type="text" class="rd-option-input" data-key="' + escAttr(opt.key) + '" value="' + escAttr(opt.value) + '"' + '>';
            }

            html += '</div>'; // input col
            html += '</div>'; // option row

        });

            html += '</div>'; // end rd-options-section
        }); // end optionGroups loop

        // Auto-save status bar (no save button — saves on change)
        html += '<div class="rd-options-autosave-bar" id="rd-save-result"></div>';

        html += '</form></div>';

        $('#rd-options-main-panel').html(html);
    }

    // Sub-tab toggle — both always reload fresh
    $(document).on('click', '.rd-options-subtab', function() {
        var subtab = $(this).data('subtab');
        $('.rd-options-subtab').removeClass('active');
        $(this).addClass('active');

        if (subtab === 'options-main') {
            $('#rd-options-history-panel').hide();
            // Reload options fresh into the main panel
            rdAjax('get_settings', {}, function(result) {
                renderOptionsMainPanel(result.options || []);
                $('#rd-options-main-panel').show();
            });
        } else {
            $('#rd-options-main-panel').hide();
            $('#rd-options-history-panel').show();
            loadOptionsHistory(1);
        }
    });

    function loadOptionsHistory() {
        var $panel = $('#rd-options-history-panel');
        var html = '<div class="rd-card">';
        html += '<div class="rd-card-header"><h3>' + __('Change History', 'vollstart-repair-desk') + '</h3></div>';
        html += '<div class="rd-card-body">';
        html += '<table id="rd-options-history-dt" class="display" style="width:100%"><thead><tr>';
        html += '<th>' + __('Date', 'vollstart-repair-desk') + '</th>';
        html += '<th>' + __('Option', 'vollstart-repair-desk') + '</th>';
        html += '<th>' + __('Old Value', 'vollstart-repair-desk') + '</th>';
        html += '<th>' + __('New Value', 'vollstart-repair-desk') + '</th>';
        html += '<th>' + __('Changed By', 'vollstart-repair-desk') + '</th>';
        html += '<th></th>';
        html += '</tr></thead></table>';
        html += '</div></div>';
        $panel.html(html);

        $('#rd-options-history-dt').DataTable({
            serverSide: true,
            processing: true,
            ajax: function (dtParams, callback) {
                rdAjax('get_options_history', {
                    draw: dtParams.draw,
                    start: dtParams.start,
                    length: dtParams.length,
                    'search[value]': dtParams.search.value
                }, function (result) {
                    callback({
                        draw: result.draw,
                        recordsTotal: result.recordsTotal,
                        recordsFiltered: result.recordsFiltered,
                        data: (result.data || []).map(function (row) {
                            var oldVal = (row.old_value || '').length > 50 ? row.old_value.substring(0, 50) + '…' : (row.old_value || '');
                            var newVal = (row.new_value || '').length > 50 ? row.new_value.substring(0, 50) + '…' : (row.new_value || '');
                            return [
                                '<span style="white-space:nowrap;font-size:12px">' + escHtml((row.changed_at || '').substring(0, 16)) + '</span>',
                                '<code style="font-size:11px">' + escHtml(row.option_key) + '</code>',
                                '<span style="font-size:12px;color:#64748b" title="' + escAttr(row.old_value || '') + '">' + escHtml(oldVal) + '</span>',
                                '<span style="font-size:12px;color:#1e293b" title="' + escAttr(row.new_value || '') + '">' + escHtml(newVal) + '</span>',
                                '<span style="font-size:12px;color:#94a3b8">' + escHtml(row.changed_by_name || '—') + '</span>',
                                '<div style="text-align:right"><button class="rd-btn rd-btn-sm rd-btn-secondary rd-revert-btn" data-id="' + row.id + '" data-key="' + escAttr(row.option_key) + '">' + __('Revert', 'vollstart-repair-desk') + '</button></div>'
                            ];
                        })
                    });
                });
            },
            pageLength: 25,
            order: [[0, 'desc']],
            columnDefs: [{ orderable: false, targets: [-1] }],
            language: { emptyTable: __('No changes recorded yet.', 'vollstart-repair-desk') }
        });
    }

    // Revert option
    $(document).on('click', '.rd-revert-btn', function() {
        var id = $(this).data('id');
        var key = $(this).data('key');
        if (!confirm(__('Revert option', 'vollstart-repair-desk') + ' "' + key + '" ' + __('to its previous value?', 'vollstart-repair-desk'))) return;
        rdAjax('revert_option', { history_id: id }, function(result) {
            if (result.reverted) {
                loadOptionsHistory($('#rd-options-history-panel .rd-history-page.rd-btn-primary').data('page') || 1);
            }
        }, {spin: true});
    });

    // --- Scroll to Top ---

    function initScrollTop() {
        var $btn = $('#rd-scroll-top');
        $(window).on('scroll', function() {
            var st = $(this).scrollTop();
            $btn.toggleClass('visible', st > 300);
            $('.rd-options-nav').toggleClass('scrolled', st > 80);
        });
        $btn.on('click', function() {
            $('html, body').animate({ scrollTop: 0 }, 300);
        });
    }

    // --- Event Delegation ---

    $(document).on('click', '.rd-filter-pill', function() {
        currentStatusFilter = $(this).data('status');
        $('.rd-filter-pill').removeClass('active').css({ 'border-color': '', 'color': '', 'background': '' });
        $(this).addClass('active');
        if (currentStatusFilter) {
            var color = getStatusColor(currentStatusFilter);
            $(this).css({ 'border-color': color, 'color': color, 'background': color + '10' });
        }
        if (repairsDT) repairsDT.ajax.reload();
    });

    // DataTables handles search natively — no manual search handlers needed

    // Close modals
    $(document).on('click', '.rd-close-modal', function() {
        $(this).closest('.rd-modal-backdrop').remove();
    });
    $(document).on('click', '.rd-modal-backdrop', function(e) {
        if (e.target === this) $(this).remove();
    });

    // Cancel repair form — cleanup temp files
    $(document).on('click', '.rd-cancel-repair-form', function() {
        var tempToken = $('#rd-f-temp-token').val();
        if (tempToken) {
            rdAjax('cancel_temp_files', { temp_token: tempToken });
        }
        currentTempToken = '';
        $(this).closest('.rd-modal-backdrop').remove();
    });

    // Quick-start new repair from repairs list toolbar
    $(document).on('click', '.rd-quick-new-repair', function() {
        var typeId = $(this).data('type-id');
        var price = $(this).data('price');
        // Open create form, then pre-select the repair type
        openRepairForm(null);
        // Wait for form to render, then set values
        setTimeout(function() {
            if ($('#rd-f-repair-type').length) {
                $('#rd-f-repair-type').val(typeId).trigger('change');
            }
        }, 600);
    });

    // Quick-start repair type button in create form
    $(document).on('click', '.rd-quick-repair-type', function() {
        var id = $(this).data('id');
        $('#rd-f-repair-type').val(id).trigger('change');
    });

    // Repair type dropdown change → auto-fill price
    $(document).on('change', '#rd-f-repair-type', function() {
        var $opt = $(this).find(':selected');
        var price = $opt.data('price');
        if (price && price !== '0.00' && !$('#rd-f-estimated-price').val()) $('#rd-f-estimated-price').val(price);
        // Auto-fill estimated date from duration
        var durationHours = parseFloat($opt.data('duration')) || 0;
        if (durationHours > 0 && !$('#rd-f-estimated-date').val()) {
            var est = new Date();
            est.setHours(est.getHours() + Math.ceil(durationHours));
            // Skip weekends
            while (est.getDay() === 0 || est.getDay() === 6) est.setDate(est.getDate() + 1);
            $('#rd-f-estimated-date').val(est.toISOString().split('T')[0]);
        }
        // Highlight matching quick-start button
        $('.rd-quick-repair-type').removeClass('rd-btn-primary').addClass('rd-btn-secondary');
        $('.rd-quick-repair-type[data-id="' + $(this).val() + '"]').removeClass('rd-btn-secondary').addClass('rd-btn-primary');
    });

    // Customer search (live autocomplete in create form)
    var custSearchTimer;
    $(document).on('input', '#rd-f-customer-search', function() {
        var val = $(this).val().trim();
        if (val.length < 2) {
            $('#rd-customer-results').html('');
            return;
        }
        clearTimeout(custSearchTimer);
        custSearchTimer = setTimeout(function() {
            rdAjax('get_customers', { search: val, page: 1, per_page: 5 }, function(data) {
                var customers = data.customers || [];
                var html = '';
                if (customers.length === 0) {
                    html = '<p style="color:#94a3b8;font-size:13px;padding:8px 0">' + __('No customers found.', 'vollstart-repair-desk') + '</p>';
                } else {
                    $.each(customers, function(i, c) {
                        html += '<div class="rd-customer-result" data-id="' + c.id + '" style="display:flex;align-items:center;gap:10px;padding:8px 12px;border:1px solid #e2e8f0;border-radius:8px;margin-bottom:4px;cursor:pointer;transition:background 0.15s">';
                        html += '<div style="flex:1"><strong>' + escHtml(c.name) + '</strong> <span style="color:#94a3b8;font-size:12px">' + escHtml(c.customer_number) + '</span>';
                        if (c.phone || c.email) html += '<br><span style="color:#64748b;font-size:12px">' + escHtml([c.phone, c.email].filter(Boolean).join(' · ')) + '</span>';
                        html += '</div></div>';
                    });
                }
                $('#rd-customer-results').html(html);
            });
        }, 300);
    });

    // Select customer from search results
    $(document).on('click', '.rd-customer-result', function() {
        var id = $(this).data('id');
        rdAjax('get_customer', { id: id }, function(result) {
            var c = result.customer;
            selectedCustomer = c;
            $('#rd-f-customer').val(c.id);
            $('#rd-f-customer-search').val('').closest('.rd-search').hide();
            $('#rd-customer-results').html('');
            $('#rd-inline-new-customer, #rd-inline-customer-form').hide();

            // Show selected customer card
            var cardHtml = '<div style="display:flex;align-items:center;gap:12px;padding:12px;background:#f0fdf4;border:1px solid #a7f3d0;border-radius:8px">';
            cardHtml += '<div style="flex:1"><strong>' + escHtml(c.name) + '</strong> <span style="color:#94a3b8;font-size:12px">' + escHtml(c.customer_number) + '</span>';
            if (c.phone) cardHtml += '<br><span style="font-size:12px;color:#64748b">' + escHtml(c.phone) + '</span>';
            if (c.email) cardHtml += ' <span style="font-size:12px;color:#64748b">' + escHtml(c.email) + '</span>';
            cardHtml += '</div>';
            cardHtml += '<button class="rd-btn rd-btn-sm rd-btn-secondary" id="rd-change-customer"><span class="dashicons dashicons-no-alt"></span></button>';
            cardHtml += '</div>';
            $('#rd-selected-customer').html(cardHtml).show();

            // Load products for this customer
            $('#rd-f-customer').trigger('change');
        });
    });

    // Change customer (deselect)
    $(document).on('click', '#rd-change-customer', function() {
        selectedCustomer = null;
        $('#rd-f-customer').val('');
        $('#rd-selected-customer').hide().html('');
        $('#rd-f-customer-search').val('').closest('.rd-search').show();
        $('#rd-inline-new-customer').show();
        $('#rd-product-row').hide();
        $('#rd-f-product-id').val('');
    });

    // Inline new customer toggle
    $(document).on('click', '#rd-inline-new-customer', function() {
        $('#rd-inline-customer-form').slideToggle(200);
    });

    // Save inline customer
    $(document).on('click', '#rd-save-inline-customer', function() {
        var data = {
            name: $('#rd-f-new-cust-name').val(),
            phone: $('#rd-f-new-cust-phone').val(),
            email: $('#rd-f-new-cust-email').val(),
            notes: $('#rd-f-new-cust-notes').val()
        };
        if (!data.name) { alert(__('Name is required.', 'vollstart-repair-desk')); return; }

        rdAjax('create_customer', data, function(result) {
            if (result.customer) {
                // Auto-select the new customer
                $('.rd-customer-result[data-id="' + result.customer.id + '"]').length ||
                $('#rd-inline-customer-form').hide();
                selectedCustomer = result.customer;
                var c = result.customer;
                $('#rd-f-customer').val(c.id);
                $('#rd-f-customer-search').val('').closest('.rd-search').hide();
                $('#rd-customer-results').html('');
                $('#rd-inline-new-customer').hide();
                var cardHtml = '<div style="display:flex;align-items:center;gap:12px;padding:12px;background:#f0fdf4;border:1px solid #a7f3d0;border-radius:8px">';
                cardHtml += '<div style="flex:1"><strong>' + escHtml(c.name) + '</strong> <span style="color:#94a3b8;font-size:12px">' + escHtml(c.customer_number) + '</span>';
                cardHtml += '</div>';
                cardHtml += '<button class="rd-btn rd-btn-sm rd-btn-secondary" id="rd-change-customer"><span class="dashicons dashicons-no-alt"></span></button>';
                cardHtml += '</div>';
                $('#rd-selected-customer').html(cardHtml).show();
                $('#rd-f-customer').trigger('change');
            }
        }, {spin: true});
    });

    // Cancel repair form (full page) — back to repairs list
    $(document).on('click', '.rd-cancel-repair-form', function() {
        var tempToken = $('#rd-f-temp-token').val();
        if (tempToken) {
            rdAjax('cancel_temp_files', { temp_token: tempToken });
        }
        currentTempToken = '';
        selectedCustomer = null;
        // Close modal if in modal, or go back to list
        var $modal = $(this).closest('.rd-modal-backdrop');
        if ($modal.length) {
            $modal.remove();
        } else {
            loadRepairs();
        }
    });

    // Customer change in repair form → load products dropdown
    // If product was from old customer, clear it and keep device fields as text
    $(document).on('change', '#rd-f-customer', function() {
        var customerId = $(this).val();
        var $row = $('#rd-product-row');
        var $select = $('#rd-f-product');
        var oldProductId = $('#rd-f-product-id').val();

        // Clear product selection — device text fields stay as they are
        // so user can review/edit before saving
        $('#rd-f-product-id').val('');

        if (!customerId) {
            $row.hide();
            $select.html('<option value="">' + __('— New device (enter below) —', 'vollstart-repair-desk') + '</option>');
            return;
        }

        rdAjax('get_products_dropdown', { customer_id: customerId }, function(result) {
            var products = result.products || [];
            var opts = '<option value="">' + __('— New device (enter below) —', 'vollstart-repair-desk') + '</option>';
            $.each(products, function(i, p) {
                var label = [p.brand, p.model].filter(Boolean).join(' ') || p.name;
                if (p.serial_number) label += ' (' + p.serial_number + ')';
                opts += '<option value="' + p.id + '" data-brand="' + escAttr(p.brand) + '" data-model="' + escAttr(p.model) + '" data-serial="' + escAttr(p.serial_number) + '" data-name="' + escAttr(p.name) + '" data-interval="' + (p.service_interval_days || '') + '" data-next-service="' + escAttr(p.next_service_date || '') + '">' + escHtml(label) + '</option>';
            });
            $select.html(opts);
            $row.toggle(products.length > 0);
        });
    });

    // Product change → auto-fill device fields + maintenance warning
    $(document).on('change', '#rd-f-product', function() {
        var $opt = $(this).find(':selected');
        var productId = $(this).val();
        $('#rd-f-product-id').val(productId);
        $('#rd-maint-warning').remove();

        if (productId) {
            $('#rd-f-device-type').val($opt.data('name') || '');
            $('#rd-f-device-brand').val($opt.data('brand') || '');
            $('#rd-f-device-model').val($opt.data('model') || '');
            $('#rd-f-device-serial').val($opt.data('serial') || '');

            // Maintenance warning
            var nextService = $opt.data('next-service');
            var interval = parseInt($opt.data('interval')) || 0;
            if (nextService && interval) {
                var fToday = new Date(); fToday.setHours(0,0,0,0);
                var fNext = new Date(nextService + 'T00:00:00');
                var fDiff = Math.round((fNext - fToday) / 86400000);
                if (fDiff <= 0) {
                    $(this).after('<div id="rd-maint-warning" style="margin-top:6px;padding:8px 12px;background:#fef2f2;border:1px solid #fecaca;border-radius:8px;font-size:12px;color:#ef4444;font-weight:600"><span class="dashicons dashicons-warning" style="font-size:14px;width:14px;height:14px;margin-right:4px"></span>' + __('Maintenance overdue since', 'vollstart-repair-desk') + ' ' + nextService + ' (' + Math.abs(fDiff) + ' ' + __('days', 'vollstart-repair-desk') + ')</div>');
                }
            }
        }
    });

    // Warranty prefill button
    $(document).on('click', '#rd-warranty-prefill', function() {
        var days = parseInt(cfg.warrantyDefaultDays) || 0;
        if (!days) return;
        var d = new Date();
        d.setDate(d.getDate() + days);
        var val = d.getFullYear() + '-' + String(d.getMonth() + 1).padStart(2, '0') + '-' + String(d.getDate()).padStart(2, '0');
        $('#rd-f-warranty').val(val);
    });

    // New repair
    $(document).on('click', '#rd-new-repair, #rd-new-repair-empty', function() {
        openRepairForm(null);
    });

    // View repair
    $(document).on('click', '.rd-view-repair', function() {
        var id = $(this).data('id');
        if (id) {
            if (currentTab === 'repairs') {
                openRepairFullView(id);
            } else {
                openRepairDetail(id); // modal from other contexts
            }
        }
    });

    // Edit repair
    $(document).on('click', '.rd-edit-repair', function() {
        var id = $(this).data('id');
        $('.rd-modal-backdrop').remove();
        rdAjax('get_repair', { id: id }, function(result) {
            openRepairForm(result.repair);
        });
    });

    // Bottom save button triggers top save
    $(document).on('click', '.rd-save-repair-bottom', function() {
        $('#rd-save-repair').trigger('click');
    });

    // Save repair
    $(document).on('click', '#rd-save-repair', function() {
        var id = $(this).data('id');
        var isNew = !id;

        // Warn if repair type changed on existing repair (steps will be replaced)
        if (id) {
            var originalType = $('#rd-f-original-repair-type').val() || '';
            var newType = $('#rd-f-repair-type').val() || '';
            if (originalType !== newType && originalType !== '') {
                if (!confirm(__('Changing the repair type will remove all existing work steps checklist items (including time tracking and checkmarks) and replace them with the new type\'s work steps. Continue?', 'vollstart-repair-desk'))) {
                    return;
                }
            }
        }
        var data = {
            customer_id: $('#rd-f-customer').val(),
            product_id: $('#rd-f-product-id').val() || '',
            repair_type_id: $('#rd-f-repair-type').val() || '',
            device_type: $('#rd-f-device-type').val(),
            device_brand: $('#rd-f-device-brand').val(),
            device_model: $('#rd-f-device-model').val(),
            device_serial: $('#rd-f-device-serial').val(),
            defect_description: $('#rd-f-defect').val(),
            priority: $('#rd-f-priority').val(),
            estimated_date: $('#rd-f-estimated-date').val(),
            estimated_price: $('#rd-f-estimated-price').val(),
            warranty_until: $('#rd-f-warranty').val(),
            internal_notes: $('#rd-f-notes').val(),
            temp_token: $('#rd-f-temp-token').val() || '',
            save_as_device: $('#rd-f-save-as-device').is(':checked') ? '1' : '0'
        };

        // Include staff assignment if field exists
        if ($('#rd-f-assigned-to').length) {
            data.assigned_to = $('#rd-f-assigned-to').val() || '';
        }

        var action = id ? 'update_repair' : 'create_repair';
        if (id) data.id = id;

        rdAjax(action, data, function(result) {
            $('.rd-modal-backdrop').remove();
            if (isNew && result.repair && currentTab === 'repairs') {
                // New repair: go directly to full view (for photo upload etc.)
                openRepairFullView(result.repair.id);
            } else if (currentRepair && result.repair && result.repair.id == currentRepair.id) {
                // Edit from full view: refresh full view
                openRepairFullView(result.repair.id);
            } else {
                reloadTables();
            }
        }, {spin: true});
    });

    // Change status — opens note dialog first
    $(document).on('click', '#rd-change-status-btn', function() {
        var id = $(this).data('id');
        var newStatus = $('#rd-change-status').val();
        var newLabel = getStatusLabel(newStatus);

        // Mini dialog for optional note
        var noteBody2 = '<p style="margin-bottom:12px">' + __('New status:', 'vollstart-repair-desk') + ' <strong style="color:' + getStatusColor(newStatus) + '">' + escHtml(newLabel) + '</strong></p>';
        noteBody2 += '<div class="rd-form-group"><label>' + __('Note (optional)', 'vollstart-repair-desk') + '</label>';
        noteBody2 += '<textarea id="rd-status-note" rows="2" placeholder="' + __('e.g. Waiting for customer approval', 'vollstart-repair-desk') + '"></textarea></div>';
        var noteFooter2 = '<button class="rd-btn rd-btn-secondary rd-close-modal">' + __('Cancel', 'vollstart-repair-desk') + '</button>';
        noteFooter2 += '<button class="rd-btn rd-btn-primary" id="rd-confirm-status" data-id="' + id + '" data-status="' + newStatus + '">' + __('Confirm', 'vollstart-repair-desk') + '</button>';
        rdModal('rd-status-note-modal', __('Change Status', 'vollstart-repair-desk'), noteBody2, { maxWidth: '440px', footer: noteFooter2 });
        $('#rd-status-note').focus();
    });

    // Confirm status change (from note dialog)
    $(document).on('click', '#rd-confirm-status', function() {
        var id = $(this).data('id');
        var status = $(this).data('status');
        var note = $('#rd-status-note').val();
        $('#rd-status-note-modal').remove();

        rdAjax('change_status', { id: id, status: status, note: note }, function(result) {
            // Remove the repair detail modal and re-open with fresh data
            $('#rd-repair-modal').remove();
            if (result.repair) {
                renderRepairModal(result.repair, null, result.timeline);
            }
            reloadTables();
        });
    });

    // Delete repair
    $(document).on('click', '.rd-delete-repair', function() {
        if (!confirm(__('Delete this repair and all related data?', 'vollstart-repair-desk'))) return;
        var id = $(this).data('id');
        rdAjax('delete_repair', { id: id }, function() {
            $('.rd-modal-backdrop').remove();
            currentRepair = null;
            if (currentTab === 'repairs') {
                loadRepairs();
            } else {
                reloadTables();
            }
        }, {spin: true});
    });

    // New customer
    $(document).on('click', '#rd-new-customer, #rd-new-customer-empty', function() {
        openCustomerForm(null);
    });

    // View customer — full view from Customers tab, peek modal from elsewhere
    $(document).on('click', '.rd-view-customer', function() {
        var id = $(this).data('id');
        if (id) {
            if (currentTab === 'customers') {
                openCustomerFullView(id);
            } else {
                openCustomerDetail(id);
            }
        }
    });

    // Edit customer from detail view
    $(document).on('click', '.rd-edit-customer-from-view', function() {
        var id = $(this).data('id');
        // Use currentCustomer if available (no extra AJAX call needed)
        if (currentCustomer && currentCustomer.id == id) {
            openCustomerForm(currentCustomer);
        } else {
            rdAjax('get_customer', { id: id }, function(result) {
                openCustomerForm(result.customer);
            });
        }
    });

    // Click repair row inside customer detail → open repair detail
    $(document).on('click', '.rd-customer-repair-row', function() {
        var id = $(this).data('id');
        if (id) {
            $('.rd-modal-backdrop').remove();
            currentTab = 'repairs';
            $('.rd-tab').removeClass('active');
            $('.rd-tab[data-tab="repairs"]').addClass('active');
            $('html, body').animate({ scrollTop: 0 }, 200);
            openRepairFullView(id);
        }
    });

    // Save customer
    $(document).on('click', '#rd-save-customer', function() {
        var id = $(this).data('id');
        var data = {
            name: $('#rd-cf-name').val(),
            email: $('#rd-cf-email').val(),
            phone: $('#rd-cf-phone').val(),
            address: $('#rd-cf-address').val(),
            vat_number: $('#rd-cf-vat').val(),
            notes: $('#rd-cf-notes').val()
        };

        var action = id ? 'update_customer' : 'create_customer';
        if (id) data.id = id;

        rdAjax(action, data, function(result) {
            $('.rd-modal-backdrop').remove();

            // If in customer full view → update in place, no reload
            if (currentTab === 'customers' && currentCustomer && result.customer && result.customer.id == currentCustomer.id) {
                updateCustomerViewInPlace(result.customer);
            } else {
                reloadTables();
            }

            // If we were in the repair form, refresh the dropdown
            if ($('#rd-f-customer').length && result.customer) {
                var c = result.customer;
                if ($('#rd-f-customer option[value="' + c.id + '"]').length) {
                    $('#rd-f-customer option[value="' + c.id + '"]').text(c.customer_number + ' — ' + c.name).prop('selected', true);
                } else {
                    $('#rd-f-customer').append('<option value="' + c.id + '" selected>' + escHtml(c.customer_number + ' — ' + c.name) + '</option>');
                }
            }
        }, {spin: true});
    });

    // Delete customer
    // GDPR: Anonymize customer
    $(document).on('click', '.rd-anonymize-customer', function() {
        var id = $(this).data('id');
        if (!confirm(__('GDPR: Erase all personal data for this customer? Name, email, phone, address, device details and photos will be permanently deleted. Repairs stay as records with anonymized customer. This cannot be undone!', 'vollstart-repair-desk'))) return;
        rdAjax('anonymize_customer', { id: id }, function() {
            openCustomerFullView(id);
        });
    });

    // GDPR: Export customer data
    $(document).on('click', '.rd-export-customer-data', function() {
        var id = $(this).data('id');
        var name = $(this).data('name') || 'customer';
        rdAjax('export_customer_data', { id: id }, function(result) {
            if (result.data) {
                downloadJSON(result.data, 'customer-data-' + name.replace(/\s+/g, '-').toLowerCase() + '-' + new Date().toISOString().slice(0, 10) + '.json');
            }
        });
    });

    $(document).on('click', '.rd-delete-customer', function() {
        if (!confirm(__('Delete this customer and ALL related data (repairs, messages, files, devices)? This cannot be undone!', 'vollstart-repair-desk'))) return;
        var id = $(this).data('id');
        rdAjax('delete_customer', { id: id }, function() {
            $('.rd-modal-backdrop').remove();
            // If in full view, go back to list
            if (currentTab === 'customers' && !$('.rd-modal-backdrop').length) {
                loadCustomers();
            } else {
                reloadTables();
            }
        }, {spin: true});
    });

    // Auto-save: save individual option on change (like Appointment Desk)
    var autoSaveTimer = {};

    function autoSaveOption($input) {
        if ($input.prop('disabled')) return;
        var key = $input.data('key');
        if (!key) return;
        var value = $input.is(':checkbox') ? ($input.is(':checked') ? '1' : '0') : $input.val();
        var $result = $('#rd-save-result');
        $result.html('<span style="font-size:12px;color:#94a3b8">' + __('Saving...', 'vollstart-repair-desk') + '</span>');
        // Update local cfg immediately, then fire and forget to server
        cfg[key] = $input.is(':checkbox') ? $input.is(':checked') : value;
        rdAjax('save_option', { key: key, value: value }, function() {
            $result.html(statusBadge('ok', __('Saved!', 'vollstart-repair-desk')));
            setTimeout(function() { $result.html(''); }, 2000);
        });
    }

    // Checkbox + Select: save immediately on change
    $(document).on('change', '.rd-option-input:checkbox, select.rd-option-input', function() {
        autoSaveOption($(this));
    });

    // Status multiselect checkboxes
    $(document).on('change', '.rd-status-checkboxes input', function() {
        var $container = $(this).closest('.rd-status-checkboxes');
        var key = $container.data('key');
        var values = [];
        $container.find('input:checked').each(function() { values.push($(this).val()); });
        // Save as comma-separated (empty = all)
        var value = values.length === Object.keys(cfg.statuses || {}).length ? '' : values.join(',');
        var $result = $('#rd-save-result');
        $result.html('<span style="font-size:12px;color:#94a3b8">' + __('Saving...', 'vollstart-repair-desk') + '</span>');
        rdAjax('save_option', { key: key, value: value }, function() {
            $result.html(statusBadge('ok', __('Saved!', 'vollstart-repair-desk')));
            setTimeout(function() { $result.html(''); }, 2000);
            cfg[key] = value;
        });
    });


    // Text + Textarea: save after 800ms pause
    $(document).on('input', 'input.rd-option-input:not(:checkbox):not([type="hidden"]), textarea.rd-option-input', function() {
        var $input = $(this);
        var key = $input.data('key') || '';
        if (autoSaveTimer[key]) clearTimeout(autoSaveTimer[key]);
        autoSaveTimer[key] = setTimeout(function() {
            autoSaveOption($input);
        }, 800);
    });

    // Prevent form submit (no save button, but user might press Enter)
    $(document).on('submit', '#rd-settings-form', function(e) {
        e.preventDefault();
    });

    // Export options
    $(document).on('click', '#rd-export-options', function() {
        rdAjax('export_options', {}, function(result) {
            var json = JSON.stringify(result, null, 2);
            var blob = new Blob([json], { type: 'application/json' });
            var url = URL.createObjectURL(blob);
            var a = document.createElement('a');
            a.href = url;
            a.download = 'vollstart-repair-desk-options-' + new Date().toISOString().slice(0, 10) + '.json';
            document.body.appendChild(a);
            a.click();
            document.body.removeChild(a);
            URL.revokeObjectURL(url);
        });
    });

    // Import options
    $(document).on('click', '#rd-import-options-btn', function() {
        $('#rd-import-file').val('').trigger('click');
    });

    $(document).on('change', '#rd-import-file', function() {
        var file = this.files[0];
        if (!file) return;
        var reader = new FileReader();
        reader.onload = function(e) {
            var parsed;
            try { parsed = JSON.parse(e.target.result); } catch (err) {
                alert(__('Invalid JSON file.', 'vollstart-repair-desk'));
                return;
            }
            if (!parsed.options || typeof parsed.options !== 'object') {
                alert(__('Invalid options file: missing options data.', 'vollstart-repair-desk'));
                return;
            }
            var count = Object.keys(parsed.options).length;
            if (!confirm(__('Import', 'vollstart-repair-desk') + ' ' + count + ' ' + __('options? This will overwrite current settings.', 'vollstart-repair-desk'))) return;

            rdAjax('import_options', { options: JSON.stringify(parsed.options) }, function(result) {
                alert(__('Imported:', 'vollstart-repair-desk') + ' ' + result.imported + '. ' + __('Skipped:', 'vollstart-repair-desk') + ' ' + result.skipped);
                loadOptions();
            }, {spin: true});
        };
        reader.readAsText(file);
    });

    // Reset options to default
    $(document).on('click', '#rd-reset-options', function() {
        if (!confirm(__('Reset ALL options to their default values? This cannot be undone. You can export your current settings first.', 'vollstart-repair-desk'))) return;
        rdAjax('reset_options', {}, function() {
            loadOptions();
        }, {spin: true});
    });

    // Copy support text
    // Copy status link
    $(document).on('click', '.rd-copy-link', function() {
        var url = $(this).attr('data-url');
        if (navigator.clipboard) {
            navigator.clipboard.writeText(url);
        } else {
            var $ta = $('<textarea>').val(url).appendTo('body');
            $ta[0].select();
            document.execCommand('copy');
            $ta.remove();
        }
        var $btn = $(this);
        $btn.find('.dashicons').removeClass('dashicons-admin-page').addClass('dashicons-yes');
        setTimeout(function() { $btn.find('.dashicons').removeClass('dashicons-yes').addClass('dashicons-admin-page'); }, 2000);
    });

    // Print QR label
    $(document).on('click', '.rd-print-qr', function() {
        var url = $(this).attr('data-url');
        var number = $(this).attr('data-number');
        var code = $(this).attr('data-code');
        var w = window.open('', '_blank', 'width=400,height=500');
        w.document.write('<html><head><title>' + number + '</title>');
        w.document.write('<style>body{font-family:-apple-system,sans-serif;text-align:center;padding:20px}#qr{display:inline-block;margin:10px 0}h2{margin:0;font-size:24px}p{margin:4px 0;color:#64748b;font-size:14px}code{font-size:18px;letter-spacing:2px;font-weight:700}</style>');
        w.document.write('</head><body>');
        w.document.write('<h2>' + number + '</h2>');
        w.document.write('<div id="qr"></div>');
        w.document.write('<p>' + __('Access Code', 'vollstart-repair-desk') + '</p><code>' + code + '</code>');
        w.document.write('<p style="margin-top:12px;font-size:11px;color:#94a3b8">' + url + '</p>');
        w.document.write('<script src="' + cfg.pluginUrl + 'assets/js/libs/qrcode/qrcode.min.js"><\/script>');
        w.document.write('<script>new QRCode(document.getElementById("qr"),{text:"' + url + '",width:200,height:200,colorDark:"#1e293b",colorLight:"#fff"});setTimeout(function(){window.print()},300);<\/script>');
        w.document.write('</body></html>');
        w.document.close();
    });

    // QR Scanner
    $(document).on('click', '#rd-scan-qr', function() {
        rdModal('rd-scanner-modal', __('Scan QR Code', 'vollstart-repair-desk'), '<div id="rd-qr-reader" style="width:100%"></div>', { maxWidth: '400px' });

        if (typeof Html5QrcodeScanner === 'undefined') return;
        var scanner = new Html5QrcodeScanner('rd-qr-reader', { fps: 10, qrbox: 250 }, false);
        scanner.render(function(decoded) {
            scanner.clear();
            $('#rd-scanner-modal').remove();
            // Extract repair number from URL: /slug/REP-0001/CODE
            var match = decoded.match(/\/([A-Z]+-\d+)\//i);
            if (match) {
                // Find repair by number
                var repairNumber = match[1].toUpperCase();
                rdAjax('search_repair_by_number', { repair_number: repairNumber }, function(result) {
                    if (result.repair_id) {
                        openRepairFullView(result.repair_id);
                    }
                });
            }
        });
    });

    // Scanner modal close — handled by rdModal close handlers

    $(document).on('click', '#rd-copy-support', function() {
        var text = $('#rd-support-text').text();
        if (navigator.clipboard) {
            navigator.clipboard.writeText(text);
        } else {
            var $ta = $('<textarea>').val(text).appendTo('body');
            $ta[0].select();
            document.execCommand('copy');
            $ta.remove();
        }
        var $btn = $(this);
        $btn.find('.dashicons').removeClass('dashicons-admin-page').addClass('dashicons-yes');
        setTimeout(function() { $btn.find('.dashicons').removeClass('dashicons-yes').addClass('dashicons-admin-page'); }, 2000);
    });

    // --- Helpers ---

    // --- Support Info Tab ---

    function loadSupportInfo() {
        rdAjax('get_support_info', {}, function(result) {
            renderSupportInfo(result.support || result, result.errorLogs || []);
        });
    }

    function renderSupportInfo(data, errorLogs) {
        var html = '';

        // Info cards grid
        html += '<div class="rd-info-grid">';

        // Versions Card
        html += '<div class="rd-card">';
        html += '<div class="rd-card-header"><h3><span class="dashicons dashicons-info-outline" style="margin-right:6px;color:#6366f1"></span>' + __('Versions', 'vollstart-repair-desk') + '</h3></div>';
        html += '<div class="rd-card-body">';
        html += infoRow(__('Plugin', 'vollstart-repair-desk'), data.versions.plugin);
        if (data.versions.pro) {
            html += infoRow(__('Pro', 'vollstart-repair-desk'), data.versions.pro);
        }
        html += infoRow(__('Database', 'vollstart-repair-desk'), data.versions.db);
        if (data.first_activated_at) {
            html += infoRow(__('First Activated', 'vollstart-repair-desk'), formatActivationDate(data.first_activated_at));
        }
        html += infoRow(__('WordPress', 'vollstart-repair-desk'), data.versions.wp);
        html += infoRow(__('PHP', 'vollstart-repair-desk'), data.versions.php);
        html += infoRow(__('MySQL', 'vollstart-repair-desk'), data.versions.mysql);
        html += '</div></div>';

        // Site Card
        html += '<div class="rd-card">';
        html += '<div class="rd-card-header"><h3><span class="dashicons dashicons-admin-site-alt3" style="margin-right:6px;color:#3b82f6"></span>' + __('Site', 'vollstart-repair-desk') + '</h3></div>';
        html += '<div class="rd-card-body">';
        html += infoRow(__('Home URL', 'vollstart-repair-desk'), '<a href="' + escAttr(data.site.home) + '" target="_blank" style="color:#3b82f6">' + escHtml(data.site.domain) + '</a>');
        html += infoRow(__('Multisite', 'vollstart-repair-desk'), data.site.is_multisite ? statusBadge('warn', __('Yes', 'vollstart-repair-desk')) : __('No', 'vollstart-repair-desk'));
        html += infoRow(__('WooCommerce', 'vollstart-repair-desk'), data.woocommerce ? statusBadge('ok', __('Active', 'vollstart-repair-desk')) : statusBadge('neutral', __('Not installed', 'vollstart-repair-desk')));
        html += infoRow(__('Debug Mode', 'vollstart-repair-desk'), data.debug ? statusBadge('warn', __('Active', 'vollstart-repair-desk')) : statusBadge('ok', __('Off', 'vollstart-repair-desk')));
        html += infoRow(__('Timezone', 'vollstart-repair-desk'), data.timezone);
        html += '</div></div>';

        // URLs Card
        if (data.urls) {
            html += '<div class="rd-card">';
            html += '<div class="rd-card-header"><h3><span class="dashicons dashicons-admin-links" style="margin-right:6px;color:#8b5cf6"></span>' + __('URLs', 'vollstart-repair-desk') + '</h3></div>';
            html += '<div class="rd-card-body">';
            html += infoRow(__('Status Page', 'vollstart-repair-desk'), '<a href="' + escAttr(data.urls.status_page) + '" target="_blank" style="color:#3b82f6">' + escHtml(data.urls.status_page) + '</a>');
            html += infoRow(__('Slug', 'vollstart-repair-desk'), '<code>' + escHtml(data.urls.slug) + '</code>');
            html += '</div></div>';
        }

        // Stats Card
        html += '<div class="rd-card">';
        html += '<div class="rd-card-header"><h3><span class="dashicons dashicons-chart-bar" style="margin-right:6px;color:#22c55e"></span>' + __('Statistics', 'vollstart-repair-desk') + '</h3></div>';
        html += '<div class="rd-card-body">';
        html += infoRow(__('Repairs', 'vollstart-repair-desk'), data.stats.repairs);
        html += infoRow(__('Customers', 'vollstart-repair-desk'), data.stats.customers);
        html += infoRow(__('Repair Types', 'vollstart-repair-desk'), data.stats.repair_types);
        html += infoRow(__('Staff', 'vollstart-repair-desk'), data.stats.staff);
        html += '</div></div>';

        html += '</div>'; // end grid

        // Help text
        html += '<div style="margin:20px 0;padding:16px;background:#eff6ff;border:1px solid #bfdbfe;border-radius:8px">';
        html += '<strong>' + __('Need help?', 'vollstart-repair-desk') + '</strong> ';
        html += __('Copy the info below and email it to', 'vollstart-repair-desk');
        html += ' <a href="mailto:support@vollstart.com" style="color:#f97316;font-weight:600">support@vollstart.com</a> ';
        html += __('for faster support.', 'vollstart-repair-desk');
        html += '</div>';

        // Libraries + Support Context — two-column row, 50/50
        html += '<div style="display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-bottom:16px">';

        // Libraries Card (left)
        html += '<div class="rd-card" style="margin:0">';
        html += '<div class="rd-card-header"><h3><span class="dashicons dashicons-book-alt" style="margin-right:6px;color:#64748b"></span>' + __('Libraries', 'vollstart-repair-desk') + '</h3></div>';
        html += '<div class="rd-card-body">';
        if (data.libraries) {
            if (data.libraries.datatables) html += infoRow('DataTables', data.libraries.datatables);
            if (data.libraries.datatables_responsive) html += infoRow('DataTables Responsive', data.libraries.datatables_responsive);
            if (data.libraries.qrcodejs) html += infoRow('qrcodejs', data.libraries.qrcodejs);
            if (data.libraries.html5_qrcode) html += infoRow('html5-qrcode', data.libraries.html5_qrcode);
            if (data.libraries.tcpdf) html += infoRow('TCPDF', data.libraries.tcpdf);
        }
        html += '</div></div>';

        // Support Context Card (right)
        html += '<div class="rd-card" style="margin:0">';
        html += '<div class="rd-card-header"><h3><span class="dashicons dashicons-clipboard" style="margin-right:6px"></span>' + __('Support Context', 'vollstart-repair-desk') + '</h3>';
        html += '<div class="rd-card-actions">';
        html += '<button class="rd-btn rd-btn-primary rd-btn-sm" id="rd-copy-support"><span class="dashicons dashicons-admin-page"></span> ' + __('Copy', 'vollstart-repair-desk') + '</button>';
        html += '</div></div>';
        html += '<div class="rd-card-body">';

        // Prominent support-email CTA (above the support info block)
        html += '<div style="margin:0 0 14px;padding:14px 16px;background:linear-gradient(135deg,#fff7ed 0%,#ffedd5 100%);border:1px solid #fed7aa;border-radius:10px;display:flex;align-items:center;gap:12px;flex-wrap:wrap">';
        html += '<span class="dashicons dashicons-email-alt" style="font-size:24px;width:24px;height:24px;color:#f97316;flex-shrink:0"></span>';
        html += '<div style="flex:1;min-width:200px">';
        html += '<div style="font-size:13px;color:#1e293b;line-height:1.5">' + __('Write us an email to', 'vollstart-repair-desk');
        html += ' <a href="mailto:support@vollstart.com?subject=' + encodeURIComponent('Repair Desk Support') + '" style="color:#c2410c;font-weight:700;text-decoration:none">support@vollstart.com</a> ';
        html += __('with the following infos:', 'vollstart-repair-desk') + '</div>';
        html += '</div>';
        html += '</div>';

        var lines = buildSupportText(data);
        html += '<pre id="rd-support-text" style="font-family:monospace;font-size:12px;background:#f8fafc;padding:16px;border-radius:8px;border:1px solid #e2e8f0;color:#475569;overflow-x:auto;white-space:pre-wrap;margin:0">' + escHtml(lines.join('\n')) + '</pre>';
        html += '</div></div>';

        html += '</div>'; // end two-column row

        // Error Logs
        html += '<div class="rd-card" style="margin-top:16px">';
        html += '<div class="rd-card-header"><h3><span class="dashicons dashicons-warning" style="margin-right:6px;color:#ef4444"></span>' + __('Error Log', 'vollstart-repair-desk') + '</h3>';
        if (errorLogs && errorLogs.length > 0) {
            html += '<div class="rd-card-actions">';
            html += '<button class="rd-btn rd-btn-secondary rd-btn-sm" id="rd-export-errors"><span class="dashicons dashicons-download"></span> ' + __('CSV', 'vollstart-repair-desk') + '</button>';
            html += '<button class="rd-btn rd-btn-danger rd-btn-sm" id="rd-clear-errors"><span class="dashicons dashicons-trash"></span> ' + __('Clear', 'vollstart-repair-desk') + '</button>';
            html += '</div>';
        }
        html += '</div>';
        html += '<div class="rd-card-body">';

        if (!errorLogs || errorLogs.length === 0) {
            html += '<p style="color:#22c55e;font-size:13px;text-align:center;padding:16px 0"><span class="dashicons dashicons-yes-alt" style="font-size:16px;width:16px;height:16px;vertical-align:middle"></span> ' + __('No errors logged. That\'s good!', 'vollstart-repair-desk') + '</p>';
        } else {
            html += '<table id="rd-error-log-dt" class="display" style="width:100%">';
            html += '<thead><tr><th>' + __('Time', 'vollstart-repair-desk') + '</th><th>' + __('Error', 'vollstart-repair-desk') + '</th><th>' + __('Details', 'vollstart-repair-desk') + '</th><th>' + __('Caller', 'vollstart-repair-desk') + '</th></tr></thead><tbody>';
            $.each(errorLogs, function(i, log) {
                html += '<tr>';
                html += '<td style="white-space:nowrap;font-size:12px">' + escHtml(log.time) + '</td>';
                html += '<td style="font-size:12px;color:#ef4444">' + escHtml(log.exception_msg || '') + '</td>';
                html += '<td style="font-size:12px;color:#64748b">' + escHtml(log.msg || '') + '</td>';
                html += '<td style="font-size:11px;color:#94a3b8;font-family:monospace">' + escHtml(log.caller_name || '') + '</td>';
                html += '</tr>';
            });
            html += '</tbody></table>';
        }

        html += '</div></div>';

        $('#rd-tab-content').html(html);

        // Init Error Log DataTable
        if (errorLogs && errorLogs.length > 0) {
            $('#rd-error-log-dt').DataTable({
                paging: true,
                pageLength: 25,
                order: [[0, 'desc']],
                searching: true,
                info: false
            });
        }
    }

    // Export error logs as CSV
    $(document).on('click', '#rd-export-errors', function() {
        var rows = [['Time', 'Error', 'Details', 'Caller']];
        $('#rd-error-log-dt tbody tr').each(function() {
            var cells = [];
            $(this).find('td').each(function() { cells.push($(this).text()); });
            rows.push(cells);
        });
        downloadCSV(rows, 'error-log-' + new Date().toISOString().slice(0, 10) + '.csv');
    });

    // Clear error logs
    $(document).on('click', '#rd-clear-errors', function() {
        if (!confirm(__('Clear all error logs?', 'vollstart-repair-desk'))) return;
        rdAjax('clear_error_logs', {}, function() {
            loadSupportInfo();
        });
    });

    function buildSupportText(data) {
        var lines = [];
        lines.push('=== Vollstart Repair Desk Support Info ===');
        lines.push('');
        lines.push('Plugin: Vollstart Repair Desk ' + data.versions.plugin + '  |  DB: ' + data.versions.db);
        if (cfg.proVersion) {
            lines.push('Pro: ' + cfg.proVersion);
        }
        if (data.first_activated_at) {
            lines.push('First Activated: ' + formatActivationDate(data.first_activated_at));
        }
        lines.push('WordPress: ' + data.versions.wp + '  |  PHP: ' + data.versions.php + '  |  MySQL: ' + data.versions.mysql);
        lines.push('');
        lines.push('Edition: ' + (data.premium ? 'Pro' : 'Free'));
        lines.push('');
        lines.push('Domain: ' + data.site.domain);
        lines.push('Home: ' + data.site.home);
        lines.push('Multisite: ' + (data.site.is_multisite ? 'Yes' : 'No'));
        lines.push('WooCommerce: ' + (data.woocommerce ? 'Yes' : 'No'));
        lines.push('Debug: ' + (data.debug ? 'Yes' : 'No'));
        lines.push('Timezone: ' + data.timezone);
        if (data.urls) {
            lines.push('');
            lines.push('Status Page: ' + data.urls.status_page);
            lines.push('Slug: ' + data.urls.slug);
        }
        lines.push('');
        lines.push('Repairs: ' + data.stats.repairs + '  |  Customers: ' + data.stats.customers);
        lines.push('Repair Types: ' + data.stats.repair_types + '  |  Staff: ' + data.stats.staff);
        if (data.libraries) {
            lines.push('');
            lines.push('Libraries:');
            Object.keys(data.libraries).forEach(function(key) {
                if (data.libraries[key] !== null && data.libraries[key] !== undefined && data.libraries[key] !== '') {
                    lines.push('  ' + key + ': ' + data.libraries[key]);
                }
            });
        }
        lines.push('');
        lines.push('=== End ===');
        return lines;
    }

    function infoRow(label, value) {
        return '<div style="display:flex;justify-content:space-between;padding:6px 0;border-bottom:1px solid #f1f5f9;font-size:13px">'
            + '<span style="color:#64748b">' + label + '</span>'
            + '<span style="color:#1e293b;font-weight:500;text-align:right">' + (value !== null && value !== undefined ? value : '—') + '</span>'
            + '</div>';
    }

    // Standard tab-info box. Pass ready-to-render HTML (titles via <strong>, etc).
    function infoBox(html) {
        return '<div class="rd-info-box">'
            + '<span class="dashicons dashicons-info-outline"></span>'
            + '<div>' + html + '</div>'
            + '</div>';
    }

    // Format activation timestamp ("YYYY-MM-DD HH:MM:SS" or trailing "~" for estimate).
    function formatActivationDate(s) {
        if (!s) return '';
        var isEstimate = s.slice(-1) === '~';
        if (isEstimate) s = s.slice(0, -1);
        var d = new Date(s.replace(' ', 'T') + 'Z');
        if (isNaN(d.getTime())) return s + (isEstimate ? ' (estimate)' : '');
        return d.toLocaleDateString() + (isEstimate ? ' (estimate)' : '');
    }

    function statusBadge(type, text) {
        var colors = { ok: '#22c55e', warn: '#f59e0b', error: '#ef4444', neutral: '#94a3b8' };
        var bgColors = { ok: '#f0fdf4', warn: '#fffbeb', error: '#fef2f2', neutral: '#f8fafc' };
        var c = colors[type] || colors.neutral;
        var bg = bgColors[type] || bgColors.neutral;
        return '<span style="display:inline-flex;align-items:center;gap:4px;font-size:12px;font-weight:600;padding:2px 10px;border-radius:999px;background:' + bg + ';color:' + c + ';border:1px solid ' + c + '30">' + text + '</span>';
    }

    // ============================================================
    // FILE UPLOAD WIDGET (reusable for repair, product, staff, ...)
    // ============================================================

    /**
     * Render upload widget for temp files (new repair, before save).
     */
    function renderTempUploadWidget(containerSelector, tempToken) {
        var $container = $(containerSelector);
        if (!$container.length) return;

        var html = '<div class="rd-upload-widget" data-entity-type="temp" data-entity-id="0" data-temp-token="' + escAttr(tempToken) + '">';
        html += '<div class="rd-file-gallery" id="rd-gallery-temp-' + escAttr(tempToken) + '">';

        // Upload tile as first grid item
        html += '<div class="rd-file-item rd-upload-tile">';
        html += '<div class="rd-upload-drop">';
        html += '<span class="dashicons dashicons-camera"></span>';
        html += '<input type="file" class="rd-file-input" accept="image/*,.pdf" multiple style="display:none">';
        html += '</div>';
        var limitText = __('Upload', 'vollstart-repair-desk');
        html += '<div class="rd-file-info" style="text-align:center;color:#94a3b8">' + limitText + '</div>';
        html += '<div class="rd-file-btn-group"><button class="rd-file-btn rd-camera-btn" title="' + __('Camera', 'vollstart-repair-desk') + '"><span class="dashicons dashicons-camera"></span></button></div>';
        html += '</div>';

        html += '</div>';
        html += '</div>';
        $container.html(html);
    }

    /**
     * Render a file upload widget into a container.
     * @param {string} containerSelector  CSS selector for the container
     * @param {string} entityType         'repair', 'product', 'staff'
     * @param {int}    entityId           Entity ID
     * @param {object} options            { showThumbnail: bool, showCamera: bool }
     */
    function renderUploadWidget(containerSelector, entityType, entityId, options) {
        var opts = $.extend({ showThumbnail: false, showCamera: true }, options || {});
        var $container = $(containerSelector);
        if (!$container.length) return;

        // Load existing files
        rdAjax('get_files', { entity_type: entityType, entity_id: entityId }, function(result) {
            var files = result.files || [];
            var html = '<div class="rd-upload-widget" data-entity-type="' + entityType + '" data-entity-id="' + entityId + '">';

            // Gallery with upload tile as first item
            html += '<div class="rd-file-gallery" id="rd-gallery-' + entityType + '-' + entityId + '">';

            // Upload tile — same size as file items
            html += '<div class="rd-file-item rd-upload-tile">';
            html += '<div class="rd-upload-drop" id="rd-drop-' + entityType + '-' + entityId + '">';
            html += '<span class="dashicons dashicons-' + (opts.showCamera ? 'camera' : 'upload') + '"></span>';
            html += '<input type="file" class="rd-file-input" accept="image/*,.pdf" multiple style="display:none">';
            html += '</div>';
            html += '<div class="rd-file-info" style="text-align:center;color:#94a3b8">' + __('Upload', 'vollstart-repair-desk') + '</div>';
            if (opts.showCamera) {
                html += '<div class="rd-file-btn-group"><button class="rd-file-btn rd-camera-btn" title="' + __('Camera', 'vollstart-repair-desk') + '"><span class="dashicons dashicons-camera"></span></button></div>';
            }
            html += '</div>';

            html += renderFileGallery(files, entityType, entityId, opts.showThumbnail);
            html += '</div>';

            html += '</div>';
            $container.html(html);
        });
    }

    function renderFileGallery(files, entityType, entityId, showThumbnail, opts) {
        if (!files || files.length === 0) return '';
        opts = opts || {};
        var html = '';
        $.each(files, function(i, f) {
            var isThumbnail = f.is_thumbnail && f.is_thumbnail !== '0';
            html += '<div class="rd-file-item' + (isThumbnail ? ' is-thumbnail' : '') + '" data-file-id="' + f.id + '">';

            if (f.is_image) {
                html += '<img src="' + escAttr(f.url) + '" class="rd-file-thumb" title="' + escAttr(f.original_name) + '">';
            } else {
                html += '<div class="rd-file-icon"><span class="dashicons dashicons-media-document"></span></div>';
            }

            html += '<div class="rd-file-info" title="' + escAttr(f.original_name) + '">' + escHtml(f.original_name) + '</div>';

            // Action buttons below filename
            html += '<div class="rd-file-btn-group">';
            if (showThumbnail && f.is_image) {
                html += '<button class="rd-file-btn rd-set-thumb" data-file-id="' + f.id + '" data-entity-type="' + entityType + '" data-entity-id="' + entityId + '" title="' + __('Thumbnail', 'vollstart-repair-desk') + '"><span class="dashicons dashicons-star-filled"></span></button>';
            }
            html += '<a class="rd-file-btn" href="' + escAttr(f.url) + '" download="' + escAttr(f.original_name) + '" title="' + __('Download', 'vollstart-repair-desk') + '" style="text-decoration:none"><span class="dashicons dashicons-download"></span></a>';
            if (!opts.noDelete) {
                html += '<button class="rd-file-btn rd-file-btn-danger rd-delete-file" data-file-id="' + f.id + '" data-entity-type="' + entityType + '" data-entity-id="' + entityId + '" title="' + __('Delete', 'vollstart-repair-desk') + '"><span class="dashicons dashicons-trash"></span></button>';
            }
            html += '</div>';

            html += '</div>';
        });
        return html;
    }

    // Refresh gallery: keep upload tile, replace file items
    function refreshGallery($gallery, files, entityType, entityId) {
        var showThumb = entityType === 'product';
        $gallery.find('.rd-file-item:not(.rd-upload-tile)').remove();
        $gallery.append(renderFileGallery(files, entityType, entityId, showThumb));
    }

    // Drop zone click → trigger file input
    $(document).on('click', '.rd-upload-drop', function(e) {
        if ($(e.target).is('input')) return;
        $(this).find('.rd-file-input').trigger('click');
    });

    // Drag & drop
    $(document).on('dragover', '.rd-upload-drop', function(e) {
        e.preventDefault();
        $(this).addClass('dragover');
    });
    $(document).on('dragleave drop', '.rd-upload-drop', function(e) {
        e.preventDefault();
        $(this).removeClass('dragover');
    });
    $(document).on('drop', '.rd-upload-drop', function(e) {
        e.preventDefault();
        var files = e.originalEvent.dataTransfer.files;
        if (files.length) {
            var $widget = $(this).closest('.rd-upload-widget');
            uploadFiles(files, $widget);
        }
    });

    // File input change
    $(document).on('change', '.rd-file-input', function() {
        if (this.files.length) {
            var $widget = $(this).closest('.rd-upload-widget');
            uploadFiles(this.files, $widget);
        }
    });

    function uploadFiles(fileList, $widget) {
        var entityType = $widget.data('entity-type');
        var entityId = $widget.data('entity-id');
        var tempToken = $widget.data('temp-token') || '';

        for (var i = 0; i < fileList.length; i++) {
            (function(file) {
                var formData = new FormData();
                formData.append('action', 'vollstart_rd_admin');
                formData.append('sub_action', 'upload_file');
                formData.append('nonce', cfg.nonce);
                formData.append('entity_type', entityType);
                formData.append('entity_id', entityId);
                if (tempToken) formData.append('temp_token', tempToken);
                formData.append('file', file);

                $.ajax({
                    url: cfg.ajaxurl,
                    type: 'POST',
                    data: formData,
                    processData: false,
                    contentType: false,
                    success: function(response) {
                        if (response.success && response.data.files) {
                            var $gallery = $widget.find('.rd-file-gallery');
                            refreshGallery($gallery, response.data.files, entityType, entityId);
                            if (entityType === 'product') updateProductRowThumbnail(entityId, response.data.files);
                            handleResponse(response.data);
                        } else if (!response.success) {
                            alert(response.data && response.data.message ? response.data.message : __('Upload failed.', 'vollstart-repair-desk'));
                        }
                    }
                });
            })(fileList[i]);
        }
    }

    // Camera capture
    $(document).on('click', '.rd-camera-btn', function() {
        var $widget = $(this).closest('.rd-upload-widget');
        var entityType = $widget.data('entity-type');
        var entityId = $widget.data('entity-id');
        var tempToken = $widget.data('temp-token') || '';
        openCameraModal(entityType, entityId, tempToken);
    });

    function openCameraModal(entityType, entityId, tempToken) {
        var camBody = '<div style="text-align:center">';
        camBody += '<video id="rd-camera-video" class="rd-camera-preview" autoplay playsinline></video>';
        camBody += '<canvas id="rd-camera-canvas" style="display:none"></canvas>';
        camBody += '<div style="margin-top:12px;display:flex;gap:8px;justify-content:center">';
        camBody += '<button class="rd-btn rd-btn-primary" id="rd-camera-snap" data-entity-type="' + entityType + '" data-entity-id="' + entityId + '" data-temp-token="' + escAttr(tempToken || '') + '"><span class="dashicons dashicons-camera"></span> ' + __('Capture', 'vollstart-repair-desk') + '</button>';
        camBody += '<button class="rd-btn rd-btn-secondary rd-close-modal">' + __('Cancel', 'vollstart-repair-desk') + '</button>';
        camBody += '</div></div>';

        var stopCamera = function() {
            var video = document.getElementById('rd-camera-video');
            if (video && video._stream) {
                video._stream.getTracks().forEach(function(t) { t.stop(); });
            }
        };

        rdModal('rd-camera-modal', __('Take Photo', 'vollstart-repair-desk'), camBody, { maxWidth: '520px', onClose: stopCamera });

        // Start camera
        if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
            navigator.mediaDevices.getUserMedia({ video: { facingMode: 'environment' } })
                .then(function(stream) {
                    var video = document.getElementById('rd-camera-video');
                    if (video) {
                        video.srcObject = stream;
                        video._stream = stream;
                    }
                })
                .catch(function() {
                    alert(__('Camera access denied or not available.', 'vollstart-repair-desk'));
                    $('#rd-camera-modal').remove();
                });
        } else {
            alert(__('Camera not supported in this browser.', 'vollstart-repair-desk'));
            $('#rd-camera-modal').remove();
        }
    }

    // Capture photo
    $(document).on('click', '#rd-camera-snap', function() {
        var video = document.getElementById('rd-camera-video');
        var canvas = document.getElementById('rd-camera-canvas');
        var entityType = $(this).data('entity-type');
        var entityId = $(this).data('entity-id');

        canvas.width = video.videoWidth;
        canvas.height = video.videoHeight;
        canvas.getContext('2d').drawImage(video, 0, 0);

        var base64 = canvas.toDataURL('image/jpeg', 0.85);
        var tempToken = $(this).data('temp-token') || '';

        // Stop camera
        if (video._stream) {
            video._stream.getTracks().forEach(function(t) { t.stop(); });
        }
        $('#rd-camera-modal').remove();

        // Upload
        var uploadData = {
            entity_type: entityType,
            entity_id: entityId,
            base64_data: base64
        };
        if (tempToken) uploadData.temp_token = tempToken;

        rdAjax('upload_file', uploadData, function(result) {
            if (result.files) {
                // Find the right gallery
                var $gallery;
                if (tempToken) {
                    $gallery = $('[id^="rd-gallery-temp"]').first();
                } else {
                    $gallery = $('#rd-gallery-' + entityType + '-' + entityId);
                }
                if ($gallery.length) {
                    refreshGallery($gallery, result.files, entityType, entityId);
                }
                if (entityType === 'product') updateProductRowThumbnail(entityId, result.files);
            }
        });
    });

    // Close camera modal — stream stopping handled by rdModal onClose callback

    /**
     * Update the thumbnail image in the product table row after file changes.
     */
    function updateProductRowThumbnail(productId, files) {
        var $td = $('#rd-product-thumb-' + productId);
        if (!$td.length) return;

        // Find thumbnail: explicit first, then first image
        var thumbFile = null;
        $.each(files, function(i, f) {
            if (f.is_thumbnail && f.is_thumbnail !== '0' && f.is_image) { thumbFile = f; return false; }
        });
        if (!thumbFile) {
            $.each(files, function(i, f) {
                if (f.is_image) { thumbFile = f; return false; }
            });
        }

        if (thumbFile) {
            $td.html('<img src="' + escAttr(thumbFile.url) + '" style="width:52px;height:52px;object-fit:cover;border-radius:8px;display:block">');
        } else {
            $td.html('<span style="display:flex;width:52px;height:52px;border-radius:8px;background:#f1f5f9;align-items:center;justify-content:center;color:#cbd5e1"><span class="dashicons dashicons-camera" style="font-size:20px;width:20px;height:20px"></span></span>');
        }
    }

    // Set thumbnail
    $(document).on('click', '.rd-set-thumb', function() {
        var fileId = $(this).data('file-id');
        var entityType = $(this).data('entity-type');
        var entityId = $(this).data('entity-id');
        rdAjax('set_thumbnail', { entity_type: entityType, entity_id: entityId, file_id: fileId }, function(result) {
            if (result.files) {
                var $gallery = $('#rd-gallery-' + entityType + '-' + entityId);
                refreshGallery($gallery, result.files, entityType, entityId);

                updateProductRowThumbnail(entityId, result.files);
            }
        });
    });

    // Preview image — lightbox (button below filename)
    $(document).on('click', '.rd-file-preview-btn', function() {
        var url = $(this).data('url');
        var name = $(this).data('name');
        openLightbox(url, name, 'image');
    });

    // Also preview when clicking the image thumbnail itself
    $(document).on('click', '.rd-file-thumb', function() {
        var src = $(this).attr('src');
        var name = $(this).attr('title') || '';
        if (src) {
            openLightbox(src, name, 'image');
        }
    });

    // Preview document (PDF) — click on file icon
    $(document).on('click', '.rd-file-icon', function() {
        var $item = $(this).closest('.rd-file-item');
        var $dl = $item.find('a[download]');
        if ($dl.length) {
            var url = $dl.attr('href');
            var name = $dl.attr('download');
            if (name && name.toLowerCase().match(/\.pdf$/)) {
                openLightbox(url, name, 'pdf');
            } else {
                // Non-PDF: just download
                window.open(url, '_blank');
            }
        }
    });

    function openLightbox(url, name, type) {
        var html = '<div class="rd-lightbox" id="rd-lightbox">';
        html += '<button class="rd-lightbox-close">&times;</button>';
        if (type === 'pdf') {
            html += '<iframe src="' + escAttr(url) + '"></iframe>';
        } else {
            html += '<img src="' + escAttr(url) + '">';
        }
        html += '<div class="rd-lightbox-name">' + escHtml(name) + '</div>';
        html += '</div>';
        $('body').append(html);
    }

    // Close lightbox
    $(document).on('click', '#rd-lightbox', function(e) {
        if ($(e.target).is('img') || $(e.target).is('iframe')) return;
        $(this).remove();
    });
    $(document).on('click', '.rd-lightbox-close', function() {
        $('#rd-lightbox').remove();
    });
    $(document).on('keydown', function(e) {
        if (e.key === 'Escape') $('#rd-lightbox').remove();
    });

    // Delete file
    $(document).on('click', '.rd-delete-file', function() {
        if (!confirm(__('Delete this file?', 'vollstart-repair-desk'))) return;
        var fileId = $(this).data('file-id');
        var entityType = $(this).data('entity-type');
        var entityId = $(this).data('entity-id');
        rdAjax('delete_file', { id: fileId }, function(result) {
            if (result.files) {
                var $gallery = $('#rd-gallery-' + entityType + '-' + entityId);
                refreshGallery($gallery, result.files, entityType, entityId);
                if (entityType === 'product') updateProductRowThumbnail(entityId, result.files);
            }
        }, {spin: true});
    });

    var auditEventLabels = null;
    function getAuditEventLabels() {
        if (!auditEventLabels) {
            auditEventLabels = {
                'file_uploaded': __('File uploaded', 'vollstart-repair-desk'),
                'file_deleted': __('File deleted', 'vollstart-repair-desk'),
                'note_updated': __('Notes updated', 'vollstart-repair-desk'),
                'customer_changed': __('Customer changed', 'vollstart-repair-desk'),
                'customer_assigned': __('Customer assigned', 'vollstart-repair-desk'),
                'product_linked': __('Device linked', 'vollstart-repair-desk'),
                'repair_updated': __('Repair updated', 'vollstart-repair-desk'),
                'repair_created': __('Repair created', 'vollstart-repair-desk'),
                'time_tracked': __('Time tracked', 'vollstart-repair-desk'),
                'status_change': __('Status changed', 'vollstart-repair-desk')
            };
        }
        return auditEventLabels;
    }

    var auditFieldLabels = {
        'customer_id': 'Customer', 'product_id': 'Device', 'repair_type_id': 'Repair Type',
        'device_type': 'Device Type', 'device_brand': 'Brand', 'device_model': 'Model',
        'device_serial': 'Serial', 'defect_description': 'Defect', 'priority': 'Priority',
        'estimated_date': 'Est. Date', 'estimated_price': 'Est. Price', 'warranty_until': 'Warranty', 'internal_notes': 'Notes',
        'assigned_to': 'Assigned To'
    };

    function getAuditTrailRows(auditLog) {
        var events = (auditLog || []).filter(function(e) { return e.event_type !== 'status_change'; });
        if (events.length === 0) return '<tr><td colspan="4" style="text-align:center;color:#94a3b8;padding:12px">' + __('No events yet.', 'vollstart-repair-desk') + '</td></tr>';
        var labels = getAuditEventLabels();
        var html = '';
        $.each(events, function(i, e) {
            var detail = e.note || '';
            // For repair_updated: note = field name, old_status/new_status = values
            if (e.old_status || e.new_status) {
                var fieldLabel = auditFieldLabels[detail] || detail;
                var oldVal = (e.old_status || '').substring(0, 40);
                var newVal = (e.new_status || '').substring(0, 40);
                detail = fieldLabel;
                if (oldVal || newVal) {
                    detail += ': ';
                    if (oldVal) detail += '<span style="color:#dc2626;text-decoration:line-through">' + escHtml(oldVal) + '</span> ';
                    if (oldVal && newVal) detail += '\u2192 ';
                    if (newVal) detail += '<span style="color:#22c55e">' + escHtml(newVal) + '</span>';
                }
            }
            html += '<tr>';
            html += '<td style="white-space:nowrap;color:#94a3b8">' + escHtml(formatDateTime(e.created_at)) + '</td>';
            html += '<td>' + escHtml(labels[e.event_type] || e.event_type) + '</td>';
            html += '<td style="color:#64748b;font-size:12px">' + detail + '</td>';
            html += '<td style="color:#94a3b8">' + escHtml(e.changed_by || '') + '</td>';
            html += '</tr>';
        });
        return html;
    }

    function renderAuditTrailRows(auditLog) {
        $('#rd-audit-trail-body').html(getAuditTrailRows(auditLog));
    }

    /**
     * Get label for a status slug from cfg.statuses (rich objects) or cfg.allStatuses.
     */
    function getStatusLabel(slug) {
        var all = cfg.allStatuses || {};
        if (all[slug]) {
            return typeof all[slug] === 'object' ? (all[slug].label || slug) : all[slug];
        }
        var active = cfg.statuses || {};
        if (active[slug]) {
            return typeof active[slug] === 'object' ? (active[slug].label || slug) : active[slug];
        }
        return slug;
    }

    /**
     * Get color for a status slug.
     */
    function getStatusColor(slug) {
        var all = cfg.allStatuses || {};
        if (all[slug] && all[slug].color) return all[slug].color;
        return '#94a3b8';
    }

    function isFinalStatus(slug) {
        var all = cfg.allStatuses || {};
        return all[slug] && all[slug].is_final;
    }

    /**
     * Format datetime string for display.
     */
    function formatDateTime(dt) {
        if (!dt) return '';
        // Input: "2026-03-26 14:30:00" → "26.03.2026, 14:30"
        var parts = dt.split(' ');
        if (parts.length < 2) return dt;
        var dateParts = parts[0].split('-');
        if (dateParts.length < 3) return dt;
        var timeParts = parts[1].split(':');
        return dateParts[2] + '.' + dateParts[1] + '.' + dateParts[0] + ', ' + timeParts[0] + ':' + timeParts[1];
    }

    function formatTimerMinutes(min) {
        min = parseFloat(min) || 0;
        if (min < 1) return '< 1 min';
        if (min < 60) return Math.round(min) + ' min';
        var h = Math.floor(min / 60);
        var m = Math.round(min % 60);
        return h + 'h ' + (m > 0 ? m + 'm' : '');
    }

    // Format seconds as h:mm:ss or m:ss
    function formatTimerHMS(totalSec) {
        totalSec = Math.max(0, Math.floor(totalSec));
        var h = Math.floor(totalSec / 3600);
        var m = Math.floor((totalSec % 3600) / 60);
        var s = totalSec % 60;
        if (h > 0) return h + ':' + String(m).padStart(2, '0') + ':' + String(s).padStart(2, '0');
        return m + ':' + String(s).padStart(2, '0');
    }

    // Registry: stepId → { started: Date.now()-adjusted, trackedSec: seconds already tracked }
    var runningTimers = {};

    // One global timer — ticks every second, updates all running elapsed spans
    setInterval(function() {
        var keys = Object.keys(runningTimers);
        for (var i = 0; i < keys.length; i++) {
            var stepId = keys[i];
            var t = runningTimers[stepId];
            var elapsedSec = (Date.now() - t.started) / 1000;
            var totalSec = t.trackedSec + elapsedSec;
            var el = document.getElementById('rd-elapsed-' + stepId);
            if (el) el.textContent = formatTimerHMS(totalSec);
        }
    }, 1000);

    function escHtml(str) {
        if (str === null || str === undefined) return '';
        return String(str)
            .replace(/&/g, '&amp;')
            .replace(/</g, '&lt;')
            .replace(/>/g, '&gt;')
            .replace(/"/g, '&quot;')
            .replace(/'/g, '&#39;');
    }

    function escAttr(str) {
        return escHtml(str);
    }

    // --- Export/Import handlers ---

    // Repairs CSV
    $(document).on('click', '#rd-export-repairs', function() {
        rdAjax('export_repairs_csv', {}, function(result) {
            var rows = result.rows || [];
            var header = ['Repair #', 'Status', 'Customer', 'Customer #', 'Email', 'Device Brand', 'Device Model', 'Serial', 'Defect', 'Priority', 'Est. Date', 'Est. Price', 'Warranty', 'Access Code', 'Created'];
            var data = [header];
            $.each(rows, function(i, r) {
                data.push([r.repair_number, r.status, r.customer_name, r.customer_number, r.customer_email, r.device_brand, r.device_model, r.device_serial, r.defect_description, r.priority, r.estimated_date, r.estimated_price, r.warranty_until || '', r.access_code, r.created_at]);
            });
            downloadCSV(data, 'repairs-' + new Date().toISOString().slice(0, 10) + '.csv');
        });
    });

    // Customers CSV export
    $(document).on('click', '#rd-export-customers', function() {
        rdAjax('export_customers_csv', {}, function(result) {
            var rows = result.rows || [];
            var header = ['ID', 'Customer #', 'Name', 'Email', 'Phone', 'Address', 'Notes', 'Created'];
            var data = [header];
            $.each(rows, function(i, c) {
                data.push([c.id, c.customer_number, c.name, c.email, c.phone, c.address, c.notes, c.created_at]);
            });
            downloadCSV(data, 'customers-' + new Date().toISOString().slice(0, 10) + '.csv');
        });
    });

    // Customers CSV import
    $(document).on('click', '#rd-import-customers', function() {
        importFileDialog('.csv', function(content) {
            var lines = content.split('\n').filter(function(l) { return l.trim(); });
            if (lines.length < 2) { alert(__('Empty or invalid CSV.', 'vollstart-repair-desk')); return; }
            var headers = lines[0].split(',').map(function(h) { return h.replace(/"/g, '').trim().toLowerCase(); });
            var nameIdx = headers.indexOf('name');
            var emailIdx = headers.indexOf('email');
            var phoneIdx = headers.indexOf('phone');
            var addressIdx = headers.indexOf('address');
            var notesIdx = headers.indexOf('notes');
            if (nameIdx < 0) { alert(__('CSV must have a "Name" column.', 'vollstart-repair-desk')); return; }
            var items = [];
            for (var i = 1; i < lines.length; i++) {
                var cols = lines[i].match(/("([^"]|"")*"|[^,]*)/g) || [];
                var clean = cols.map(function(c) { return c.replace(/^"|"$/g, '').replace(/""/g, '"').trim(); });
                items.push({
                    name: clean[nameIdx] || '',
                    email: clean[emailIdx] || '',
                    phone: clean[phoneIdx] || '',
                    address: clean[addressIdx] || '',
                    notes: clean[notesIdx] || ''
                });
            }
            if (!confirm(__('Import', 'vollstart-repair-desk') + ' ' + items.length + ' ' + __('customers?', 'vollstart-repair-desk'))) return;
            rdAjax('import_customers', { data: JSON.stringify(items) }, function(result) {
                alert(result.imported + ' ' + __('customers imported.', 'vollstart-repair-desk'));
                loadCustomers();
            }, {spin: true});
        });
    });

    // Devices CSV export
    $(document).on('click', '#rd-export-devices', function() {
        rdAjax('export_devices_csv', {}, function(result) {
            var rows = result.rows || [];
            var header = ['ID', 'Name', 'Brand', 'Model', 'Serial', 'Customer', 'Notes', 'Created'];
            var data = [header];
            $.each(rows, function(i, p) {
                data.push([p.id, p.name, p.brand, p.model, p.serial_number, p.customer_name, p.notes, p.created_at]);
            });
            downloadCSV(data, 'devices-' + new Date().toISOString().slice(0, 10) + '.csv');
        });
    });

    // Repair Types JSON export
    $(document).on('click', '#rd-export-repair-types', function() {
        rdAjax('export_repair_types_json', {}, function(result) {
            downloadJSON(result.data || [], 'repair-types-' + new Date().toISOString().slice(0, 10) + '.json');
        });
    });

    // Repair Types JSON import
    $(document).on('click', '#rd-import-repair-types', function() {
        importFileDialog('.json', function(content) {
            var items;
            try { items = JSON.parse(content); } catch(e) { alert(__('Invalid JSON file.', 'vollstart-repair-desk')); return; }
            if (!Array.isArray(items)) { alert(__('Expected an array of repair types.', 'vollstart-repair-desk')); return; }
            if (!confirm(__('Import', 'vollstart-repair-desk') + ' ' + items.length + ' ' + __('repair types?', 'vollstart-repair-desk'))) return;
            rdAjax('import_repair_types', { data: JSON.stringify(items) }, function(result) {
                alert(result.imported + ' ' + __('repair types imported.', 'vollstart-repair-desk'));
                loadRepairTypes();
            }, {spin: true});
        });
    });

    // Work Steps JSON export
    $(document).on('click', '#rd-export-work-steps', function() {
        rdAjax('export_work_steps_json', {}, function(result) {
            downloadJSON(result.data || [], 'work-steps-' + new Date().toISOString().slice(0, 10) + '.json');
        });
    });

    // Work Steps JSON import
    $(document).on('click', '#rd-import-work-steps', function() {
        importFileDialog('.json', function(content) {
            var items;
            try { items = JSON.parse(content); } catch(e) { alert(__('Invalid JSON file.', 'vollstart-repair-desk')); return; }
            if (!Array.isArray(items)) { alert(__('Expected an array of work step lists.', 'vollstart-repair-desk')); return; }
            if (!confirm(__('Import', 'vollstart-repair-desk') + ' ' + items.length + ' ' + __('work step lists?', 'vollstart-repair-desk'))) return;
            rdAjax('import_work_steps', { data: JSON.stringify(items) }, function(result) {
                alert(result.imported + ' ' + __('work step lists imported.', 'vollstart-repair-desk'));
                loadStepLists();
            }, {spin: true});
        });
    });

    // --- Export/Import helpers ---

    function downloadCSV(rows, filename) {
        var csv = rows.map(function(r) {
            return r.map(function(c) { return '"' + String(c || '').replace(/"/g, '""') + '"'; }).join(',');
        }).join('\n');
        downloadBlob('\uFEFF' + csv, filename, 'text/csv;charset=utf-8');
    }

    function downloadJSON(data, filename) {
        downloadBlob(JSON.stringify(data, null, 2), filename, 'application/json;charset=utf-8');
    }

    function downloadBlob(content, filename, type) {
        var blob = new Blob([content], { type: type });
        var a = document.createElement('a');
        a.href = URL.createObjectURL(blob);
        a.download = filename;
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
    }

    function importFileDialog(accept, callback) {
        var $input = $('<input type="file" accept="' + accept + '" style="display:none">');
        $input.on('change', function() {
            if (!this.files.length) return;
            var reader = new FileReader();
            reader.onload = function(e) { callback(e.target.result); };
            reader.readAsText(this.files[0]);
        });
        $('body').append($input);
        $input.trigger('click');
        setTimeout(function() { $input.remove(); }, 60000);
    }

    // --- Add-on Helpers ---

    /**
     * getHelpers — returns API object for a registered add-on's JS.
     * The add-on receives this via VollstartRD_ProAdmin(helpers).
     */
    function getHelpers() {
        return {
            ajax: rdAjax,
            CONFIG: cfg,
            option_getVal: option_getVal,
            rdModal: rdModal,
            rdModalClose: rdModalClose,
            rdButton: rdButton,
            escHtml: escHtml,
            escAttr: escAttr,
            __: __,
            loadTab: loadTab,
            infoRow: infoRow,
            downloadCSV: downloadCSV,
            downloadJSON: downloadJSON
        };
    }

})(jQuery);
