import { mount } from 'enzyme'
import React from 'react'
import { DateTimeProvider, useDateTime } from '../DateTime'

const sampleDate = new Date(2020, 9, 31, 14, 30, 42) // Halloween, a Saturday at 2:30 PM
// Testing is set up to run in time zone "America/Los_Angeles" as local
const timeZone1 = 'Australia/Sydney' // ahead of California
const timeZone2 = 'America/Adak' // behind California
const timeZoneLocalFormatted = '2:30 PM PDT on 10/31/2020'
const timeZoneLocalTimeFormatted = '2:30 PM PDT'
const timeZoneLocalTimeFormatted24Hour = '14:30 PDT'
const timeZone1Formatted = '8:30 AM GMT+11 on 11/1/2020'
const timeZone2Formatted = '12:30 PM HADT on 10/31/2020'
const timeZone2TimeFormatted24Hour = '12:30 HADT'
const timeZone1TimeFormatted = '8:30 AM GMT+11'

function ComponentUsingHook({
  date = sampleDate,
  format = 'time-on-numeric-date',
  optionsDate,
  optionsTime,
}) {
  const dateTime = useDateTime()

  return dateTime.format(date, format, optionsDate, optionsTime)
}

describe('Context and Time Zone Shifting', () => {
  describe('Does not time zone shift', () => {
    it('when no provider', () => {
      const wrapper = mount(<ComponentUsingHook />)

      expect(wrapper.text()).toEqual(timeZoneLocalFormatted)
    })

    it('when a provider but no time zone', () => {
      const wrapper = mount(
        <DateTimeProvider>
          <ComponentUsingHook />
        </DateTimeProvider>
      )
      expect(wrapper.text()).toEqual(timeZoneLocalFormatted)
    })
    it('when a provider with default time zone is inside a provider with time zone', () => {
      const wrapper = mount(
        <DateTimeProvider timeZone={timeZone1}>
          <DateTimeProvider>
            <ComponentUsingHook />
          </DateTimeProvider>
        </DateTimeProvider>
      )
      expect(wrapper.text()).toEqual(timeZoneLocalFormatted)
    })
    it('when a provider with undefined time zone is inside a provider with time zone', () => {
      const wrapper = mount(
        <DateTimeProvider timeZone={timeZone1}>
          <DateTimeProvider timeZone={undefined}>
            <ComponentUsingHook />
          </DateTimeProvider>
        </DateTimeProvider>
      )
      expect(wrapper.text()).toEqual(timeZoneLocalFormatted)
    })
  })
  describe('Does time zone shift', () => {
    it('when a provider has time zome', () => {
      const wrapper = mount(
        <DateTimeProvider timeZone={timeZone1}>
          <ComponentUsingHook />
        </DateTimeProvider>
      )
      expect(wrapper.text()).toEqual(timeZone1Formatted)
    })
    it('using the nearest provider', () => {
      const wrapper = mount(
        <DateTimeProvider timeZone={timeZone1}>
          <DateTimeProvider timeZone={timeZone2}>
            <ComponentUsingHook />
          </DateTimeProvider>
        </DateTimeProvider>
      )
      expect(wrapper.text()).toEqual(timeZone2Formatted)
    })
    it('when passed as an option', () => {
      const wrapper = mount(
        <ComponentUsingHook
          format="time"
          optionsDate={{ timeZone: timeZone1 }}
        />
      )

      expect(wrapper.text()).toEqual(timeZone1TimeFormatted)
    })
  })
})

describe('Context and 24 Hour Clock', () => {
  it('can change 24 hour clock', () => {
    const wrapper = mount(
      <DateTimeProvider hour12={true}>
        <DateTimeProvider hour12={false}>
          <ComponentUsingHook format="time" />
        </DateTimeProvider>
      </DateTimeProvider>
    )
    expect(wrapper.text()).toEqual(timeZoneLocalTimeFormatted24Hour)
  })
  it('can change 24 hour clock in time zone', () => {
    const wrapper = mount(
      <DateTimeProvider hour12={true}>
        <DateTimeProvider timeZone={timeZone2} hour12={false}>
          <ComponentUsingHook format="time" />
        </DateTimeProvider>
      </DateTimeProvider>
    )
    expect(wrapper.text()).toEqual(timeZone2TimeFormatted24Hour)
  })
  it('when passed as an option can be 24 hours', () => {
    const wrapper = mount(
      <DateTimeProvider hour12={false}>
        <ComponentUsingHook format="time" optionsDate={{ hour12: true }} />
      </DateTimeProvider>
    )

    expect(wrapper.text()).toEqual(timeZoneLocalTimeFormatted)
  })
  it('when passed as an option can be 12 hours', () => {
    const wrapper = mount(
      <DateTimeProvider hour12={true}>
        <ComponentUsingHook format="time" optionsDate={{ hour12: false }} />
      </DateTimeProvider>
    )

    expect(wrapper.text()).toEqual(timeZoneLocalTimeFormatted24Hour)
  })
})
