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 fixturePath = 'excels_general/'

context('filtering tests: ', function () {
  this.beforeAll(() => {
    cy.visit(`${hostUrl}/SASLogon/logout`, { timeout: longerCommandTimeout })
    cy.loginAndUpdateValidKey()
  })

  this.beforeEach(() => {
    cy.visit(hostUrl + appLocation, { timeout: longerCommandTimeout })

    visitPage('home')
  })

  it('1 | filter char field', (done) => {
    openTableFromTree(libraryToOpenIncludes, 'mpe_x_test')

    openFilterPopup(() => {
      setFilterWithValue('SOME_CHAR', 'this is dummy data', 'value', () => {
        checkInfoBarIncludes(
          `AND,AND,0,SOME_CHAR,=,"'this is dummy data'"`,
          (includes: boolean) => {
            if (includes) done()
          }
        )
      })
    })
  })

  it('2 | filter number field', (done) => {
    openTableFromTree(libraryToOpenIncludes, 'mpe_x_test')

    openFilterPopup(() => {
      setFilterWithValue('SOME_NUM', '42', 'value', () => {
        checkInfoBarIncludes(`AND,AND,0,SOME_NUM,=,42`, (includes: boolean) => {
          if (includes) done()
        })
      })
    })
  })

  it('3 | filter time field', (done) => {
    openTableFromTree(libraryToOpenIncludes, 'mpe_x_test')

    openFilterPopup(() => {
      setFilterWithValue('SOME_TIME', '00:00:42', 'time', () => {
        checkInfoBarIncludes(
          `AND,AND,0,SOME_TIME,=,42`,
          (includes: boolean) => {
            if (includes) done()
          }
        )
      })
    })
  })

  it('3.1 | Non picker - filter time field', (done) => {
    openTableFromTree(libraryToOpenIncludes, 'mpe_x_test')

    openFilterPopup(() => {
      setFilterWithValue('SOME_TIME', '42', 'value', () => {
        checkInfoBarIncludes(
          `AND,AND,0,SOME_TIME,=,42`,
          (includes: boolean) => {
            if (includes) done()
          }
        )
      })
    }, false)
  })

  it('4 | filter date field', (done) => {
    openTableFromTree(libraryToOpenIncludes, 'mpe_x_test')

    openFilterPopup(() => {
      setFilterWithValue('SOME_DATE', '12/02/1960', 'date', () => {
        checkInfoBarIncludes(
          `AND,AND,0,SOME_DATE,=,42`,
          (includes: boolean) => {
            if (includes) done()
          }
        )
      })
    })
  })

  it('4.1 | Non picker - filter date field', (done) => {
    openTableFromTree(libraryToOpenIncludes, 'mpe_x_test')

    openFilterPopup(() => {
      setFilterWithValue('SOME_DATE', '42', 'value', () => {
        checkInfoBarIncludes(
          `AND,AND,0,SOME_DATE,=,42`,
          (includes: boolean) => {
            if (includes) done()
          }
        )
      })
    }, false)
  })

  it('5 | filter datetime field', (done) => {
    openTableFromTree(libraryToOpenIncludes, 'mpe_x_test')

    openFilterPopup(() => {
      setFilterWithValue(
        'SOME_DATETIME',
        '01/01/1960 00:00:42',
        'datetime',
        () => {
          checkInfoBarIncludes(
            `AND,AND,0,SOME_DATETIME,=,42`,
            (includes: boolean) => {
              if (includes) done()
            }
          )
        }
      )
    })
  })

  it('5.1 | Non picker - filter datetime field', (done) => {
    openTableFromTree(libraryToOpenIncludes, 'mpe_x_test')

    openFilterPopup(() => {
      setFilterWithValue('SOME_DATETIME', '42', 'value', () => {
        checkInfoBarIncludes(
          `AND,AND,0,SOME_DATETIME,=,42`,
          (includes: boolean) => {
            if (includes) done()
          }
        )
      })
    }, false)
  })

  it('6 | filter date field IN', (done) => {
    openTableFromTree(libraryToOpenIncludes, 'mpe_x_test')

    openFilterPopup(() => {
      setFilterWithValue('SOME_DATE', '', 'in', () => {
        checkInfoBarIncludes(
          `AND,AND,0,SOME_DATE,IN,(0)`,
          (includes: boolean) => {
            if (includes) done()
          }
        )
      })
    })
  })

  // TODO: fix
  // it('7 | filter bestnum field BETWEEN', (done) => {
  //   openTableFromTree(libraryToOpenIncludes, 'mpe_x_test')

  //   openFilterPopup(() => {
  //     setFilterWithValue('SOME_BESTNUM', '0-10', 'between', () => {
  //       checkInfoBarIncludes(
  //         `AND,AND,0,SOME_BESTNUM,BETWEEN,0 AND 10`,
  //         (includes: boolean) => {
  //           if (includes) done()
  //         }
  //       )
  //     })
  //   })
  // })
})

const checkInfoBarIncludes = (text: string, callback: any) => {
  cy.get('.infoBar b', { timeout: longerCommandTimeout }).then((el: any) => {
    const includes = el[0].innerText.toLowerCase().includes(text.toLowerCase())

    if (callback) callback(includes)
  })
}

const openFilterPopup = (
  callback?: any,
  usePickers: boolean = true,
  isViewerFiltering: boolean = false
) => {
  const filterButton = isViewerFiltering
    ? '.btn-outline.filterSide'
    : '.btnCtrl .btnView'

  cy.get(filterButton, { timeout: longerCommandTimeout }).then(
    (optionsButton: any) => {
      optionsButton.click()

      if (isViewerFiltering) {
        cy.wait(300)

        cy.get('.dropdown-menu button').then(async (dropdownButtons: any) => {
          let filterButton = null

          for (let btn of dropdownButtons) {
            if (btn.innerText.toLowerCase().includes('filter')) {
              filterButton = btn

              break
            }
          }

          if (filterButton) {
            filterButton.click()

            if (usePickers) turnOnPickers()

            if (callback) callback()

            return
          }
        })
      }

      if (usePickers) turnOnPickers()
      if (callback) callback()
    }
  )
}

const turnOnPickers = () => {
  cy.get('#usePickers')
    .should('exist')
    .then((picker: any) => {
      picker[0].click()
    })
}

const setFilterWithValue = (
  variableValue: string,
  valueString: string,
  valueField: 'value' | 'time' | 'date' | 'datetime' | 'in' | 'between',
  callback?: any
) => {
  cy.wait(600)

  cy.focused().type(variableValue)
  cy.wait(100)
  // cy.focused().trigger('input')
  cy.get('.variable-col .autocomplete-wrapper', { withinSubject: null })
    .first()
    .trigger('keydown', { key: 'ArrowDown' })
  cy.get('.variable-col .autocomplete-wrapper', {
    withinSubject: null
  }).trigger('keydown', { key: 'Enter' })
  cy.focused().tab()
  cy.wait(100)

  if (valueField === 'in') {
    cy.focused().select(valueField.toUpperCase()).trigger('change')
  } else if (valueField === 'between') {
    cy.focused().select(valueField.toUpperCase()).trigger('change')
  } else {
    cy.focused().tab()
    cy.wait(100)
  }

  switch (valueField) {
    case 'value': {
      cy.focused().type(valueString)

      break
    }
    case 'time': {
      cy.focused().type(valueString)

      break
    }
    case 'date': {
      cy.focused().type(valueString)
      cy.focused().tab()

      break
    }
    case 'datetime': {
      const date = valueString.split(' ')[0]
      const time = valueString.split(' ')[1]

      cy.focused().type(date)
      cy.focused().tab()
      cy.focused().tab()
      cy.focused().type(time)

      break
    }
    case 'in': {
      cy.get('.checkbox-vals').then(() => {
        cy.focused().tab()
        cy.focused().click()
        cy.get('.no-values')
          .should('not.exist')
          .then(() => {
            cy.get('.in-values-modal clr-checkbox-wrapper input').then(
              (inputs: any) => {
                inputs[0].click()
                cy.get('.in-values-modal .modal-footer button').click()

                cy.get('.modal-footer .btn-success-outline').click()

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

      break
    }
    case 'between': {
      cy.focused().tab()

      const start = valueString.split('-')[0]
      const end = valueString.split('-')[1]

      cy.focused().type(start)
      cy.focused().tab()
      cy.focused().type(end)
    }
    default: {
      break
    }
  }

  cy.wait(100)
  cy.focused().tab()
  cy.wait(100)
  cy.focused().tab()
  cy.wait(100)
  cy.focused().tab()
  cy.wait(100)
  cy.focused().tab()
  cy.wait(100)
  cy.focused().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 (new RegExp(libNameIncludes).test(node.innerText.toLowerCase())) {
            viyaLib = node
            break
          }
        }

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

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

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