"use client"

import * as CollapsiblePrimitive from "@radix-ui/react-collapsible"
import React, { ComponentRef, forwardRef } from "react"
import { ChevronLeft, IconProps } from "../../icons"
import { disabledVariants } from "../../styles"
import { classNames, tv } from "../../utils"
import { UnstyledButton } from "../UnstyledButton"

export type CollapsibleProps = Omit<
  CollapsiblePrimitive.CollapsibleProps,
  "content"
> &
  Omit<CollapsiblePrimitive.CollapsibleTriggerProps, "content"> & {
    content: React.ReactNode
    size?: "sm" | "md" | "lg"
    locked?: boolean
    overrides?: {
      Icon?: IconProps
    }
    toggleClosedDirection?: "down" | "right"
  }

const collapsibleVariants = tv({
  base: classNames(
    "flex justify-between focus:outline-hidden",
    "transition-colors duration-150 ease-out-quint",
    "text-text-secondary hover:text-text-primary",
    "[&[data-state=open]]:text-text-primary",
  ),
  variants: {
    size: {
      sm: "gap-0.5 text-xs",
      md: "gap-1 text-sm",
      lg: "gap-0.5 text-md",
    },
    disabled: {
      true: disabledVariants({ disabled: true }),
    },
    toggleClosedDirection: {
      down: "[&[data-state=closed]>svg]:-rotate-90 [&[data-state=open]>svg]:rotate-90",
      right:
        "[&[data-state=closed]>svg]:rotate-180 [&[data-state=open]>svg]:rotate-270",
    },
  },
})

/**
 * An interactive component which expands/collapses a panel. This is a low-level component that other
 * collapsibles/panels build on top of.
 */
export const Collapsible = forwardRef<
  ComponentRef<typeof CollapsiblePrimitive.CollapsibleTrigger>,
  CollapsibleProps
>(function Collapsible(
  {
    children,
    className,
    content,
    disabled,
    size = "md",
    defaultOpen,
    open,
    onOpenChange,
    locked,
    toggleClosedDirection = "down",
    overrides,
    ...rest
  },
  ref,
) {
  return (
    <CollapsiblePrimitive.Root
      defaultOpen={defaultOpen}
      disabled={disabled}
      open={open}
      onOpenChange={onOpenChange}
    >
      <CollapsiblePrimitive.CollapsibleTrigger asChild>
        <UnstyledButton
          className={classNames(
            collapsibleVariants({ disabled, size, toggleClosedDirection }),
            locked && "pointer-events-none",
            className,
          )}
          disabled={disabled}
          {...rest}
          ref={ref}
        >
          {children}
          {!locked && (
            <ChevronLeft
              size={size === "sm" ? 16 : size === "md" ? 20 : 24}
              {...overrides?.Icon}
              className={classNames(
                "transition duration-150 ease-out-quint",
                overrides?.Icon?.className,
              )}
            />
          )}
        </UnstyledButton>
      </CollapsiblePrimitive.CollapsibleTrigger>
      <CollapsiblePrimitive.CollapsibleContent>
        {content}
      </CollapsiblePrimitive.CollapsibleContent>
    </CollapsiblePrimitive.Root>
  )
})
