/**
 * Clients screen (Yatoon > Clients).
 *
 * Lifted out of admin/views/clients.php. The nonce it used to have baked into
 * the page now arrives on yatoonClientsData, localized from the view itself
 * because that is where the nonce is created.
 */
/* global jQuery, ajaxurl, yatoonClientsData */
jQuery(function($){
    /**
     * 4.6.2: i18n bridge, matching the one at the top of frontend.js.
     *
     * This file had no __() of any kind, so every string it renders - the whole
     * booking-history table header, the empty states, the confirm dialogs, the
     * button labels - was hardcoded English printed into a screen that is
     * otherwise fully translated by PHP. A salon running the admin in another
     * locale saw the page switch to English the moment this script rendered.
     *
     * Defensive on purpose: wp.i18n is not a guaranteed dependency of this
     * handle, and an admin screen that throws ReferenceError renders nothing at
     * all. Falling back to the original English is the correct failure mode.
     *
     * NOTE for the PHP side: the strings only actually translate once the
     * enqueue for this handle calls
     * wp_set_script_translations( 'yatoon-admin-clients', 'yatoon-booking-system' ).
     * Until then this is a no-op wrapper - correct, but inert.
     */
    const __ = (function () {
        const d = 'yatoon-booking-system';
        if (window.wp && window.wp.i18n && typeof window.wp.i18n.__ === 'function') {
            return function (str) { return window.wp.i18n.__(str, d); };
        }
        return function (str) { return str; };
    })();

    // 4.6.2: tiny %d/%s filler so counted strings stay one translatable msgid
    // instead of being concatenated out of fragments no translator can reorder.
    function fmt(str, value) {
        return String(str).replace(/%[ds]/, value);
    }

    const nonce = yatoonClientsData.nonce;
    const initialClientId = new URLSearchParams(window.location.search).get('client_id') || '';

    function escapeHtml(value) {
        return $('<div>').text(value || '').html();
    }

    function buildMetaPreview(tags, allergies, preferences, notes) {
        let html = '';
        const allergyText = (allergies || '').trim();
        if (allergyText) {
            const shortened = allergyText.length > 40 ? allergyText.slice(0, 40) + '...' : allergyText;
            html += '<span class="yc-tag allergy">' + escapeHtml(__('Warning:')) + ' ' + escapeHtml(shortened) + '</span><br>';
        }

        if ((preferences || '').trim()) {
            html += '<span class="yc-tag">' + escapeHtml(__('Prefs saved')) + '</span>';
        }

        (tags || '').split(',').map(tag => tag.trim()).filter(Boolean).forEach(tag => {
            html += '<span class="yc-tag">' + escapeHtml(tag) + '</span>';
        });

        if ((notes || '').trim()) {
            html += '<div class="yc-note-preview">' + escapeHtml(notes.trim()) + '</div>';
        }

        return html || '-';
    }

    function updateClientRowPreview(id) {
        const $row = $('tr[data-client-id="' + id + '"]');
        if (!$row.length) {
            return;
        }

        $row.find('.yc-client-name-cell strong').text($('#yc-client-name').val().trim() || '-');
        $row.find('.yc-client-meta-cell').html(buildMetaPreview(
            $('#yc-client-tags').val(),
            $('#yc-client-allergies').val(),
            $('#yc-client-preferences').val(),
            $('#yc-client-notes').val()
        ));
    }

    // Open modal
    $(document).on('click', '.yc-open-modal', function(){
        const id = $(this).data('id');
        $('#yc-current-client-id').val(id);
        $('#yc-modal-loading').show();
        $('#yc-modal-content').hide();
        $('#yc-modal-title').text(__('Client Profile'));
        $('#yc-modal-overlay').addClass('open');

        $.post(ajaxurl, { action: 'yatoon_get_client', nonce, id }, function(res){
            if (!res.success) { $('#yc-modal-loading').text(__('Error loading client.')); return; }
            const c  = res.data.client;
            const bk = res.data.bookings;
            const st = res.data.staff_list;
            const stats = res.data.stats || {};

            $('#yc-modal-title').text(c.customer_name || c.customer_phone || 'Client');
            $('#yc-client-name').val(c.customer_name || '');
            $('#yc-client-phone').val(c.customer_phone || '');
            $('#yc-client-email').val(c.customer_email || '');
            $('#yc-client-notes').val(c.notes || '');
            $('#yc-client-allergies').val(c.allergies || '');
            $('#yc-client-preferences').val(c.preferences || '');
            $('#yc-client-tags').val(c.tags || '');

            $('#yc-stats-total').text(stats.total_bookings || 0);
            $('#yc-stats-spent').text('$' + parseFloat(stats.lifetime_value || 0).toFixed(0));
            $('#yc-stats-noshow').text(stats.no_show_count || 0);
            $('#yc-stats-unpaid').text(stats.unpaid_count || 0);

            renderLooks(res.data.looks || []);
            populateLookBookingSelect(bk || []);
            resetLookForm();

            // Populate staff dropdown
            let staffOpts = '<option value="">' + escapeHtml(__('No preference')) + '</option>';
            st.forEach(s => {
                const sel = c.preferred_staff == s.id ? ' selected' : '';
                staffOpts += `<option value="${s.id}"${sel}>${s.name}</option>`;
            });
            $('#yc-client-staff').html(staffOpts);

            // Booking history
            if (!bk || !bk.length) {
                $('#yc-history-wrap').html('<p style="color:#888;font-size:13px;">' + escapeHtml(__('No booking history yet.')) + '</p>');
            } else {
                let rows = bk.map(b => {
                    // 4.6.2: dropped the hardcoded 'en-US' locale (4 places in this
                    // file). It forced US date order and a US 12-hour clock on a
                    // screen whose every other string is translated, so a salon
                    // running the admin in de_DE read "Sep 5, 2026 2:00 PM" in an
                    // otherwise German table. undefined = the browser's locale,
                    // which is what the rest of the plugin does.
                    const dt   = b.start_time ? new Date(b.start_time).toLocaleDateString(undefined,{month:'short',day:'numeric',year:'numeric'}) : '-';
                    const time = b.start_time ? new Date(b.start_time).toLocaleTimeString(undefined,{hour:'numeric',minute:'2-digit'}) : '';
                    const st_cls = 'status-' + (b.status||'');
                    return `<tr>
                        <td>${dt} ${time}</td>
                        <td>${b.service_name||'-'}</td>
                        <td>${b.staff_name||'-'}</td>
                        <td class="${st_cls}">${b.status||'-'}</td>
                        <td class="payment-${b.payment_status||'unpaid'}">${b.payment_status||'unpaid'}</td>
                        <td>$${parseFloat(b.total_price||0).toFixed(2)}</td>
                        <td style="color:#888;font-size:12px;">${b.notes||''}</td>
                    </tr>`;
                }).join('');
                $('#yc-history-wrap').html(`
                    <table class="yc-history-table">
                        <thead><tr><th>${escapeHtml(__('Date'))}</th><th>${escapeHtml(__('Service'))}</th><th>${escapeHtml(__('Staff'))}</th><th>${escapeHtml(__('Status'))}</th><th>${escapeHtml(__('Payment'))}</th><th>${escapeHtml(__('Price'))}</th><th>${escapeHtml(__('Notes'))}</th></tr></thead>
                        <tbody>${rows}</tbody>
                    </table>`);
            }

            $('#yc-modal-loading').hide();
            $('#yc-modal-content').show();
            $('#yc-save-msg').text('');
        });
    });

    // ------------------------------------------------------------ Look history
    let currentLooks = [];

    function escapeAttr(value) {
        return $('<div>').text(value || '').html();
    }

    function renderLooks(looks) {
        currentLooks = looks || [];
        if (!currentLooks.length) {
            $('#yc-looks-grid').html('<p class="yc-look-empty">' + escapeHtml(__('No visits logged yet. Click "Log this visit" to start this client\'s history.')) + '</p>');
            return;
        }
        const cards = currentLooks.map(look => {
            const photo = look.result_image_url || look.reference_image_url || '';
            const thumb = photo
                ? `<img class="yc-look-thumb" src="${escapeAttr(photo)}" alt="" data-full="${escapeAttr(photo)}">`
                : '<div class="yc-look-thumb-empty">💅</div>';
            const dateSrc = look.visit_date || look.created_at;
            const date = dateSrc ? new Date(dateSrc.replace(' ', 'T')).toLocaleDateString(undefined, {month:'short', day:'numeric', year:'numeric'}) : '';
            const service = look.service_name ? `<div class="yc-look-service">${escapeAttr(look.service_name)}</div>` : '';
            const notes = look.notes ? `<div class="yc-look-notes">${escapeAttr(look.notes)}</div>` : (look.reference_image_url && !look.result_image_url ? `<div class="yc-look-notes" style="color:#9d174d;">${escapeAttr(__('Client\'s reference photo — no result logged yet'))}</div>` : '');
            return `<div class="yc-look-card" data-look-id="${look.id}">
                <div class="yc-look-card-actions">
                    <button type="button" class="yc-look-edit" title="${escapeAttr(__('Edit'))}">✎</button>
                    <button type="button" class="yc-look-delete" title="${escapeAttr(__('Delete'))}">✕</button>
                </div>
                ${thumb}
                <div class="yc-look-body">
                    <div class="yc-look-date">${date}</div>
                    ${service}
                    ${notes}
                </div>
            </div>`;
        }).join('');
        $('#yc-looks-grid').html(cards);
    }

    function populateLookBookingSelect(bookings) {
        let opts = '<option value="">' + escapeHtml(__('Not tied to a specific booking')) + '</option>';
        (bookings || []).forEach(b => {
            if (!b.id) { return; }
            const dt = b.start_time ? new Date(b.start_time.replace(' ', 'T')).toLocaleDateString(undefined, {month:'short', day:'numeric'}) : '';
            opts += `<option value="${b.id}">${dt} — ${escapeAttr(b.service_name || __('Service'))}</option>`;
        });
        $('#yc-look-booking').html(opts);
    }

    function resetLookForm() {
        $('#yc-look-form').hide();
        $('#yc-look-id').val('');
        $('#yc-look-booking').val('');
        $('#yc-look-date').val(new Date().toISOString().slice(0, 10));
        $('#yc-look-notes').val('');
        $('#yc-look-photo-url').val('');
        $('#yc-look-photo-preview').hide().attr('src', '');
        $('#yc-look-photo-remove').hide();
        $('#yc-look-status').text('');
    }

    $('#yc-add-look-btn').on('click', function () {
        resetLookForm();
        $('#yc-look-form').show();
    });

    $('#yc-look-cancel').on('click', function () {
        resetLookForm();
    });

    $(document).on('click', '.yc-look-edit', function () {
        const id = $(this).closest('.yc-look-card').data('look-id');
        const look = currentLooks.find(l => String(l.id) === String(id));
        if (!look) { return; }
        resetLookForm();
        $('#yc-look-id').val(look.id);
        $('#yc-look-booking').val(look.booking_id || '');
        const dateSrc = look.visit_date || look.created_at;
        if (dateSrc) { $('#yc-look-date').val(dateSrc.replace(' ', 'T').slice(0, 10)); }
        $('#yc-look-notes').val(look.notes || '');
        if (look.result_image_url) {
            $('#yc-look-photo-url').val(look.result_image_url);
            $('#yc-look-photo-preview').attr('src', look.result_image_url).show();
            $('#yc-look-photo-remove').show();
        }
        $('#yc-look-form').show();
        $('#yc-look-form')[0].scrollIntoView({block: 'nearest'});
    });

    $(document).on('click', '.yc-look-delete', function () {
        const id = $(this).closest('.yc-look-card').data('look-id');
        if (!window.confirm(__('Delete this look history entry? This cannot be undone.'))) { return; }
        const clientId = $('#yc-current-client-id').val();
        $.post(ajaxurl, { action: 'yatoon_delete_client_look', nonce, client_id: clientId, look_id: id }, function (res) {
            if (res && res.success) {
                renderLooks(currentLooks.filter(l => String(l.id) !== String(id)));
            } else {
                window.alert(__('Could not delete this entry.'));
            }
        });
    });

    $(document).on('click', '.yc-look-thumb', function () {
        window.open($(this).data('full'), '_blank', 'noopener');
    });

    let lookPhotoFrame = null;
    $('#yc-look-photo-btn').on('click', function (e) {
        e.preventDefault();
        if (lookPhotoFrame) { lookPhotoFrame.open(); return; }
        lookPhotoFrame = wp.media({
            title: 'Choose Result Photo',
            button: { text: 'Use this photo' },
            library: { type: 'image' },
            multiple: false,
        });
        lookPhotoFrame.on('select', function () {
            const attachment = lookPhotoFrame.state().get('selection').first().toJSON();
            const url = (attachment.sizes && attachment.sizes.medium) ? attachment.sizes.medium.url : attachment.url;
            $('#yc-look-photo-url').val(url);
            $('#yc-look-photo-preview').attr('src', url).show();
            $('#yc-look-photo-remove').show();
        });
        lookPhotoFrame.open();
    });

    $('#yc-look-photo-remove').on('click', function () {
        $('#yc-look-photo-url').val('');
        $('#yc-look-photo-preview').hide().attr('src', '');
        $(this).hide();
    });

    $('#yc-look-save').on('click', function () {
        const clientId = $('#yc-current-client-id').val();
        const notes = $('#yc-look-notes').val().trim();
        const photo = $('#yc-look-photo-url').val();
        if (!notes && !photo) {
            $('#yc-look-status').css('color', '#c62828').text(__('Add a photo or a note first.'));
            return;
        }
        const $btn = $(this).prop('disabled', true);
        $('#yc-look-status').css('color', '#888').text(__('Saving...'));
        $.post(ajaxurl, {
            action:            'yatoon_save_client_look',
            nonce,
            client_id:         clientId,
            look_id:           $('#yc-look-id').val(),
            booking_id:        $('#yc-look-booking').val(),
            visit_date:        $('#yc-look-date').val(),
            notes:              notes,
            result_image_url:  photo,
        }, function (res) {
            $btn.prop('disabled', false);
            if (res && res.success) {
                const id = res.data.look.id;
                const without = currentLooks.filter(l => String(l.id) !== String(id));
                renderLooks([res.data.look, ...without]);
                resetLookForm();
            } else {
                $('#yc-look-status').css('color', '#c62828').text((res && res.data && res.data.message) || __('Could not save.'));
            }
        }).fail(function () {
            $btn.prop('disabled', false);
            $('#yc-look-status').css('color', '#c62828').text(__('Network error.'));
        });
    });

    // Close modal
    $('#yc-modal-close, #yc-modal-overlay').on('click', function(e){
        if (e.target.id === 'yc-modal-overlay' || e.target.id === 'yc-modal-close') {
            $('#yc-modal-overlay').removeClass('open');
        }
    });

    // Save
    $('#yc-save-btn').on('click', function(){
        const id = $('#yc-current-client-id').val();
        const btn = $(this).prop('disabled', true).text(__('Saving...'));
        $.post(ajaxurl, {
            action:          'yatoon_save_client_notes',
            nonce,
            id,
            customer_name:   $('#yc-client-name').val(),
            notes:           $('#yc-client-notes').val(),
            allergies:       $('#yc-client-allergies').val(),
            preferences:     $('#yc-client-preferences').val(),
            preferred_staff: $('#yc-client-staff').val(),
            tags:            $('#yc-client-tags').val(),
        }, function(res){
            btn.prop('disabled', false).text('💾 ' + __('Save Profile'));
            if (res.success) {
                updateClientRowPreview(id);
                $('#yc-save-msg').text(__('Saved!')).css('color','#2e7d32');
                setTimeout(() => { $('#yc-save-msg').text(''); }, 3000);
            } else {
                $('#yc-save-msg').text('❌ ' + __('Error saving.')).css('color','#c62828');
            }
        });
    });

    if (initialClientId) {
        const $initialClient = $('.yc-open-modal[data-id="' + initialClientId + '"]').first();
        if ($initialClient.length) {
            $initialClient.trigger('click');
        }
    }

    // -- Bulk select / delete --------------------------------------------
    function updateClientSelectionState() {
        const total = $('.yc-client-checkbox').length;
        const checked = $('.yc-client-checkbox:checked').length;
        $('#yc-delete-selected').prop('disabled', checked === 0);
        // 4.6.2: was `checked + ' selected'`, which a translator cannot reorder.
        // Translators: %d is the number of selected clients.
        $('#yc-selected-summary').text(checked > 0 ? fmt(__('%d selected'), checked) : '');
        $('#yc-select-all')
            .prop('checked', total > 0 && checked === total)
            .prop('indeterminate', checked > 0 && checked < total);
        $('.yc-client-checkbox').each(function() {
            $(this).closest('tr').toggleClass('is-selected', $(this).is(':checked'));
        });
    }

    $('#yc-select-all').on('change', function() {
        $('.yc-client-checkbox').prop('checked', $(this).is(':checked'));
        updateClientSelectionState();
    });

    $(document).on('change', '.yc-client-checkbox', function() {
        updateClientSelectionState();
        // See bookings.php: reading offsetHeight does not reliably force
        // Chromium/Edge to repaint this checkbox's own check-mark. Cloning
        // the element and swapping it in does.
        const cb = this;
        const isChecked = cb.checked;
        const freshCb = cb.cloneNode(true);
        freshCb.checked = isChecked;
        cb.parentNode.replaceChild(freshCb, cb);
    });

    $('#yc-delete-selected').on('click', function() {
        const ids = $('.yc-client-checkbox:checked').map(function() { return $(this).val(); }).get();
        if (!ids.length) return;
        // 4.6.2: both branches translated; the plural one keeps its count as a
        // %d placeholder rather than being glued together from three fragments.
        const confirmMsg = ids.length === 1
            ? __('Delete this client? Their booking history will be kept, but they will no longer appear as a client profile.')
            // Translators: %d is the number of clients being deleted.
            : fmt(__('Delete these %d clients? Their booking history will be kept, but they will no longer appear as client profiles.'), ids.length);
        if (!confirm(confirmMsg)) return;

        const $btn = $(this);
        const originalText = $btn.text();
        $btn.prop('disabled', true).text(__('Deleting...'));

        $.post(ajaxurl, {
            action: 'yatoon_delete_clients',
            nonce: nonce,
            client_ids: ids
        }, function(resp) {
            if (resp.success) {
                ids.forEach(function(id) {
                    $('.yc-client-checkbox[value="' + id + '"]').closest('tr').fadeOut(200, function() { $(this).remove(); });
                });
                setTimeout(function() {
                    if (!$('.yc-client-checkbox').length) location.reload();
                    updateClientSelectionState();
                }, 220);
            } else {
                $btn.prop('disabled', false).text(originalText);
                alert(resp.data && resp.data.message ? resp.data.message : __('Failed to delete selected clients.'));
            }
        }).fail(function() {
            $btn.prop('disabled', false).text(originalText);
            alert(__('Network error. Please try again.'));
        });
    });
});
