import type { JSX, ComponentChildren } from "preact";
import { cn } from "../../utils/cn.ts";

type TextVariant =
  | "primary" // Main body text: text-zinc-900 dark:text-white
  | "secondary" // Medium text: text-zinc-600 dark:text-zinc-400
  | "muted" // Muted text: text-zinc-500 dark:text-zinc-400
  | "label" // Form labels: text-zinc-700 dark:text-zinc-300
  | "subtle" // Subtle text: text-zinc-400 dark:text-zinc-500
  | "error" // Error text: text-red-600 dark:text-red-400
  | "warning" // Warning text: text-yellow-600 dark:text-yellow-400
  | "success"; // Success text: text-green-600 dark:text-green-400

type TextSize = "xs" | "sm" | "base" | "lg" | "xl" | "2xl" | "3xl";

type TextWeight = "normal" | "medium" | "semibold" | "bold";

type TextElement =
  | "p"
  | "span"
  | "div"
  | "time"
  | "label"
  | "h1"
  | "h2"
  | "h3"
  | "h4"
  | "h5"
  | "h6"
  | "dt"
  | "dd"
  | "strong";

interface TextProps {
  variant?: TextVariant;
  size?: TextSize;
  weight?: TextWeight;
  as?: TextElement;
  className?: string;
  children: ComponentChildren;
}

const textColors = {
  primary: "text-zinc-900 dark:text-white",
  secondary: "text-zinc-600 dark:text-zinc-400",
  muted: "text-zinc-500 dark:text-zinc-400",
  label: "text-zinc-700 dark:text-zinc-300",
  subtle: "text-zinc-400 dark:text-zinc-500",
  error: "text-red-600 dark:text-red-400",
  warning: "text-yellow-600 dark:text-yellow-400",
  success: "text-green-600 dark:text-green-400",
};

const textSizes = {
  xs: "text-xs",
  sm: "text-sm",
  base: "text-base",
  lg: "text-lg",
  xl: "text-xl",
  "2xl": "text-2xl",
  "3xl": "text-3xl",
};

const textWeights = {
  normal: "font-normal",
  medium: "font-medium",
  semibold: "font-semibold",
  bold: "font-bold",
};

export function Text({
  variant = "primary",
  size = "base",
  weight,
  as = "span",
  className,
  children,
}: TextProps): JSX.Element {
  const Component = as;

  const classes = cn(
    textColors[variant],
    textSizes[size],
    weight && textWeights[weight],
    className
  );

  return <Component className={classes}>{children}</Component>;
}
