/*
 * Copyright (C) 2018 Robert Bosch GmbH Copyright (C) 2018 Robert Bosch Manufacturing Solutions GmbH, Germany. All rights reserved.
 */

import { MasterDetailViewPage } from '../support/master-detail-view.po';

describe('master-detail-view', {retries: {openMode: 2, runMode: 2}}, () => {
  let page: MasterDetailViewPage;

  beforeEach(() => {
    // master-detail-view tests require maximized window
    // to prevent that the master-view is covered by the detail-view and click a row is not possible
    cy.viewport(1500, 800);
    page = new MasterDetailViewPage();
    page.navigateToList();
    page.getMasterDetailView().should('exist');
  });

  describe('expand and collapse', () => {
    it('master-view should be visible', () => {
      page.getMasterDetailView().should('exist');
      page.getMasterView().should('exist');
      page.getDetailView().should('exist');
    });

    it('should toggle sidebar', () => {
      page.switchToSidebar(() => {
        const rows = page.getListRows();
        rows.should('have.length.greaterThan', 0);
        rows.first().click();
        page.waitSidebarToBeVisible();
        page.expectCloseButtonToBeEnabled();
        page.getCloseButton().click();
        page.waitSidebarToBeClosed();
      });
    });

    it('should toggle dialog', () => {
      page.getListRows().should('have.length.greaterThan', 0);
      page.switchToDialog(() => {
        page.getListRows().first().click();
        page.waitDialogToBeVisible();
        page.expectCloseButtonToBeEnabled();
        page.getCloseButton().click();
        page.waitDialogToBeClosed();
      });
    });

    it('should change name in first row by sidebar', () => {
      const changedText = 'changed once';

      page.getListRows().should('have.length.greaterThan', 0);
      page.getListRows().first().should('not.contain', changedText);

      page.switchToSidebar(() => {
        page.getListRows().first().click();
        page.waitSidebarToBeVisible();
        page.getNameField().click();
        page.getNameField().clear();
        page.getNameField().type(changedText);
        page.getSaveButton().click();
        page.waitSidebarToBeClosed();
        page.getListRowContaining(changedText);
      });
    });

    it('should change name in first row by dialog', () => {
      const changedText = 'changed twice';

      page.getListRows().should('have.length.greaterThan', 0);
      page.getListRows().first().should('not.contain', changedText);

      page.switchToDialog(() => {
        page.getListRows().first().click();
        page.waitDialogToBeVisible();
        page.getNameField().click();
        page.getNameField().clear();
        page.getNameField().type(changedText);
        page.getSaveButton().click();
        page.waitDialogToBeClosed();
        page.getListRowContaining(changedText);
      });
    });

    it('should not navigate if changes not saved', () => {
      page.navigateToTable();

      const changedText1 = 'changed but not saved';
      const changedText2 = 'changed and saved';

      page.waitSidebarToBeClosed();
      page.waitDialogToBeClosed();

      page.switchToSidebar(() => {
        page.getTableRows().should('have.length.greaterThan', 0);
        page.getTableRows().first().should('not.contain', changedText1);

        page.getTableRows().first().click();

        page.waitSidebarToBeVisible();
        page.expectNameFieldToBeEnabled();

        page.getNameField().click();
        page.getNameField().clear();
        page.getNameField().type(changedText1);

        // now click second row to navigate
        page.getTableRows().eq(1).click();

        // when navigation to second row happens, the name field will contain the name contained in the second row.
        // but when we stuck on this page because of the CloseDetailsGuard we should still see the text we entered before.
        // we change and save again and expect to see the change in the first row, not in the second row.

        page.getNameField().click();
        page.getNameField().clear();
        page.getNameField().type(changedText2);
        page.getSaveButton().click();

        page.getTableRowContaining(changedText2);
      });
    });

    it('should NOT switch to mobile mode when size is larger', () => {
      // the table demo requires less space for the master-view
      // we take this demo because the window width on TFS server is limited to 1040x784
      // and that means that the detail view covers the master-view completely.
      // The table demo slides over when width is lower than lt-md
      // while the list demo slides over when the width is lower than lt-lg
      page.navigateToTable();
      page.waitSidebarToBeClosed();
      page.waitDialogToBeClosed();

      page.switchToSidebar(() => {
        page.getTableRows().first().click();
        page.waitSidebarToBeVisible();
        cy.viewport(1600, 600);
        page.expectSidebarSplit();
      });
    });

    it('should switch to mobile mode when size is small', () => {
      page.waitSidebarToBeClosed();
      page.waitDialogToBeClosed();

      page.switchToSidebar(() => {
        page.getListRows().first().click();
        page.waitSidebarToBeVisible();
        cy.viewport(800, 600);
        page.expectSidebarFullSize();
      });
    });
  });

  describe('resize handle', () => {
    it('should toggle resize handle', () => {
      page.getListRows().should('have.length.greaterThan', 0);

      page.switchToSidebar(() => {
        page.getListRows().first().click();
        page.waitSidebarToBeVisible();

        page.toggleResizeHandleSlide(() => {
          page.expectResizeHandleToBeEnabled();
        });
      });
    });

    it('should resize detail view', () => {
      const move = -100;
      const offset = 5;
      page.prepareResizeHandle();

      let oldWidth;

      page
        .getDetailView()
        .then(($detailView) => {
          oldWidth = $detailView.width();
        })
        .then(() => page.getResizeHandle())
        .then(($handle) => {
          const targetX = $handle[0].getBoundingClientRect().left + move + offset;

          page.getResizeHandle().trigger('mousedown', { button: 0 });
          cy.document().trigger('mousemove', { pageX: targetX })
          cy.document().trigger('mouseup', { force: true });

          page
            .getDetailView()
            .invoke('width')
            .should('be.lte', oldWidth - move + offset);
          page
            .getDetailView()
            .invoke('width')
            .should('be.gte', oldWidth + move + offset);
        });
    });
  });

  describe('Nested Tabs Row Click', () => {
    it('should split screen to half and display detail pane', () => {
      page.navigateToNestedTabs();
      page.getTableRows().first().click();
      page.getDetailContainer().invoke('width').should('be.at.least', 100);
    });
  });
});
