// Each entry includes the following information in order:
// - ID
// - Codename
// - Color (for the label in the legend)
const kDataKeys = [
  [4, 'recommended', '#34A853'],
  [6, 'replies', '#DADCE0'],
  [5, 'questions', '#77909D'],
];
const kRoles = {
  1: 'bronze',
  2: 'silver',
  3: 'gold',
  4: 'platinum',
  5: 'diamond',
  10: 'community_manager',
  20: 'community_specialist',
  100: 'google_employee',
  30: 'alumnus',
};

export default class PerForumStatsSection {
  constructor(existingChartSection, profile, locale) {
    this.locale = locale;
    this.parseAndSetData(profile);
    this.buildDOM(existingChartSection);
    if (this.data.length) this.injectChart(this.data[0]?.id);
  }

  parseAndSetData(profile) {
    const forumUserInfos = profile?.[1]?.[7] ?? [];
    const forumTitles = profile?.[1]?.[8] ?? [];

    const forumUserInfoIDs = forumUserInfos.map(ui => ui[1]);
    const forumTitleIDs = forumTitles.map(t => t[1]);
    const intersectionForumIDs =
        forumUserInfoIDs.filter(id => forumTitleIDs.includes(id));

    this.data = [];
    for (const id of intersectionForumIDs) {
      const fui = forumUserInfos.find(ui => ui[1] === id)?.[2];
      const numMessages = kDataKeys.reduce((prevVal, key) => {
        if (!fui?.[key[0]]) return prevVal;
        return prevVal + fui[key[0]].reduce((prevVal, userActivity) => {
          return prevVal + (userActivity?.[3] ?? 0);
        }, /* initialValue = */ 0);
      }, /* initialValue = */ 0);
      this.data.push({
        id,
        forumTitle: forumTitles.find(t => t[1] === id)?.[2],
        forumUserInfo: fui,
        numMessages,
      });
    }
    this.data.sort((a, b) => {
      // First sort by number of messages
      if (b.numMessages > a.numMessages) return 1;
      if (b.numMessages < a.numMessages) return -1;
      // Then sort by name
      return a.forumTitle.localeCompare(
          b.forumTitle, 'en', {sensitivity: 'base'});
    });
  }

  buildDOM(existingChartSection) {
    let section = document.createElement('div');
    section.classList.add('scTailwindUser_profileUserprofilesection');

    let root = document.createElement('div');
    root.classList.add(
        'scTailwindSharedActivitychartroot',
        'TWPT-scTailwindSharedActivitychartroot');

    let title = document.createElement('h2');
    title.classList.add('scTailwindSharedActivitycharttitle');
    title.textContent = chrome.i18n.getMessage('inject_perforumstats_heading');

    let selector = this.createForumSelector();

    let chartEl = document.createElement('div');
    chartEl.classList.add('scTailwindSharedActivitychartchart');
    chartEl.setAttribute('data-twpt-per-forum-chart', '');

    root.append(title, selector, chartEl);
    section.append(root);
    existingChartSection.after(section);
  }

  getAplosData(forumId) {
    let aplosData = [];
    for (const [key, name, color] of kDataKeys) {
      let rawData = this.data.find(f => f.id === forumId)?.forumUserInfo?.[key];
      let data;
      if (!rawData)
        data = [];
      else
        data = rawData.map(m => JSON.stringify(Object.values(m)));
      aplosData.push({
        color,
        data,
        label: chrome.i18n.getMessage('inject_perforumstats_chart_' + name),
        name,
      });
    }
    return aplosData;
  }

  getMessagesString(num) {
    if (num == 1) {
      return chrome.i18n.getMessage(
          'inject_perforumstats_nummessages_singular');
    }
    return chrome.i18n.getMessage(
        'inject_perforumstats_nummessages_plural', [num]);
  }

  getForumOptionString(forumTitle, labels) {
    if (labels.length == 0) return forumTitle;
    if (labels.length == 1)
      return chrome.i18n.getMessage(
          'inject_perforumstats_forumoption_1helper', [forumTitle, ...labels]);
    if (labels.length == 2)
      return chrome.i18n.getMessage(
          'inject_perforumstats_forumoption_2helpers', [forumTitle, ...labels]);

    // If labels.length > 3, this is unexpected. Here's a sensible fallback:
    return forumTitle + ' (' + labels.join(', ') + ')';
  }

  createForumSelector() {
    let div = document.createElement('div');
    div.classList.add('TWPT-select-container');

    let select = document.createElement('select');
    let noPostsGroup;
    let noPostsGroupFlag = false;
    for (const forumData of this.data) {
      const hasPosted = forumData.numMessages > 0;

      if (!hasPosted && !noPostsGroupFlag) {
        noPostsGroup = document.createElement('optgroup');
        noPostsGroup.label =
            chrome.i18n.getMessage('inject_perforumstats_optgroup_notposted');
        noPostsGroupFlag = true;
      }

      let additionalLabels = [];
      if (hasPosted)
        additionalLabels.push(this.getMessagesString(forumData.numMessages));
      let role = forumData.forumUserInfo?.[1]?.[3] ?? 0;
      if (role)
        additionalLabels.push(chrome.i18n.getMessage(
            'inject_perforumstats_role_' + kRoles[role]));

      let option = document.createElement('option');
      option.textContent =
          this.getForumOptionString(forumData.forumTitle, additionalLabels);
      option.value = forumData.id;
      if (hasPosted)
        select.append(option);
      else
        noPostsGroup.append(option);
    }
    if (noPostsGroupFlag) select.append(noPostsGroup);
    select.addEventListener('change', e => {
      let forumId = e.target.value;
      this.injectChart(forumId);
    });

    div.append(select);
    return div;
  }

  injectChart(forumId) {
    let data = this.getAplosData(forumId);
    let metadata = {
      activities: [],
      finalMonth: undefined,
      locale: this.locale,
      shouldDisableTransitions: true,
    };
    let chartTitle = chrome.i18n.getMessage('inject_perforumstats_chart_label');
    const message = {
      action: 'renderProfileActivityChart',
      prefix: 'TWPT-extrainfo',
      data,
      metadata,
      chartTitle,
    };
    window.postMessage(message, '*');
  }
}
