import { forwardRef } from "react";

import {
  cardContentVariants,
  cardDescriptionVariants,
  cardFooterVariants,
  cardHeaderVariants,
  cardTitleVariants,
  cardVariants
} from "./card.variants";
import { cn } from "../lib/cn";
import type { VariantProps } from "../lib/cva";
import { createDataAttributes, createSlot } from "../lib/contracts";

export type CardProps = React.ComponentPropsWithoutRef<"div"> &
  VariantProps<typeof cardVariants>;

export const Card = forwardRef<HTMLDivElement, CardProps>(function Card(
  {
    className,
    interactive,
    tone,
    ...props
  },
  ref
) {
  return (
    <div
      {...props}
      {...createSlot("root")}
      {...createDataAttributes({
        interactive,
        tone
      })}
      className={cn(cardVariants({ interactive, tone }), className)}
      ref={ref}
    />
  );
});

export type CardHeaderProps = React.ComponentPropsWithoutRef<"div">;

export const CardHeader = forwardRef<HTMLDivElement, CardHeaderProps>(function CardHeader(
  { className, ...props },
  ref
) {
  return (
    <div
      {...props}
      {...createSlot("header")}
      className={cn(cardHeaderVariants(), className)}
      ref={ref}
    />
  );
});

export type CardTitleProps = React.ComponentPropsWithoutRef<"h3">;

export const CardTitle = forwardRef<HTMLHeadingElement, CardTitleProps>(function CardTitle(
  { className, ...props },
  ref
) {
    return (
      <h3
        {...props}
        {...createSlot("label")}
        className={cn(cardTitleVariants(), className)}
        ref={ref}
      />
    );
  }
);

export type CardDescriptionProps = React.ComponentPropsWithoutRef<"p">;

export const CardDescription = forwardRef<HTMLParagraphElement, CardDescriptionProps>(
  function CardDescription({ className, ...props }, ref) {
    return (
      <p
        {...props}
        {...createSlot("description")}
        className={cn(cardDescriptionVariants(), className)}
        ref={ref}
      />
    );
  }
);

export type CardContentProps = React.ComponentPropsWithoutRef<"div">;

export const CardContent = forwardRef<HTMLDivElement, CardContentProps>(function CardContent(
  { className, ...props },
  ref
) {
  return (
    <div
      {...props}
      {...createSlot("content")}
      className={cn(cardContentVariants(), className)}
      ref={ref}
    />
  );
});

export type CardFooterProps = React.ComponentPropsWithoutRef<"div">;

export const CardFooter = forwardRef<HTMLDivElement, CardFooterProps>(function CardFooter(
  { className, ...props },
  ref
) {
  return (
    <div
      {...props}
      {...createSlot("footer")}
      className={cn(cardFooterVariants(), className)}
      ref={ref}
    />
  );
});
