import { clsx } from 'clsx';
import React, { forwardRef, LabelHTMLAttributes, LiHTMLAttributes } from 'react';

import { TitleTypes, Typography, Heading } from '../common';

const DEFAULT_TYPE = Typography.TITLE_GROUP;

const titleTypeMapping = {
  [Typography.TITLE_SCREEN]: 'h1',
  [Typography.TITLE_SECTION]: 'h2',
  [Typography.TITLE_SUBSECTION]: 'h3',
  [Typography.TITLE_BODY]: 'h4',
  [Typography.TITLE_GROUP]: 'h5',
} as const;

type Props = LabelHTMLAttributes<HTMLHeadingElement | HTMLSpanElement | HTMLLabelElement> &
  LiHTMLAttributes<HTMLLIElement> & {
    /**
     * Default value will based one `type` prop
     */
    as?: 'span' | 'label' | 'li' | 'legend' | 'header' | Heading;
    /**
     * Default value: {@link DEFAULT_TYPE}
     */
    type?: TitleTypes;
  };

const Title = React.forwardRef<HTMLHeadingElement | HTMLSpanElement | HTMLLabelElement, Props>(
  ({ as, type = DEFAULT_TYPE, className, ...props }, ref) => {
    const mapping = titleTypeMapping[type as keyof typeof titleTypeMapping];
    const isTypeSupported = mapping !== undefined;
    if (isTypeSupported) {
      const HeaderTag = as ?? mapping;
      return (
        <HeaderTag
          ref={ref as React.Ref<any>}
          {...props}
          className={clsx(`np-text-${type}`, className)}
        />
      );
    }
    const HeaderTag = as ?? titleTypeMapping[DEFAULT_TYPE];
    return (
      <HeaderTag
        ref={ref as React.Ref<any>}
        {...props}
        className={clsx(`np-text-${DEFAULT_TYPE}`, className)}
      />
    );
  },
);

export default Title;
