/**
 * @jest-environment jsdom
 */
import React from 'react'
import { render } from '@testing-library/react'

import dataFixture from '../fixtures/index'
import { Header } from '../../index'

// data.currentPath to enable the mobile header
const headerFixture = {
  ...dataFixture,
  data: { ...dataFixture.data, currentPath: '/' }
}
const subscribedUserFixture = {
  ...dataFixture,
  showUserNavigation: true,
  userIsSubscribed: true,
  showRestartSubscriptionButton: true
}
const loggedInUserFixture = { ...dataFixture, showUserNavigation: true, showRestartSubscriptionButton: true }
const loggedInUserWithoutRestartFixture = {
  ...dataFixture,
  showUserNavigation: true,
  showRestartSubscriptionButton: false
}
const anonymousUserFixture = {
  ...dataFixture,
  userIsAnonymous: true,
  userIsLoggedIn: false,
  showRestartSubscriptionButton: false,
  showUserNavigation: true
}

const commonHeader = <Header {...headerFixture} />
const subscribedUserHeader = <Header {...subscribedUserFixture} />
const loggedInUserHeader = <Header {...loggedInUserFixture} />
const loggedInUserWithoutRestartHeader = <Header {...loggedInUserWithoutRestartFixture} />
const anonymousUserHeader = <Header {...anonymousUserFixture} />

describe('dotcom-ui-header', () => {
  it('renders the expected common header elements', () => {
    const { container } = render(commonHeader)

    const logo = container.querySelector('div[data-trackable="header-top"] .o-header__top-logo')
    expect(logo?.hasChildNodes()).toBe(true)
  })

  it('renders an inlined SVG logo image', () => {
    const { container } = render(commonHeader)

    const logo = container.querySelector('div[data-trackable="header-top"] .o-header__top-logo')
    expect(logo?.hasChildNodes()).toBe(true)
    expect(logo?.innerHTML).toContain('Financial Times')
    expect(logo?.querySelector('div[data-trackable="header-top"] .o-header__top-logo svg')).not.toBeNull()
  })

  it('renders the sticky header', () => {
    const { container } = render(commonHeader)
    const header = container.querySelector('.o-header--sticky')
    expect(header).not.toBeNull()
  })

  it('renders the mobile header', () => {
    const { container } = render(commonHeader)
    const mobileHeader = container.querySelector('#o-header-nav-mobile')
    expect(mobileHeader).not.toBeNull()
  })

  it('renders one search widget anchor in the primary search row', () => {
    const { container } = render(commonHeader)
    const primarySearch = container.querySelector('#o-header-search-primary')
    const primarySearchMain = primarySearch?.querySelector('.o-header__search-main')
    const primaryForm = primarySearch?.querySelector('.o-header__search-form')
    const primaryAnchor = primarySearch?.querySelector('[data-o-header-search-widget-anchor="primary"]')
    const primaryAnchors = container.querySelectorAll('[data-o-header-search-widget-anchor="primary"]')
    const widgetAnchors = container.querySelectorAll('[data-o-header-search-widget-anchor]')

    expect(primarySearchMain).not.toBeNull()
    expect(primaryForm?.parentElement).toBe(primarySearchMain)
    expect(primarySearchMain?.nextElementSibling).toBe(primaryAnchor)
    expect(primaryAnchors).toHaveLength(1)
    expect(widgetAnchors).toHaveLength(2)
  })

  it('renders one search widget anchor in sticky search', () => {
    const { container } = render(commonHeader)
    const searchMainNodes = container.querySelectorAll('.o-header__search-main')
    const stickySearch = container.querySelector('#o-header-search-sticky')
    const stickySearchMain = stickySearch?.querySelector('.o-header__search-main')
    const stickyForm = stickySearch?.querySelector('.o-header__search-form')
    const stickyAnchor = stickySearch?.querySelector('[data-o-header-search-widget-anchor="sticky"]')
    const stickyAnchors = container.querySelectorAll('[data-o-header-search-widget-anchor="sticky"]')

    expect(searchMainNodes).toHaveLength(2)
    expect(stickySearchMain).not.toBeNull()
    expect(stickyForm?.parentElement).toBe(stickySearchMain)
    expect(stickySearchMain?.nextElementSibling).toBe(stickyAnchor)
    expect(stickyAnchors).toHaveLength(1)
  })

  describe('When the user is subscribed', () => {
    it('renders the expected logged in user header links', () => {
      const { container } = render(subscribedUserHeader)

      expect(container.querySelector('a[data-trackable="Portfolio"]')).not.toBeNull()
      expect(container.querySelector('a[data-trackable="My Account"]')).not.toBeNull()
      expect(container.querySelector('a[data-trackable="myFT Feed"]')).not.toBeNull()
    })

    it('does not render sign in link', () => {
      const { container } = render(subscribedUserHeader)

      expect(container.querySelector('a[data-trackable="Subscribe"]')).toBeNull()
      expect(container.querySelector('a[data-trackable="Sign In"]')).toBeNull()
    })
  })

  describe('When the user is logged in', () => {
    it('renders the expected logged in user header links', () => {
      const { container } = render(loggedInUserWithoutRestartHeader)

      expect(container.querySelector('a[data-trackable="Portfolio"]')).not.toBeNull()
      expect(container.querySelector('a[data-trackable="My Account"]')).not.toBeNull()
      expect(container.querySelector('a[data-trackable="myFT Feed"]')).not.toBeNull()
    })

    it('does not render sign in link', () => {
      const { container } = render(loggedInUserWithoutRestartHeader)

      expect(container.querySelector('a[data-trackable="Subscribe"]')).not.toBeNull()
      expect(container.querySelector('a[data-trackable="Sign In"]')).toBeNull()
    })

    it('renders restart subscription button (but no subscribe button) when showRestartSubscriptionButton is true', () => {
      const { container } = render(loggedInUserHeader)

      expect(container.querySelector('a[data-trackable="Restart Subscription"]')).not.toBeNull()
      expect(container.querySelector('a[data-trackable="Subscribe"]')).toBeNull()
    })

    it('does not render restart subscription button when showRestartSubscriptionButton is false', () => {
      const { container } = render(loggedInUserWithoutRestartHeader)

      expect(container.querySelector('a[data-trackable="Restart Subscription"]')).toBeNull()
    })
  })

  describe('When the user is anonymous', () => {
    it('renders the expected anonymous user header links', () => {
      const { container } = render(anonymousUserHeader)

      expect(
        container.querySelector(
          '.o-header__top-column.o-header__top-column--right a[data-trackable="Subscribe"]'
        )
      ).not.toBeNull()
      expect(
        container.querySelector(
          '.o-header__top-column.o-header__top-column--right a[data-trackable="Sign In"]'
        )
      ).not.toBeNull()
    })

    it('does not render the logged in user header links', () => {
      const { container } = render(anonymousUserHeader)

      expect(container.querySelector('a[data-trackable="Portfolio"]')).toBeNull()
      expect(container.querySelector('a[data-trackable="My Account"]')).toBeNull()
      expect(container.querySelector('a[data-trackable="myFT Feed"]')).toBeNull()
    })
  })
})
