(function () {
  'use strict';

  // ---------- utils ----------
  function $(id) { return document.getElementById(id); }
  function el(tag, attrs, children) {
    var n = document.createElement(tag);
    if (attrs) for (var k in attrs) {
      if (k === 'class') n.className = attrs[k];
      else if (k === 'dataset') { for (var d in attrs[k]) n.dataset[d] = attrs[k][d]; }
      else if (k === 'onclick') n.addEventListener('click', attrs[k]);
      else if (k === 'hidden') { if (attrs[k]) n.setAttribute('hidden',''); }
      else if (k in n) { try { n[k] = attrs[k]; } catch (_) { n.setAttribute(k, attrs[k]); } }
      else n.setAttribute(k, attrs[k]);
    }
    if (children) children.forEach(function (c) {
      if (c == null) return;
      if (typeof c === 'string') n.appendChild(document.createTextNode(c));
      else n.appendChild(c);
    });
    return n;
  }
  function escapeHtml(s) {
    s = String(s == null ? '' : s);
    return s.replace(/[&<>"']/g, function (c) {
      return ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' })[c];
    });
  }
  // FA digits
  var FA = '۰۱۲۳۴۵۶۷۸۹';
  function toFa(n) {
    return String(n).replace(/\d/g, function (d) { return FA[+d]; });
  }
  // normalize digits for search (fa/ar → en)
  function normDigits(s) {
    if (!s) return '';
    return String(s)
      .replace(/[۰-۹]/g, function (c) { return '۰۱۲۳۴۵۶۷۸۹'.indexOf(c); })
      .replace(/[٠-٩]/g, function (c) { return '٠١٢٣٤٥٦٧٨٩'.indexOf(c); });
  }
  function api(action, opts) {
    opts = opts || {};
    var url = 'api.php?action=' + encodeURIComponent(action);
    var init = { method: opts.method || 'GET', credentials: 'same-origin' };
    if (opts.body instanceof FormData) init.body = opts.body;
    else if (opts.body) { init.headers = { 'Content-Type': 'application/json' }; init.body = JSON.stringify(opts.body); }
    return fetch(url, init).then(function (r) {
      return r.json().then(function (j) { if (!j.ok) throw new Error(j.error || 'خطا'); return j; });
    });
  }

  // ---------- modal ----------
  function openModal(id) { var m = $(id); if (m) m.hidden = false; document.body.style.overflow = 'hidden'; }
  function closeModal(id) { var m = $(id); if (m) m.hidden = true; document.body.style.overflow = ''; }
  document.addEventListener('click', function (ev) {
    var t = ev.target;
    if (t.matches && t.matches('[data-close]')) {
      var modal = t.closest('.modal'); if (modal) closeModal(modal.id);
    }
  });
  document.addEventListener('keydown', function (ev) {
    if (ev.key === 'Escape') {
      document.querySelectorAll('.modal:not([hidden])').forEach(function (m) { closeModal(m.id); });
    }
  });

  // ---------- theme ----------
  var LS_THEME = 'phonebook.theme';
  function applyTheme(t) {
    document.documentElement.setAttribute('data-theme', t);
    var btn = $('themeToggle'); if (btn) btn.textContent = t === 'dark' ? '☀️' : '🌙';
    try { localStorage.setItem(LS_THEME, t); } catch (_) {}
  }
  (function () {
    var t = 'dark';
    try { var saved = localStorage.getItem(LS_THEME); if (saved === 'dark' || saved === 'light') t = saved; } catch (_) {}
    applyTheme(t);
  })();
  document.addEventListener('click', function (ev) {
    if (ev.target && ev.target.id === 'themeToggle') {
      var cur = document.documentElement.getAttribute('data-theme') || 'dark';
      applyTheme(cur === 'dark' ? 'light' : 'dark');
    }
  });

  // ---------- state ----------
  var CONFIG = {};
  var ALL_CONTACTS = [];      // all approved (fetched once)
  var FILTERED = [];          // after search/filter
  var RENDERED = 0;           // how many currently in DOM
  var CHUNK_SIZE = 30;
  var INITIAL_CHUNK = 30;
  var CURRENT_DEPT = '';      // '' = all
  var CURRENT_Q = '';

  var $grid, $meta, $empty, $noRes, $sentinel, $chips, $search, $searchClear;

  // ---------- load ----------
  function loadConfig() {
    return api('config').then(function (j) {
      CONFIG = j;
      var limits = j.limits || {};
      CHUNK_SIZE = limits.chunkSize || 30;
      INITIAL_CHUNK = limits.initialChunk || 30;
      return j;
    });
  }
  function loadContacts() {
    return api('list').then(function (j) {
      ALL_CONTACTS = j.contacts || [];
      return ALL_CONTACTS;
    });
  }

  // ---------- search index ----------
  function buildHaystack(c) {
    // Pre-compute lowercased searchable text (with normalized digits)
    var parts = [
      c.firstName, c.lastName, c.role,
      c.landline, c.internal, c.phone,
      c.telegram, c.rubika, c.eitaa, c.bale, c.whatsapp,
      c.email, c.description,
    ];
    var s = parts.filter(Boolean).join(' ').toLowerCase();
    return normDigits(s);
  }
  function ensureIndex() {
    ALL_CONTACTS.forEach(function (c) { if (!c.__hs) c.__hs = buildHaystack(c); });
  }

  // ---------- dept chips ----------
  function renderDeptChips() {
    var counts = { __all: 0 };
    ALL_CONTACTS.forEach(function (c) {
      counts.__all++;
      var d = c.department || '__none';
      counts[d] = (counts[d] || 0) + 1;
    });
    var deps = CONFIG.departments || [];
    $chips.innerHTML = '';

    function chip(id, label, icon, count) {
      var b = el('button', {
        class: 'chip' + (CURRENT_DEPT === id ? ' is-active' : ''),
        onclick: function () { CURRENT_DEPT = id; renderDeptChips(); applyFilter(); }
      }, [
        icon ? (icon + ' ') : null,
        label,
        el('span', { class: 'chip-count' }, [toFa(count)])
      ]);
      $chips.appendChild(b);
    }

    chip('', 'همه', '📇', counts.__all || 0);
    deps.forEach(function (d) {
      var c = counts[d.id] || 0;
      if (!c && CURRENT_DEPT !== d.id) return; // hide empty depts
      chip(d.id, d.label, d.icon, c);
    });
  }

  // ---------- filter + render ----------
  function applyFilter() {
    ensureIndex();
    var q = CURRENT_Q.trim().toLowerCase();
    var nq = normDigits(q);
    var dept = CURRENT_DEPT;
    FILTERED = ALL_CONTACTS.filter(function (c) {
      if (dept && c.department !== dept) return false;
      if (nq && c.__hs.indexOf(nq) === -1) return false;
      return true;
    });
    RENDERED = 0;
    $grid.innerHTML = '';
    if (ALL_CONTACTS.length === 0) {
      $empty.hidden = false; $noRes.hidden = true; $meta.textContent = '';
    } else if (FILTERED.length === 0) {
      $empty.hidden = true; $noRes.hidden = false;
      $meta.textContent = 'هیچ نتیجه‌ای پیدا نشد';
    } else {
      $empty.hidden = true; $noRes.hidden = true;
      renderChunk(INITIAL_CHUNK);
      updateMeta();
    }
  }

  function updateMeta() {
    var total = ALL_CONTACTS.length, filt = FILTERED.length;
    var txt = 'نمایش ' + toFa(Math.min(RENDERED, filt)) + ' از ' + toFa(filt);
    if (filt !== total) txt += ' (از مجموع ' + toFa(total) + ')';
    $meta.textContent = txt;
  }

  function renderChunk(n) {
    var end = Math.min(RENDERED + n, FILTERED.length);
    for (var i = RENDERED; i < end; i++) {
      $grid.appendChild(contactCard(FILTERED[i]));
    }
    RENDERED = end;
    updateMeta();
  }

  // ---------- cards ----------
  function initials(c) {
    var fn = (c.firstName || '').trim();
    var ln = (c.lastName || '').trim();
    if (fn && ln) return (fn[0] + ln[0]);
    if (fn) return fn[0];
    if (ln) return ln[0];
    return '?';
  }
  function fullName(c) {
    return ((c.firstName || '') + ' ' + (c.lastName || '')).trim() || '—';
  }
  function deptLabel(id) {
    var d = (CONFIG.departments || []).find(function (x) { return x.id === id; });
    return d ? (d.icon + ' ' + d.label) : '';
  }
  function contactCard(c) {
    var card = el('div', { class: 'contact-card', onclick: function () { openDetail(c); } });
    var avatar = el('div', { class: 'avatar' });
    if (c.photo) avatar.appendChild(el('img', { src: c.photo, alt: '', loading: 'lazy' }));
    else avatar.appendChild(el('div', { class: 'avatar-fallback' }, [initials(c)]));
    card.appendChild(avatar);

    var main = el('div', { class: 'contact-main' });
    main.appendChild(el('div', { class: 'contact-name' }, [fullName(c)]));
    if (c.role) main.appendChild(el('div', { class: 'contact-role' }, [c.role]));

    var chips = el('div', { class: 'contact-chips' });
    if (c.landline || c.phone) chips.appendChild(el('span', { class: 'contact-chip has-phone' }, ['📞 تماس']));
    if (c.telegram) chips.appendChild(el('span', { class: 'contact-chip has-tg' }, ['✈️ تلگرام']));
    if (c.rubika) chips.appendChild(el('span', { class: 'contact-chip has-rb' }, ['🇮🇷 روبیکا']));
    if (c.eitaa) chips.appendChild(el('span', { class: 'contact-chip' }, ['⛰️ ایتا']));
    if (c.bale) chips.appendChild(el('span', { class: 'contact-chip' }, ['🅱 بله']));
    if (c.email) chips.appendChild(el('span', { class: 'contact-chip' }, ['📧 ایمیل']));
    if (c.department) {
      var dep = (CONFIG.departments || []).find(function (x) { return x.id === c.department; });
      if (dep) chips.appendChild(el('span', { class: 'contact-chip', style: 'color:' + dep.color + '; border-color: color-mix(in srgb, ' + dep.color + ' 45%, transparent)' }, [dep.icon + ' ' + dep.label]));
    }
    if (chips.childNodes.length) main.appendChild(chips);
    card.appendChild(main);
    return card;
  }

  // ---------- detail modal ----------
  function openDetail(c) {
    var body = $('detailBody');
    body.innerHTML = '';

    var hero = el('div', { class: 'detail-hero' });
    var av = el('div', { class: 'avatar' });
    if (c.photo) av.appendChild(el('img', { src: c.photo, alt: '' }));
    else av.appendChild(el('div', { class: 'avatar-fallback' }, [initials(c)]));
    hero.appendChild(av);
    var hInfo = el('div', {}, [
      el('h3', {}, [fullName(c)]),
      c.role ? el('p', { class: 'detail-role' }, [c.role]) : null,
    ]);
    if (c.department) {
      var d = (CONFIG.departments || []).find(function (x) { return x.id === c.department; });
      if (d) hInfo.appendChild(el('span', { class: 'detail-dept-chip', style: 'color:' + d.color + '; border-color: color-mix(in srgb, ' + d.color + ' 40%, transparent)' }, [d.icon + ' ' + d.label]));
    }
    hero.appendChild(hInfo);
    body.appendChild(hero);

    // rows
    body.appendChild(el('div', { class: 'detail-section-title' }, ['راه‌های تماس']));
    var rows = el('div', { class: 'detail-rows' });

    function row(icon, label, value, type, opts) {
      if (!value) return;
      opts = opts || {};
      var valNode;
      if (type === 'tel') {
        valNode = el('a', { href: 'tel:' + value, class: 'row-value' }, [value]);
      } else if (type === 'mail') {
        valNode = el('a', { href: 'mailto:' + value, class: 'row-value' }, [value]);
      } else if (type === 'link') {
        valNode = el('a', { href: opts.href, class: 'row-value', target: '_blank', rel: 'noopener' }, [value]);
      } else {
        valNode = el('span', { class: 'row-value' }, [value]);
      }
      var copyBtn = el('button', {
        class: 'copy-btn', title: 'کپی',
        onclick: function (ev) {
          ev.stopPropagation();
          try {
            navigator.clipboard.writeText(opts.copyText || value).then(function () {
              copyBtn.classList.add('is-ok');
              copyBtn.textContent = '✓';
              setTimeout(function () {
                copyBtn.classList.remove('is-ok');
                copyBtn.textContent = '⧉';
              }, 1200);
            });
          } catch (_) {}
        }
      }, ['⧉']);

      var r = el('div', { class: 'detail-row' + (opts.rtl ? ' is-rtl' : '') }, [
        el('span', { class: 'row-icon' }, [icon]),
        el('span', { class: 'row-label' }, [label]),
        valNode,
        copyBtn,
      ]);
      rows.appendChild(r);
    }

    row('📞', 'ثابت',   c.landline, 'tel');
    row('#',  'داخلی',  c.internal, 'text');
    row('📱', 'شخصی',   c.phone,    'tel');
    if (c.telegram) row('✈️', 'تلگرام', '@' + c.telegram, 'link', { href: 'https://t.me/' + c.telegram, copyText: c.telegram });
    if (c.rubika)   row('🇮🇷', 'روبیکا',  '@' + c.rubika,   'link', { href: 'https://rubika.ir/' + c.rubika, copyText: c.rubika });
    if (c.eitaa)    row('⛰️', 'ایتا',    '@' + c.eitaa,    'link', { href: 'https://eitaa.com/' + c.eitaa, copyText: c.eitaa });
    if (c.bale)     row('🅱', 'بله',     '@' + c.bale,     'link', { href: 'https://ble.ir/' + c.bale, copyText: c.bale });
    if (c.whatsapp) row('🟢', 'واتس‌اپ', c.whatsapp,       'link', { href: 'https://wa.me/' + c.whatsapp.replace(/\D/g, '') });
    row('📧', 'ایمیل', c.email, 'mail');

    body.appendChild(rows);

    if (c.description) {
      body.appendChild(el('div', { class: 'detail-section-title' }, ['توضیحات']));
      body.appendChild(el('div', { class: 'detail-desc' }, [c.description]));
    }

    openModal('detailModal');
  }

  // ---------- suggest form ----------
  function wireSuggestForm() {
    // populate department select
    var sel = $('suggestDept');
    if (sel) {
      (CONFIG.departments || []).forEach(function (d) {
        var o = document.createElement('option');
        o.value = d.id; o.textContent = d.icon + ' ' + d.label;
        sel.appendChild(o);
      });
    }
    var form = $('suggestForm');
    form.addEventListener('submit', function (ev) {
      ev.preventDefault();
      var btn = form.querySelector('button[type="submit"]');
      btn.disabled = true; btn.textContent = 'در حال ارسال…';
      var fd = new FormData(form);
      api('suggest', { method: 'POST', body: fd }).then(function (j) {
        closeModal('suggestModal');
        form.reset();
        $('successMessage').textContent = j.message || 'پیشنهاد شما ثبت شد.';
        openModal('successModal');
      }).catch(function (err) {
        alert(err.message || 'خطا در ارسال');
      }).finally(function () {
        btn.disabled = false; btn.textContent = '📤 ارسال پیشنهاد';
      });
    });
  }

  // ---------- init ----------
  document.addEventListener('DOMContentLoaded', function () {
    $grid = $('contactGrid');
    $meta = $('listMeta');
    $empty = $('emptyState');
    $noRes = $('noResultState');
    $sentinel = $('chunkSentinel');
    $chips = $('deptChips');
    $search = $('searchInput');
    $searchClear = $('searchClear');

    // search
    var searchTimer;
    $search.addEventListener('input', function () {
      $searchClear.hidden = ($search.value === '');
      clearTimeout(searchTimer);
      searchTimer = setTimeout(function () {
        CURRENT_Q = $search.value;
        applyFilter();
      }, 120);
    });
    $searchClear.addEventListener('click', function () {
      $search.value = '';
      $searchClear.hidden = true;
      CURRENT_Q = '';
      applyFilter();
      $search.focus();
    });

    // suggest button
    $('btnSuggest').addEventListener('click', function () { openModal('suggestModal'); });

    // IntersectionObserver for chunked render
    if ('IntersectionObserver' in window) {
      var io = new IntersectionObserver(function (entries) {
        entries.forEach(function (e) {
          if (e.isIntersecting && RENDERED < FILTERED.length) {
            renderChunk(CHUNK_SIZE);
          }
        });
      }, { rootMargin: '400px' });
      io.observe($sentinel);
    } else {
      // fallback: scroll event
      window.addEventListener('scroll', function () {
        if (RENDERED >= FILTERED.length) return;
        var rect = $sentinel.getBoundingClientRect();
        if (rect.top < window.innerHeight + 400) renderChunk(CHUNK_SIZE);
      });
    }

    loadConfig()
      .then(function () { wireSuggestForm(); })
      .then(loadContacts)
      .then(function () {
        renderDeptChips();
        applyFilter();
      })
      .catch(function (err) { console.error(err); alert('خطا در بارگذاری: ' + err.message); });
  });
})();
