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

import {parseUrl} from '../../common/commonUtils.js';
import {injectStylesheet} from '../../common/contentScriptsUtils.js';
import {getDocURL} from '../../common/extUtils.js';
import {getOptions} from '../../common/optionsUtils.js';

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

const kSMEINestedReplies = 15;
const kViewThreadResponse = 'TWPT_ViewThreadResponse';

export default class ThreadPageDesignWarning {
  constructor() {
    this.lastThread = {
      body: {},
      id: -1,
      timestamp: 0,
    };
    this.setUpHandler();

    // We have to save whether the old UI was enabled at startup, since that's
    // the moment when it takes effect. If the option changes while the tab is
    // open, it won't take effect.
    getOptions([
      'interopthreadpage', 'interopthreadpage_mode'
    ]).then(options => {
      this.shouldShowWarning = options.interopthreadpage &&
          options.interopthreadpage_mode == 'previous';

      if (this.shouldShowWarning) {
        injectStylesheet(
            chrome.runtime.getURL('css/thread_page_design_warning.css'));
      } else {
        this.removeHandler();
      }
    });

    this.isExperimentEnabled = this.isNestedRepliesExperimentEnabled();
  }

  isNestedRepliesExperimentEnabled() {
    if (!document.documentElement.hasAttribute('data-startup')) return false;

    let startup =
        JSON.parse(document.documentElement.getAttribute('data-startup'));
    return startup?.[1]?.[6]?.includes?.(kSMEINestedReplies);
  }

  eventHandler(e) {
    if (e.detail.id < this.lastThread.id) return;

    this.lastThread = {
      body: e.detail.body,
      id: e.detail.id,
      timestamp: Date.now(),
    };
  }

  setUpHandler() {
    window.addEventListener(kViewThreadResponse, this.eventHandler.bind(this));
  }

  removeHandler() {
    window.removeEventListener(
        kViewThreadResponse, this.eventHandler.bind(this));
  }

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

    let icon = document.createElement('material-icon');
    icon.classList.add('TWPT-warning--icon');

    let iconContent = document.createElement('i');
    iconContent.classList.add('material-icon-i', 'material-icons-extended');
    iconContent.setAttribute('role', 'img');
    iconContent.setAttribute('aria-hidden', 'true');
    iconContent.textContent = 'warning';

    icon.append(iconContent);

    let text = document.createElement('div');
    text.classList.add('TWPT-warning--text');
    text.textContent =
        chrome.i18n.getMessage('inject_threadpagedesign_warning');

    let btn = document.createElement('a');
    btn.classList.add('TWPT-warning--btn');
    btn.href =
        getDocURL('features.md#Thread-page-design-in-the-Community-Console');
    btn.setAttribute('target', '_blank');
    btn.setAttribute('rel', 'noopener noreferrer');

    const [badge, badgeTooltip] = createExtBadge();

    let btnText = document.createElement('div');
    btnText.textContent = chrome.i18n.getMessage('btn_learnmore');

    btn.append(badge, btnText);

    div.append(icon, text, btn);
    content.prepend(div);

    new MDCTooltip(badgeTooltip);
  }

  injectWarningIfApplicable(content) {
    return waitFor(
               () => {
                 if (this.shouldShowWarning === undefined)
                   return Promise.reject(
                       new Error('shouldShowWarning is not defined.'));

                 return Promise.resolve({result: this.shouldShowWarning});
               },
               {
                 interval: 500,
                 timeout: 10 * 1000,
               })
        .then(preShouldShowWarning => {
          if (!preShouldShowWarning.result) return;

          // If the global SMEI experiment is enabled, all threads use nested
          // replies, so we'll skip the per-thread check and always show the
          // warning banner.
          if (this.isExperimentEnabled) return Promise.resolve({result: true});

          let currentThread = parseUrl(location.href);
          if (currentThread === false)
            throw new Error('current thread id cannot be parsed.');

          return waitFor(() => {
            let now = Date.now();
            let lastThreadInfo = this.lastThread.body['1']?.['2']?.['1'];
            if (now - this.lastThread.timestamp > 30 * 1000 ||
                lastThreadInfo?.['1'] != currentThread.thread ||
                lastThreadInfo?.['3'] != currentThread.forum)
              throw new Error(
                  'cannot obtain information about current thread.');

            // If the messageOrGap field contains any items, the thread is using
            // nested replies. Otherwise, it probably isn't using them.
            return Promise.resolve(
                {result: this.lastThread.body['1']?.['40']?.length > 0});
          }, {
            interval: 500,
            timeout: 10 * 1000,
          });
        })
        .then(shouldShowWarning => {
          if (shouldShowWarning.result) this.injectWarning(content);
        })
        .catch(err => {
          console.error(
              '[threadPageDesignWarning] An error ocurred while trying to decide whether to show warning: ',
              err);
        });
  }
}
