'use client'

import classNames from 'classnames'
import { forwardRef, HTMLAttributes, ReactNode } from 'react'
import type { THeadingLevel, THeadingSize, THeadingWeight } from 'shared-types'

export type TPktHeadingLevel = THeadingLevel
export type TPktHeadingSize = THeadingSize
export type TPktHeadingWeight = THeadingWeight

export interface IPktHeading extends HTMLAttributes<HTMLHeadingElement> {
  size?: TPktHeadingSize
  level?: TPktHeadingLevel
  weight?: TPktHeadingWeight
  visuallyHidden?: boolean
  align?: 'start' | 'center' | 'end'
  children?: ReactNode
}

const defaultSizeForLevel = (level: TPktHeadingLevel): TPktHeadingSize => {
  switch (level) {
    case 1:
      return 'xlarge'
    case 2:
      return 'large'
    case 3:
      return 'medium'
    case 4:
      return 'small'
    case 5:
    case 6:
      return 'xsmall'
    default:
      return 'medium'
  }
}

const defaultWeightForLevel = (level: TPktHeadingLevel): TPktHeadingWeight => {
  switch (level) {
    case 1:
    case 2:
      return 'regular'
    case 3:
    case 4:
    case 5:
    case 6:
      return 'medium'
    default:
      return 'medium'
  }
}

export const PktHeading = forwardRef<HTMLHeadingElement, IPktHeading>(function PktHeading(
  { level = 2, size, weight, visuallyHidden, align, className, children, ...rest },
  ref,
) {
  const effectiveSize = size ?? defaultSizeForLevel(level)
  const effectiveWeight = weight ?? defaultWeightForLevel(level)

  const classes = classNames(
    'pkt-heading',
    `pkt-heading--${effectiveSize}`,
    `pkt-heading--fw-${effectiveWeight}`,
    align && `pkt-heading--${align}`,
    visuallyHidden && 'pkt-sr-only',
    className,
  )

  const Tag = `h${level}` as 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'

  return (
    <Tag {...rest} ref={ref} className={classes} data-testid="pkt-heading">
      {children}
    </Tag>
  )
})

PktHeading.displayName = 'PktHeading'
