import { type VariantProps } from 'class-variance-authority';

import * as React from 'react';

import { cn } from '@/lib/utils';

import { headingVariants, bodyVariants } from './typography-variants';

/**
 * DS-004: Reusable Typography / Heading components.
 *
 * Provides consistent heading hierarchy (h1–h4) and prose variants
 * using the spacing and type scale documented in app.css.
 *
 * Usage:
 *   <PageHeading>Recommendations</PageHeading>
 *   <SectionHeading>Winners & Losers</SectionHeading>
 *   <BodyText variant="muted">Select a site to get started.</BodyText>
 *
 * The `as` prop overrides the HTML element while keeping the visual style.
 * Always use the semantically correct heading level — never skip levels.
 */

// ---- Heading ----

type HeadingTag = 'h1' | 'h2' | 'h3' | 'h4';

export interface HeadingProps
  extends React.HTMLAttributes<HTMLHeadingElement>, VariantProps<typeof headingVariants> {
  as?: HeadingTag;
}

export const Heading = React.forwardRef<HTMLHeadingElement, HeadingProps>(
  ({ className, level = 'h2', as, children, ...props }, ref) => {
    const Tag = (as ?? level ?? 'h2') as HeadingTag;
    return (
      <Tag ref={ref} className={cn(headingVariants({ level }), className)} {...props}>
        {children}
      </Tag>
    );
  },
);
Heading.displayName = 'Heading';

/** h1 — Page-level title. Use once per page. */
export const PageHeading = React.forwardRef<HTMLHeadingElement, Omit<HeadingProps, 'level'>>(
  (props, ref) => <Heading ref={ref} level="h1" as="h1" {...props} />,
);
PageHeading.displayName = 'PageHeading';

/** h2 — Section heading. Use for major sections on a page. */
export const SectionHeading = React.forwardRef<HTMLHeadingElement, Omit<HeadingProps, 'level'>>(
  (props, ref) => <Heading ref={ref} level="h2" as="h2" {...props} />,
);
SectionHeading.displayName = 'SectionHeading';

/** h3 — Subsection heading. Use within sections. */
export const SubsectionHeading = React.forwardRef<HTMLHeadingElement, Omit<HeadingProps, 'level'>>(
  (props, ref) => <Heading ref={ref} level="h3" as="h3" {...props} />,
);
SubsectionHeading.displayName = 'SubsectionHeading';

/** h4 — Detail heading. Use for granular sub-items. */
export const DetailHeading = React.forwardRef<HTMLHeadingElement, Omit<HeadingProps, 'level'>>(
  (props, ref) => <Heading ref={ref} level="h4" as="h4" {...props} />,
);
DetailHeading.displayName = 'DetailHeading';

// ---- Body text ----

export interface BodyTextProps
  extends React.HTMLAttributes<HTMLParagraphElement>, VariantProps<typeof bodyVariants> {
  as?: 'p' | 'span' | 'div' | 'label';
}

export const BodyText = React.forwardRef<HTMLParagraphElement, BodyTextProps>(
  ({ className, variant, as: Tag = 'p', children, ...props }, ref) => {
    const TagEl = Tag as 'p';
    return (
      <TagEl
        ref={ref}
        className={cn(bodyVariants({ variant }), className)}
        {...(props as React.HTMLAttributes<HTMLParagraphElement>)}
      >
        {children}
      </TagEl>
    );
  },
);
BodyText.displayName = 'BodyText';
