(function () {
  function esc(s) {
    const d = document.createElement('div');
    d.textContent = s || '';
    return d.innerHTML;
  }

  function pageMatches(page, filters) {
    const q = (filters.search || '').trim().toLowerCase();
    const terms = filters.terms || [];
    const siteId = filters.siteId ? String(filters.siteId) : '';
    const minWords = parseInt(filters.minWords, 10) || 0;
    const minHype = parseInt(filters.minHype, 10) || 0;

    if (siteId && String(page.site_id) !== siteId) return false;
    if ((page.word_count || 0) < minWords) return false;
    if ((page.hype_score || 0) < minHype) return false;
    if (filters.changedOnly && !page.recently_changed) return false;

    const hay = [
      page.site_name,
      page.title,
      page.url,
      page.excerpt,
      page.content_read,
      page.meta_description,
      (page.headings || []).join(' '),
      (page.signals || []).join(' '),
      (page.links_sample || []).map(function (l) {
        return (l.label || '') + ' ' + (l.href || '');
      }).join(' '),
    ]
      .join(' ')
      .toLowerCase();

    if (q && hay.indexOf(q) < 0) return false;

    for (let i = 0; i < terms.length; i++) {
      if (hay.indexOf(String(terms[i]).toLowerCase()) < 0) return false;
    }
    return true;
  }

  function sortPages(pages, col, dir) {
    const mul = dir === 'asc' ? 1 : -1;
    const copy = pages.slice();
    copy.sort(function (a, b) {
      let va;
      let vb;
      switch (col) {
        case 'site_name':
          va = (a.site_name || '').toLowerCase();
          vb = (b.site_name || '').toLowerCase();
          return va < vb ? -mul : va > vb ? mul : 0;
        case 'title':
          va = (a.title || a.url || '').toLowerCase();
          vb = (b.title || b.url || '').toLowerCase();
          return va < vb ? -mul : va > vb ? mul : 0;
        case 'word_count':
          return ((a.word_count || 0) - (b.word_count || 0)) * mul;
        case 'links_count':
          return ((a.links_count || 0) - (b.links_count || 0)) * mul;
        case 'crawled_at':
          va = a.crawled_at || '';
          vb = b.crawled_at || '';
          return va < vb ? -mul : va > vb ? mul : 0;
        case 'hype_score':
        default:
          return ((a.hype_score || 0) - (b.hype_score || 0)) * mul;
      }
    });
    return copy;
  }

  function filterPages(pages, filters) {
    if (!pages || !pages.length) return [];
    return pages.filter(function (p) {
      return pageMatches(p, filters);
    });
  }

  function highlightHtml(text, queries) {
    const raw = text || '';
    if (!raw) return '<span class="muted">Geen tekst</span>';
    let html = esc(raw);
    const list = [];
    if (queries && queries.length) {
      queries.forEach(function (q) {
        if (q && String(q).trim()) list.push(String(q).trim());
      });
    }
    list.sort(function (a, b) {
      return b.length - a.length;
    });
    list.forEach(function (term) {
      if (term.length < 2) return;
      const re = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + ')', 'gi');
      html = html.replace(re, '<mark>$1</mark>');
    });
    return html;
  }

  function exportCsv(pages) {
    const rows = [['site', 'title', 'url', 'words', 'hype', 'changed', 'crawled_at', 'excerpt']];
    pages.forEach(function (p) {
      rows.push([
        p.site_name || '',
        (p.title || '').replace(/"/g, '""'),
        p.url || '',
        String(p.word_count || 0),
        String(p.hype_score || 0),
        p.recently_changed ? 'yes' : 'no',
        p.crawled_at || '',
        (p.excerpt || '').replace(/"/g, '""').slice(0, 500),
      ]);
    });
    return rows
      .map(function (r) {
        return r.map(function (c) {
          return '"' + c + '"';
        }).join(',');
      })
      .join('\n');
  }

  function downloadCsv(pages, filename) {
    const csv = exportCsv(pages);
    const blob = new Blob(['\ufeff' + csv], { type: 'text/csv;charset=utf-8' });
    const a = document.createElement('a');
    a.href = URL.createObjectURL(blob);
    a.download = filename || 'parse-analyse.csv';
    a.click();
    URL.revokeObjectURL(a.href);
  }

  window.ParseIntel = {
    filterPages: filterPages,
    sortPages: sortPages,
    highlightHtml: highlightHtml,
    exportCsv: exportCsv,
    downloadCsv: downloadCsv,
  };
})();
