import {MDCTooltip} from '@material/tooltip';

import {createExtBadge} from './common.js';

// 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'],
  [7, 'communityvideos', '#F4511E'],
  [8, 'communityguides', '#9334E6'],
];
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, isCommunityConsole) {
    this.locale = locale;
    this.isCommunityConsole = isCommunityConsole;
    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');

    let badge, badgeTooltip;
    if (this.isCommunityConsole) {
      [badge, badgeTooltip] = createExtBadge();
    } else {
      badge = document.createElement('span');
      badge.classList.add('TWPT-badge');

      var badgeImg = document.createElement('img');
      badgeImg.src =
          'https://fonts.gstatic.com/s/i/materialicons/repeat/v6/24px.svg';

      badge.appendChild(badgeImg);
    }

    let titleText = document.createElement('span');
    titleText.textContent =
        chrome.i18n.getMessage('inject_perforumstats_heading');

    title.append(badge, titleText);

    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);
    if (this.isCommunityConsole) new MDCTooltip(badgeTooltip);
  }

  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 {
        // We're filtering empty strings since in the public forum there a lose
        // conversion takes place and the first element of the array is always
        // null, which breaks the Aplos graph rendering.
        data =
            rawData.map(m => JSON.stringify(Object.values(m))).filter(m => !!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, '*');
  }
}
