/* global window, document, localStorage, clearTimeout, setTimeout, fetch, CustomEvent, location, WebSocket, setInterval, navigator, Notification, atob, toast */
document.documentElement.classList.toggle('dark', localStorage.getItem('theme') === 'dark');

window.themeController = () => ({
  dark: document.documentElement.classList.contains('dark'),
  toggle() {
    this.dark = !this.dark;
    document.documentElement.classList.toggle('dark', this.dark);
    localStorage.setItem('theme', this.dark ? 'dark' : 'light');
  }
});

window.searchableSelect = (url, initial = null) => ({
  query: initial?.name || '', value: initial?.id || '', results: [], open: false, active: 0, timer: null,
  search() {
    clearTimeout(this.timer);
    this.value = '';
    this.timer = setTimeout(async () => {
      const response = await fetch(`${url}?q=${encodeURIComponent(this.query)}`);
      this.results = response.ok ? await response.json() : [];
      this.open = true; this.active = 0;
    }, 250);
  },
  choose(item) { this.value = item.id; this.query = item.name; this.open = false; },
  move(delta) { if (!this.results.length) return; this.active = (this.active + delta + this.results.length) % this.results.length; },
  chooseActive() { if (this.results[this.active]) this.choose(this.results[this.active]); }
});

window.manualInvoiceForm = () => ({
  items: [],
  addFromSelect(select) {
    const option = select.options[select.selectedIndex];
    if (!option?.value || this.items.some((item) => item.productId === option.value)) return;
    this.items.push({ productId: option.value, productCode: option.dataset.code, productName: option.dataset.name, unit: option.dataset.unit, quantity: 1 });
    select.value = '';
  },
  remove(index) { this.items.splice(index, 1); },
  serialize() { return JSON.stringify(this.items); }
});

window.toast = (message, kind = 'info') => {
  window.dispatchEvent(new CustomEvent('app-toast', { detail: { message, kind } }));
};

const realtimeToken = document.querySelector('meta[name="realtime-token"]')?.content;
if (realtimeToken) {
  let reconnectDelay = 1000;
  const connect = () => {
    const scheme = location.protocol === 'https:' ? 'wss' : 'ws';
    const socket = new WebSocket(`${scheme}://${location.host}/ws?token=${encodeURIComponent(realtimeToken)}`);
    socket.addEventListener('open', () => { reconnectDelay = 1000; document.body.dataset.realtime = 'connected'; });
    socket.addEventListener('message', (event) => {
      if (event.data === 'pong') return;
      try {
        const payload = JSON.parse(event.data);
        if (payload.type !== 'connected') {
          window.dispatchEvent(new CustomEvent('realtime-event', { detail: payload }));
          toast('اطلاعات سامانه به‌روزرسانی شد.', 'info');
          document.querySelectorAll('[data-live-refresh]').forEach((element) => {
            const url = element.getAttribute('data-live-refresh');
            if (url) fetch(url, { headers: { 'X-Partial': '1' } }).then((r) => r.text()).then((html) => { element.innerHTML = html; });
          });
        }
      } catch { /* پیام غیر JSON نادیده گرفته می‌شود. */ }
    });
    socket.addEventListener('close', () => {
      document.body.dataset.realtime = 'disconnected';
      setTimeout(connect, reconnectDelay);
      reconnectDelay = Math.min(reconnectDelay * 2, 30000);
    });
    setInterval(() => { if (socket.readyState === WebSocket.OPEN) socket.send('ping'); }, 25000);
  };
  connect();
}

window.enableBrowserNotifications = async () => {
  if (!('serviceWorker' in navigator) || !('PushManager' in window)) {
    toast('این مرورگر اعلان پس‌زمینه را پشتیبانی نمی‌کند.', 'error'); return;
  }
  const publicKey = document.querySelector('meta[name="vapid-public-key"]')?.content;
  if (!publicKey) { toast('کلید اعلان مرورگر در سرور تنظیم نشده است.', 'error'); return; }
  const permission = await Notification.requestPermission();
  if (permission !== 'granted') { toast('مجوز اعلان مرورگر داده نشد؛ اعلان‌های داخل سامانه همچنان فعال‌اند.', 'info'); return; }
  const registration = await navigator.serviceWorker.register('/sw.js');
  const key = Uint8Array.from(atob(publicKey.replace(/-/g, '+').replace(/_/g, '/')), (char) => char.charCodeAt(0));
  const subscription = await registration.pushManager.subscribe({ userVisibleOnly: true, applicationServerKey: key });
  const csrf = document.querySelector('meta[name="csrf-token"]')?.content;
  const response = await fetch('/notifications/subscribe', {
    method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': csrf }, body: JSON.stringify(subscription)
  });
  toast(response.ok ? 'اعلان مرورگر فعال شد.' : 'فعال‌سازی اعلان مرورگر ناموفق بود.', response.ok ? 'success' : 'error');
};

document.addEventListener('submit', (event) => {
  const form = event.target.closest?.('form[data-confirm]');
  if (form?.dataset.confirm && !window.confirm(form.dataset.confirm)) event.preventDefault();
});

document.addEventListener('click', (event) => {
  if (event.target.closest?.('[data-enable-notifications]')) void window.enableBrowserNotifications();
});
