/*!
 * Copyright (c) 2021 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>
 *   Zhou Fang <zhou.fang@eclipse-foundation.org>
 *
 * SPDX-License-Identifier: EPL-2.0
 */

import $ from 'jquery';
import 'jquery-match-height';
import getMembers from '../api/eclipsefdn.members';
import { displayErrMsg, validateURL } from '../utils/utils';
import template from './templates/explore-members/member.mustache';
import templateOnlyLogos from './templates/wg-members/wg-member-only-logos.mustache';
import templateLogoTitleWithLevels from './templates/wg-members/wg-member-logo-title-with-levels.mustache';
import templateLoading from './templates/loading-icon.mustache';
import { SD_IMG, AP_IMG, AS_IMG } from './eclipsefdn.constants.js';

const SD_NAME = 'Strategic Members';
const AP_NAME = 'Contributing Members';
const AS_NAME = 'Associate Members';

const EclipseFdnMembersList = (async () => {
  const element = document.querySelector('.eclipsefdn-members-list');
  if (!element) {
    return;
  }
  element.innerHTML = templateLoading();

  let membersListArray = [
    { level: SD_NAME, members: [] },
    { level: AP_NAME, members: [] },
    { level: AS_NAME, members: [] },
  ];
  let url = 'https://membership.eclipse.org/api/organizations?pagesize=100';

  const isRandom = element.getAttribute('data-ml-sort') === 'random';
  const level = element.getAttribute('data-ml-level');
  const wg = element.getAttribute('data-ml-wg');
  const linkMemberWebsite = element.getAttribute('data-ml-link-member-website') === 'true' ? true : false;

  if (level) {
    level.split(' ').forEach((item) => (url = `${url}&levels=${item}`));
  }

  if (wg) {
    url = `${url}&working_group=${wg}`;
    // When we show members belong to a wg, no need to show EF levels
    membersListArray = [{ level: '', members: [] }];
  }

  let membersData = await getMembers(url, [], (err) => displayErrMsg(element, err));

  const addMembersWithoutDuplicates = (levelName, memberData) => {
    // When we show members belong to a wg, only 1 item exits in membersListArray
    const currentLevelMembers = wg ? membersListArray[0] : membersListArray.find((item) => item.level === levelName);
    const isDuplicatedMember = currentLevelMembers.members.find(
      (item) => item.organization_id === memberData.organization_id
    );
    !isDuplicatedMember && currentLevelMembers.members.push(memberData);
  };

  membersData = membersData.map((member) => {
    if (!member.name) {
      // will not add members without a title/name into membersListArray to display
      return member;
    }
    if (member.levels.find((item) => item.level?.toUpperCase() === 'SD')) {
      if (!member.logos.web) {
        member.logos.web = SD_IMG;
      }
      addMembersWithoutDuplicates(SD_NAME, member);
      return member;
    }

    if (member.levels.find((item) => item.level?.toUpperCase() === 'AP' || item.level?.toUpperCase() === 'OHAP')) {
      if (!member.logos.web) {
        member.logos.web = AP_IMG;
      }
      addMembersWithoutDuplicates(AP_NAME, member);
      return member;
    }

    if (member.levels.find((item) => item.level?.toUpperCase() === 'AS')) {
      if (!member.logos.web) {
        member.logos.web = AS_IMG;
      }
      addMembersWithoutDuplicates(AS_NAME, member);
      return member;
    }
    return member;
  });

  if (isRandom) {
    // Sort randomly
    membersListArray.forEach((eachLevel) => {
      let tempArray = eachLevel.members.map((item) => item);
      const randomItems = [];
      eachLevel.members.forEach(() => {
        const randomIndex = Math.floor(Math.random() * tempArray.length);
        randomItems.push(tempArray[randomIndex]);
        tempArray.splice(randomIndex, 1);
      });
      eachLevel.members = randomItems;
    });
  } else {
    // Sort alphabetically by default
    membersListArray.forEach((eachLevel) => {
      eachLevel.members.sort((a, b) => {
        const preName = a.name.toUpperCase();
        const nextName = b.name.toUpperCase();
        if (preName < nextName) {
          return -1;
        }
        if (preName > nextName) {
          return 1;
        }
        return 0;
      });
    });
  }

  if (level) {
    membersListArray = membersListArray.filter((list) => list.members.length !== 0);
  }

  const urlLinkToLogo = function () {
    if (linkMemberWebsite && validateURL(this.website)) {
      return this.website;
    }
    return `https://www.eclipse.org/membership/showMember.php?member_id=${this.organization_id}`;
  };

  const displayMembersByLevels = async (theTemplate) => {
    const allWGData = await (await fetch('https://membership.eclipse.org/api/working_groups')).json();
    let currentWGLevels = allWGData.find((item) => item.alias === wg).levels;
    // defaultLevel is for members without a valid level. So far, only occurs on IoT.
    const defaultLevel = element.getAttribute('data-ml-default-level');
    const specifiedLevel = element.getAttribute('data-ml-wg-level');
    if (specifiedLevel) {
      currentWGLevels = currentWGLevels.filter((level) =>
        specifiedLevel.toLowerCase().includes(level.relation.toLowerCase())
      );
    }
    element.innerHTML = '';
    if (defaultLevel) {
      currentWGLevels.push({ relation: 'default', description: defaultLevel, members: [] });
    }

    // categorize members into corresponding levels
    currentWGLevels.forEach((level) => {
      level['members'] = [];
      membersListArray[0].members.forEach((member) => {
        const memberLevel = member.wgpas.find((wgpa) => wgpa.working_group === wg)?.level;
        if (memberLevel === level.relation) {
          level.members.push(member);
        }
        if (level.relation === 'default' && memberLevel === null) {
          level.members.push(member);
        }
      });

      if (level.members.length === 0) {
        return;
      }

      const showLevelUnderLogo = () => {
        if (
          !element.getAttribute('data-ml-level-under-logo') ||
          element.getAttribute('data-ml-level-under-logo') === 'false'
        ) {
          return false;
        }
        return level.description.replaceAll(' Member', '');
      };

      element.innerHTML =
        element.innerHTML +
        theTemplate({ item: level.members, levelDescription: level.description, urlLinkToLogo, showLevelUnderLogo });
    });
  };

  switch (element.getAttribute('data-ml-template')) {
    case 'only-logos':
      element.innerHTML = templateOnlyLogos({
        item: membersListArray[0].members,
        urlLinkToLogo,
      });
      return;

    case 'logo-title-with-levels':
      await displayMembersByLevels(templateLogoTitleWithLevels);
      $.fn.matchHeight._applyDataApi();
      return;
    case 'logo-with-levels':
      displayMembersByLevels(templateOnlyLogos);
      return;
    default:
      break;
  }

  element.innerHTML = template({
    sections: membersListArray,
    hostname: window.location.hostname.includes('staging.eclipse.org')
      ? 'https://staging.eclipse.org'
      : 'https://www.eclipse.org',
  });
  $.fn.matchHeight._applyDataApi();
})();

export default EclipseFdnMembersList;
