import {getDocURL, getDocURLWithRef, getExtVersion, isProdVersion} from '../common/extUtils.js';
import {ensureOptPermissions, grantedOptPermissions, isPermissionsObjectEmpty, missingPermissions} from '../common/options/optionsPermissions.js';
import {cleanUpOptions, optionsPrototype, specialOptions} from '../common/options/optionsUtils.js';

import optionsPage from './optionsPage.json5';

var savedSuccessfullyTimeout = null;

const exclusiveOptions = [['thread', 'threadall']];
const kClickShouldEnableFeat = 'data-click-should-enable-feature';

// Get the value of the option set in the options/experiments page
function getOptionValue(opt) {
  if (specialOptions.includes(opt)) {
    switch (opt) {
      case 'profileindicatoralt_months':
        return document.getElementById(opt).value || 12;

      case 'ccdarktheme_mode':
        return document.getElementById(opt).value || 'switch';

      default:
        console.warn('Unrecognized option: ' + opt);
        return undefined;
    }
  }

  return document.getElementById(opt).checked || false;
}

// Returns whether the option is included in the current context
function isOptionShown(opt) {
  if (!optionsPrototype.hasOwnProperty(opt)) return false;
  return optionsPrototype[opt].context == window.CONTEXT;
}

function save(e) {
  // Validation checks before saving
  if (isOptionShown('profileindicatoralt_months')) {
    var months = document.getElementById('profileindicatoralt_months');
    if (!months.checkValidity()) {
      console.warn(months.validationMessage);
      return;
    }
  }

  e.preventDefault();

  chrome.storage.sync.get(null, function(items) {
    var options = cleanUpOptions(items, true);

    // Save
    Object.keys(options).forEach(function(opt) {
      if (!isOptionShown(opt)) return;
      options[opt] = getOptionValue(opt);
    });

    chrome.storage.sync.set(options, function() {
      window.close();

      // In browsers like Firefox window.close is not supported:
      if (savedSuccessfullyTimeout !== null)
        window.clearTimeout(savedSuccessfullyTimeout);

      document.getElementById('save-indicator').innerText =
          '✓ ' + chrome.i18n.getMessage('options_saved');
      savedSuccessfullyTimeout = window.setTimeout(_ => {
        document.getElementById('save-indicator').innerText = '';
      }, 3699);
    });
  });
}

function i18n() {
  document.querySelectorAll('[data-i18n]')
      .forEach(
          el => el.innerHTML = chrome.i18n.getMessage(
              'options_' + el.getAttribute('data-i18n')));
}

window.addEventListener('load', function() {
  if (window.CONTEXT == 'options') {
    if (!isProdVersion()) {
      var experimentsLink = document.querySelector('.experiments-link');
      experimentsLink.removeAttribute('hidden');
      experimentsLink.addEventListener('click', _ => chrome.tabs.create({
        url: chrome.runtime.getURL('options/experiments.html'),
      }));
    }

    // Add options to page
    let optionsContainer = document.getElementById('options-container');
    for (let section of optionsPage.sections) {
      if (section?.name) {
        let sectionHeader = document.createElement('h4');
        sectionHeader.setAttribute('data-i18n', section.name);
        optionsContainer.append(sectionHeader);
      }

      if (section?.options) {
        for (let option of section.options) {
          if (option?.customHTML) {
            optionsContainer.insertAdjacentHTML('beforeend', option.customHTML);
          } else {
            let optionEl = document.createElement('div');
            optionEl.classList.add('option');

            let checkbox = document.createElement('input');
            checkbox.setAttribute('type', 'checkbox');
            checkbox.id = option.codename;

            let label = document.createElement('label');
            label.setAttribute('for', checkbox.id);
            label.setAttribute('data-i18n', option.codename);

            optionEl.append(checkbox, ' ', label);

            if (option?.experimental) {
              let experimental = document.createElement('span');
              experimental.classList.add('experimental-label');
              experimental.setAttribute('data-i18n', 'experimental_label');

              optionEl.append(' ', experimental);
            }

            optionsContainer.append(optionEl);
          }

          // Add optional permissions warning label and kill switch component
          // after each option.
          let optionalPermissionsWarningLabel = document.createElement('div');
          optionalPermissionsWarningLabel.classList.add(
              'optional-permissions-warning-label');
          optionalPermissionsWarningLabel.setAttribute('hidden', '');
          optionalPermissionsWarningLabel.setAttribute(
              'data-feature', option.codename);
          optionalPermissionsWarningLabel.setAttribute(
              'data-i18n', 'optionalpermissionswarning_label');

          let killSwitchComponent = document.createElement('div');
          killSwitchComponent.classList.add('kill-switch-label');
          killSwitchComponent.setAttribute('hidden', '');
          killSwitchComponent.setAttribute('data-feature', option.codename);
          killSwitchComponent.setAttribute('data-i18n', 'killswitchenabled');

          optionsContainer.append(
              optionalPermissionsWarningLabel, killSwitchComponent);
        }
      }

      if (section?.footerHTML) {
        optionsContainer.insertAdjacentHTML('beforeend', section.footerHTML);
      }
    }

    var featuresLink = document.querySelector('.features-link');
    featuresLink.href = getDocURL('features.md');

    var profileIndicatorLink =
        document.getElementById('profileIndicatorMoreInfo');
    profileIndicatorLink.href = getDocURL('op_indicator.md');
  }

  i18n();

  // Add custom handlers
  let manageWorkflowsBtn = document.getElementById('manage-workflows');
  if (manageWorkflowsBtn)
    manageWorkflowsBtn.addEventListener('click', e => {
      e.preventDefault();
      chrome.tabs.create({
        url: chrome.runtime.getURL('options/workflows.html'),
      })
    });

  chrome.storage.sync.get(null, function(items) {
    items = cleanUpOptions(items, false);

    // If some features have been force disabled, communicate this to the user.
    if (items?._forceDisabledFeatures &&
        items._forceDisabledFeatures.length > 0) {
      if (window.CONTEXT == 'options') {
        document.getElementById('kill-switch-warning')
            .removeAttribute('hidden');
      }
    }

    for (var entry of Object.entries(optionsPrototype)) {
      var opt = entry[0];
      var optMeta = entry[1];

      if (!isOptionShown(opt)) continue;

      if (specialOptions.includes(opt)) {
        switch (opt) {
          case 'profileindicatoralt_months':
            var input = document.createElement('input');
            input.type = 'number';
            input.id = 'profileindicatoralt_months';
            input.max = '12';
            input.min = '1';
            input.value = items[opt];
            input.required = true;
            document.getElementById('profileindicatoralt_months--container')
                .appendChild(input);
            break;

          case 'ccdarktheme_mode':
            var select = document.createElement('select');
            select.id = 'ccdarktheme_mode';

            const modes = ['switch', 'system'];
            for (const mode of modes) {
              var modeOption = document.createElement('option');
              modeOption.value = mode;
              modeOption.textContent =
                  chrome.i18n.getMessage('options_ccdarktheme_mode_' + mode);
              if (items.ccdarktheme_mode == mode) modeOption.selected = true;
              select.appendChild(modeOption);
            }

            document.getElementById('ccdarktheme_mode--container')
                .appendChild(select);
            break;

          default:
            console.warn('Unrecognized option: ' + opt);
            break;
        }
        continue;
      }

      if (items[opt] === true) document.getElementById(opt).checked = true;
      if (window.CONTEXT == 'options' &&
          items?._forceDisabledFeatures?.includes?.(opt))
        document.querySelector('.kill-switch-label[data-feature="' + opt + '"]')
            .removeAttribute('hidden');
    }

    exclusiveOptions.forEach(exclusive => {
      if (!isOptionShown(exclusive[0]) || !isOptionShown(exclusive[1])) return;

      exclusive.forEach(
          el => document.getElementById(el).addEventListener('change', e => {
            if (document.getElementById(exclusive[0]).checked &&
                document.getElementById(exclusive[1]).checked) {
              document
                  .getElementById(
                      exclusive[(e.currentTarget.id == exclusive[0] ? 1 : 0)])
                  .checked = false;
            }
          }));
    });

    // Handle options which need optional permissions.
    grantedOptPermissions()
        .then(grantedPerms => {
          for (const [opt, optMeta] of Object.entries(optionsPrototype)) {
            if (!optMeta.requiredOptPermissions || !isOptionShown(opt))
              continue;

            let warningLabel = document.querySelector(
                '.optional-permissions-warning-label[data-feature="' + opt +
                '"]');

            // Ensure we have the appropriate permissions when the checkbox
            // switches from disabled to enabled.
            //
            // Also, if the checkbox was indeterminate because the feature was
            // enabled but not all permissions had been granted, enable the
            // feature in order to trigger the permission request again.
            let checkbox = document.getElementById(opt);
            if (!checkbox) {
              console.error('Expected checkbox for feature "' + opt + '".');
              continue;
            }
            checkbox.addEventListener('change', () => {
              if (checkbox.hasAttribute(kClickShouldEnableFeat)) {
                checkbox.removeAttribute(kClickShouldEnableFeat);
                checkbox.checked = true;
              }

              if (checkbox.checked)
                ensureOptPermissions(opt)
                    .then(granted => {
                      if (granted) {
                        warningLabel.setAttribute('hidden', '');
                        if (!document.querySelector(
                                '.optional-permissions-warning-label:not([hidden])'))
                          document
                              .getElementById('optional-permissions-warning')
                              .setAttribute('hidden', '');
                      } else
                        document.getElementById(opt).checked = false;
                    })
                    .catch(err => {
                      console.error(
                          'An error ocurred while ensuring that the optional ' +
                              'permissions were granted after the checkbox ' +
                              'was clicked for feature "' + opt + '":',
                          err);
                      document.getElementById(opt).checked = false;
                    });
            });

            // Add warning message if some permissions are missing and the
            // feature is enabled.
            if (items[opt] === true) {
              let shownHeaderMessage = false;
              missingPermissions(opt, grantedPerms)
                  .then(missingPerms => {
                    if (!isPermissionsObjectEmpty(missingPerms)) {
                      checkbox.indeterminate = true;
                      checkbox.setAttribute(kClickShouldEnableFeat, '');

                      warningLabel.removeAttribute('hidden');

                      if (!shownHeaderMessage) {
                        shownHeaderMessage = true;
                        document.getElementById('optional-permissions-warning')
                            .removeAttribute('hidden');
                      }
                    }
                  })
                  .catch(err => console.error(err));
            }
          }
        })
        .catch(err => console.error(err));

    document.querySelector('#save').addEventListener('click', save);
  });
});
