const username = Cypress.env('username')
const password = Cypress.env('password')
const hostUrl = Cypress.env('hosturl')
const appLocation = Cypress.env('appLocation')
const longerCommandTimeout = Cypress.env('longerCommandTimeout')
const serverType = Cypress.env('serverType')
const libraryToOpenIncludes = Cypress.env(`libraryToOpenIncludes_${serverType}`)
const downloadsFolder = Cypress.config('downloadsFolder')

import { deleteDownloadsFolder } from '../util/deleteDownloadFolder'

context('download files test: ', function () {
  this.beforeAll(() => {
    cy.visit(`${hostUrl}/SASLogon/logout`)
    cy.loginAndUpdateValidKey()
  })

  this.beforeEach(() => {
    cy.visit(hostUrl + appLocation)
    cy.get('input.username').type(username)
    cy.get('input.password').type(password)
    cy.get('.login-group button').click()

    visitPage('home')
  })

  this.afterEach(() => {
    deleteDownloadsFolder()
  })

  it('1 | downloads audit file', (done) => {
    visitPage('approve/toapprove')

    cy.get('.app-loading', { timeout: longerCommandTimeout })
      .should('not.exist')
      .then(() => {
        cy.get('.btn.btn-success')
          .should('be.visible')
          .then((buttons) => {
            buttons[0].click()
            const id = buttons[0].id

            checkForFileDownloaded(id, 'zip', () => done())
          })
      })
  })

  it('2 | downloads viewer csv', (done) => {
    visitPage('view/data')

    openTableFromTree(libraryToOpenIncludes, 'mpe_x_test')

    openDownloadModal(() => {
      cy.get('select')
        .select('CSV')
        .then(() => {
          cy.get('.btn.btn-sm.btn-success-outline').then((button) => {
            button.trigger('click')

            const id = button[0].id

            checkForFileDownloaded(id, 'csv', () => done())
          })
        })
    })
  })

  it('3 | downloads viewer excel', (done) => {
    visitPage('view/data')

    openTableFromTree(libraryToOpenIncludes, 'mpe_x_test')

    openDownloadModal(() => {
      cy.get('select')
        .select('Excel')
        .then(() => {
          cy.get('.btn.btn-sm.btn-success-outline').then((button) => {
            button.trigger('click')

            const id = button[0].id

            checkForFileDownloaded(id, 'xlsx', () => done())
          })
        })
    })
  })

  it('4 | downloads viewer SAS Datalines', (done) => {
    visitPage('view/data')

    openTableFromTree(libraryToOpenIncludes, 'mpe_x_test')

    openDownloadModal(() => {
      cy.get('select')
        .select('SAS Datalines')
        .then(() => {
          cy.get('.btn.btn-sm.btn-success-outline').then((button) => {
            button.trigger('click')

            const id = button[0].id

            checkForFileDownloaded(id, 'sas', () => done())
          })
        })
    })
  })

  it('5 | downloads viewer SAS DDL', (done) => {
    visitPage('view/data')

    openTableFromTree(libraryToOpenIncludes, 'mpe_x_test')

    openDownloadModal(() => {
      cy.get('select')
        .select('SAS DDL')
        .then(() => {
          cy.get('.btn.btn-sm.btn-success-outline').then((button) => {
            button.trigger('click')

            const id = button[0].id

            checkForFileDownloaded(id, 'ddl', () => done(), '_')
          })
        })
    })
  })

  it('6 | downloads viewer TSQL DDL', (done) => {
    visitPage('view/data')

    openTableFromTree(libraryToOpenIncludes, 'mpe_x_test')

    openDownloadModal(() => {
      cy.get('select')
        .select('TSQL DDL')
        .then(() => {
          cy.get('.btn.btn-sm.btn-success-outline').then((button) => {
            button.trigger('click')

            const id = button[0].id

            checkForFileDownloaded(id, 'ddl', () => done(), '_')
          })
        })
    })
  })

  it('7 | downloads viewer PGSQL DDL', (done) => {
    visitPage('view/data')

    openTableFromTree(libraryToOpenIncludes, 'mpe_x_test')

    openDownloadModal(() => {
      cy.get('select')
        .select('PGSQL DDL')
        .then(() => {
          cy.get('.btn.btn-sm.btn-success-outline').then((button) => {
            button.trigger('click')

            const id = button[0].id

            checkForFileDownloaded(id, 'ddl', () => done(), '_')
          })
        })
    })
  })

  this.afterEach(() => {
    cy.visit(`${hostUrl}/SASLogon/logout`)
  })
})

const visitPage = (url: string) => {
  cy.visit(`${hostUrl}${appLocation}/#/${url}`)
}

const checkForFileDownloaded = (
  id: string,
  extension: string,
  callback?: any,
  libDivider: string = '.'
) => {
  cy.on('url:changed', (newUrl) => {
    console.log('newUrl', newUrl)
  })

  id = id.replace('.', libDivider)

  const filename = downloadsFolder + '/' + id + '.' + extension
  // browser might take a while to download the file,
  // so use "cy.readFile" to retry until the file exists
  // and has length - and we assume that it has finished downloading then
  cy.readFile(filename, { timeout: longerCommandTimeout })
    .should('have.length.gt', 10)
    .then((file) => {
      if (callback) callback()
    })
}

const openDownloadModal = (callback?: any) => {
  cy.get('.btn.btn-sm.btn-outline.filterSide.dropdown-toggle')
    .click()
    .then(() => {
      cy.get('clr-dropdown-menu button').then((buttons) => {
        for (let button of buttons) {
          if (button.innerText.toLowerCase().includes('download')) {
            button.click()

            if (callback) callback()
          }
        }
      })
    })
}

const openTableFromTree = (libNameIncludes: string, tablename: string) => {
  cy.get('.app-loading', { timeout: longerCommandTimeout })
    .should('not.exist')
    .then(() => {
      cy.get('.nav-tree clr-tree > clr-tree-node', {
        timeout: longerCommandTimeout
      }).then((treeNodes: any) => {
        let viyaLib

        for (let node of treeNodes) {
          if (node.innerText.toLowerCase().includes(libNameIncludes)) {
            viyaLib = node
            break
          }
        }

        console.log('viyaLib', viyaLib)

        cy.get(viyaLib).within(() => {
          cy.get(
            '.clr-tree-node-content-container .clr-treenode-content p'
          ).click()

          cy.get('.clr-treenode-link').then((innerNodes: any) => {
            for (let innerNode of innerNodes) {
              if (innerNode.innerText.toLowerCase().includes(tablename)) {
                innerNode.click()
                break
              }
            }
          })
        })
      })
    })
}
