// ***********************************************
// 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) => { ... })

const logger = console;
Cypress.Commands.add(
  'console',
  {
    prevSubject: true,
  },
  (subject, method = 'log') => {
    logger[method]('The subject is', subject);
    return subject;
  }
);

Cypress.Commands.add('visitStorybook', () => {
  cy.log('visitStorybook');
  const host = Cypress.env('location') || 'http://localhost:8001';
  return cy
    .clearLocalStorage()
    .visit(`${host}/?path=/story/example-introduction--docs`)
    .get(`#storybook-preview-iframe`, { log: false })
    .its('0.contentDocument.body', { log: false })
    .should('not.be.empty')
    .then((body) => cy.wrap(body, { log: false }))
    .find('#docs-root', { log: false })
    .should('not.be.empty');
});

Cypress.Commands.add('getStoryElement', {}, () => {
  cy.log('getStoryElement');
  return cy
    .get(`#storybook-preview-iframe`, { log: false })
    .its('0.contentDocument.body', { log: false })
    .should('not.be.empty')
    .then((body) => cy.wrap(body, { log: false }))
    .find('#root', { log: false })
    .should('not.be.empty')
    .then((storyRoot) => cy.wrap(storyRoot, { log: false }));
});

Cypress.Commands.add('getDocsElement', {}, () => {
  cy.log('getDocsElement');
  return cy
    .get(`#storybook-preview-iframe`, { log: false })
    .its('0.contentDocument.body', { log: false })
    .should('not.be.empty')
    .then((body) => cy.wrap(body, { log: false }))
    .find('#docs-root', { log: false })
    .should('not.be.empty')
    .then((storyRoot) => cy.wrap(storyRoot, { log: false }));
});

Cypress.Commands.add('getCanvasElement', {}, () => {
  cy.log('getCanvasElement');
  return cy
    .get(`#storybook-preview-iframe`, { log: false })
    .then((iframe) => cy.wrap(iframe, { log: false }));
});

Cypress.Commands.add('getCanvasBodyElement', {}, () => {
  cy.log('getCanvasBodyElement');
  return cy
    .getCanvasElement()
    .its('0.contentDocument.body', { log: false })
    .should('not.be.empty')
    .then((body) => cy.wrap(body, { log: false }));
});

Cypress.Commands.add('navigateToStory', (kind, name) => {
  const kindId = kind.replace(/ /g, '-').toLowerCase();
  const storyId = name.replace(/ /g, '-').toLowerCase();

  const storyLinkId = `#${kindId}--${storyId}`;
  cy.log(`navigateToStory ${kind} ${name}`);

  // Section might be collapsed
  if (Cypress.$(`#${kindId}`).length) {
    cy.get(`#${kindId}`).then(async ($item) => {
      if ($item.attr('aria-expanded') === 'false') {
        await $item.click();
        // eslint-disable-next-line cypress/no-unnecessary-waiting
        cy.wait(300);
      }
    });
  }

  cy.get(storyLinkId).click({ force: true });

  // FIXME: Find a way to not wait like this but check for an element in the UI
  // A pause is good when switching stories
  // eslint-disable-next-line cypress/no-unnecessary-waiting
  cy.wait(300);

  // assert url changes
  const viewMode = name === 'docs' ? 'docs' : 'story';
  cy.url().should('include', `path=/${viewMode}/${kindId}--${storyId}`);
  cy.get(storyLinkId).should('have.attr', 'data-selected', 'true');

  // A pause is good when switching stories
  // eslint-disable-next-line cypress/no-unnecessary-waiting
  cy.wait(50);
});

Cypress.Commands.add('viewAddonPanel', (name) => {
  cy.get(`[role=tablist] button[role=tab]`).contains(name).click();
});

Cypress.Commands.add('viewAddonTab', (name) => {
  cy.get(`[role=main] button[type=button]`).contains(name).click();
});
