/* Local, server-filtered search. Explicit choice only; no customer data in storage. */ (() => { 'use strict'; const root = document.querySelector('[data-payment-customer-picker]'); if (!root) return; const search = root.querySelector('input[type=search]'); const value = root.querySelector('#id_customer'); const results = root.querySelector('[data-customer-results]'); const selected = root.querySelector('[data-selected-customer]'); const status = root.querySelector('[role=status]'); let timer, controller, version = 0; const node = (tag, text, className) => { const element = document.createElement(tag); if (text !== undefined) element.textContent = text; if (className) element.className = className; return element; }; const history = customer => { const details = node('details', undefined, 'pay-customer-history'); details.append(node('summary', `سوابق قابل مشاهده · ${customer.ticket_count.toLocaleString('fa-IR')} تیکت`)); if (!customer.history.length) details.append(node('p', 'سابقه تیکت قابل مشاهده‌ای وجود ندارد.')); customer.history.forEach(ticket => { const link = node('a', `${ticket.number} · ${ticket.subject}`); link.href = ticket.url; link.target = '_blank'; link.rel = 'noopener'; const row = node('div'); row.append(link, node('small', ticket.status)); details.append(row); }); return details; }; const identity = customer => { const container = node('div', undefined, 'pay-customer-identity'); container.append(node('strong', customer.name), node('bdi', customer.mobile)); if (customer.organization) container.append(node('span', customer.organization)); container.append(node('small', customer.location || 'موقعیت ثبت نشده')); return container; }; const choose = (customer, focus = true) => { clearTimeout(timer); version++; controller?.abort(); value.value = customer.value; value.dispatchEvent(new Event('change', {bubbles:true})); search.value = ''; results.hidden = true; results.replaceChildren(); selected.replaceChildren(node('span', 'مشتری انتخاب‌شده', 'pay-selected-label'), identity(customer), history(customer)); const change = node('button', 'تغییر مشتری', 'pay-button secondary'); change.type = 'button'; change.addEventListener('click', () => { value.value = ''; value.dispatchEvent(new Event('change', {bubbles:true})); selected.hidden = true; search.focus(); status.textContent = 'مشتری جدید را جست‌وجو و انتخاب کنید.'; }); selected.append(change); selected.hidden = false; status.textContent = 'قبل از صدور، نام و شماره تماس مشتری انتخاب‌شده را بررسی کنید.'; if (focus) change.focus({preventScroll:true}); }; const lookup = async () => { const query = search.value.trim(), current = ++version; controller?.abort(); controller = new AbortController(); if (query.length < 2) { results.hidden = true; status.textContent = 'حداقل دو حرف یا رقم وارد کنید.'; return; } status.textContent = 'در حال جست‌وجو…'; try { const response = await fetch(`${root.dataset.searchUrl}?q=${encodeURIComponent(query)}`, { credentials: 'same-origin', cache: 'no-store', signal: controller.signal }); if (!response.ok) throw new Error('lookup'); const data = await response.json(); if (current !== version) return; results.replaceChildren(); data.results.forEach(customer => { const card = node('article', undefined, 'pay-customer-result'); const button = node('button', 'انتخاب این مشتری', 'pay-button secondary'); button.type = 'button'; button.addEventListener('click', () => choose(customer)); card.append(identity(customer), history(customer), button); results.append(card); }); results.hidden = !data.results.length; status.textContent = data.results.length ? `${data.results.length.toLocaleString('fa-IR')} نتیجه${data.has_more ? '؛ برای نتایج دقیق‌تر نام یا شماره کامل‌تری وارد کنید.' : '؛ مشتری موردنظر را انتخاب کنید.'}` : 'مشتری فعالی پیدا نشد؛ نام یا شماره تماس را بررسی کنید.'; } catch (error) { if (error.name === 'AbortError' || current !== version) return; results.hidden = true; status.textContent = 'جست‌وجو انجام نشد؛ اتصال را بررسی کنید و دوباره جست‌وجو کنید.'; } }; search.addEventListener('input', () => { clearTimeout(timer); version++; controller?.abort(); value.value = ''; value.dispatchEvent(new Event('change', {bubbles:true})); selected.hidden = true; results.hidden = true; if (search.value.trim().length < 2) { status.textContent = 'حداقل دو حرف یا رقم وارد کنید.'; return; } timer = setTimeout(lookup, 350); }); search.addEventListener('keydown', event => { if (event.key === 'Enter') { event.preventDefault(); clearTimeout(timer); lookup(); } }); root.closest('form').addEventListener('submit', event => { if (!value.value) { event.preventDefault(); status.textContent = 'مشتری را از نتایج جست‌وجو انتخاب کنید.'; search.focus(); search.scrollIntoView({block:'center'}); } }); const initial = JSON.parse(document.querySelector('#payment-selected-customer').textContent); if (initial && String(initial.value) === value.value) choose(initial, false); })();