import classNames from 'classnames'
import React from 'react'

import CardCta from '../LinkAttachment/components/_shared/CardCta'
import type { LinkAttachmentVariant } from '../LinkAttachment/components/_shared/CardShell'

import type { RichCardActionButton } from './types'

export interface RichCardBodyProps {
  /** Surface the action buttons paint against (from `useChinPalette().surface`). */
  ctaSurface: LinkAttachmentVariant
  /** Ink for the title + subtitle, from `useChinPalette` — fixed per surface. */
  chinTextColor: string
  title?: string
  subtitle?: string
  subtitleLines?: number
  appIcon?: React.ReactNode
  actions?: RichCardActionButton[]
}

// body/small from Figma. Title is medium; subtitle is regular. No
// `text-wrap:balance` — it evened two-line titles by breaking mid-phrase.
const TITLE_CLASS =
  'line-clamp-2 text-[14px] font-medium leading-5 tracking-[0.02em]'
const SUBTITLE_CLASS = 'text-[14px] leading-5 tracking-[0.02em]'

/** `<br>` ignores vertical margin; the spacer is the 6px Figma gap. */
const LineBreak: React.FC = () => (
  <>
    <br />
    <span aria-hidden className="block h-1.5" />
  </>
)

const withLineBreaks = (text: string) =>
  text.split(/\r?\n/).map((line, index, lines) => (
    <React.Fragment key={index}>
      {line}
      {index < lines.length - 1 ? <LineBreak /> : null}
    </React.Fragment>
  ))

/**
 * The action footer. `layout` (chosen by the first action's `variant` in
 * {@link RichCardBody}) picks the presentation: `stacked` (`primary`) →
 * full-width buttons stacked below the copy; `row` (`secondary`) → content-width
 * buttons pinned to the right of the chin row (`shrink-0`, so they never
 * compress the title/subtitle). Each button still paints in its own emphasis.
 * Returns `null` when there are no actions.
 */
const RichCardFooter: React.FC<{
  surface: LinkAttachmentVariant
  actions?: RichCardActionButton[]
  layout: 'stacked' | 'row'
}> = ({ surface, actions, layout }) => {
  if (actions == null || actions.length === 0) return null

  const stacked = layout === 'stacked'

  return (
    <div
      className={classNames(
        'flex gap-2',
        // `row` is capped (`max-w-[60%]`) and shrinkable (`min-w-0`) so a long
        // or localized secondary label can never grow the footer past the
        // card's width; the button truncates within it and the copy yields
        // first. `stacked` keeps the full-width buttons-below layout.
        stacked
          ? 'mt-4 flex-col'
          : 'min-w-0 max-w-[60%] flex-row flex-wrap justify-end'
      )}
    >
      {actions.map((action, index) => (
        <CardCta
          key={`${action.label}-${index}`}
          variant={surface}
          cta={action}
          fullWidth={stacked}
          standalone
        />
      ))}
    </div>
  )
}

/**
 * The rich card's "chin": title, subtitle (prose, multi-line by default), and
 * the action footer. Padding matches `CardBody` (16px x, 12px y) so a rich card
 * lines up with the link cards around it.
 */
const RichCardBody: React.FC<RichCardBodyProps> = ({
  ctaSurface,
  chinTextColor,
  title,
  subtitle,
  subtitleLines = 3,
  appIcon,
  actions,
}) => {
  const hasTitle = title != null && title.trim() !== ''
  const hasSubtitle = subtitle != null && subtitle.trim() !== ''
  const hasActions = actions != null && actions.length > 0

  if (!hasTitle && !hasSubtitle && !hasActions) return null

  const chinTextStyle: React.CSSProperties = { color: chinTextColor }
  const subtitleStyle: React.CSSProperties =
    subtitleLines > 1
      ? {
          ...chinTextStyle,
          display: '-webkit-box',
          WebkitBoxOrient: 'vertical',
          WebkitLineClamp: subtitleLines,
          overflow: 'hidden',
        }
      : chinTextStyle

  // A secondary primary-action lays out as a row (copy left, action right);
  // primary stacks the button full-width below the copy.
  const inline =
    hasActions && (actions?.[0]?.variant ?? 'primary') === 'secondary'

  const textBlock = (
    <div className="flex min-w-0 flex-1 flex-col gap-4">
      {hasTitle && (
        <div className="flex min-w-0 items-center gap-2">
          {appIcon ? <span className="shrink-0">{appIcon}</span> : null}
          <p
            className={classNames('min-w-0', TITLE_CLASS)}
            style={chinTextStyle}
          >
            {title}
          </p>
        </div>
      )}

      {hasSubtitle && (
        <p
          className={classNames(
            SUBTITLE_CLASS,
            subtitleLines <= 1 && 'truncate'
          )}
          style={subtitleStyle}
        >
          {subtitleLines > 1 ? withLineBreaks(subtitle ?? '') : subtitle}
        </p>
      )}
    </div>
  )

  return (
    <div className="shrink-0 px-4 py-3">
      {inline ? (
        <div className="flex items-center justify-between gap-3">
          {textBlock}
          <RichCardFooter surface={ctaSurface} actions={actions} layout="row" />
        </div>
      ) : (
        <>
          {textBlock}
          <RichCardFooter
            surface={ctaSurface}
            actions={actions}
            layout="stacked"
          />
        </>
      )}
    </div>
  )
}

export default RichCardBody
