import styled from 'styled-components'
import Button from './button.js'
import Icon from './icon.js'
import Banner from './banner.js'
import Copy from './copy.js'
import LoadingDots from './loading-dots.js'
import { Header } from './header.js'
import CDNIllustration from './cdn-illustration.js'
import { ReactEventHandler, ReactNode } from 'react'
import { InferComponentProps } from './types.js'
import isRebrand from './is-rebrand.js'

export const StyledBackButton = styled(Button).attrs(() => ({
  variation: 'noOutline',
}))`
  margin-right: auto;
  padding: 8px;
  color: ${({ theme }) => theme.neutral400};
`

export const StyledCDNIllustration = styled(CDNIllustration)`
  margin-top: 16px;
  height: 180px;
  width: 180px;
`

type ContentProps = { hasImage?: boolean }
const Content = styled.div<ContentProps>`
  align-items: center;
  display: flex;
  flex-direction: column;
  ${({ hasImage }) =>
    !hasImage &&
    `
    height: 400px;
    justify-content: center;
  `}

  & > ${LoadingDots} {
    color: ${({ theme }) => theme.azure};
  }
`

type StandardCardLoadingContentProps = InferComponentProps<typeof Content> & {
  imageFilename?: string
  title?: string
}
export const StandardCardLoadingContent = ({ imageFilename, title, ...props }: StandardCardLoadingContentProps) => (
  <>
    {!!title && <Header>{title}</Header>}
    <Content hasImage={!!imageFilename} {...props}>
      <LoadingDots />
      {imageFilename && <StyledCDNIllustration filename={imageFilename} data-testid="card:loading-image" />}
    </Content>
  </>
)
StandardCardLoadingContent.displayName = 'LoadingContent'

type StandardCardBackButtonProps = InferComponentProps<typeof StyledBackButton>
export const StandardCardBackButton = styled(({ onClick, href, ...props }: StandardCardBackButtonProps) =>
  !(onClick || href) ? null : (
    <StyledBackButton onClick={onClick} href={href} {...props}>
      <Icon name="actions/arrow-back" />
    </StyledBackButton>
  )
)``
StandardCardBackButton.displayName = 'BackButton'

const StyledHeader = styled.div`
  position: relative;
  padding-bottom: 16px;
    margin-bottom: ${({ theme }) => isRebrand(theme) && '16px'};

  & > *:not(:first-child) {
    margin-top: 4px;
  }

 &::before {
    content: '';
    width: ${({ theme }) => isRebrand(theme) && '100%'};
    height: ${({ theme }) => isRebrand(theme) && '4px'};
    position: ${({ theme }) => isRebrand(theme) && 'absolute'};
    bottom:${({ theme }) => isRebrand(theme) && 0};
    background: ${({ theme }) => isRebrand(theme) && theme.navNeutral200};
    border-radius: ${({ theme }) => isRebrand(theme) && '100px'};};
  };
`

const Label = styled(Copy).attrs(() => ({ size: 'sm' }))`
  color: ${({ theme }) => theme.neutral400};
`

const Title = styled(Header).attrs(() => ({ size: 'md' }))``

const StyledFooter = styled.div`
  position: relative;
  display: flex;
  justify-content: flex-end;
  align-items: center;
  margin-top: ${({ theme }) => (isRebrand(theme) ? '32px' : '24px')};
  padding-top: 16px;
  background: ${({ theme }) => (isRebrand(theme) ? theme.navSecondary100 : theme.white)};

  &::before {
    content: '';
    width: 100%;
    height: 4px;
    position: absolute;
    top: 0;
    background: ${({ theme }) => (isRebrand(theme) ? theme.navNeutral200 : theme.neutral200)};
    border-radius: ${({ theme }) => (isRebrand(theme) ? '100px' : '14px')};
  }

  /* For button spacing when there are multiple buttons */
  & > *:not(${StandardCardBackButton}) {
    margin: 0 8px;
  }
  & > *:first-child:not(${StandardCardBackButton}) {
    margin-left: 0;
  }
  & > *:last-child:not(${StandardCardBackButton}) {
    margin-right: 0;
  }
`

type StandardCardHeaderProps = InferComponentProps<typeof StyledHeader> & {
  label?: string
  title?: string
  children?: ReactNode
}
export const StandardCardHeader = styled(({ children, label, title, ...remainingProps }: StandardCardHeaderProps) => (
  <StyledHeader {...remainingProps}>
    {label && <Label>{label}</Label>}
    {title && <Title>{title}</Title>}
    {children}
  </StyledHeader>
))``
StandardCardHeader.displayName = 'Header'

const highlightVariation = {
  default: null,
  positive: 'navStatusPositive',
  neutral: 'navSecondary600',
  negative: 'navStatusNegative',
}

const getHighlightColor = (highlightColor, theme) => {
  return highlightVariation[highlightColor] ? theme[highlightVariation[highlightColor]] : highlightColor
}

type StandardCardHighlightedHeaderProps = { highlightColor?: string }
export const StandardCardHighlightedHeader = styled.div<StandardCardHighlightedHeaderProps>`
  margin: ${({ theme }) => (isRebrand(theme) ? `-24px -24px 12px` : `-24px -24px 0`)};

  padding: 8px 24px;
  ${({ highlightColor, theme }) => highlightColor && `background: ${getHighlightColor(highlightColor, theme)}`}
`
StandardCardHighlightedHeader.displayName = 'HighlightedHeader'

type ButtonProps = InferComponentProps<typeof Button>
type StandardCardFooterProps = InferComponentProps<typeof StyledFooter> & {
  children?: ReactNode
  actionText?: ReactNode
  actionForm?: string
  actionDataTestId?: string
  actionHref?: string
  actionButtonType?: ButtonProps['type']
  onAction?: ReactEventHandler
  isActionDisabled?: boolean
  isLoading?: boolean
  onBack?: ReactEventHandler
  backHref?: string
  actionTarget?: string
}
export const StandardCardFooter = styled(
  ({
    actionText = 'Next',
    actionForm,
    actionButtonType,
    actionDataTestId,
    onAction,
    actionHref,
    isActionDisabled,
    isLoading,
    onBack,
    backHref,
    actionTarget,
    children,
    ...remainingProps
  }: StandardCardFooterProps) => (
    <StyledFooter {...remainingProps}>
      {(!!onBack || !!backHref) && (
        <StandardCardBackButton data-testid="card:back" type="button" onClick={onBack} href={backHref} />
      )}
      {children}
      {(!!onAction || !!actionHref || !!actionForm) && (
        <Button
          data-testid={actionDataTestId || 'card:next'}
          onClick={onAction}
          form={actionForm}
          href={actionHref}
          isLoading={isLoading}
          disabled={isLoading || isActionDisabled}
          size="cardButton"
          variation="noOutline"
          target={actionTarget}
          {...(actionButtonType && { type: actionButtonType })}
        >
          {actionText}
        </Button>
      )}
    </StyledFooter>
  )
)<StandardCardFooterProps>``
StandardCardFooter.displayName = 'Footer'

const focusedCSS = `
  text-align: center;
    width: 100%;


  & ${StandardCardHeader} {
  display: flex;
  justify-content: center;
  padding-bottom: 8px;
  text-align: center;
}

  & ${Title} {
  max-width: 400px;
}
`

export const StandardCardFocusedContent = styled.div`
  align-items: center;
  display: flex;
  flex-direction: column;

  & > * {
    max-width: 400px;
  }
`

export const StandardCardTermsFooter = styled.section`
  padding: 16px 32px;
  margin: 24px -24px -24px -24px;
  background-color: ${({ theme }) => (isRebrand(theme) ? theme.navNeutral100 : theme.neutral100)};
`

type StandardCardProps = { isFocused?: boolean; highlightColor?: string }
const Card = styled.div<StandardCardProps>`
  position: relative;
  padding: 24px;
  border-radius: ${({ theme }) => (isRebrand(theme) ? '16px' : '20px')};
  background-color: ${({ theme }) => (isRebrand(theme) ? theme.navSecondary100 : theme.white)};
  box-shadow: 0 24px 16px -16px rgba(0, 0, 0, 0.05);
  overflow: hidden;
  ${({ highlightColor, theme }) => highlightColor && `border: solid 2px ${getHighlightColor(highlightColor, theme)};`}

  & ${Banner} {
    margin: ${({ theme }) => (isRebrand(theme) ? '0 0 16px' : '-24px -24px 16px')};
    border-bottom-left-radius: 0;
    border-bottom-right-radius: 0;
  }

  ${({ isFocused }) => isFocused && focusedCSS}
`
Card.displayName = 'StandardCard'

type StandardCardType = typeof Card & {
  Header: typeof StandardCardHeader
  HighlightedHeader: typeof StandardCardHighlightedHeader
  Footer: typeof StandardCardFooter
  BackButton: typeof StandardCardBackButton
  FocusedContent: typeof StandardCardFocusedContent
  LoadingContent: typeof StandardCardLoadingContent
  TermsFooter: typeof StandardCardTermsFooter
}
export const StandardCard = Card as StandardCardType

StandardCard.Header = StandardCardHeader
StandardCard.HighlightedHeader = StandardCardHighlightedHeader
StandardCard.Footer = StandardCardFooter
StandardCard.BackButton = StandardCardBackButton
StandardCard.FocusedContent = StandardCardFocusedContent
StandardCard.LoadingContent = StandardCardLoadingContent
StandardCard.TermsFooter = StandardCardTermsFooter
