import React, { Fragment, ReactElement } from 'react'
import Wrapper from './Wrapper'
import HeaderSlot from './HeaderSlot'
import Tags from './Tags'
import Headline from './Headline'
import Intro from './Intro'
import Picture from './Picture'
import Headshot from '../Headshot'
import Columnists from './Columnists'
import LiveBlogIndicator from './LiveBlogIndicator'
import MainImage from '../MainImage'
import { FollowButtonSlot } from './FollowButtonSlot'
import Flourish from '../content-tree/Flourish'
import classnames from 'classnames'
import type { ArticleQuery } from '@financial-times/cp-content-pipeline-client'

export type TopperProps = {
  content: ArticleQuery['content']
  slot?: string
  followButtonSlot?: FollowButtonSlot
  showPremiumLabel?: boolean
  readNextSlot?: () => ReactElement
}

const Topper: React.FC<TopperProps> = ({
  content,
  slot,
  followButtonSlot,
  showPremiumLabel = false,
  readNextSlot,
}) => {
  const { topper } = content

  if (!topper) {
    return null
  }

  const isPackage = content.__typename === 'ContentPackage'
  const isLiveBlog = content.__typename === 'LiveBlogPackage'
  const isBasic = topper.__typename === 'BasicTopper'
  const isOpinion = topper.__typename === 'OpinionTopper'
  const isFlourish =
    topper.__typename === 'TopperWithFlourish' && !!topper.leadFlourish
  const mainImageTopper =
    isBasic || isOpinion || topper.__typename === 'BrandedTopper'
  const hasLayout =
    ('layoutConfiguration' in topper && topper.layoutConfiguration) ||
    ('layout' in topper && topper.layout)
  const hasLayoutWidth = 'layoutWidth' in topper && topper.layoutWidth
  const hasDesign = 'design' in topper && topper.design
  const hasHeadshot = 'headshot' in topper && topper.headshot
  const hasCoverImage = 'coverImage' in topper && topper.coverImage
  const hasByline = !!content.byline
  const hasColumnists =
    'columnists' in topper &&
    !!topper.columnists &&
    topper.columnists.length > 0

  const modifiers: string[] = []

  isPackage && modifiers.push('package')
  isPackage && hasDesign && modifiers.push(`package-${topper.design}`)
  isOpinion && modifiers.push('opinion')
  if (hasLayout) {
    const layoutName =
      'layoutConfiguration' in topper
        ? topper.layoutConfiguration?.name
        : 'layout' in topper
        ? topper.layout
        : undefined
    layoutName && modifiers.push(layoutName)
  }
  // TODO: Split this modifier into two separate ones when refactoring styles and markup
  ;(hasHeadshot || hasCoverImage) && modifiers.push('has-headshot')
  slot && modifiers.push('right-rail')
  hasLayoutWidth &&
    modifiers.push(topper.layoutWidth === 'full-grid' ? 'full-grid' : 'in-line')

  const getMostRecentPostPublishedDate = () => {
    const defaultPublishDate = content.publishedDate

    if (isLiveBlog) {
      const posts = content?.liveBlogPosts || []

      const mostRecentPublishedDate = posts.reduce(
        (storedPublishDate, currentPost) => {
          const thisDate = currentPost?.publishedDate ?? ''
          return thisDate > storedPublishDate ? thisDate : storedPublishDate
        },
        posts[0]?.publishedDate ?? ''
      )

      if (mostRecentPublishedDate) {
        return mostRecentPublishedDate
      }
    }

    return defaultPublishDate
  }

  return (
    <Fragment>
      {topper.headerSlot && <HeaderSlot content={content} />}
      <div
        className={classnames({
          'article-topper': true,
          'pinned-post__topper--no-image': isLiveBlog,
        })}
      >
        <Wrapper
          backgroundColor={topper.backgroundColour ?? undefined}
          isBasic={isBasic}
          modifiers={modifiers}
        >
          <div
            className={classnames('o-topper__content', {
              'o-topper__content--text-shadow': topper.textShadow,
              'o-topper__content--background-box': topper.backgroundBox,
            })}
            id="o-topper"
          >
            {isLiveBlog ? (
              <div className="o-topper__tags">
                <LiveBlogIndicator
                  realtime={content.realtime ?? undefined}
                  lastUpdatedDateTime={getMostRecentPostPublishedDate()}
                />
              </div>
            ) : (
              <Tags
                __typename={topper.__typename}
                isPackage={isPackage}
                displayConcept={topper.displayConcept ?? undefined}
                brandConcept={
                  ('brandConcept' in topper && topper.brandConcept) || undefined
                }
                genreConcept={
                  ('genreConcept' in topper && topper.genreConcept) || undefined
                }
                hasColumnists={hasColumnists && hasByline}
                followButtonVariant={topper.followButtonVariant}
                FollowButtonSlot={followButtonSlot}
              />
            )}
            <Headline
              headline={topper.headline}
              showPremiumLabel={
                showPremiumLabel && content.accessLevel === 'premium'
              }
              isLargeHeadline={
                ('isLargeHeadline' in topper && topper.isLargeHeadline) ??
                undefined
              }
            />
            {topper.intro && (
              <Intro
                structured={topper.intro.structured}
                source={topper.intro.source}
              />
            )}
            {isLiveBlog && isFlourish ? (
              <Flourish
                content={{
                  type: 'flourish',
                  id: topper.leadFlourish.id ?? '',
                  flourishType: topper.leadFlourish.type ?? '',
                  description: topper.leadFlourish.description ?? '',
                  fallbackImage: topper.leadFlourish.fallbackImage ?? undefined,
                  layoutWidth: 'in-line',
                }}
                iFrame={true}
                inArticleBody={false}
              />
            ) : (
              ''
            )}
            {hasLayout &&
              mainImageTopper &&
              topper.layoutConfiguration?.assetSlot === 'inside-topper' && (
                <MainImage content={content} />
              )}
            {hasHeadshot && hasColumnists && hasByline && (
              <div className="o-topper__headshot">
                <Headshot
                  headshot={topper.headshot}
                  prefLabel={topper.columnists?.[0]?.prefLabel ?? ''}
                  className={'o-topper__headshot-image'}
                />
              </div>
            )}
            {hasCoverImage && (
              // TODO: Move to its own styles
              <div className="o-topper__headshot">
                <img
                  className={'o-topper__headshot-image'}
                  src={topper.coverImage}
                  role="presentation"
                  alt=""
                />
              </div>
            )}
            {hasColumnists && hasByline && (
              <Columnists
                authorConcepts={[...topper.columnists]}
                followButtonVariant={topper.followButtonVariant}
                followButtonSlot={followButtonSlot}
              />
            )}
          </div>

          <div className="o-topper__right-rail-content">
            {readNextSlot && (
              <div className="o-topper__read-next">{readNextSlot()}</div>
            )}
            <div data-component="topper__right-rail-placeholder" />
          </div>

          <div className="o-topper__background" />
          {'images' in topper && !mainImageTopper && (
            <Picture topper={topper} />
          )}
        </Wrapper>
      </div>
    </Fragment>
  )
}

export default Topper
