import React, { createContext, useContext } from 'react'
import type { ContentTree } from '@financial-times/content-tree'
import classnames from 'classnames'
import type scrollytelling from '@financial-times/n-scrollytelling-image/server'
import { ParagraphContext } from '../Paragraph'
import { ContentProps } from '../../types'

export const ScrollyIDContext = createContext<string | null>(null)

interface ScrollyBlockProps
  extends ContentProps<ContentTree.transit.ScrollyBlock> {}

export const ScrollyBlock: React.FC<
  React.PropsWithChildren<ScrollyBlockProps>
> = ({ content: { theme }, children, parentIndex }) => (
  <div
    className="n-content-layout n-content-layout--scrollytelling"
    data-layout-name="auto"
  >
    <div
      className={classnames(
        'n-scrollytelling',
        `n-scrollytelling--theme-${theme}`
      )}
      data-component="scrollytelling-image"
      data-scrollytelling-theme={theme}
    >
      <div className="n-scrollytelling__viewport">
        {React.Children.map(children, (child, index) => (
          <ScrollyIDContext.Provider value={`${parentIndex}-${index}`}>
            {child}
          </ScrollyIDContext.Provider>
        ))}
      </div>
    </div>
  </div>
)

type ScrollySectionOptions = Pick<
  ContentTree.ScrollySection,
  'display' | 'noBox' | 'position' | 'transition'
>

const ScrollySectionOptionsContext =
  createContext<ScrollySectionOptions | null>(null)

interface ScrollySectionProps
  extends ContentProps<ContentTree.transit.ScrollySection> {}

export const ScrollySection: React.FC<
  React.PropsWithChildren<ScrollySectionProps>
> = ({ content: { display, noBox, position, transition }, children }) => (
  <ScrollySectionOptionsContext.Provider
    value={{ display, noBox, position, transition }}
  >
    <>{children}</>
  </ScrollySectionOptionsContext.Provider>
)

type ScrollytellingDisplaySuffix =
  scrollytelling.ScrollytellingOptionsMap['display'][keyof scrollytelling.ScrollytellingOptionsMap['display']]

interface ScrollyCopyProps extends ContentProps<ContentTree.ScrollyCopy> {}

export const ScrollyCopy: React.FC<
  React.PropsWithChildren<ScrollyCopyProps>
> = ({ children }) => {
  const { display, noBox, position, transition } = useContext(
    ScrollySectionOptionsContext
  ) ?? {
    display: 'dark-background',
    position: 'center',
  }

  const scrollyId = useContext(ScrollyIDContext)

  const displaySuffix: ScrollytellingDisplaySuffix =
    display === 'dark-background' ? 'background-dark' : 'background-light'

  return (
    <div
      className={classnames(
        'n-scrollytelling__overlay-text-slide',
        `n-scrollytelling__overlay-text-slide--position-${position}`,
        {
          'n-scrollytelling__overlay-text-slide-box--transparent': noBox,
          [`n-scrollytelling__overlay-text-slide-box--${displaySuffix}`]:
            display,
          [`n-scrollytelling__overlay-text-slide--${transition}`]: transition,
        }
      )}
      data-scrollytelling-text-slide={scrollyId}
    >
      <div
        className={classnames('n-scrollytelling__overlay-text-box', {
          'n-scrollytelling__overlay-text-box--transparent': noBox,
          [`n-scrollytelling__overlay-text-box--${displaySuffix}`]: display,
        })}
      >
        <ParagraphContext.Provider
          value={{ className: 'n-scrollytelling__overlay-text' }}
        >
          <>{children}</>
        </ParagraphContext.Provider>
      </div>
    </div>
  )
}

interface ScrollyHeadingProps
  extends ContentProps<ContentTree.ScrollyHeading> {}

export const ScrollyHeading: React.FC<
  React.PropsWithChildren<ScrollyHeadingProps>
> = ({ content: { level }, children }) => {
  const classNames = classnames(
    'n-scrollytelling__overlay-text',
    `n-scrollytelling__overlay-text--text-style-${level}`
  )

  switch (level) {
    case 'chapter':
      return <h2 className={classNames}> {children} </h2>
    case 'heading':
      return <h3 className={classNames}> {children} </h3>
    case 'subheading':
      return <h4 className={classNames}> {children} </h4>
  }
}
