import * as React from "react"
import { cn } from "@/lib/utils"

/* ---------------------------------- Stack ---------------------------------- */
interface StackProps extends React.HTMLAttributes<HTMLDivElement> {
  direction?: "row" | "column"
  spacing?: "none" | "xs" | "sm" | "md" | "lg" | "xl"
  align?: "start" | "center" | "end" | "stretch"
  justify?: "start" | "center" | "end" | "between" | "around"
  wrap?: boolean
}

export const Stack = React.forwardRef<HTMLDivElement, StackProps>(
  (
    { className, direction = "column", spacing = "md", align = "start", justify = "start", wrap = false, ...props },
    ref,
  ) => {
    const directionClasses = {
      row: "flex-row",
      column: "flex-col",
    }

    const spacingClasses = {
      none: "gap-0",
      xs: direction === "row" ? "gap-x-1" : "gap-y-1",
      sm: direction === "row" ? "gap-x-2" : "gap-y-2",
      md: direction === "row" ? "gap-x-4" : "gap-y-4",
      lg: direction === "row" ? "gap-x-6" : "gap-y-6",
      xl: direction === "row" ? "gap-x-8" : "gap-y-8",
    }

    const alignClasses = {
      start: "items-start",
      center: "items-center",
      end: "items-end",
      stretch: "items-stretch",
    }

    const justifyClasses = {
      start: "justify-start",
      center: "justify-center",
      end: "justify-end",
      between: "justify-between",
      around: "justify-around",
    }

    return (
      <div
        ref={ref}
        className={cn(
          "flex",
          directionClasses[direction],
          spacingClasses[spacing],
          alignClasses[align],
          justifyClasses[justify],
          wrap && "flex-wrap",
          className,
        )}
        {...props}
      />
    )
  },
)
Stack.displayName = "Stack"

/* ---------------------------------- Grid ---------------------------------- */
interface GridProps extends React.HTMLAttributes<HTMLDivElement> {
  columns?: 1 | 2 | 3 | 4 | 5 | 6 | 12 | "auto-fill" | "auto-fit"
  gap?: "none" | "xs" | "sm" | "md" | "lg" | "xl"
  minChildWidth?: string
}

export const Grid = React.forwardRef<HTMLDivElement, GridProps>(
  ({ className, columns = 3, gap = "md", minChildWidth, style, ...props }, ref) => {
    const gapClasses = {
      none: "gap-0",
      xs: "gap-1",
      sm: "gap-2",
      md: "gap-4",
      lg: "gap-6",
      xl: "gap-8",
    }

    let gridTemplateColumns: string

    if (minChildWidth) {
      gridTemplateColumns = `repeat(auto-fill, minmax(${minChildWidth}, 1fr))`
    } else if (typeof columns === "number") {
      gridTemplateColumns = `repeat(${columns}, minmax(0, 1fr))`
    } else {
      gridTemplateColumns = `repeat(${columns}, minmax(0, 1fr))`
    }

    return (
      <div
        ref={ref}
        className={cn("grid", gapClasses[gap], className)}
        style={{
          gridTemplateColumns,
          ...style,
        }}
        {...props}
      />
    )
  },
)
Grid.displayName = "Grid"

/* ---------------------------------- Container ---------------------------------- */
interface ContainerProps extends React.HTMLAttributes<HTMLDivElement> {
  size?: "sm" | "md" | "lg" | "xl" | "full"
  centered?: boolean
  padded?: boolean
}

export const Container = React.forwardRef<HTMLDivElement, ContainerProps>(
  ({ className, size = "lg", centered = true, padded = true, ...props }, ref) => {
    const sizeClasses = {
      sm: "max-w-screen-sm",
      md: "max-w-screen-md",
      lg: "max-w-screen-lg",
      xl: "max-w-screen-xl",
      full: "max-w-full",
    }

    return (
      <div ref={ref} className={cn(sizeClasses[size], centered && "mx-auto", padded && "px-4", className)} {...props} />
    )
  },
)
Container.displayName = "Container"

/* ---------------------------------- Divider ---------------------------------- */
interface DividerProps extends React.HTMLAttributes<HTMLHRElement> {
  orientation?: "horizontal" | "vertical"
  decorative?: boolean
}

export const Divider = React.forwardRef<HTMLHRElement, DividerProps>(
  ({ className, orientation = "horizontal", decorative = true, ...props }, ref) => {
    return (
      <hr
        ref={ref}
        className={cn("border-border", orientation === "horizontal" ? "w-full border-t" : "h-full border-l", className)}
        aria-orientation={orientation}
        {...(decorative ? { "aria-hidden": true } : {})}
        {...props}
      />
    )
  },
)
Divider.displayName = "Divider"
