import React from 'react'
import PropTypes from 'prop-types'
import styled from 'styled-components'
import { PressableCardBase, StackView } from '@telus-uds/components-base'
import { CardContent } from './CardContent'
import { FullBleedContent } from '../shared/FullBleedContent'
import { ConditionalWrapper } from '../shared/ConditionalWrapper/ConditionalWrapper'
import { DynamicWidthContainer, FullBleedPaddingWrapper } from './Card.styles'
import { getCardContentTokens, getStackViewTokens, POSITION } from './helpers'

const OVERLAY_OPACITY_DEFAULT = 0
const OVERLAY_OPACITY_PRESSED = 0.2
const OVERLAY_OPACITY_HOVER = 0.1
const OVERLAY_TRANSITION_DURATION = '0.2s'

// Focus border sits above the hover/press overlay.
const Z_INDEX_OVERLAY = 1
const Z_INDEX_FOCUS_BORDER = 2

const InteractiveCardWrapper = styled.div(() => ({
  position: 'relative',
  flex: 1,
  display: 'flex',
  flexDirection: 'column'
}))

const InteractiveOverlay = styled.div(({ $overlayOpacity, $borderRadius }) => ({
  position: 'absolute',
  top: 0,
  left: 0,
  right: 0,
  bottom: 0,
  backgroundColor: `rgba(0, 0, 0, ${$overlayOpacity || OVERLAY_OPACITY_DEFAULT})`,
  borderRadius: $borderRadius,
  pointerEvents: 'none',
  transition: `background-color ${OVERLAY_TRANSITION_DURATION} ease`,
  zIndex: Z_INDEX_OVERLAY
}))

const FocusBorder = styled.div(({ $borderWidth, $borderColor, $borderRadius }) => ({
  position: 'absolute',
  top: 0,
  left: 0,
  right: 0,
  bottom: 0,
  borderWidth: $borderWidth,
  borderColor: $borderColor,
  borderRadius: $borderRadius,
  borderStyle: 'solid',
  pointerEvents: 'none',
  zIndex: Z_INDEX_FOCUS_BORDER
}))

/**
 * Renders the `fullBleedContent.interactive: true` branch.
 * Wraps the card body and the full-bleed content in a single pressable surface,
 * with hover/press overlay and focus border.
 */
export const FullBleedInteractiveLayout = React.forwardRef(
  (
    {
      tokensWithoutBg,
      variant,
      withFooter,
      backgroundImage,
      children,
      contentStackDirection,
      contentStackAlign,
      columnFlex,
      contentWrapperStyleProps,
      imageWrapperStyleProps,
      isImageWidthAdjustable,
      isHorizontalFullBleed,
      isVerticalFullBleed,
      fullBleedContentPosition,
      fullBleedContentChildrenAlign,
      fullBleedContentPropsClean,
      fullBleedBorderRadius,
      fullBleedPaddingValues,
      hasFullBleedPadding,
      borderRadius,
      getFullBleedInteractiveCardTokens,
      getFocusBorderTokens,
      dataSet,
      effectiveFullBleedOnPress,
      effectiveFullBleedHref,
      effectiveFullBleedHrefAttrs,
      systemProps,
      testID
    },
    ref
  ) => (
    <PressableCardBase
      ref={ref}
      tokens={getFullBleedInteractiveCardTokens}
      dataSet={dataSet}
      onPress={effectiveFullBleedOnPress}
      href={effectiveFullBleedHref}
      hrefAttrs={effectiveFullBleedHrefAttrs}
      testID={testID && `${testID}-card-pressable-full-bleed`}
      {...systemProps}
    >
      {(cardState) => {
        let overlayOpacity = OVERLAY_OPACITY_DEFAULT
        if (cardState.pressed) {
          overlayOpacity = OVERLAY_OPACITY_PRESSED
        } else if (cardState.hover) {
          overlayOpacity = OVERLAY_OPACITY_HOVER
        }

        const focusTokens = getFocusBorderTokens(cardState)
        const showFocusBorder = cardState.focus && focusTokens.borderWidth > 0

        return (
          <InteractiveCardWrapper data-testid={testID && `${testID}-card-interactive-wrapper`}>
            <StackView
              direction={contentStackDirection}
              tokens={getStackViewTokens(columnFlex, contentStackAlign)}
              space={0}
            >
              {children ? (
                <ConditionalWrapper
                  WrapperComponent={DynamicWidthContainer}
                  wrapperProps={contentWrapperStyleProps}
                  condition={isImageWidthAdjustable}
                >
                  <CardContent
                    tokens={getCardContentTokens(tokensWithoutBg, {
                      backgroundImage,
                      fullBleedContentChildrenAlign,
                      useTransparentBackground: true
                    })}
                    variant={variant}
                    withFooter={withFooter}
                    backgroundImage={backgroundImage}
                    data-testid={testID && `${testID}-card-content`}
                  >
                    {children}
                  </CardContent>
                </ConditionalWrapper>
              ) : null}
              {fullBleedContentPosition !== POSITION.NONE && (
                <ConditionalWrapper
                  WrapperComponent={DynamicWidthContainer}
                  wrapperProps={imageWrapperStyleProps}
                  condition={isImageWidthAdjustable || isHorizontalFullBleed || isVerticalFullBleed}
                >
                  <ConditionalWrapper
                    WrapperComponent={FullBleedPaddingWrapper}
                    wrapperProps={fullBleedPaddingValues}
                    condition={hasFullBleedPadding}
                  >
                    <FullBleedContent
                      borderRadius={fullBleedBorderRadius}
                      {...fullBleedContentPropsClean}
                      position={fullBleedContentPosition}
                      cardState={undefined}
                      testID={testID && `${testID}-card-full-bleed`}
                    />
                  </ConditionalWrapper>
                </ConditionalWrapper>
              )}
            </StackView>
            <InteractiveOverlay
              $overlayOpacity={overlayOpacity}
              $borderRadius={borderRadius}
              data-testid={testID && `${testID}-card-interactive-overlay`}
            />
            {showFocusBorder && (
              <FocusBorder
                $borderWidth={`${focusTokens.borderWidth}px`}
                $borderColor={focusTokens.borderColor}
                $borderRadius={borderRadius}
                data-testid={testID && `${testID}-card-focus-border`}
              />
            )}
          </InteractiveCardWrapper>
        )
      }}
    </PressableCardBase>
  )
)

FullBleedInteractiveLayout.displayName = 'FullBleedInteractiveLayout'

FullBleedInteractiveLayout.propTypes = {
  tokensWithoutBg: PropTypes.object,
  variant: PropTypes.object,
  withFooter: PropTypes.bool,
  backgroundImage: PropTypes.object,
  children: PropTypes.node,
  contentStackDirection: PropTypes.string,
  contentStackAlign: PropTypes.string,
  columnFlex: PropTypes.object,
  contentWrapperStyleProps: PropTypes.object,
  imageWrapperStyleProps: PropTypes.object,
  isImageWidthAdjustable: PropTypes.bool,
  isHorizontalFullBleed: PropTypes.bool,
  isVerticalFullBleed: PropTypes.bool,
  fullBleedContentPosition: PropTypes.string,
  fullBleedContentChildrenAlign: PropTypes.string,
  fullBleedContentPropsClean: PropTypes.object,
  fullBleedBorderRadius: PropTypes.object,
  fullBleedPaddingValues: PropTypes.object,
  hasFullBleedPadding: PropTypes.bool,
  borderRadius: PropTypes.number,
  getFullBleedInteractiveCardTokens: PropTypes.func.isRequired,
  getFocusBorderTokens: PropTypes.func.isRequired,
  dataSet: PropTypes.object,
  effectiveFullBleedOnPress: PropTypes.func,
  effectiveFullBleedHref: PropTypes.string,
  effectiveFullBleedHrefAttrs: PropTypes.object,
  systemProps: PropTypes.object,
  testID: PropTypes.string
}
