(() => {
  const WESTGATE_LATEST_CONFIG = [
    {
      key: 'announcement',
      cid: 1,
      emptyTitle: 'No announcements yet',
    },
    {
      key: 'patch',
      cid: 10,
      emptyTitle: 'No patch notes yet',
    },
  ];

  const getRelativePath = () => {
    return window.config && window.config.relative_path ? window.config.relative_path : '';
  };

  const unwrap = (payload) => {
    return payload && payload.response ? payload.response : payload;
  };

  const textFromHtml = (html) => {
    const el = document.createElement('div');
    el.innerHTML = html || '';

    const firstParagraph = Array.from(el.querySelectorAll('p'))
      .map((p) => (p.textContent || '').replace(/\s+/g, ' ').trim())
      .find(Boolean);

    return (firstParagraph || el.textContent || '').replace(/\s+/g, ' ').trim();
  };

  const truncate = (text, limit = 240) => {
    if (!text || text.length <= limit) {
      return text || '';
    }

    return `${text.slice(0, limit).replace(/\s+\S*$/, '')}...`;
  };

  const formatDate = (value) => {
    const timestamp = Number(value);
    if (!timestamp) {
      return '';
    }

    const date = new Date(timestamp);
    if (Number.isNaN(date.getTime())) {
      return '';
    }

    return new Intl.DateTimeFormat(undefined, {
      month: 'short',
      day: 'numeric',
    }).format(date);
  };

  const getJSON = async (url) => {
    const response = await fetch(url, {
      credentials: 'same-origin',
      headers: {
        accept: 'application/json',
      },
    });

    if (!response.ok) {
      throw new Error(`Request failed: ${response.status}`);
    }

    return unwrap(await response.json());
  };
  
  const getTopicExcerpt = async (topic) => {
  const relativePath = getRelativePath();
  const topicPath = topic.slug || topic.tid;

  try {
    const topicData = await getJSON(`${relativePath}/api/topic/${topicPath}?page=1&sort=oldest_to_newest`);
    const firstPost = topicData.posts && topicData.posts[0];
    const firstPostText = textFromHtml(firstPost && firstPost.content);

    if (firstPostText) {
      return truncate(firstPostText);
    }
    } catch (error) {
      console.warn('[Westgate latest widget original post excerpt]', error);
    }

    if (topic.mainPost && topic.mainPost.content) {
      const mainPostText = textFromHtml(topic.mainPost.content);
      if (mainPostText) {
        return truncate(mainPostText);
      }
    }

    if (topic.teaser && topic.teaser.content) {
      return truncate(textFromHtml(topic.teaser.content));
    }

    return '';
  };

  const getLatestTopic = async (cid) => {
    const relativePath = getRelativePath();
    const category = await getJSON(`${relativePath}/api/v3/categories/${cid}/topics?sort=recently_created&after=0`);
    const topic = category.topics && category.topics[0];

    if (!topic) {
      return null;
    }

    let excerpt = '';

    try {
      excerpt = await getTopicExcerpt(topic);
    } catch (error) {
      console.warn('[Westgate latest widget excerpt]', error);
    }

    return {
      title: topic.titleRaw || topic.title || 'Untitled',
      url: `${relativePath}/topic/${topic.slug || topic.tid}`,
      author: topic.user && (topic.user.displayname || topic.user.username),
      date: formatDate(topic.timestamp || topic.lastposttime),
      excerpt,
    };
  };

  const renderCard = async (root, source) => {
    const card = root.querySelector(`[data-card="${source.key}"]`);
    if (!card) {
      return;
    }

    const title = card.querySelector('.wg-latest-title');
    const meta = card.querySelector('.wg-latest-meta');
    const excerpt = card.querySelector('.wg-latest-excerpt');

    card.classList.add('is-loading');
    card.classList.remove('is-empty');
    title.textContent = 'Loading...';
    title.removeAttribute('href');
    meta.textContent = '';
    excerpt.textContent = '';

    try {
      const topic = await getLatestTopic(source.cid);

      if (!topic) {
        card.classList.remove('is-loading');
        card.classList.add('is-empty');
        title.textContent = source.emptyTitle;
        return;
      }

      title.textContent = topic.title;
      title.href = topic.url;
      meta.textContent = [topic.author, topic.date].filter(Boolean).join(' · ');
      excerpt.textContent = topic.excerpt || '';
      card.classList.remove('is-loading', 'is-empty');
    } catch (error) {
      console.warn('[Westgate latest widget]', error);
      card.classList.remove('is-loading');
      card.classList.add('is-empty');
      title.textContent = source.emptyTitle;
      meta.textContent = 'Unable to load right now';
    }
  };

  const renderLatestStrip = () => {
    const root = document.querySelector('[data-westgate-latest]');

    if (!root || root.dataset.loaded === '1') {
      return;
    }

    root.dataset.loaded = '1';
    WESTGATE_LATEST_CONFIG.forEach((source) => renderCard(root, source));
  };

  document.addEventListener('DOMContentLoaded', renderLatestStrip);
  window.addEventListener('load', renderLatestStrip);

  if (window.jQuery) {
    window.jQuery(window).on('action:ajaxify.end', renderLatestStrip);
  }

  renderLatestStrip();
})();
