import { JSX, ParentComponent, splitProps, type Ref } from "solid-js";
import { Dynamic } from "solid-js/web";
import typography from "./typography.module.css";
import { mergeClass } from "../utils";

type AnyElement = keyof JSX.IntrinsicElements | ParentComponent<any>;

type PropsOf<E extends AnyElement> =
  E extends ParentComponent<infer Props>
    ? Props
    : E extends keyof JSX.IntrinsicElements
      ? JSX.IntrinsicElements[E]
      : JSX.HTMLAttributes<HTMLElement>;

export type TypographyProps<E extends AnyElement> = {
  ref?: Ref<E>;
  component?: E;
  class?: string;
} & PropsOf<E>;

type TypographyKind =
  | "display4"
  | "display3"
  | "display2"
  | "display1"
  | "headline"
  | "title"
  | "subheading"
  | "body1"
  | "body2"
  | "caption"
  | "buttonText";

export function Typography<T extends AnyElement>(
  props: { typography: TypographyKind } & TypographyProps<T>,
) {
  const [managed, passthough] = splitProps(props, [
    "ref",
    "component",
    "class",
    "typography",
  ]);
  const classes = () =>
    mergeClass(managed.class, typography[managed.typography]);
  return (
    <Dynamic
      ref={managed.ref}
      component={managed.component ?? "span"}
      class={classes()}
      {...passthough}
    ></Dynamic>
  );
}

export function Display4<E extends AnyElement>(props: TypographyProps<E>) {
  return <Typography typography={"display4"} {...props}></Typography>;
}
export function Display3<E extends AnyElement>(props: TypographyProps<E>) {
  return <Typography typography={"display3"} {...props}></Typography>;
}
export function Display2<E extends AnyElement>(props: TypographyProps<E>) {
  return <Typography typography={"display2"} {...props}></Typography>;
}
export function Display1<E extends AnyElement>(props: TypographyProps<E>) {
  return <Typography typography={"display1"} {...props}></Typography>;
}
export function Headline<E extends AnyElement>(props: TypographyProps<E>) {
  return <Typography typography={"headline"} {...props}></Typography>;
}
export function Title<E extends AnyElement>(props: TypographyProps<E>) {
  return <Typography typography={"title"} {...props}></Typography>;
}
export function Subheading<E extends AnyElement>(props: TypographyProps<E>) {
  return <Typography typography={"subheading"} {...props}></Typography>;
}
export function Body1<E extends AnyElement>(props: TypographyProps<E>) {
  return <Typography typography={"body1"} {...props}></Typography>;
}
export function Body2<E extends AnyElement>(props: TypographyProps<E>) {
  return <Typography typography={"body2"} {...props}></Typography>;
}
export function Caption<E extends AnyElement>(props: TypographyProps<E>) {
  return <Typography typography={"caption"} {...props}></Typography>;
}
export function ButtonText<E extends AnyElement>(props: TypographyProps<E>) {
  return <Typography typography={"buttonText"} {...props}></Typography>;
}
