<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title id="pageTitle">Vance Algeria — Media & Press</title>
  <meta name="description" id="metaDesc" content="Official press and media coverage for Vance Algeria. Latest news, announcements and articles." />
  <meta property="og:title" id="ogTitle" content="Vance Algeria — Media & Press" />
  <meta property="og:description" id="ogDesc" content="Official press and media coverage for Vance Algeria." />
  <meta property="og:image" id="ogImage" content="" />
  <meta property="og:url" id="ogUrl" content="https://media.vancealgeria.com/" />
  <meta property="og:type" id="ogType" content="website" />
  <meta property="og:site_name" content="Vance Algeria Media" />
  <meta name="author" id="metaAuthor" content="Vance Algeria Media" />
  <meta name="news_keywords" id="newsKeywords" content="" />
  <link rel="canonical" id="canonical" href="https://media.vancealgeria.com/" />
  <link rel="stylesheet" href="/assets/style.css" />
  <link rel="icon" href="/favicon.ico" sizes="any">
  <link rel="icon" href="/favicon-32x32.png" type="image/png" sizes="32x32">
  <link rel="icon" href="/favicon-16x16.png" type="image/png" sizes="16x16">
  <link rel="apple-touch-icon" href="/favicon-180x180.png">
  <link rel="sitemap" type="application/xml" href="/sitemap.xml" />
  <script type="application/ld+json" id="ldJson">{"@context":"https://schema.org","@type":"WebSite","name":"Vance Algeria Media","url":"https://media.vancealgeria.com"}</script>
</head>
<body>

  <header class="site-header">
    <div class="header-inner">
      <a href="/" class="site-logo">
        <span class="logo-eyebrow">Official Press</span>
        <span class="logo-name">Vance <span>Algeria</span></span>
      </a>
      <div class="header-date" id="headerDate"></div>
    </div>
  </header>

  <!-- Homepage view -->
  <div id="homeView">
    <main class="container home-main" style="padding-bottom:1rem;">
      <div class="section-rule">
        <h2>Latest Coverage</h2>
      </div>

      <div class="date-filter-bar">
        <div class="filter-left">
          <label for="dateFilter" class="date-filter-label">Filter by date</label>
          <div class="date-filter-controls">
            <span class="date-filter-icon">📅</span>
            <input type="date" id="dateFilter" class="date-filter-input" />
            <button class="date-filter-clear" id="dateClearBtn" onclick="clearDateFilter()" style="display:none;" title="Clear filter">✕ Clear</button>
          </div>
        </div>
        <div class="filter-right">
          <label for="searchFilter" class="date-filter-label">Search articles</label>
          <div class="search-filter-controls">
            <span class="date-filter-icon">🔍</span>
            <input type="search" id="searchFilter" class="date-filter-input search-filter-input" placeholder="Search title or body…" autocomplete="off" />
            <button class="date-filter-clear" id="searchClearBtn" onclick="clearSearchFilter()" style="display:none;" title="Clear search">✕ Clear</button>
          </div>
        </div>
        <div class="date-filter-badge" id="dateFilterBadge" style="display:none;"></div>
      </div>
      <div id="articleList" class="article-list" aria-live="polite">
        <div class="skeleton skeleton-card"></div>
        <div class="skeleton skeleton-card"></div>
        <div class="skeleton skeleton-card"></div>
        <div class="skeleton skeleton-card"></div>
        <div class="skeleton skeleton-card"></div>
      </div>
      <div id="emptyState" style="display:none; text-align:center; padding:5rem 0; color:var(--ink-3); font-family:var(--font-ui);">
        <div style="font-size:2rem; margin-bottom:0.75rem;">📰</div>
        <p style="font-size:14px; letter-spacing:0.1em; text-transform:uppercase;">No articles published yet</p>
      </div>
      <div class="pagination" id="pagination" style="display:none;">
        <button class="page-btn" id="prevBtn" onclick="changePage(-1)" disabled>← Previous</button>
        <span class="page-info" id="pageInfo"></span>
        <button class="page-btn" id="nextBtn" onclick="changePage(1)">Next →</button>
      </div>
    </main>
  </div>

  <!-- Article view -->
  <div id="articleView" style="display:none;">
    <main class="container article-page">
      <div class="col">
        <a href="/" class="back-link"><span>←</span> All Articles</a>
        <div id="articleContent">
          <div class="skeleton" style="height:2rem; width:60%; margin-bottom:1rem;"></div>
          <div class="skeleton" style="height:3rem; width:90%; margin-bottom:0.5rem;"></div>
          <div class="skeleton" style="height:3rem; width:75%; margin-bottom:1.5rem;"></div>
          <div class="skeleton" style="height:300px; margin-bottom:2rem;"></div>
          <div class="skeleton" style="height:1rem; width:100%; margin-bottom:0.75rem;"></div>
          <div class="skeleton" style="height:1rem; width:95%; margin-bottom:0.75rem;"></div>
          <div class="skeleton" style="height:1rem; width:80%;"></div>
        </div>
      </div>
    </main>
  </div>

  <footer class="site-footer">
    <p>© <span id="year"></span> Vance Algeria · All Rights Reserved</p>
  </footer>

  <div class="toast" id="toast"></div>

  <script>
    const API = '';
    let currentPage = 1;
    let activeDate = null;
    let activeSearch = '';
    const LIMIT = 5;

    document.getElementById('year').textContent = new Date().getFullYear();
    document.getElementById('headerDate').textContent = new Date().toLocaleDateString('en-US', {
      weekday: 'long', year: 'numeric', month: 'long', day: 'numeric'
    });

    // Wire up date input
    document.getElementById('dateFilter').addEventListener('change', function() {
      activeDate = this.value || null;
      loadArticles(1);
    });

    // Wire up search input (debounced)
    let searchDebounce;
    document.getElementById('searchFilter').addEventListener('input', function() {
      clearTimeout(searchDebounce);
      searchDebounce = setTimeout(() => {
        activeSearch = this.value.trim();
        const clearBtn = document.getElementById('searchClearBtn');
        clearBtn.style.display = activeSearch ? 'inline-flex' : 'none';
        loadArticles(1);
      }, 350);
    });

    // Router — read pathname to decide which view to show
    const slug = location.pathname.replace(/^\//, '').replace(/\/$/, '');

    if (slug === '' || slug === 'index.html') {
      document.getElementById('homeView').style.display = '';
      document.getElementById('articleView').style.display = 'none';
      loadArticles(1);
    } else {
      document.getElementById('homeView').style.display = 'none';
      document.getElementById('articleView').style.display = '';
      loadArticle(slug);
    }

    // ── Homepage ──
    async function loadArticles(page) {
      currentPage = page;
      const list = document.getElementById('articleList');
      list.innerHTML = Array(5).fill('<div class="skeleton skeleton-card"></div>').join('');

      // Update filter badge UI
      const badge = document.getElementById('dateFilterBadge');
      const clearBtn = document.getElementById('dateClearBtn');
      if (activeDate) {
        const label = new Date(activeDate + 'T00:00:00').toLocaleDateString('en-US', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' });
        let badgeText = `Showing articles from ${label}`;
        if (activeSearch) badgeText += ` matching "${activeSearch}"`;
        badge.textContent = badgeText;
        badge.style.display = 'block';
        clearBtn.style.display = 'inline-flex';
      } else if (activeSearch) {
        badge.textContent = `Showing results matching "${activeSearch}"`;
        badge.style.display = 'block';
        clearBtn.style.display = 'none';
      } else {
        badge.style.display = 'none';
        clearBtn.style.display = 'none';
      }

      try {
        let url = `${API}/api/articles?page=${page}&limit=${LIMIT}`;
        if (activeDate) url += `&date=${encodeURIComponent(activeDate)}&tz=${new Date().getTimezoneOffset()}`;
        if (activeSearch) url += `&search=${encodeURIComponent(activeSearch)}`;
        const res = await fetch(url);
        const data = await res.json();
        list.innerHTML = '';
        if (!data.articles || data.articles.length === 0) {
          document.getElementById('emptyState').style.display = 'block';
          document.getElementById('emptyState').querySelector('p').textContent =
            (activeDate && activeSearch) ? 'No articles found for this date matching your search'
            : activeDate ? 'No articles published on this date'
            : activeSearch ? 'No articles found matching your search'
            : 'No articles published yet';
          document.getElementById('pagination').style.display = 'none';
          return;
        }
        document.getElementById('emptyState').style.display = 'none';
        data.articles.forEach((a, i) => list.appendChild(buildCard(a, i)));
        const pag = document.getElementById('pagination');
        pag.style.display = 'flex';
        document.getElementById('prevBtn').disabled = page <= 1;
        document.getElementById('nextBtn').disabled = page >= data.pages;
        document.getElementById('pageInfo').textContent = `Page ${page} of ${data.pages}`;
      } catch (e) {
        list.innerHTML = '<div style="padding:3rem; text-align:center; color:var(--ink-3); font-family:var(--font-ui); font-size:13px;">Failed to load articles. Please try again.</div>';
      }
    }

    function buildCard(a, i) {
      const el = document.createElement('a');
      el.className = 'article-card';
      el.href = `/${a.slug}`;
      el.style.animationDelay = `${i * 60}ms`;
      const date = formatDate(a.published_at);
      const excerpt = truncate(stripHtml(a.excerpt || a.body || ''), 200);
      el.innerHTML = `
        <div class="card-body">
          <div class="card-meta"><span class="card-date">${date}</span></div>
          <h2 class="card-title">${escHtml(a.title)}</h2>
          ${excerpt ? `<p class="card-excerpt">${escHtml(excerpt)}</p>` : ''}
        </div>
        ${a.image_url ? `<img class="card-image" src="${escHtml(a.image_url)}" alt="" loading="lazy" onerror="this.style.display='none'" />` : ''}
      `;
      return el;
    }

    function clearDateFilter() {
      activeDate = null;
      document.getElementById('dateFilter').value = '';
      loadArticles(1);
    }

    function clearSearchFilter() {
      activeSearch = '';
      document.getElementById('searchFilter').value = '';
      document.getElementById('searchClearBtn').style.display = 'none';
      loadArticles(1);
    }

    function changePage(dir) {
      loadArticles(currentPage + dir);
      window.scrollTo({ top: 0, behavior: 'smooth' });
    }

    // ── Article ──
    async function loadArticle(slug) {
      try {
        const res = await fetch(`${API}/api/articles/slug/${encodeURIComponent(slug)}`);
        if (!res.ok) throw new Error('Not found');
        const a = await res.json();
        renderArticle(a);
      } catch (e) {
        document.getElementById('articleContent').innerHTML =
          '<p style="color:var(--ink-3); font-family:var(--font-ui); font-size:14px;">Article not found or could not be loaded.</p>';
      }
    }

    function renderArticle(a) {
      const date = formatDate(a.published_at);
      document.getElementById('pageTitle').textContent = `${a.title} — Vance Algeria Media`;
      document.getElementById('metaDesc').content = stripHtml(a.body).substring(0, 160);
      document.getElementById('ogTitle').content = a.title;
      document.getElementById('ogDesc').content = stripHtml(a.body).substring(0, 200);
      document.getElementById('ogType').content = 'article';
      document.getElementById('ogUrl').content = `https://media.vancealgeria.com/${a.slug}`;
      if (a.image_url) document.getElementById('ogImage').content = a.image_url;
      document.getElementById('canonical').href = `https://media.vancealgeria.com/${a.slug}`;
      document.getElementById('metaAuthor').content = 'Vance Algeria Media';
      document.getElementById('newsKeywords').content = a.title;
      // JSON-LD NewsArticle structured data for Google News
      document.getElementById('ldJson').textContent = JSON.stringify({
        "@context": "https://schema.org",
        "@type": "NewsArticle",
        "headline": a.title,
        "image": a.image_url ? [a.image_url] : [],
        "datePublished": a.published_at,
        "dateModified": a.updated_at || a.published_at,
        "author": [{ "@type": "Organization", "name": "Vance Algeria Media", "url": "https://media.vancealgeria.com" }],
        "publisher": { "@type": "Organization", "name": "Vance Algeria Media", "url": "https://media.vancealgeria.com" },
        "mainEntityOfPage": { "@type": "WebPage", "@id": `https://media.vancealgeria.com/${a.slug}` },
        "description": stripHtml(a.body).substring(0, 200)
      });
      document.getElementById('articleContent').innerHTML = `
        <article>
          <header class="article-header">
            <div class="article-eyebrow">Press Coverage</div>
            <h1 class="article-title">${escHtml(a.title)}</h1>
            <div class="article-dateline">
              <span class="dateline-label">Original release:</span> ${formatDateTime(a.published_at)}
              ${isModified(a) ? `<br><span class="dateline-label dateline-modified">Last modified:</span> <span class="dateline-modified-date">${formatDateTime(a.updated_at)}</span>` : ''}
            </div>
          </header>
          ${a.image_url ? `<img class="article-image" src="${escHtml(a.image_url)}" alt="${escHtml(a.title)}" />` : ''}
          <hr class="article-divider" />
          <div class="article-body">${a.body}</div>
        </article>
      `;
      // Force all links in article body to open in new tab
      document.querySelectorAll('.article-body a[href]').forEach(a => {
        a.target = '_blank';
        a.rel = 'noopener noreferrer';
      });
    }

    // ── Helpers ──
    function formatDateTime(d) {
      if (!d) return '';
      // DB stores as "YYYY-MM-DD HH:MM:SS" (UTC) or ISO — normalise to ISO UTC
      const iso = d.includes('T') ? d : d.replace(' ', 'T') + 'Z';
      const dt = new Date(iso);
      return dt.toLocaleDateString(undefined, { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' })
        + ' at '
        + dt.toLocaleTimeString(undefined, { hour: 'numeric', minute: '2-digit', timeZoneName: 'short' });
    }

    function isModified(a) {
      if (!a.updated_at || !a.published_at) return false;
      const pub = new Date(a.published_at.includes('T') ? a.published_at : a.published_at.replace(' ', 'T') + 'Z');
      const upd = new Date(a.updated_at.includes('T') ? a.updated_at : a.updated_at.replace(' ', 'T') + 'Z');
      return upd > pub;
    }

    function formatDate(d) {
      if (!d) return '';
      // Parse as UTC (DB stores UTC), then display in the browser's local timezone
      // so the date shown matches what it was locally when the article was published
      const iso = d.includes('T') ? d : d.replace(' ', 'T') + 'Z';
      const dt = new Date(iso);
      return dt.toLocaleDateString('en-US', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' });
    }

    function truncate(text, max) {
      if (text.length <= max) return text;
      const cut = text.lastIndexOf(' ', max);
      return text.substring(0, cut > 0 ? cut : max) + '…';
    }

    function stripHtml(html) {
      let s = (html || '');
      // Step 1: Decode HTML entities so encoded tags become real tags
      s = s.replace(/&lt;/g,'<').replace(/&gt;/g,'>').replace(/&amp;/g,'&').replace(/&quot;/g,'"').replace(/&#39;/g,"'");
      // Step 2: Remove complete embed/iframe/script/style blocks including inner content
      s = s.replace(/<(iframe|script|style|object|embed|video|audio|noscript)[^>]*>[\s\S]*?<\/\1>/gi, ' ');
      // Step 3: If any of those tags are cut off mid-content (excerpt truncated), nuke from that tag onwards
      s = s.replace(/<(iframe|script|style|object|embed|video|audio|noscript)[^>]*>[\s\S]*/gi, '');
      // Step 4: Catch self-closing or unclosed opening tags of those elements
      s = s.replace(/<(iframe|embed|object|script|style)[^>]*\/?>/gi, ' ');
      // Step 5: Strip any trailing unclosed < tag (excerpt cut mid-tag e.g. <iframe src="...)
      s = s.replace(/<[^>]*$/, '');
      // Step 6: Space around block tags so words don't run together
      s = s.replace(/<\/?(p|div|li|h[1-6]|blockquote|pre|br|tr|td|th)(\s[^>]*)?\/?>/gi, ' ');
      // Step 7: Strip remaining tags iteratively — handles attributes that contain > characters
      let prev;
      do {
        prev = s;
        s = s.replace(/<[^>]*>/g, '');
        // Mop up leftover attribute fragments like style="text-align: center;"
        s = s.replace(/\s[a-z][a-z0-9-]*=["'][^"']*["']/gi, '');
      } while (s !== prev);
      // Step 8: Remove any stray angle brackets left from malformed markup
      s = s.replace(/[<>]/g, '');
      // Step 9: Replace &nbsp; with a regular space
      s = s.replace(/&nbsp;/g, ' ');
      // Step 10: Collapse whitespace
      return s.replace(/\s+/g, ' ').trim();
    }

    function escHtml(s) {
      return String(s).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;');
    }
  </script>
</body>
</html>
