import { test } from 'qunit';
import moduleForAcceptance from 'web-client/tests/helpers/module-for-acceptance';
import ExtensionSettingsPage from 'web-client/tests/pages/settings/extensions';
import { stubLogin } from 'web-client/tests/helpers/stub-login';

const TOTAL_EXTENSION_COUNT = 10;
const INSTALLED_EXTENSION_COUNT = 5;
const ACTIVE_EXTENSION_COUNT = 2;
const INACTIVE_EXTENSION_COUNT = INSTALLED_EXTENSION_COUNT - ACTIVE_EXTENSION_COUNT;
const AVAILABLE_EXTENION_COUNT = TOTAL_EXTENSION_COUNT - INSTALLED_EXTENSION_COUNT;

const AVAILABLE_CARD_SELECTOR = '[data-test-selector="ext-available"]';
const AVAILABLE_CARD_INSTALL_SELECTOR = '[data-test-selector="ext-available-install"]';

const INSTALLED_CARD_SELECTOR = '[data-test-selector="ext-installed"]';
const INSTALLED_CARD_ACTIVATE_SELECTOR = '[data-test-selector="ext-installed-activate"]';
const INSTALLED_CARD_UNINSTALL_SELECTOR = '[data-test-selector="ext-installed-uninstall"]';
const INSTALLED_CARD_DEACTIVATE_SELECTOR = '[data-test-selector="ext-installed-deactivate"]';
const ACTIVATION_NEW_SELECTOR = '[data-test-selector="ext-activate-new"] .balloon__link';

const EXT_DIALOG_CANCEL_SELECTOR = '[data-test-selector="ext-modal-cancel"]';
const EXT_DIALOG_PROCEED_SELECTOR = '[data-test-selector="ext-modal-proceed"]';

moduleForAcceptance('Acceptance | /settings/extensions', {
  beforeEach() {
    this.page = ExtensionSettingsPage.create();
    this.allExtensions = this.server.createList('extension', TOTAL_EXTENSION_COUNT);

    let installedExtensions = this.allExtensions.slice(-INSTALLED_EXTENSION_COUNT);
    this.installedExtensions = installedExtensions.map(extension => {
      return this.server.create('extension-installation', { channelId: '12345', extension });
    });

    let activeExtensions = this.installedExtensions.slice(-ACTIVE_EXTENSION_COUNT);

    let slotIndex = 0;
    this.activeExtensions = activeExtensions.map(installation => {
      ++slotIndex;
      installation.update({
        active: true,
        config: JSON.stringify({ slot: `extension-slot-${slotIndex}`})
      });
    });
  }
});

test('visiting extension settings redirects to default settings page when not in EXTENSIONS experiment', function(assert) {
  assert.expect(1);

  stubLogin();

  visit(this.page.url());

  andThen(() => {
    assert.notEqual(currentURL(), this.page.url());
  });
});

test('visiting extension settings redirects to default settings page when in EXTENSIONS experiment, but not logged in as staff', function(assert) {
  assert.expect(1);

  stubLogin();
  this.experiments.use({ EXTENSIONS: 'yes' });

  visit(this.page.url());

  andThen(() => {
    assert.notEqual(currentURL(), this.page.url());
  });
});

test('visiting extension settings loads properly when in EXTENSIONS experiment as staff', function(assert) {
  assert.expect(1);

  stubLogin({ is_staff: true });
  this.experiments.use({ EXTENSIONS: 'yes' });

  visit(this.page.url());

  andThen(() => {
    assert.equal(currentURL(), this.page.url());
  });
});

test('visiting extension settings loads available and installed extensions', function(assert) {
  assert.expect(2);

  stubLogin({ is_staff: true });
  this.experiments.use({ EXTENSIONS: 'yes' });

  visit(this.page.url());

  andThen(() => {
    assert.equal(find(AVAILABLE_CARD_SELECTOR).length, INSTALLED_EXTENSION_COUNT, `${INSTALLED_EXTENSION_COUNT} available extensions were rendered.`);
    assert.equal(find(INSTALLED_CARD_SELECTOR).length, INSTALLED_EXTENSION_COUNT, `${INSTALLED_EXTENSION_COUNT} installed extensions were rendered.`);
  });
});

test('visiting extension settings, user is able install extensions', function(assert) {
  assert.expect(4);

  stubLogin({ is_staff: true });
  this.experiments.use({ EXTENSIONS: 'yes' });

  visit(this.page.url());

  andThen(() => {
    assert.equal(find(AVAILABLE_CARD_SELECTOR).length, AVAILABLE_EXTENION_COUNT, `${AVAILABLE_EXTENION_COUNT} available extensions were rendered.`);
    assert.equal(find(INSTALLED_CARD_SELECTOR).length, INSTALLED_EXTENSION_COUNT, `${INSTALLED_EXTENSION_COUNT} installed extensions were rendered.`);
  });

  click(`${AVAILABLE_CARD_INSTALL_SELECTOR}:eq(0)`);
  click(EXT_DIALOG_CANCEL_SELECTOR);

  andThen(() => {
    assert.equal(find(AVAILABLE_CARD_SELECTOR).length, AVAILABLE_EXTENION_COUNT - 1, `${AVAILABLE_EXTENION_COUNT - 1} available extensions were rendered after installation.`);
    assert.equal(find(INSTALLED_CARD_SELECTOR).length, INSTALLED_EXTENSION_COUNT + 1, `${INSTALLED_EXTENSION_COUNT + 1} installed extensions were rendered after installation.`);
  });
});

test('visiting extension settings, user is able uninstall extensions', function(assert) {
  assert.expect(4);

  stubLogin({ is_staff: true });
  this.experiments.use({ EXTENSIONS: 'yes' });

  visit(this.page.url());

  andThen(() => {
    assert.equal(find(AVAILABLE_CARD_SELECTOR).length, AVAILABLE_EXTENION_COUNT, `${AVAILABLE_EXTENION_COUNT} available extensions were rendered.`);
    assert.equal(find(INSTALLED_CARD_SELECTOR).length, INSTALLED_EXTENSION_COUNT, `${INSTALLED_EXTENSION_COUNT} installed extensions were rendered.`);
  });

  click(`${INSTALLED_CARD_UNINSTALL_SELECTOR}:eq(0)`);
  click(EXT_DIALOG_PROCEED_SELECTOR);

  andThen(() => {
    assert.equal(find(AVAILABLE_CARD_SELECTOR).length, AVAILABLE_EXTENION_COUNT + 1, `${AVAILABLE_EXTENION_COUNT + 1} available extensions were rendered after uninstallation.`);
    assert.equal(find(INSTALLED_CARD_SELECTOR).length, INSTALLED_EXTENSION_COUNT - 1, `${INSTALLED_EXTENSION_COUNT - 1} installed extensions were rendered after uninstallation.`);
  });
});

test('visiting extension settings, user is able activate extensions', function(assert) {
  assert.expect(3);

  stubLogin({ is_staff: true });
  this.experiments.use({ EXTENSIONS: 'yes' });

  visit(this.page.url());

  let extensionToActivate = this.installedExtensions[0];
  andThen(() => {
    assert.equal(find(INSTALLED_CARD_ACTIVATE_SELECTOR).length, INACTIVE_EXTENSION_COUNT, `${INACTIVE_EXTENSION_COUNT} inactive installed extensions were rendered.`);
  });

  click(`${INSTALLED_CARD_ACTIVATE_SELECTOR}:eq(0)`);
  click(ACTIVATION_NEW_SELECTOR);
  click(EXT_DIALOG_PROCEED_SELECTOR);

  andThen(() => {
    extensionToActivate.reload();
    let { id, version } = extensionToActivate.extension;
    let config = JSON.parse(extensionToActivate.config);
    assert.equal(config.slot, `ext-${id}-${version}`, 'Extension activation created a new panel with the expected slot name.');
    assert.equal(find(INSTALLED_CARD_ACTIVATE_SELECTOR).length, INACTIVE_EXTENSION_COUNT - 1, `${INACTIVE_EXTENSION_COUNT - 1} inactive installed extensions were rendered after activation.`);
  });
});

test('visiting extension settings, user is able deactivate extensions', function(assert) {
  assert.expect(2);

  stubLogin({ is_staff: true });
  this.experiments.use({ EXTENSIONS: 'yes' });

  visit(this.page.url());

  andThen(() => {
    assert.equal(find(INSTALLED_CARD_DEACTIVATE_SELECTOR).length, ACTIVE_EXTENSION_COUNT, `${ACTIVE_EXTENSION_COUNT} active extensions were rendered.`);
  });

  click(`${INSTALLED_CARD_DEACTIVATE_SELECTOR}:eq(0)`);

  andThen(() => {
    assert.equal(find(INSTALLED_CARD_DEACTIVATE_SELECTOR).length, ACTIVE_EXTENSION_COUNT - 1, `${ACTIVE_EXTENSION_COUNT + 1} active extensions were rendered after deactivation.`);
  });
});


