/*!
 * Copyright (c) 2021, 2024 Eclipse Foundation, Inc.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * Contributors:
 *  Christopher Guindon <chris.guindon@eclipse-foundation.org>
 *  Olivier Goulet <olivier.goulet@eclipse-foundation.org>
 *
 * SPDX-License-Identifier: EPL-2.0
 */

import jQuery from 'jquery';
import template from './templates/tpl-news-list-item.mustache';
import Mustache from 'mustache';
import { format as dateFormat } from 'date-fns';
import ellipsize from 'ellipsize';
import { fetchXML, resolveURL } from '../api/utils';

export const processXML = (xml) => {
  const processItem = (el, value) => {
    if (!el.querySelector(value.selector)) {
      return '';
    }
    let content = el.querySelector(value.selector).textContent;
    if (
      value.attribute &&
      el.querySelector(value.selector).getAttribute(value.attribute)
    ) {
      content = el.querySelector(value.selector).getAttribute(value.attribute);
    }

    content = filterHTML(content);

    if (value.maxLenth) {
      content = ellipsize(content, value.maxLenth, {
        char: ['.'],
        truncate: false,
      });
    }
    return content;
  }

  let items = xml.querySelectorAll('item');
  if (items.length === 0) {
    items = xml.querySelectorAll('entry');
  }

  const posts = [];
  items.forEach((el) => {
    const item = {
      title: '',
      link: '',
      summary: '',
      date: '',
      id: '',
      author: '',
      formatDate: function () {
        return function (format) {
          format = format.trim();
          // Default format
          if (!format) {
            format = "EEEE, MMMM d, yyyy - hh:MM";
          }
          return dateFormat(item.date, format);
        };
      },
    };

    const childrens = [
      { selector: 'title' },
      { selector: 'pubDate', key: 'date' },
      { selector: 'published', key: 'date' },
      { selector: 'author' },
      { selector: 'name', key: 'author' },
      { selector: 'id' },
      { selector: 'guid', key: 'id' },
      { selector: 'summary', maxLenth: 400 },
      { selector: 'description', key: 'summary', maxLenth: 400 },
      { selector: 'link', attribute: 'href' },
    ];

    childrens.forEach((value) => {
      if (!el.querySelector(value.selector)) {
        return;
      }
      const key = !value.key ? value.selector : value.key;
      item[key] = processItem(el, value);
    });

    // Normalize dates
    if (item.date) {
      item.date = new Date(item.date);
    }

    posts.push(item);
  });
  return posts;
};

(function ($, document) {
  $('.solstice-rss-blog-list').each(function (_index, element) {
    // @todo create pagination
    const options = {
      limit: 9999,
      urls: '',
      templateId: '',
      ...$(element).data(),
    };

    const urls = options.urls
      .split(',')
      .map(resolveURL);

    const promises = [];
    urls.forEach((element) => promises.push(fetchXML(element)));

    let results = [];
    Promise.allSettled(promises).then(function (responses) {
      responses.forEach((el) => {
        // skip rejected promises
        if (el.status === 'fulfilled') {
          const posts = processXML(el.value);
          if (posts.length > 0) {
            results = results.concat(posts);
          }
        }
      });

      // remove duplicate on link prop
      results = [...new Map(results.map((v) => [v.link, v])).values()];

      // sort by date
      results.sort((a, b) => b.date - a.date);

      // limit results
      results = results.slice(0, options.limit);

      // function to recognize external site
      const shouldShowExternalIcon = function () {
        return document.querySelector('.show-external-icon') && !this.link.includes(window.location.hostname)
      };

      const data = {
        items: results,
        shouldShowExternalIcon,
        shouldShowRssOrigin: document.querySelector('.show-rss-origin'),
      };

      // Render component
      let html = '';
      if (options.templateId !== '' && document.getElementById(options.templateId)) {
        const theme = document.getElementById(options.templateId).innerHTML;
        html = Mustache.render(theme, data);
      } else {
        html = template(data);
      }
      element.innerHTML = html;
    });
  });
})(jQuery, document);

export const filterHTML = (html) => {
  const txt = document.createElement('div');
  txt.innerHTML = html;
  return txt.textContent;
};
