import React from 'react'
import { ComponentsContext } from '../../RichText'
import type { BodyProps } from '../../Body'
import { presets, Teaser as TeaserComponent } from '@financial-times/x-teaser'
import { TeaserFragment } from '@financial-times/cp-content-pipeline-client'
import classnames from 'classnames'

type Teasers = TeaserFragment[]

function validTeasers(teasers: (TeaserFragment | null)[]) {
  return teasers.filter((teaser): teaser is TeaserFragment => !!teaser)
}

function packageIndicatorClassNames(
  indicators: Record<string, unknown> | null | undefined
) {
  return Object.entries(indicators ?? {})
    .filter(([, value]) => value === true)
    .map(([indicator]) => {
      const indicatorName = indicator.startsWith('is')
        ? indicator.slice('is'.length)
        : indicator

      return `${indicatorName.toLowerCase()}-package`
    })
}

type PackageTeasersProps = {
  primaryTeasers: Teasers
  secondaryTeasers: Teasers
  secondaryTeaserTitle: string
  secondaryTeaserMods: string[]
  AdSlot?: React.FC
}

type PrimaryTeasersProps = {
  teasers: Teasers
}

type SecondaryTeasersProps = {
  teasers: Teasers
  teaserTitle: string
  teaserMods: string[]
  AdSlot?: React.FC
}

type ContentPackageBodyProps = BodyProps & {
  AdSlot?: React.FC
}

const ContentPackageBody: React.FC<ContentPackageBodyProps> = ({
  content,
  richTextComponents,
  AdSlot,
}) => {
  if (content.__typename !== 'ContentPackage') {
    return null
  }
  const { design, contains: teasers } = content

  if (!teasers) {
    return null
  }

  const primaryTeasers: TeaserFragment[] = validTeasers(teasers.slice(0, 6))
  const secondaryTeasers: TeaserFragment[] = validTeasers(teasers.slice(6))

  const secondaryTeaserTitle = content.clientName
    ? `More from ${content.clientName}`
    : design?.theme === 'special-report'
    ? 'More from this Special Report'
    : 'More from this Series'

  const secondaryTeaserMods = design?.theme?.startsWith('extra')
    ? ['inverse']
    : []
  return (
    <ComponentsContext.Provider value={richTextComponents}>
      <section
        data-attribute="article-content-body"
        data-content-id={content.id}
        data-syndicatable={content.canBeSyndicated}
        className={
          design?.theme
            ? classnames(
                `design-theme--${design.theme}`,
                packageIndicatorClassNames(content.indicators),
                'article',
                'o3-type-body-content-base'
              )
            : 'article n-content-body js-article__content-body o3-type-body-content-base'
        }
      >
        <PackageTeasers
          {...content}
          primaryTeasers={primaryTeasers}
          secondaryTeasers={secondaryTeasers}
          secondaryTeaserTitle={secondaryTeaserTitle}
          secondaryTeaserMods={secondaryTeaserMods}
          AdSlot={AdSlot}
        />
      </section>
    </ComponentsContext.Provider>
  )
}

const PackageTeasers: React.FC<PackageTeasersProps> = ({
  primaryTeasers,
  secondaryTeasers,
  secondaryTeaserTitle,
  secondaryTeaserMods,
  AdSlot,
}) => {
  return (
    <div
      className={classnames('package-container', {
        'package-grid-1-column': !AdSlot,
        'package-grid-3-column': AdSlot,
      })}
    >
      {!!primaryTeasers.length && <PrimaryTeasers teasers={primaryTeasers} />}

      {!!secondaryTeasers.length && (
        <SecondaryTeasers
          teasers={secondaryTeasers}
          teaserTitle={secondaryTeaserTitle}
          teaserMods={secondaryTeaserMods}
        />
      )}

      {AdSlot && <AdSlot />}
    </div>
  )
}

const PrimaryTeasers: React.FC<PrimaryTeasersProps> = ({ teasers }) => {
  return (
    <div className="package-contents package-teasers--large">
      <ul className="package-contents package-teasers__list">
        {teasers.map(
          (teaser: TeaserFragment | null) =>
            teaser && (
              <li
                key={teaser.id}
                className="package-contents__item o-teaser-collection__item o-teaser-collection__item--stretched"
              >
                <TeaserComponent
                  {...teaser}
                  {...presets.Hero}
                  package={'x-teaser'}
                  component={'Teaser'}
                  modifiers={['centre', 'stretched']}
                  showMeta={false}
                  showStandfirst={true}
                />
              </li>
            )
        )}
      </ul>
    </div>
  )
}

const SecondaryTeasers: React.FC<SecondaryTeasersProps> = ({
  teaserTitle,
  teasers,
  teaserMods,
}) => {
  return (
    <div className="o-teaser-collection package-more">
      {teaserTitle && (
        <h2 className="o-teaser-collection__heading">{teaserTitle}</h2>
      )}
      <ul>
        {teasers.map((teaser: TeaserFragment) => (
          <li key={teaser.id} className="o-teaser-collection__item">
            <TeaserComponent
              {...teaser}
              {...presets.SmallHeavy}
              package={'x-teaser'}
              component={'Teaser'}
              modifiers={teaserMods}
              showMeta={false}
            />
          </li>
        ))}
      </ul>
    </div>
  )
}

export default ContentPackageBody
