import module from '../../../fixtures/module.minimal';
import { getMinimalMe } from '../../../support/helpers';
import { hasOperationName } from '../../../support/graphql';

let snapshotTitle;
let deleteSuccess;
let page;

const moduleWithSnapshots = {
  ...module,
  snapshots: [
    {
      id: 'U25hcHNob3ROb2RlOjQ=',
      title: 'Old Title',
      created: '2020-01-01',
      mine: true,
      shared: false,
      creator: 'me',
    },
    {
      id: 'U25hcHNob3ROb2RlOjU=',
      title: 'Shared snapshot',
      created: '2020-01-02',
      mine: false,
      shared: true,
      creator: 'someone else',
    },
  ],
};

const mockDeleteSnapshot = (success) => {
  cy.intercept('POST', '/api/graphql', (req) => {
    if (hasOperationName(req, 'DeleteSnapshot')) {
      let result;
      if (success) {
        result = {
          message: 'yay!',
          __typename: 'Success',
        };
      } else {
        result = {
          reason: 'Not the owner',
          __typename: 'NotOwner',
        };
      }
      req.reply({
        data: {
          deleteSnapshot: {
            result,
          },
        },
      });
    }
  });
};

const mockUpdateSnapshot = (title) => {
  cy.intercept('POST', '/api/graphql', (req) => {
    if (hasOperationName(req, 'UpdateSnapshot')) {
      let snapshot;
      if (title) {
        snapshot = {
          __typename: 'SnapshotNode',
          id: 'U25hcHNob3ROb2RlOjQ=',
          title,
        };
      } else {
        snapshot = {
          __typename: 'NotOwner',
          reason: 'Not the owner',
        };
      }
      req.reply({
        data: {
          updateSnapshot: {
            snapshot,
          },
        },
      });
    }
  });
};

// wait for the specified amount of requests in the test, so they don't spill over to the next test
const waitForNRequests = (n) => {
  for (let i = 0; i < n; i++) {
    cy.wait('@graphqlRequest');
  }
};

describe('Snapshot', () => {
  const operations = (isTeacher) => ({
    operations: {
      UpdateSnapshot: {
        updateSnapshot: {
          snapshot() {
            let result;
            if (snapshotTitle) {
              result = {
                __typename: 'SnapshotNode',
                id: 'U25hcHNob3ROb2RlOjQ=',
                title: snapshotTitle,
              };
            } else {
              result = {
                __typename: 'NotOwner',
                reason: 'Not the owner',
              };
            }
            return result;
          },
        },
      },
      DeleteSnapshot: {
        deleteSnapshot: {
          result() {
            let result;
            if (deleteSuccess) {
              result = {
                message: 'yay!',
                __typename: 'Success',
              };
            } else {
              result = {
                reason: 'Not the owner',
                __typename: 'NotOwner',
              };
            }
            return result;
          },
        },
      },
      MeQuery: getMinimalMe({ isTeacher }),
      ModuleDetailsQuery: {
        module,
      },
      CreateSnapshot: {
        createSnapshot: {
          snapshot: {
            id: 'snapshot-id',
            title: 'Mi Snapshot',
            created: '2022-01-01',
            creator: 'me',
            shared: false,
            mine: true,
          },
          success: true,
        },
      },
      UpdateLastModule: {},
      ModuleEditModeQuery: {
        module: {
          slug: module.slug,
        },
      },
      ModuleSnapshotsQuery: {
        module: {
          ...module,
          snapshots: [
            {
              id: 'U25hcHNob3ROb2RlOjQ=',
              title: 'Old Title',
              created: '2020-01-01',
              mine: true,
              shared: false,
              creator: 'me',
            },
            {
              id: 'U25hcHNob3ROb2RlOjU=',
              title: 'Shared snapshot',
              created: '2020-01-02',
              mine: false,
              shared: true,
              creator: 'someone else',
            },
          ],
        },
      },
      SnapshotDetail: {
        snapshot: {
          title: 'Shared snapshot',
          chapters: [],
          module: {},
        },
      },
      ApplySnapshot: {
        applySnapshot: {
          success: true,
        },
      },
    },
  });

  beforeEach(() => {
    snapshotTitle = false;
    deleteSuccess = false;
    page = moduleWithSnapshots;
    cy.setup();
  });

  it('Menu is visible for teacher', () => {
    cy.mockGraphqlOps(operations(true));
    cy.visit('module/miteinander-reden/');
    cy.getByDataCy('snapshot-menu').should('be.visible');
    waitForNRequests(4);
  });

  it('Menu is not visible for student', () => {
    cy.mockGraphqlOps(operations(false));
    cy.visit('module/miteinander-reden/');

    cy.getByDataCy('module-title').should('be.visible');
    cy.getByDataCy('snapshot-menu').should('not.exist');
    waitForNRequests(3);
  });

  it('Creates Snapshot', () => {
    cy.mockGraphqlOps(operations(true));
    cy.visit('module/miteinander-reden/snapshots');
    cy.getByDataCy('snapshot-list')
      .should('exist')
      .within(() => {
        cy.get('.snapshots__snapshot').should('have.length', 1);
      });
    cy.getByDataCy('back-link').click();
    cy.getByDataCy('module-snapshots-button').click();
    cy.getByDataCy('create-snapshot-button').click();
    cy.getByDataCy('show-all-snapshots-button').click();
    cy.getByDataCy('snapshot-list')
      .should('exist')
      .within(() => {
        cy.get('.snapshots__snapshot').should('have.length', 2);
      });
    waitForNRequests(7);
  });

  it('Applies Snapshot', () => {
    cy.mockGraphqlOps(operations(true));
    cy.visit('module/miteinander-reden/snapshots');
    cy.getByDataCy('snapshot-link').click();
    cy.getByDataCy('apply-checkbox').click();
    cy.getByDataCy('apply-button').click();

    cy.getByDataCy('module-title').should('exist');
    cy.getByDataCy('snapshot-header').should('not.exist');
    waitForNRequests(8);
  });

  it('Renames Snapshot', () => {
    cy.mockGraphqlOps(operations(true));
    const newTitle = 'New Title';
    snapshotTitle = newTitle;
    // mockUpdateSnapshot(newTitle);
    cy.visit('module/miteinander-reden/snapshots');
    cy.getByDataCy('snapshot-link').should('contain.text', 'Old Title');
    cy.getByDataCy('rename-snapshot-button').click();
    cy.getByDataCy('edit-name-input').clear().type(newTitle);
    cy.getByDataCy('modal-save-button').click();
    cy.getByDataCy('snapshot-link').should('contain.text', 'New Title');
    waitForNRequests(5);
  });

  it('Deletes Snapshot', () => {
    cy.mockGraphqlOps(operations(true));
    deleteSuccess = true;
    // mockDeleteSnapshot(true);
    cy.visit('module/miteinander-reden/snapshots');
    cy.getByDataCy('snapshot-entry').should('have.length', 1);
    cy.getByDataCy('delete-snapshot-button').click();
    cy.getByDataCy('modal-save-button').click();
    cy.getByDataCy('snapshot-entry').should('have.length', 0);
    waitForNRequests(6);
  });

  it('Displays the Snapshot list correcly', () => {
    cy.mockGraphqlOps(operations(true));
    cy.visit('module/miteinander-reden/snapshots');
    cy.getByDataCy('snapshot-entry').should('have.length', 1);
    cy.getByDataCy('delete-snapshot-button').should('exist');
    cy.getByDataCy('rename-snapshot-button').should('exist');
    cy.getByDataCy('snapshot-link').should('contain.text', 'Old Title');
    cy.getByDataCy('team-snapshots-link').click();
    cy.getByDataCy('snapshot-entry').should('have.length', 1);
    cy.getByDataCy('snapshot-link').should('contain.text', 'Shared snapshot');
    cy.getByDataCy('delete-snapshot-button').should('not.exist');
    cy.getByDataCy('rename-snapshot-button').should('not.exist');
    cy.getByDataCy('snapshot-link').click();
    cy.getByDataCy('module-title').should('contain.text', 'Shared snapshot');
    waitForNRequests(5);
  });

  afterEach(() => {});
});
