import actionApi from './common/actionApi';
import {isoLangs} from './common/consts';
import Options from './common/options';
import ExtSessionStorage from './common/sessionStorage';
import URLFactory from './common/urlFactory';

type NonEmptyArray<T> = [T, ...T[]];

// Data types that the extension can translate.
export enum DataType {
  DataTypeText,
  DataTypeURL,
}

// Information about a context menu item which we have added to the browser.
interface MenuItemInfo {
  language: string;    // Target language displayed in the item.
  dataType: DataType;  // Data type handled by the context menu item.
}

// Object with the context menu items that have been added by the extension and
// information about them.
interface ContextMenuItems {
  [id: string]: MenuItemInfo;
}

// Definition of the types of context menu items that the extension can inject.
interface MenuItemType {
  // Type of data which can be translated with this type of context menu items.
  dataType: DataType;
  // Contexts in which this type of context menu item will be shown.
  contexts: NonEmptyArray<chrome.contextMenus.ContextType>;
  // Prefix of the i18n messages for this type of context menu item, and used to
  // generate the unique IDs of context menu items.
  prefix: string;
}
type MenuItemTypes = MenuItemType[];

const MENU_ITEM_TYPES: MenuItemTypes = [
  {
    dataType: DataType.DataTypeText,
    contexts: ['selection'],
    prefix: '',
  },
  /*
   * @TODO(https://iavm.xyz/b/translateselectedtext/7): Delete this compile-time
   * directive after the experimentation phase is done to launch the feature.
   * #!if canary || !production
   */
  {
    dataType: DataType.DataTypeURL,
    contexts: ['link'],
    prefix: 'link',
  },
  // #!endif
];

function translationClick(
    info: chrome.contextMenus.OnClickData,
    initiatorTab: chrome.tabs.Tab): void {
  const optionsPromise = Options.getOptions();
  const ssPromise =
      ExtSessionStorage.get(['contextMenuItems', 'translatorTab']);
  Promise.all([optionsPromise, ssPromise])
      .then(returnValues => {
        const [options, sessionStorageItems] = returnValues;
        const contextMenuItems: ContextMenuItems =
            sessionStorageItems.contextMenuItems;
        const contextMenuItem = contextMenuItems?.[info.menuItemId];
        const translatorTab: number = sessionStorageItems.translatorTab;

        const url = URLFactory.getTranslationURL(
            contextMenuItem?.language, info, contextMenuItem?.dataType);
        const newTabOptions: Parameters<typeof chrome.tabs.create>[0] = {
          url,
          openerTabId: initiatorTab.id,
        };
        if (initiatorTab.index) newTabOptions.index = initiatorTab.index + 1;

        if (contextMenuItem?.dataType !== DataType.DataTypeText) {
          // Always create a simple new tab for data types other than text.
          // @TODO(https://iavm.xyz/b/translateselectedtext/7): Review this
          // behavior in the future.
          chrome.tabs.create(newTabOptions);
        } else if (translatorTab && options.uniqueTab == 'yep') {
          chrome.tabs.update(translatorTab, {url}, tab => {
            chrome.tabs.highlight(
                {windowId: tab.windowId, tabs: tab.index}, () => {
                  chrome.windows.update(tab.windowId, {focused: true});
                });
          });
        } else if (options.uniqueTab == 'popup') {
          chrome.windows.create({type: 'popup', url, width: 1000, height: 382});
        } else {
          chrome.tabs.create(newTabOptions, tab => {
            ExtSessionStorage.set({translatorTab: tab?.id});
          });
        }
      })
      .catch(err => {
        console.error('Error handling translation click', err);
      });
}

function createMenus(options: Options): Promise<void> {
  chrome.contextMenus.removeAll();

  const contextMenuItems: ContextMenuItems = {};
  const langs = options.targetLangs;
  const isSingleEntry = Object.values(langs).length == 1;

  for (const type of MENU_ITEM_TYPES) {
    let parentEl;
    if (!isSingleEntry) {
      parentEl = chrome.contextMenus.create({
        'id': `${type.prefix}parent`,
        'title': chrome.i18n.getMessage(`contextmenu${type.prefix}_title`),
        'contexts': type.contexts,
      });
    }

    for (const language of Object.values(langs)) {
      const languageDetails = isoLangs[language];
      if (languageDetails === undefined) {
        console.error(language + ' doesn\'t exist!');
        continue;
      }
      let title;
      if (isSingleEntry) {
        title = chrome.i18n.getMessage(
            `contextmenu${type.prefix}_title2`, languageDetails.name);
      } else {
        title = languageDetails.name + ' (' + languageDetails.nativeName + ')';
      }
      const id = chrome.contextMenus.create({
        'id': `${type.prefix}tr_language_${language}`,
        'title': title,
        'parentId': parentEl,
        'contexts': type.contexts,
      });
      contextMenuItems[id] = {
        language,
        dataType: type.dataType,
      };
    }

    if (!isSingleEntry) {
      chrome.contextMenus.create({
        'id': `${type.prefix}tr_separator`,
        'type': 'separator',
        'parentId': parentEl,
        'contexts': type.contexts,
      });
      chrome.contextMenus.create({
        'id': `${type.prefix}tr_options`,
        'title': chrome.i18n.getMessage('contextmenu_edit'),
        'parentId': parentEl,
        'contexts': type.contexts,
      });
    }
  }

  return ExtSessionStorage.set({contextMenuItems});
}

chrome.storage.onChanged.addListener((_changes, areaName) => {
  if (areaName == 'sync') {
    Options.getOptions(/* readOnly = */ false)
        .then(options => {
          return createMenus(options);
        })
        .catch(err => {
          console.error(
              'Error setting up the extension after a change ' +
                  'in the storage area.',
              err);
        });
  }
});

Options.getOptions(/* readOnly = */ false)
    .then(options => {
      if (options.isFirstRun) {
        chrome.notifications.create('install', {
          type: 'basic',
          iconUrl: 'icons/translate-128.png',
          title: chrome.i18n.getMessage('notification_install_title'),
          message: chrome.i18n.getMessage('notification_install_message'),
          isClickable: true
        });
      }

      return createMenus(options);
    })
    .catch(err => {
      console.error('Error initializing the extension.', err);
    });

chrome.notifications.onClicked.addListener(notification_id => {
  switch (notification_id) {
    case 'install':
      chrome.runtime.openOptionsPage();
      break;
  }
  chrome.notifications.clear(notification_id);
});

chrome.contextMenus.onClicked.addListener((info, tab) => {
  for (const type of MENU_ITEM_TYPES) {
    if (info.menuItemId == `${type.prefix}tr_options`) {
      chrome.runtime.openOptionsPage();
      return;
    }
  }

  translationClick(info, tab);
});

chrome.tabs.onRemoved.addListener(tabId => {
  ExtSessionStorage.get('translatorTab')
      .then(items => {
        if (tabId == items.translatorTab) {
          ExtSessionStorage.set({translatorTab: null});
        }
      })
      .catch(err => console.log(err));
});

actionApi.onClicked.addListener(() => {
  chrome.runtime.openOptionsPage();
});

chrome.runtime.onMessage.addListener(request => {
  switch (request.action) {
    case 'clearTranslatorTab':
      ExtSessionStorage.set({translatorTab: null});
      break;

    default:
      console.error(
          `Unknown action "${request.action}" received as a message.`);
  }

  return undefined;
});
