import * as React from 'react';

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

/* ============================================================================
   TYPOGRAPHY — the single source of truth for rendered text.
   ----------------------------------------------------------------------------
   Two orthogonal axes:
     • variant  → the SHAPE  (size / leading / weight / tracking / case)
     • tone     → the COLOR  (ink opacity / inverse / accent)
   Never bake color into a variant, and never type a raw `tracking-[0.13em]`
   or `text-[13px]` at a call site again — if a string doesn't fit a variant,
   that's a signal to reuse the closest one, not to invent a one-off.

   RESPONSIVE RULE: only the four heading tiers change size across breakpoints.
   Everything else is ONE size on every screen (reading size is a constant).
   ========================================================================== */

/* ---- HEADINGS — the only fluid tokens ------------------------------------ */
export const headingVariants = {
  /** Hero / landing statement. Often bespoke per page — reach for it sparingly. */
  display: 'font-bold leading-none tracking-tight text-4xl sm:text-5xl lg:text-6xl',
  /** The one Roboto Slab title per page — the document's name. */
  pageTitle: 'font-slab font-bold leading-tight tracking-tight text-3xl sm:text-4xl lg:text-5xl',
  /** Block headers down the page. The house signature: uppercase + open tracking. */
  sectionTitle:
    'font-semibold uppercase leading-tight tracking-wider text-3xl sm:text-4xl lg:text-5xl',
  /** Subordinate block header — the sectionTitle treatment, one tier down.
   *  For sub-sections within a page (e.g. "Where it was made"). Pair with SectionHeader size="sm". */
  subsectionTitle:
    'font-semibold uppercase leading-tight tracking-wider text-2xl sm:text-3xl lg:text-4xl',
  /** In-content subheadings (h3-level). */
  heading: 'font-bold uppercase leading-tight tracking-wide text-xl sm:text-2xl',
  /** Headline inside a card or list row. Fixed size — cards don't reflow type. */
  cardTitle: 'font-semibold leading-tight text-[15px]',
} as const;

/* ---- TEXT — all one size, every breakpoint ------------------------------- */
export const textVariants = {
  /** Intro line under a section title. */
  lead: 'leading-relaxed text-lg',
  /** The workhorse: descriptions, biographies, article text. */
  body: 'leading-relaxed text-base',
  /** Dense rows, secondary body, helper text (pair with tone="muted"). */
  bodySm: 'leading-relaxed text-sm',
  /** Form field labels. */
  label: 'font-semibold tracking-m text-sm',
  /** The kicker above a section title. */
  eyebrow: 'font-normal uppercase tracking-l text-xs',
  /** Catalogue detail: dates, places, categories, control labels. */
  meta: 'font-semibold uppercase tracking-m text-[11px]',
  /** Image credits, fine print. */
  caption: 'tracking-s text-xs',
  /** Subtitle stacked under a title — e.g. a creator's profession under their
   *  name in a list row / byline. Shares the title's tracking (none), one tier down. */
  subtitle: 'leading-tight text-xs',
} as const;

/* ---- Deprecated aliases — keep call sites compiling during migration ------
   Remove each once its old name is fully swapped out of the codebase. */
const legacyTextVariants = {
  /** @deprecated use `lead` */ bodyLarge: textVariants.lead,
  /** @deprecated use `bodySm` */ bodySmall: textVariants.bodySm,
  /** @deprecated use `bodySm` + tone="muted" */ helper: textVariants.bodySm,
  /** @deprecated use `meta` */ controlLabel: textVariants.meta,
} as const;

const resolvedTextVariants = { ...textVariants, ...legacyTextVariants };

/* ---- TONES — color only -------------------------------------------------- */
export const typographyTones = {
  inherit: '',
  strong: 'text-brand-primary', // full ink #151720
  muted: 'text-brand-primary/70', // secondary copy
  soft: 'text-brand-primary/50', // meta, disabled, fine print
  inverse: 'text-brand-secondary',
  inverseMuted: 'text-brand-secondary/75',
  brand: 'text-brand-blue',
  accent: 'text-brand-yellow',
} as const;

export type HeadingVariant = keyof typeof headingVariants;
export type TextVariant = keyof typeof textVariants | keyof typeof legacyTextVariants;
export type TypographyTone = keyof typeof typographyTones;

type TextElement = 'p' | 'span' | 'div' | 'label' | 'small' | 'li' | 'dt';
type HeadingElement = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'div';

export interface TextProps extends React.HTMLAttributes<HTMLElement> {
  as?: TextElement;
  variant?: TextVariant;
  tone?: TypographyTone;
}

export function Text({
  as: Component = 'p',
  variant = 'body',
  tone = 'inherit',
  className,
  ...props
}: TextProps) {
  return (
    <Component
      className={cn(resolvedTextVariants[variant], typographyTones[tone], className)}
      {...props}
    />
  );
}

export interface HeadingProps extends React.HTMLAttributes<HTMLHeadingElement> {
  as?: HeadingElement;
  variant?: HeadingVariant;
  tone?: TypographyTone;
}

export function Heading({
  as: Component = 'h2',
  variant = 'sectionTitle',
  tone = 'inherit',
  className,
  ...props
}: HeadingProps) {
  return (
    <Component
      className={cn(headingVariants[variant], typographyTones[tone], className)}
      {...props}
    />
  );
}

/* ---- Ergonomic wrappers for the highest-traffic roles -------------------- */
export const SectionTitle = (props: Omit<HeadingProps, 'variant'>) => (
  <Heading variant="sectionTitle" {...props} />
);
export const Eyebrow = (props: Omit<TextProps, 'variant'>) => (
  <Text as="div" variant="eyebrow" {...props} />
);
export const Body = (props: Omit<TextProps, 'variant'>) => <Text variant="body" {...props} />;
export const Meta = (props: Omit<TextProps, 'variant'>) => (
  <Text as="span" variant="meta" {...props} />
);
