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 kViewForumRequest = 'TWPT_ViewForumRequest';
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,
    };
    // Threads currently loaded in the thread list
    this.lastThreadListThreads = [];
    this.lastThreadListTimestamp = 0;
    this.lastThreadListIsFirst = null;
    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(kViewForumRequest, e => {
      // Ignore ViewForum requests made by the chat feature and the "Mark as
      // duplicate" dialog.
      //
      // All those requests have |maxNum| set to 10 and 20 respectively, while
      // the requests that we want to handle are the ones to initially load the
      // thread list (which currently requests 100 threads) and the ones to load
      // more threads (which request 50 threads).
      let maxNum = e.detail.body?.['2']?.['1']?.['2'];
      if (maxNum != 10 && maxNum != 20) {
        this.lastThreadListRequestId = e.detail.id;
        this.lastThreadListIsFirst =
            !e.detail.body?.['2']?.['1']?.['3']?.['2'];  // Pagination token
      }
    });
    window.addEventListener(kViewForumResponse, e => {
      if (e.detail.id != this.lastThreadListRequestId) return;

      let threads = e.detail.body?.['1']?.['2'] ?? [];
      if (this.lastThreadListIsFirst)
        this.lastThreadListThreads = threads;
      else
        this.lastThreadListThreads = this.lastThreadListThreads.concat(threads);
      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.lastThreadListThreads?.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.lastThreadListThreads?.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);
    });
  }
}
