import HotPocketExtension from '../common';

import POPUP from './templates/popup.html';
import POPUP_CONTENT_SAVING from './templates/popup_content_saving.html';
import POPUP_CONTENT_SUCCESS from './templates/popup_content_success.html';
import POPUP_CONTENT_NETLOC_BANNED from './templates/popup_content_netloc_banned.html';
import POPUP_CONTENT_ERROR from './templates/popup_content_error.html';

class Popup {
  constructor () {
    this.container = null;
    this.timeout = null;
  }
  setCloseTimeout = () => {
    this.timeout = window.setTimeout(this.close, 5000);
  };
  clearCloseTimeout = () => {
    if (this.timeout !== null) {
      window.clearTimeout(this.timeout);
      this.timeout = null;
    }
  };
  replaceInnerHTML = (element, content) => {
    for (let child of element.childNodes) {
      element.removeChild(child);
    }

    element.insertAdjacentHTML('beforeend', content);
  };
  setContent = (content, saveUrl) => {
    const shadow = this.container.shadowRoot;

    const body = shadow.querySelector('.hotpocket-extension-popup-body');
    this.replaceInnerHTML(body, content);

    const i18nElements = shadow.querySelectorAll('[data-message]');
    for (let i18nElement of i18nElements) {
      i18nElement.textContent = HotPocketExtension.api.i18n.getMessage(
        i18nElement.dataset.message,
      );
    }

    if (saveUrl) {
      const viewLink = shadow.querySelector('.hotpocket-extension-popup-view');
      if (viewLink) {
        viewLink.href = saveUrl;
      }
    }
  };
  close = () => {
    this.clearCloseTimeout();

    if (this.container !== null) {
      this.container.remove();
      this.container = null;
    }
  };
  show = (content, saveUrl) => {
    this.close();

    this.container = document.createElement('div');
    this.container.id = 'hotpocket-extension-popup';
    this.container.hotPocketExtensionPopup = this;

    const shadow = this.container.attachShadow({mode: 'open'});
    shadow.setHTMLUnsafe(POPUP);

    this.setContent(content, saveUrl);

    const closeElements = shadow.querySelectorAll('.hotpocket-extension-popup-close');
    for (const closeElement of closeElements) {
      closeElement.addEventListener('click', this.onCloseClick);
    }

    document.body.appendChild(this.container);
  };
  update = (content, saveUrl) => {
    this.setContent(content, saveUrl);
  };
  onCloseClick = (event) => {
    this.close();
  };
}

let currentPopup = null;

const doHandleBrowserActionClickedMessage = (message) => {
  if (currentPopup !== null) {
    currentPopup.close();
  }

  currentPopup = new Popup();
  currentPopup.show(POPUP_CONTENT_SAVING);
};

const doHandleSaveMessage = (message) => {
  const save = (message.result || {});

  let content = POPUP_CONTENT_SUCCESS;
  if (message.result === null) {
    content = POPUP_CONTENT_ERROR;
  } else if (save.is_netloc_banned === true) {
    content = POPUP_CONTENT_NETLOC_BANNED;
  }

  if (currentPopup === null) {
    currentPopup = new Popup();
    currentPopup.show(content);
  } else {
    currentPopup.update(content, save.url);
  }
};

const doSendMessage = (message) => {
  HotPocketExtension.api.runtime.sendMessage(message).
    then((result) => {
      HotPocketExtension.LOGGER.debug(
        'HotPocketExtension.content.doSendMessage(): message sent', message, result,
      );
    }).
    catch((error) => {
      HotPocketExtension.LOGGER.error(
        'HotPocketExtension.content.doSendMessage(): could not send message', error,
      );
    });
};

export default ({...configuration}) => {
  HotPocketExtension.configure(configuration);

  HotPocketExtension.api.runtime.onMessage.addListener((message, sender, sendResponse) => {
    HotPocketExtension.LOGGER.debug('HotPocketExtension.content.onMessage()', message, sender, sendResponse);

    let response = {ok: true};
    try {
      if (message.type === 'HotPocket:Extension:browserActionClicked') {
        doHandleBrowserActionClickedMessage(message);
      } else if (message.type === 'HotPocket:Extension:save') {
        doHandleSaveMessage(message);
      }
    } catch (exception) {
      HotPocketExtension.LOGGER.error(
        'HotPocketExtension.content.onMessage(): Unhandled exception when handling service worker message',
        message,
        exception,
      );
      response.ok = false;
    }

    sendResponse(response);

    return true;
  });

  doSendMessage({
    type: 'HotPocket:Extension:ping',
  });

  HotPocketExtension.LOGGER.info(`HotPocket v${HotPocketExtension.version} by BTHLabs`);
};
