// ***********************************************
// This example commands.js shows you how to
// create various custom commands and overwrite
// existing commands.
//
// For more comprehensive examples of custom
// commands please read more here:
// https://on.cypress.io/custom-commands
// ***********************************************
//
//
// -- This is a parent command --
// Cypress.Commands.add("login", (email, password) => { ... })
//
//
// -- This is a child command --
// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
//
//
// -- This is a dual command --
// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
//
//
// -- This is will overwrite an existing command --
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
// installed a fork of the original package, because of this issue:
// https://github.com/tgriesser/cypress-graphql-mock/issues/23
// todo: once above issue is fixed, go back to the original repo -> npm install cypress-graphql-mock
// import 'cypress-graphql-mock';
import '@iam4x/cypress-graphql-mock';
import mocks from '../fixtures/mocks';

Cypress.Commands.add('apolloLogin', (username, password) => {
  const payload = {
    'operationName': 'BetaLogin',
    'variables': {
      'input': {
        'usernameInput': username,
        'passwordInput': password,
      },
    },
    'query': 'mutation BetaLogin($input: BetaLoginInput!) {\n  betaLogin(input: $input) {\n    success\n    __typename\n  }\n}\n',
  };

  cy.request({
    method: 'POST',
    url: '/api/graphql-public/',
    body: payload,
  });
});

// todo: replace with apollo call
Cypress.Commands.add('login', (username, password, visitLogin = false) => {
  if (visitLogin) {
    cy.visit('/beta-login');
  }

  if (username !== '') {
    cy.get('[data-cy=email-input]').type(username);
  }

  if (password !== '') {
    cy.get('[data-cy=password-input]').type(password);
  }
  cy.get('[data-cy=login-button]').click();
});

Cypress.Commands.add('logout', () => {
  cy.get('[data-cy=user-icon]').click();
  cy.get('[data-cy=logout]').click();
});

Cypress.Commands.add('loginByCsrf', (username, password, csrftoken) => {
  cy.request({
    method: 'POST',
    url: '/accounts/login/',
    failOnStatusCode: false,
    form: true,
    body: {
      username: username,
      password: password,
      csrfmiddlewaretoken: csrftoken,
    },
  });
});

Cypress.Commands.add('startGraphQLCapture', () => {
  cy.server();
  cy.route('POST', '/api/graphql/').as('graphQL');
});

// from https://stackoverflow.com/questions/53814647/how-can-i-alias-specific-graphql-requests-in-cypress
Cypress.Commands.add('waitFor', operationName => {
  cy.wait('@graphQL').then(({request}) => {
    if (request.body.operationName !== operationName) {
      return cy.waitFor(operationName);
    }
  });
});

Cypress.Commands.add('changePassword', (oldPassword, newPassword) => {
  if (oldPassword) {
    cy.get('[data-cy=old-password]').type(oldPassword);
  }

  if (newPassword) {
    cy.get('[data-cy=new-password]').type(newPassword);
  }
  cy.get('[data-cy=change-password-button]').click();
});

Cypress.Commands.add('checkEmailAvailable', (email) => {
  cy.get('[data-cy="email-input"]').type(email);
  cy.get('[data-cy="hello-button"]').click();
});

Cypress.Commands.add('enterPassword', (password) => {
  cy.get('[data-cy="password-input"]').type(password);
  cy.get('[data-cy="login-button"]').click();
});

Cypress.Commands.add('getByDataCy', (selector) => {
  return cy.get(`[data-cy=${selector}]`);
});

Cypress.Commands.add('selectClass', (schoolClass) => {
  cy.getByDataCy('user-widget-avatar').click();
  cy.getByDataCy('class-selection').click();
  cy.getByDataCy('class-selection-entry').contains(schoolClass).click();
});

Cypress.Commands.add('fakeLogin', () => {
  cy.log('Logging in (fake)');
  cy.setCookie('loginStatus', 'true');
});

Cypress.Commands.add('isSubmissionReadOnly', (myText) => {
  cy.get('.submission-form__textarea--readonly').as('textarea');

  cy.get('@textarea').invoke('val').should('contain', myText);
  cy.get('@textarea').should('have.attr', 'readonly');
  cy.getByDataCy('submission-form-submit').should('not.exist');
});

Cypress.Commands.add('openSidebar', () => {
    cy.getByDataCy('user-widget-avatar').click();
});

Cypress.Commands.add('setup', () => {
  cy.fakeLogin('nino.teacher', 'test');
    cy.server();
    cy.viewport('macbook-15');
    cy.task('getSchema').then(schema => {
      cy.mockGraphql({
        schema,
        mocks,
      });
    });
});
