import {MDCTooltip} from '@material/tooltip';
import {waitFor} from 'poll-until-promise';

import {parseUrl} from '../../common/commonUtils.js';
import OptionsWatcher from '../../common/optionsWatcher.js';
import {createPlainTooltip} from '../../common/tooltip.js';

import {createExtBadge, getDisplayLanguage} from './utils/common.js';
import PerForumStatsSection from './utils/PerForumStatsSection.js';

const kViewUnifiedUserResponseEvent = 'TWPT_ViewUnifiedUserResponse';
const kListCannedResponsesResponse = 'TWPT_ListCannedResponsesResponse';
const kViewThreadResponse = 'TWPT_ViewThreadResponse';
const kViewForumResponse = 'TWPT_ViewForumResponse';

// Used to match each category with the corresponding string.
const kAbuseCategories = [
  ['1', 'account'],
  ['2', 'displayname'],
  ['3', 'avatar'],
];
const kAbuseViolationCategories = {
  0: 'NO_VIOLATION',
  1: 'COMMUNITY_POLICY_VIOLATION',
  2: 'LEGAL_VIOLATION',
  3: 'CSAI_VIOLATION',
  4: 'OTHER_VIOLATION',
};
const kAbuseViolationCategoriesI18n = {
  0: 'noviolation',
  1: 'communitypolicy',
  2: 'legal',
  3: 'csai',
  4: 'other',
};

// The following array will appear in the interface as is (without being
// translated).
const kAbuseViolationTypes = {
  0: 'UNSPECIFIED',
  23: 'ACCOUNT_DISABLED',
  55: 'ACCOUNT_HAS_SERVICES_DISABLED',
  35: 'ACCOUNT_HIJACKED',
  96: 'ACCOUNT_LEAKED_CREDENTIALS',
  92: 'ACCOUNT_NOT_SUPPORTED',
  81: 'ARTISTIC_NUDITY',
  66: 'BAD_BEHAVIOR_PATTERN',
  78: 'BAD_ENGAGEMENT_BEHAVIOR_PATTERN',
  79: 'BORDERLINE_HARASSMENT',
  80: 'BORDERLINE_HATE_SPEECH',
  38: 'BOTNET',
  32: 'BRANDING_VIOLATION',
  100: 'CAPITALIZING_TRAGIC_EVENTS',
  105: 'CLOAKING',
  49: 'COIN_MINING',
  7: 'COMMERCIAL_CONTENT',
  97: 'COPPA_REGULATED',
  57: 'COPYRIGHT_CIRCUMVENTION',
  8: 'COPYRIGHTED_CONTENT',
  58: 'COURT_ORDER',
  51: 'CSAI',
  94: 'CSAI_INSPECT',
  52: 'CSAI_CARTOON_HUMOR',
  53: 'CSAI_SOLICITATION',
  108: 'CSAI_NON_APPARENT',
  67: 'DANGEROUS',
  37: 'DATA_SCRAPING',
  86: 'DECEPTIVE_OAUTH_IMPLEMENTATION',
  46: 'DEFAMATORY_CONTENT',
  36: 'DELINQUENT_BILLING',
  30: 'DISRUPTION_ATTEMPT',
  112: 'DOMESTIC_INTERFERENCE',
  22: 'DOS',
  9: 'DUPLICATE_CONTENT',
  68: 'DUPLICATE_LOCAL_PAGE',
  121: 'NON_QUALIFYING_ORGANIZATION',
  115: 'EGREGIOUS_INTERACTION_WITH_MINOR',
  83: 'ENGAGEMENT_COLLUSION',
  41: 'EXPLOIT_ATTACKS',
  65: 'FAKE_USER',
  2: 'FRAUD',
  21: 'FREE_TRIAL_VIOLATION',
  43: 'GIBBERISH',
  101: 'FOREIGN_INTERFERENCE',
  59: 'GOVERNMENT_ORDER',
  10: 'GRAPHICAL_VIOLENCE',
  11: 'HARASSMENT',
  12: 'HATE_SPEECH',
  90: 'IDENTICAL_PRODUCT_NAME',
  60: 'ILLEGAL_DRUGS',
  13: 'IMPERSONATION',
  69: 'IMPERSONATION_WITH_PII',
  116: 'INAPPROPRIATE_INTERACTION_WITH_MINOR',
  45: 'INAPPROPRIATE_CONTENT_SPEECH',
  106: 'INTENTIONAL_THWARTING',
  27: 'INTRUSION_ATTEMPT',
  87: 'INVALID_API_USAGE',
  14: 'INVALID_CONTENT',
  20: 'INVALID_GCE_USAGE',
  120: 'INVALID_STORAGE_USAGE',
  15: 'INVALID_IMAGE_QUALITY',
  88: 'INVALID_API_PRIVACY_POLICY_DISCLOSURE',
  54: 'INVALID_USAGE_OF_IP_PROXYING',
  99: 'KEYWORD_STUFFING',
  61: 'LEGAL_COUNTERFEIT',
  62: 'LEGAL_EXPORT',
  63: 'LEGAL_PRIVACY',
  33: 'LEGAL_REVIEW',
  91: 'LEGAL_PROTECTED',
  70: 'LOW_QUALITY_CONTENT',
  93: 'LOW_REPUTATION_PHONE_NUMBER',
  6: 'MALICIOUS_SOFTWARE',
  40: 'MALWARE',
  113: 'MISLEADING',
  114: 'MISREP_OF_ID',
  89: 'MEMBER_OF_ABUSIVE_GCE_NETWORK',
  84: 'NON_CONSENSUAL_EXPLICIT_IMAGERY',
  1: 'NONE',
  102: 'OFF_TOPIC',
  31: 'OPEN_PROXY',
  28: 'PAYMENT_FRAUD',
  16: 'PEDOPHILIA',
  71: 'PERSONAL_INFORMATION_CONTENT',
  25: 'PHISHING',
  34: 'POLICY_REVIEW',
  17: 'PORNOGRAPHY',
  29: 'QUOTA_CIRCUMVENTION',
  72: 'QUOTA_EXCEEDED',
  73: 'REGULATED',
  24: 'REPEATED_POLICY_VIOLATION',
  104: 'RESOURCE_COMPROMISED',
  107: 'REWARD_PROGRAMS_ABUSE',
  74: 'ROGUE_PHARMA',
  82: 'ESCORT',
  75: 'SPAMMY_LOCAL_VERTICAL',
  39: 'SEND_EMAIL_SPAM',
  117: 'SEXTORTION',
  118: 'SEX_TRAFFICKING',
  44: 'SEXUALLY_EXPLICIT_CONTENT',
  3: 'SHARDING',
  95: 'SOCIAL_ENGINEERING',
  109: 'SUSPICIOUS',
  19: 'TRADEMARK_CONTENT',
  50: 'TRAFFIC_PUMPING',
  76: 'UNSAFE_RACY',
  103: 'UNUSUAL_ACTIVITY_ALERT',
  64: 'UNWANTED_CONTENT',
  26: 'UNWANTED_SOFTWARE',
  77: 'VIOLENT_EXTREMISM',
  119: 'UNAUTH_IMAGES_OF_MINORS',
  85: 'UNAUTHORIZED_SERVICE_RESELLING',
  98: 'CSAI_EXTERNAL',
  5: 'SPAM',
  4: 'UNSAFE',
  47: 'CHILD_PORNOGRAPHY_INCITATION',
  18: 'TERRORISM_SUPPORT',
  56: 'CSAI_WORST_OF_WORST',
};

// These values will be translated
const kItemMetadataStateI18n = {
  1: 'published',
  2: 'draft',
  3: 'automated_abuse_take_down_hide2',
  4: 'automated_abuse_take_down_delete2',
  13: 'automated_abuse_reinstate2',
  10: 'automated_off_topic_hide2',
  14: 'automated_flagged_pending_manual_review2',
  5: 'user_flagged_pending_manual_review',
  6: 'owner_deleted',
  7: 'manual_take_down_hide2',
  17: 'manual_profile_take_down_suspend2',
  8: 'manual_take_down_delete2',
  18: 'reinstate_profile_takedown2',
  9: 'reinstate_abuse_takedown2',
  11: 'clear_off_topic2',
  12: 'confirm_off_topic2',
  15: 'googler_off_topic_hide2',
  16: 'expert_flagged_pending_manual_review',
};
const kItemMetadataState = {
  0: 'UNDEFINED',
  1: 'PUBLISHED',
  2: 'DRAFT',
  3: 'AUTOMATED_ABUSE_TAKE_DOWN_HIDE',
  4: 'AUTOMATED_ABUSE_TAKE_DOWN_DELETE',
  13: 'AUTOMATED_ABUSE_REINSTATE',
  10: 'AUTOMATED_OFF_TOPIC_HIDE',
  14: 'AUTOMATED_FLAGGED_PENDING_MANUAL_REVIEW',
  5: 'USER_FLAGGED_PENDING_MANUAL_REVIEW',
  6: 'OWNER_DELETED',
  7: 'MANUAL_TAKE_DOWN_HIDE',
  17: 'MANUAL_PROFILE_TAKE_DOWN_SUSPEND',
  8: 'MANUAL_TAKE_DOWN_DELETE',
  18: 'REINSTATE_PROFILE_TAKEDOWN',
  9: 'REINSTATE_ABUSE_TAKEDOWN',
  11: 'CLEAR_OFF_TOPIC',
  12: 'CONFIRM_OFF_TOPIC',
  15: 'GOOGLER_OFF_TOPIC_HIDE',
  16: 'EXPERT_FLAGGED_PENDING_MANUAL_REVIEW',
};

export default class ExtraInfo {
  constructor() {
    this.lastProfile = {
      body: {},
      id: -1,
      timestamp: 0,
    };
    this.lastCRsList = {
      body: {},
      id: -1,
      duplicateNames: new Set(),
    };
    this.lastThread = {
      body: {},
      id: -1,
      timestamp: 0,
    };
    this.lastThreadList = null;
    this.lastThreadListTimestamp = 0;
    this.lastThreadListRequestId = -1;
    this.displayLanguage = getDisplayLanguage();
    this.optionsWatcher = new OptionsWatcher(['extrainfo', 'perforumstats']);
    this.setUpHandlers();
  }

  setUpHandlers() {
    window.addEventListener(kViewUnifiedUserResponseEvent, e => {
      if (e.detail.id < this.lastProfile.id) return;

      this.lastProfile = {
        body: e.detail.body,
        id: e.detail.id,
        timestamp: Date.now(),
      };
    });
    window.addEventListener(kListCannedResponsesResponse, e => {
      if (e.detail.id < this.lastCRsList.id) return;

      // Look if there are duplicate names
      const crs = e.detail.body?.['1'] ?? [];
      const names = crs.map(cr => cr?.['7']).slice().sort();
      let duplicateNames = new Set();
      for (let i = 1; i < names.length; i++)
        if (names[i - 1] == names[i]) duplicateNames.add(names[i]);

      this.lastCRsList = {
        body: e.detail.body,
        id: e.detail.id,
        duplicateNames,
      };
    });
    window.addEventListener(kViewThreadResponse, e => {
      if (e.detail.id < this.lastThread.id) return;

      this.lastThread = {
        body: e.detail.body,
        id: e.detail.id,
        timestamp: Date.now(),
      };
    });
    window.addEventListener(kViewThreadResponse, e => {
      if (e.detail.id < this.lastThread.id) return;

      this.lastThread = {
        body: e.detail.body,
        id: e.detail.id,
        timestamp: Date.now(),
      };
    });
    window.addEventListener(kViewForumResponse, e => {
      if (e.detail.id < this.lastThreadListRequestId) return;

      this.lastThreadList = e.detail.body;
      this.lastThreadListTimestamp = Date.now();
    });
  }

  // Whether |feature| is enabled
  isEnabled(feature) {
    return this.optionsWatcher.isEnabled(feature);
  }

  // Add chips which contain |info| to |node|. If |withContainer| is set to
  // true, a container will contain all the chips.
  addExtraInfoElement(info, node, withContainer = false) {
    // Don't create if there's nothing to show
    if (info.length == 0) return;

    let container;
    if (withContainer) {
      container = document.createElement('div');
      container.classList.add('TWPT-extrainfo-container');
    } else {
      container = node;
    }

    let tooltips = [];

    for (const i of info) {
      let chip = document.createElement('material-chip');
      chip.classList.add('TWPT-extrainfo-chip');

      let chipCont = document.createElement('div');
      chipCont.classList.add('TWPT-chip-content-container');

      let content = document.createElement('div');
      content.classList.add('TWPT-content');

      const [badge, badgeTooltip] = createExtBadge();

      let span = document.createElement('span');
      span.append(i);

      content.append(badge, span);
      chipCont.append(content);
      chip.append(chipCont);
      container.append(chip);

      tooltips.push(badgeTooltip);
    }

    if (withContainer) node.append(container);

    for (const tooltip of tooltips) new MDCTooltip(tooltip);
  }

  /**
   * Profile functionality
   */
  injectAtProfile(card) {
    waitFor(
        () => {
          let now = Date.now();
          if (now - this.lastProfile.timestamp < 15 * 1000)
            return Promise.resolve(this.lastProfile);
          return Promise.reject(
              new Error('Didn\'t receive profile information'));
        },
        {
          interval: 500,
          timeout: 15 * 1000,
        })
        .then(profile => {
          let info = [];
          const abuseViolationCategory = profile.body?.['1']?.['6'];
          if (abuseViolationCategory) {
            let avCat = document.createElement('span');
            avCat.textContent = chrome.i18n.getMessage(
                'inject_extrainfo_profile_abusecategory',
                [chrome.i18n.getMessage(
                     'inject_extrainfo_profile_abusecategory_' +
                     kAbuseViolationCategoriesI18n[abuseViolationCategory]) ??
                 abuseViolationCategory]);
            avCat.title = kAbuseViolationCategories[abuseViolationCategory] ??
                abuseViolationCategory;
            info.push(avCat);
          }

          const profileAbuse = profile.body?.['1']?.['1']?.['8'];

          for (const [index, category] of kAbuseCategories) {
            const violation = profileAbuse?.[index]?.['1']?.['1'];
            if (violation) {
              info.push(chrome.i18n.getMessage(
                  'inject_extrainfo_profile_abuse_' + category,
                  [kAbuseViolationTypes[violation]]));
            }
          }

          const appealCount = profileAbuse?.['4'];
          if (appealCount !== undefined)
            info.push(chrome.i18n.getMessage(
                'inject_extrainfo_profile_appealsnum', [appealCount]));

          this.addExtraInfoElement(info, card, true);
        })
        .catch(err => {
          console.error(
              'extraInfo: error while injecting profile extra info: ', err);
        });
  }

  injectAtProfileIfEnabled(card) {
    this.isEnabled('extrainfo').then(isEnabled => {
      if (isEnabled) return this.injectAtProfile(card);
    });
  }

  /**
   * Canned responses (CRs) functionality
   */
  getCRName(tags, isExpanded) {
    if (!isExpanded)
      return tags.parentNode?.querySelector?.('.text .name')?.textContent;

    // https://www.youtube.com/watch?v=Z6_ZNW1DACE
    return tags.parentNode?.parentNode?.parentNode?.parentNode?.parentNode
        ?.parentNode?.parentNode?.querySelector?.('.text .name')
        ?.textContent;
  }

  getUsageCountString(num) {
    if (num == 1)
      return chrome.i18n.getMessage('inject_extrainfo_crs_used_singular');

    return chrome.i18n.getMessage('inject_extrainfo_crs_used_plural', [num]);
  }

  // Inject usage stats in the |tags| component of a CR
  injectAtCR(tags, isExpanded) {
    waitFor(
        () => {
          if (this.lastCRsList.id != -1)
            return Promise.resolve(this.lastCRsList);
          return Promise.reject(
              new Error('Didn\'t receive canned responses list'));
        },
        {
          interval: 500,
          timeout: 15 * 1000,
        })
        .then(crs => {
          let name = this.getCRName(tags, isExpanded);

          // If another CR has the same name, there's no easy way to distinguish
          // them, so don't show the usage stats.
          if (crs.duplicateNames.has(name)) {
            console.info(
                'CR "' + name +
                '" is duplicate, so skipping the injection of usage stats.');
            return;
          }

          for (const cr of (crs.body?.['1'] ?? [])) {
            if (cr['7'] == name) {
              let tag = document.createElement('material-chip');
              tag.classList.add('TWPT-tag');

              let container = document.createElement('div');
              container.classList.add('TWPT-chip-content-container');

              let content = document.createElement('div');
              content.classList.add('TWPT-content');

              const [badge, badgeTooltip] = createExtBadge();

              let label = document.createElement('span');
              label.textContent = this.getUsageCountString(cr['8'] ?? '0');

              content.append(badge, label);
              container.append(content);
              tag.append(container);
              tags.append(tag);

              new MDCTooltip(badgeTooltip);

              if (cr['9']) {
                const lastUsedTime = Math.floor(parseInt(cr['9']) / 1e3);
                let date = (new Date(lastUsedTime)).toLocaleString();
                createPlainTooltip(
                    label,
                    chrome.i18n.getMessage(
                        'inject_extrainfo_crs_lastused', [date]));
              }

              break;
            }
          }
        })
        .catch(err => {
          console.error(
              'extraInfo: error while injecting profile extra info: ', err);
        });
  }

  injectAtCRIfEnabled(tags, isExpanded) {
    // If the tag has already been injected, exit.
    if (tags.querySelector('.TWPT-tag')) return;

    this.isEnabled('extrainfo').then(isEnabled => {
      if (isEnabled) return this.injectAtCR(tags, isExpanded);
    });
  }

  /**
   * Thread view functionality
   */

  getPendingStateInfo(endPendingStateTimestampMicros) {
    const endPendingStateTimestamp =
        Math.floor(endPendingStateTimestampMicros / 1e3);
    const now = Date.now();
    if (endPendingStateTimestampMicros && endPendingStateTimestamp > now) {
      let span = document.createElement('span');
      span.textContent =
          chrome.i18n.getMessage('inject_extrainfo_message_pendingstate');

      let date = new Date(endPendingStateTimestamp).toLocaleString();
      let pendingTooltip = createPlainTooltip(
          span,
          chrome.i18n.getMessage(
              'inject_extrainfo_message_pendingstate_tooltip', [date]),
          false);
      return [span, pendingTooltip];
    }

    return [null, null];
  }

  getMetadataInfo(itemMetadata) {
    let info = [];

    const state = itemMetadata?.['1'];
    if (state && state != 1) {
      let span = document.createElement('span');
      span.textContent = chrome.i18n.getMessage(
          'inject_extrainfo_message_state',
          [chrome.i18n.getMessage(
               'inject_extrainfo_message_state_' +
               kItemMetadataStateI18n[state]) ??
           state]);
      span.title = kItemMetadataState[state] ?? state;
      info.push(span);
    }

    const shadowBlockInfo = itemMetadata?.['10'];
    const blockedTimestampMicros = shadowBlockInfo?.['2'];
    if (blockedTimestampMicros) {
      const isBlocked = shadowBlockInfo?.['1'];
      let span = document.createElement('span');
      span.textContent = chrome.i18n.getMessage(
          'inject_extrainfo_message_shadowblock' +
          (isBlocked ? 'active' : 'notactive'));
      if (isBlocked) span.classList.add('TWPT-extrainfo-bad');
      info.push(span);
    }

    return info;
  }

  getLiveReviewStatusInfo(liveReviewStatus) {
    const verdict = liveReviewStatus?.['1'];
    if (!verdict) return [null, null];
    let label, labelClass;
    switch (verdict) {
      case 1:  // LIVE_REVIEW_RELEVANT
        label = 'relevant';
        labelClass = 'TWPT-extrainfo-good';
        break;

      case 2:  // LIVE_REVIEW_OFF_TOPIC
        label = 'offtopic';
        labelClass = 'TWPT-extrainfo-bad';
        break;

      case 3:  // LIVE_REVIEW_ABUSE
        label = 'abuse';
        labelClass = 'TWPT-extrainfo-bad';
        break;
    }
    const reviewedBy = liveReviewStatus?.['2'];
    const timestamp = liveReviewStatus?.['3'];
    const date = (new Date(Math.floor(timestamp / 1e3))).toLocaleString();

    let a = document.createElement('a');
    a.href = 'https://support.google.com/s/community/user/' + reviewedBy;
    a.classList.add(labelClass);
    a.textContent = chrome.i18n.getMessage(
        'inject_extrainfo_message_livereviewverdict',
        [chrome.i18n.getMessage(
            'inject_extrainfo_message_livereviewverdict_' + label)]);
    let liveReviewTooltip = createPlainTooltip(a, date, false);
    return [a, liveReviewTooltip];
  }

  // Get an |info| array with the info related to the thread, and a |tooltips|
  // array with the corresponding tooltips which should be initialized after the
  // info is added to the DOM.
  //
  // This is used by the injectAtQuestion() and injectAtThreadList() functions.
  getThreadInfo(thread) {
    let info = [];
    let tooltips = [];

    const endPendingStateTimestampMicros = thread?.['2']?.['39'];
    const [pendingStateInfo, pendingTooltip] =
        this.getPendingStateInfo(endPendingStateTimestampMicros);
    if (pendingStateInfo) info.push(pendingStateInfo);
    if (pendingTooltip) tooltips.push(pendingTooltip);

    const isTrending = thread?.['2']?.['25'];
    const isTrendingAutoMarked = thread?.['39'];
    if (isTrendingAutoMarked)
      info.push(document.createTextNode(
          chrome.i18n.getMessage('inject_extrainfo_thread_autotrending')));
    else if (isTrending)
      info.push(document.createTextNode(
          chrome.i18n.getMessage('inject_extrainfo_thread_trending')));

    const itemMetadata = thread?.['2']?.['12'];
    const mdInfo = this.getMetadataInfo(itemMetadata);
    info.push(...mdInfo);

    const liveReviewStatus = thread?.['2']?.['38'];
    const [liveReviewInfo, liveReviewTooltip] =
        this.getLiveReviewStatusInfo(liveReviewStatus);
    if (liveReviewInfo) info.push(liveReviewInfo);
    if (liveReviewTooltip) tooltips.push(liveReviewTooltip);

    return [info, tooltips];
  }

  injectAtQuestion(stateChips) {
    let currentPage = parseUrl(location.href);
    if (currentPage === false) {
      console.error('extraInfo: couldn\'t parse current URL:', location.href);
      return;
    }

    waitFor(
        () => {
          let now = Date.now();
          let threadInfo = this.lastThread.body['1']?.['2']?.['1'];
          if (now - this.lastThread.timestamp < 30 * 1000 &&
              threadInfo?.['1'] == currentPage.thread &&
              threadInfo?.['3'] == currentPage.forum)
            return Promise.resolve(this.lastThread);
          return Promise.reject(
              new Error('Didn\'t receive thread information'));
        },
        {
          interval: 500,
          timeout: 30 * 1000,
        })
        .then(thread => {
          const [info, tooltips] = this.getThreadInfo(thread.body?.['1']);
          this.addExtraInfoElement(info, stateChips, false);
          for (const tooltip of tooltips) new MDCTooltip(tooltip);
        })
        .catch(err => {
          console.error(
              'extraInfo: error while injecting question extra info: ', err);
        });
  }

  injectAtQuestionIfEnabled(stateChips) {
    this.isEnabled('extrainfo').then(isEnabled => {
      if (isEnabled) return this.injectAtQuestion(stateChips);
    });
  }

  getMessagesByType(thread, type) {
    if (type === 'reply') return thread?.['1']?.['3'];
    if (type === 'lastMessage') return thread?.['1']?.['17']?.['3'];
    if (type === 'suggested') return thread?.['1']?.['17']?.['4'];
    if (type === 'recommended') return thread?.['1']?.['17']?.['1'];
  }

  getMessageByTypeAndIndex(thread, type, index) {
    return this.getMessagesByType(thread, type)?.[index];
  }

  // Returns true if the last message is included in the messages array (in the
  // extension context, we say those messages are of the type "reply").
  lastMessageInReplies(thread) {
    const lastMessageId = thread?.['1']?.['17']?.['3']?.[0]?.['1']?.['1'];
    if (!lastMessageId) return true;

    // If the last message is included in the lastMessage array, check if it
    // also exists in the messages/replies array.
    const replies = thread?.['1']?.['3'];
    if (!replies?.length) return false;
    const lastReplyIndex = replies.length - 1;
    const lastReplyId = replies[lastReplyIndex]?.['1']?.['1'];
    return lastMessageId && lastMessageId == lastReplyId;
  }

  getMessageInfo(thread, message) {
    const section = message.parentNode;

    let type = 'reply';
    if (section?.querySelector?.('.heading material-icon[icon="auto_awesome"]'))
      type = 'suggested';
    if (section?.querySelector?.('.heading material-icon[icon="check_circle"]'))
      type = 'recommended';

    let index = -1;
    let messagesInDom = section.querySelectorAll('ec-message');

    // Number of messages in the DOM.
    const n = messagesInDom.length;

    if (type !== 'reply') {
      for (let i = 0; i < n; ++i) {
        if (message.isEqualNode(messagesInDom[i])) {
          index = i;
          break;
        }
      }
    } else {
      // If the type of the message is a reply, things are slightly more
      // complex, since replies are paginated and the last message should be
      // treated separately (it is included diferently in the API response).
      let lastMessageInReplies = this.lastMessageInReplies(thread);
      if (message.isEqualNode(messagesInDom[n - 1]) && !lastMessageInReplies) {
        type = 'lastMessage';
        index = 0
      } else {
        // Number of messages in the current API response.
        const messagesInResponse = this.getMessagesByType(thread, type);
        const m = messagesInResponse.length;
        // If the last message is included in the replies array, we also have to
        // consider the last message in the DOM.
        let modifier = lastMessageInReplies ? 1 : 0;
        for (let k = 0; k < m; ++k) {
          let i = n - 2 - k + modifier;
          if (message.isEqualNode(messagesInDom[i])) {
            index = m - 1 - k;
            break;
          }
        }
      }
    }

    return [type, index];
  }

  injectAtMessage(messageNode) {
    let currentPage = parseUrl(location.href);
    if (currentPage === false) {
      console.error('extraInfo: couldn\'t parse current URL:', location.href);
      return;
    }

    let footer = messageNode.querySelector('.footer-fill');
    if (!footer) {
      console.error('extraInfo: message doesn\'t have a footer:', messageNode);
      return;
    }

    const [type, index] =
        this.getMessageInfo(this.lastThread.body, messageNode);
    if (index == -1) {
      console.error('extraInfo: this.getMessageInfo() returned index -1.');
      return;
    }

    waitFor(
        () => {
          let now = Date.now();
          let threadInfo = this.lastThread.body['1']?.['2']?.['1'];
          if (now - this.lastThread.timestamp < 30 * 1000 &&
              threadInfo?.['1'] == currentPage.thread &&
              threadInfo?.['3'] == currentPage.forum) {
            const message = this.getMessageByTypeAndIndex(
                this.lastThread.body, type, index);
            if (message) return Promise.resolve(message);
          }

          return Promise.reject(new Error(
              'Didn\'t receive thread information (type: ' + type +
              ', index: ' + index + ')'));
        },
        {
          interval: 1000,
          timeout: 30 * 1000,
        })
        .then(message => {
          let info = [];

          const endPendingStateTimestampMicros = message['1']?.['17'];
          const [pendingStateInfo, pendingTooltip] =
              this.getPendingStateInfo(endPendingStateTimestampMicros);
          if (pendingStateInfo) info.push(pendingStateInfo);

          const itemMetadata = message['1']?.['5'];
          const mdInfo = this.getMetadataInfo(itemMetadata);
          info.push(...mdInfo);

          const liveReviewStatus = message['1']?.['36'];
          const [liveReviewInfo, liveReviewTooltip] =
              this.getLiveReviewStatusInfo(liveReviewStatus);
          if (liveReviewInfo) info.push(liveReviewInfo);

          this.addExtraInfoElement(info, footer, true);
          if (pendingTooltip) new MDCTooltip(pendingTooltip);
          if (liveReviewTooltip) new MDCTooltip(liveReviewTooltip);
        })
        .catch(err => {
          console.error(
              'extraInfo: error while injecting message extra info: ', err);
        });
  }

  injectAtMessageIfEnabled(message) {
    this.isEnabled('extrainfo').then(isEnabled => {
      if (isEnabled) return this.injectAtMessage(message);
    });
  }

  /**
   * Thread list functionality
   */
  injectAtThreadList(li) {
    waitFor(
        () => {
          const header = li.querySelector(
              'ec-thread-summary .main-header .panel-description a.header');
          if (header === null) {
            console.error(
                'extraInfo: Header is not present in the thread item\'s DOM.');
            return;
          }

          const threadInfo = parseUrl(header.href);
          if (threadInfo === false) {
            console.error('extraInfo: Thread\'s link cannot be parsed.');
            return;
          }

          let authorLine = li.querySelector(
              'ec-thread-summary .header-content .top-row .author-line');
          if (!authorLine) {
            console.error(
                'extraInfo: Author line is not present in the thread item\'s DOM.');
            return;
          }

          let thread = this.lastThreadList?.['1']?.['2']?.find?.(t => {
            return t?.['2']?.['1']?.['1'] == threadInfo.thread &&
                t?.['2']?.['1']?.['3'] == threadInfo.forum;
          });
          if (thread) return Promise.resolve([thread, authorLine]);
          return Promise.reject(
              new Error('Didn\'t receive thread information'));
        },
        {
          interval: 500,
          timeout: 7 * 1000,
        })
        .then(response => {
          const [thread, authorLine] = response;
          const state = thread?.['2']?.['12']?.['1'];
          if (state && ![1, 13, 18, 9].includes(state)) {
            let label = document.createElement('div');
            label.classList.add('TWPT-label');

            const [badge, badgeTooltip] = createExtBadge();

            let span = document.createElement('span');
            span.textContent = chrome.i18n.getMessage(
                                   'inject_extrainfo_message_state_' +
                                   kItemMetadataStateI18n[state]) ??
                state;
            span.title = kItemMetadataState[state] ?? state;

            label.append(badge, span);
            authorLine.prepend(label);
            new MDCTooltip(badgeTooltip);
          }
        })
        .catch(err => {
          console.error(
              'extraInfo: error while injecting thread list extra info: ', err);
        });
  }

  injectAtThreadListIfEnabled(li) {
    this.isEnabled('extrainfo').then(isEnabled => {
      if (isEnabled) this.injectAtThreadList(li);
    });
  }

  injectAtExpandedThreadList(toolbelt) {
    const header =
        toolbelt?.parentNode?.parentNode?.parentNode?.querySelector?.(
            '.main-header .panel-description a.header');
    if (header === null) {
      console.error(
          'extraInfo: Header is not present in the thread item\'s DOM.');
      return;
    }

    const threadInfo = parseUrl(header.href);
    if (threadInfo === false) {
      console.error('extraInfo: Thread\'s link cannot be parsed.');
      return;
    }

    waitFor(
        () => {
          let thread = this.lastThreadList?.['1']?.['2']?.find?.(t => {
            return t?.['2']?.['1']?.['1'] == threadInfo.thread &&
                t?.['2']?.['1']?.['3'] == threadInfo.forum;
          });
          if (thread) return Promise.resolve(thread);
          return Promise.reject(
              new Error('Didn\'t receive thread information'));
        },
        {
          interval: 500,
          timeout: 7 * 1000,
        })
        .then(thread => {
          const [info, tooltips] = this.getThreadInfo(thread);
          this.addExtraInfoElement(info, toolbelt, true);
          for (const tooltip of tooltips) new MDCTooltip(tooltip);
        })
        .catch(err => {
          console.error(
              'extraInfo: error while injecting thread list extra info: ', err);
        });
  }

  injectAtExpandedThreadListIfEnabled(toolbelt) {
    this.isEnabled('extrainfo').then(isEnabled => {
      if (isEnabled) this.injectAtExpandedThreadList(toolbelt);
    });
  }

  /**
   * Per-forum stats in user profiles.
   */

  injectPerForumStats(chart) {
    waitFor(
        () => {
          let now = Date.now();
          if (now - this.lastProfile.timestamp < 15 * 1000)
            return Promise.resolve(this.lastProfile);
          return Promise.reject(new Error(
              'Didn\'t receive profile information (for per-profile stats)'));
        },
        {
          interval: 500,
          timeout: 15 * 1000,
        })
        .then(profile => {
          new PerForumStatsSection(
              chart?.parentNode, profile.body, this.displayLanguage,
              /* isCommunityConsole = */ true);
        })
        .catch(err => {
          console.error(
              'extraInfo: error while preparing to inject per-forum stats: ',
              err);
        });
  }

  injectPerForumStatsIfEnabled(chart) {
    this.isEnabled('perforumstats').then(isEnabled => {
      if (isEnabled) this.injectPerForumStats(chart);
    });
  }
}
